summaryrefslogtreecommitdiff
path: root/web
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2023-12-04 03:01:04 +0000
committerNorbert Preining <norbert@preining.info>2023-12-04 03:01:04 +0000
commitdb0fe20663f1bcb3fcf87c3fb05a727420edd203 (patch)
treee5abdee7535ece54123168f0fa9a21fa0a627464 /web
parentde2c50ca7889fda13da11c1ccf6bdbd199ba8c2b (diff)
CTAN sync 202312040301
Diffstat (limited to 'web')
-rw-r--r--web/c_cpp/cweb/Makefile27
-rw-r--r--web/c_cpp/cweb/README1
-rw-r--r--web/c_cpp/cweb/comm-mac.ch4
-rw-r--r--web/c_cpp/cweb/comm-ql.ch20
-rw-r--r--web/c_cpp/cweb/common.c151
-rw-r--r--web/c_cpp/cweb/common.h6
-rw-r--r--web/c_cpp/cweb/common.w45
-rw-r--r--web/c_cpp/cweb/ctang-bs.ch10
-rw-r--r--web/c_cpp/cweb/ctang-pc.ch4
-rw-r--r--web/c_cpp/cweb/ctang-ql.ch8
-rw-r--r--web/c_cpp/cweb/ctang-vms.ch4
-rw-r--r--web/c_cpp/cweb/ctang-w32.ch4
-rw-r--r--web/c_cpp/cweb/ctangle.c297
-rw-r--r--web/c_cpp/cweb/ctangle.w76
-rw-r--r--web/c_cpp/cweb/cweav-bs.ch10
-rw-r--r--web/c_cpp/cweb/cweav-pc.ch4
-rw-r--r--web/c_cpp/cweb/cweav-ql.ch8
-rw-r--r--web/c_cpp/cweb/cweav-vms.ch4
-rw-r--r--web/c_cpp/cweb/cweav-w32.ch4
-rw-r--r--web/c_cpp/cweb/cweave.w141
-rw-r--r--web/c_cpp/cweb/cweb.14
-rw-r--r--web/c_cpp/cweb/cwebacromac.tex175
-rw-r--r--web/c_cpp/cweb/cwebmac.tex206
-rw-r--r--web/c_cpp/cweb/cwebman.pdfbin346283 -> 347143 bytes
-rw-r--r--web/c_cpp/cweb/cwebman.tex65
-rw-r--r--web/c_cpp/cweb/prod.w2
-rw-r--r--web/pwebmac/README.md18
-rw-r--r--web/pwebmac/index.md2
-rwxr-xr-xweb/pwebmac/makeall176
-rw-r--r--web/pwebmac/pwebmac.tex39
-rw-r--r--web/pwebmac/webman.ch328
31 files changed, 1041 insertions, 802 deletions
diff --git a/web/c_cpp/cweb/Makefile b/web/c_cpp/cweb/Makefile
index c547ef9154..28ea97d554 100644
--- a/web/c_cpp/cweb/Makefile
+++ b/web/c_cpp/cweb/Makefile
@@ -1,6 +1,6 @@
# This file is part of CWEB.
# It is distributed WITHOUT ANY WARRANTY, express or implied.
-# Version 4.10 --- August 2023
+# Version 4.11 --- December 2023
# Copyright (C) 1987,1990,1993,2000 Silvio Levy and Donald E. Knuth
@@ -69,6 +69,7 @@ PDFTEX = dvipdfm
#PDFTEX = pdftex
#PDFTEX = xetex
#PDFTEX = hitex
+#PDFTEX = luatex
########## You shouldn't have to change anything after this point #######
@@ -77,15 +78,17 @@ CTANGLE = ./ctangle
SOURCES = cweave.w common.w ctangle.w
ALL = common.w ctangle.w cweave.w prod.w \
Makefile README common.c common.h ctangle.c \
- cwebman.tex cwebmac.tex comm-vms.ch ctang-vms.ch \
- cweav-vms.ch comm-man.ch ctang-man.ch cweav-man.ch \
- comm-pc.ch ctang-pc.ch cweav-pc.ch comm-amiga.ch \
+ cwebman.tex cwebacromac.tex cwebmac.tex \
+ cweb.1 cweb.el c++lib.w iso_types.w \
+ comm-man.ch ctang-man.ch cweav-man.ch \
comm-bs.ch ctang-bs.ch cweav-bs.ch makefile.bs \
+ comm-pc.ch ctang-pc.ch cweav-pc.ch comm-amiga.ch \
comm-ql.ch ctang-ql.ch cweav-ql.ch readme.ql \
+ comm-vms.ch ctang-vms.ch cweav-vms.ch \
comm-w32.ch ctang-w32.ch cweav-w32.ch \
- comm-os2.ch comm-mac.ch cweb.1 cweb.el c++lib.w iso_types.w
+ comm-os2.ch comm-mac.ch
-.SUFFIXES: .dvi .tex .w .pdf
+.SUFFIXES: .dvi .tex .w .pdf .hnt
.w.tex:
$(CWEAVE) $*
@@ -110,6 +113,12 @@ ALL = common.w ctangle.w cweave.w prod.w \
dvipdfm ) tex "\let\pdf+ \input $*"; dvipdfm $* ;; \
pdftex ) pdftex $* ;; \
xetex ) xetex $* ;; \
+ luatex ) luatex $* ;; \
+ esac
+
+.w.hnt:
+ make $*.tex
+ case "$(PDFTEX)" in \
hitex ) hitex $* ;; \
esac
@@ -178,6 +187,8 @@ install: all
$(CP) cweb.1 $(MANDIR)/cweb.$(MANEXT)
chmod 644 $(MANDIR)/cweb.$(MANEXT)
- mkdir $(MACROSDIR)
+ $(CP) cwebacromac.tex $(MACROSDIR)
+ chmod 644 $(MACROSDIR)/cwebacromac.tex
$(CP) cwebmac.tex $(MACROSDIR)
chmod 644 $(MACROSDIR)/cwebmac.tex
- mkdir $(EMACSDIR)
@@ -205,6 +216,6 @@ tarball:
tar zcvhf /tmp/cweb.tgz $(ALL) examples
ctan:
- git archive -o ~/cweb-4.10.zip --prefix=cweb/ cweb-4.10
+ git archive -o ~/cweb-4.11.zip --prefix=cweb/ cweb-4.11
make PDF=pdf usermanual
- cd ..; zip -r ~/cweb-4.10.zip cweb/cwebman.pdf
+ cd ..; zip -r ~/cweb-4.11.zip cweb/cwebman.pdf
diff --git a/web/c_cpp/cweb/README b/web/c_cpp/cweb/README
index e2caca4133..086f6af308 100644
--- a/web/c_cpp/cweb/README
+++ b/web/c_cpp/cweb/README
@@ -59,6 +59,7 @@ cweave-w32.ch
cweave.w
cweb.1
cweb.el
+cwebacromac.tex
cwebmac.tex
cwebman.tex
examples/
diff --git a/web/c_cpp/cweb/comm-mac.ch b/web/c_cpp/cweb/comm-mac.ch
index 83df560cb4..79b1ec945e 100644
--- a/web/c_cpp/cweb/comm-mac.ch
+++ b/web/c_cpp/cweb/comm-mac.ch
@@ -4,9 +4,9 @@ No changes to CTANGLE or CWEAVE are needed.
(Contributed 13 Oct 2000 by AndPio@aol.com; slightly edited by Don Knuth)
@x in limbo, change the title page document to specify Mac version
- \centerline{(Version 4.10)}
+ \centerline{(Version 4.11)}
@y
- \centerline{(Version 4.10 for MacOS)}
+ \centerline{(Version 4.11 for MacOS)}
@z
@x section 23: Make input_ln accept \n, \r, \n\r, or \r\n as line endings
diff --git a/web/c_cpp/cweb/comm-ql.ch b/web/c_cpp/cweb/comm-ql.ch
index 592c7e04a1..44cc39ec45 100644
--- a/web/c_cpp/cweb/comm-ql.ch
+++ b/web/c_cpp/cweb/comm-ql.ch
@@ -10,24 +10,24 @@ ex <dev_>cc;'-v -h -c -=500000 -DCWEBINPUTS=flp2_ common_c'
@x
\def\v{\char'174} % vertical (|) in typewriter font
-\def\title{Common code for CTANGLE and CWEAVE (Version 4.10)}
+\def\title{Common code for CTANGLE and CWEAVE (Version 4.11)}
\def\topofcontents{\null\vfill
\centerline{\titlefont Common code for {\ttitlefont CTANGLE} and
{\ttitlefont CWEAVE}}
\vskip 15pt
- \centerline{(Version 4.10)}
+ \centerline{(Version 4.11)}
\vfill}
\def\botofcontents{\vfill
\noindent
@y
\def\v{\char'174} % vertical (|) in typewriter font
-\def\title{Common code for CTANGLE and CWEAVE (QL Version 4.10)}
+\def\title{Common code for CTANGLE and CWEAVE (QL Version 4.11)}
\def\topofcontents{\null\vfill
\centerline{\titlefont Common code for {\ttitlefont CTANGLE} and
{\ttitlefont CWEAVE}}
\vskip 15pt
- \centerline{(Version 4.10)}
+ \centerline{(Version 4.11)}
\vfill}
\def\botofcontents{\vfill
\noindent
@@ -152,8 +152,10 @@ the routine as if it would work.
}
sprintf(alt_web_file_name,"%s.web",*argv);
sprintf(tex_file_name,"%s.tex",name_pos); /* strip off directory name */
- sprintf(idx_file_name,"%s.idx",name_pos);
- sprintf(scn_file_name,"%s.scn",name_pos);
+ if (make_xrefs) { /* indexes will be generated */
+ sprintf(idx_file_name,"%s.idx",name_pos);
+ sprintf(scn_file_name,"%s.scn",name_pos);
+ }
sprintf(C_file_name,"%s.c",name_pos);
found_web=true;
}
@@ -170,8 +172,10 @@ the routine as if it would work.
}
sprintf(alt_web_file_name,"%s_web",*argv);
sprintf(tex_file_name,"%s_tex",name_pos); /* strip off directory name */
- sprintf(idx_file_name,"%s_idx",name_pos);
- sprintf(scn_file_name,"%s_scn",name_pos);
+ if (make_xrefs) { /* indexes will be generated */
+ sprintf(idx_file_name,"%s_idx",name_pos);
+ sprintf(scn_file_name,"%s_scn",name_pos);
+ }
sprintf(C_file_name,"%s_c",name_pos);
found_web=true;
}
diff --git a/web/c_cpp/cweb/common.c b/web/c_cpp/cweb/common.c
index ccedc5e914..4c9ad7c198 100644
--- a/web/c_cpp/cweb/common.c
+++ b/web/c_cpp/cweb/common.c
@@ -197,7 +197,7 @@ extern name_pointer name_dir_end;
extern name_pointer name_ptr;
extern name_pointer hash[];
extern hash_pointer hash_end;
-extern hash_pointer h;
+extern hash_pointer hash_ptr;
/*:10*//*12:*/
#line 193 "common.h"
@@ -302,17 +302,17 @@ name_pointer name_ptr;
/*:44*//*46:*/
#line 621 "common.w"
-name_pointer hash[hash_size];
+name_pointer hash[hash_size]= {NULL};
hash_pointer hash_end= hash+hash_size-1;
-hash_pointer h;
+hash_pointer hash_ptr;
/*:46*//*65:*/
-#line 1002 "common.w"
+#line 999 "common.w"
int history= spotless;
/*:65*//*73:*/
-#line 1125 "common.w"
+#line 1124 "common.w"
int argc;
char**argv;
@@ -323,7 +323,7 @@ char scn_file_name[max_file_name_length];
boolean flags[128];
/*:73*//*83:*/
-#line 1266 "common.w"
+#line 1267 "common.w"
FILE*C_file;
FILE*tex_file;
@@ -383,18 +383,18 @@ static void prime_the_change_buffer(void);
static void check_change(void);
/*:33*//*55:*/
-#line 763 "common.w"
+#line 760 "common.w"
static int web_strcmp(char*,size_t,char*,size_t);
static name_pointer add_section_name(name_pointer,int,char*,char*,boolean);
static void extend_section_name(name_pointer,char*,char*,boolean);
/*:55*//*64:*/
-#line 990 "common.w"
+#line 987 "common.w"
static int section_name_cmp(char**,size_t,name_pointer);
/*:64*//*76:*/
-#line 1185 "common.w"
+#line 1184 "common.w"
static void scan_args(void);
/*:76*/
@@ -415,16 +415,11 @@ name_ptr= name_dir+1;
name_ptr->byte_start= byte_mem;
root= NULL;
-/*:45*//*47:*/
-#line 628 "common.w"
-
-for(h= hash;h<=hash_end;*h++= NULL);
-
-/*:47*/
+/*:45*/
#line 99 "common.w"
/*74:*/
-#line 1138 "common.w"
+#line 1137 "common.w"
show_banner= show_happiness= show_progress= make_xrefs= true;
@@ -432,7 +427,7 @@ show_banner= show_happiness= show_progress= make_xrefs= true;
#line 100 "common.w"
/*84:*/
-#line 1273 "common.w"
+#line 1274 "common.w"
scan_args();
if(program==ctangle){
@@ -776,7 +771,7 @@ limit= buffer;loc= buffer+1;buffer[0]= ' ';input_has_ended= false;
}
/*:40*//*48:*/
-#line 633 "common.w"
+#line 630 "common.w"
name_pointer
id_lookup(
@@ -791,17 +786,17 @@ name_pointer p;
if(last==NULL)for(last= first;*last!='\0';last++);
l= (size_t)(last-first);
/*49:*/
-#line 656 "common.w"
+#line 653 "common.w"
h= (int)((eight_bits)*i);
while(++i<last)h= (h+h+(int)((eight_bits)*i))%hash_size;
/*:49*/
-#line 646 "common.w"
+#line 643 "common.w"
/*50:*/
-#line 664 "common.w"
+#line 661 "common.w"
p= hash[h];
while(p&&!names_match(p,first,l,t))p= p->link;
@@ -811,10 +806,10 @@ p->link= hash[h];hash[h]= p;
}
/*:50*/
-#line 647 "common.w"
+#line 644 "common.w"
if(p==name_ptr)/*51:*/
-#line 675 "common.w"
+#line 672 "common.w"
{
if(byte_ptr+l> byte_mem_end)overflow("byte memory");
if(name_ptr>=name_dir_end)overflow("name");
@@ -824,13 +819,13 @@ if(program==cweave)p->ilk= t,init_node(p);
}
/*:51*/
-#line 648 "common.w"
+#line 645 "common.w"
return p;
}
/*:48*//*52:*/
-#line 707 "common.w"
+#line 704 "common.w"
void
print_section_name(
@@ -849,7 +844,7 @@ if(q)term_write("...",3);
}
/*:52*//*53:*/
-#line 724 "common.w"
+#line 721 "common.w"
void
sprint_section_name(
@@ -869,7 +864,7 @@ s= p->byte_start;
}
/*:53*//*54:*/
-#line 742 "common.w"
+#line 739 "common.w"
void
print_prefix_name(
@@ -882,7 +877,7 @@ if(s+l<(p+1)->byte_start)term_write("...",3);
}
/*:54*//*56:*/
-#line 768 "common.w"
+#line 765 "common.w"
static int web_strcmp(
char*j,
@@ -900,7 +895,7 @@ else return greater;
}
/*:56*//*57:*/
-#line 797 "common.w"
+#line 794 "common.w"
static name_pointer
add_section_name(
@@ -930,7 +925,7 @@ return par==NULL?(root= p):c==less?(par->llink= p):(par->rlink= p);
}
/*:57*//*58:*/
-#line 825 "common.w"
+#line 822 "common.w"
static void
extend_section_name(
@@ -954,7 +949,7 @@ if(ispref)*(byte_ptr-1)= ' ';
}
/*:58*//*59:*/
-#line 853 "common.w"
+#line 850 "common.w"
name_pointer
section_lookup(
@@ -969,7 +964,7 @@ name_pointer par= NULL;
size_t name_len= (size_t)(last-first+1);
/*60:*/
-#line 877 "common.w"
+#line 874 "common.w"
while(p){
c= web_strcmp(first,name_len,first_chunk(p),prefix_length(p));
@@ -979,10 +974,10 @@ par= p;
p= (c==less?p->llink:p->rlink);
}else{
if(r!=NULL){
-fputs("\n! Ambiguous prefix: matches <",stdout);
+printf("%s","\n! Ambiguous prefix: matches <");
print_prefix_name(p);
-fputs(">\n and <",stdout);
+printf("%s",">\n and <");
print_prefix_name(r);
err_print(">");
return name_dir;
@@ -996,25 +991,25 @@ p= q,q= NULL;
}
/*:60*/
-#line 867 "common.w"
+#line 864 "common.w"
/*61:*/
-#line 902 "common.w"
+#line 899 "common.w"
if(r==NULL)
return add_section_name(par,c,first,last+1,ispref);
/*:61*/
-#line 868 "common.w"
+#line 865 "common.w"
/*62:*/
-#line 910 "common.w"
+#line 907 "common.w"
switch(section_name_cmp(&first,name_len,r)){
case prefix:
if(!ispref){
-fputs("\n! New name is a prefix of <",stdout);
+printf("%s","\n! New name is a prefix of <");
print_section_name(r);
err_print(">");
@@ -1026,28 +1021,28 @@ case extension:if(!ispref||first<=last)
extend_section_name(r,first,last+1,ispref);
break;
case bad_extension:
-fputs("\n! New name extends <",stdout);
+printf("%s","\n! New name extends <");
print_section_name(r);
err_print(">");
break;
default:
-fputs("\n! Section name incompatible with <",stdout);
+printf("%s","\n! Section name incompatible with <");
print_prefix_name(r);
-fputs(">,\n which abbreviates <",stdout);
+printf("%s",">,\n which abbreviates <");
print_section_name(r);
err_print(">");
}
return r;
/*:62*/
-#line 869 "common.w"
+#line 866 "common.w"
}
/*:59*//*63:*/
-#line 958 "common.w"
+#line 955 "common.w"
static int section_name_cmp(
char**pfirst,
@@ -1081,21 +1076,23 @@ default:return c;
}
/*:63*//*66:*/
-#line 1012 "common.w"
+#line 1009 "common.w"
void
err_print(
const char*s)
{
-*s=='!'?printf("\n%s",s):printf("%s",s);
+printf(*s=='!'?"\n%s":"%s",s);
if(web_file_open)/*67:*/
-#line 1031 "common.w"
+#line 1028 "common.w"
{char*k,*l;
-if(changing&&include_depth==change_depth)
+if(changing&&include_depth==change_depth&&change_line> 0)
printf(". (l. %d of change file)\n",change_line);
-else if(include_depth==0)printf(". (l. %d)\n",cur_line);
+else if(cur_line> 0){
+if(include_depth==0)printf(". (l. %d)\n",cur_line);
else printf(". (l. %d of include file %s)\n",cur_line,cur_file_name);
+}
l= (loc>=limit?limit:loc);
if(l> buffer){
for(k= buffer;k<l;k++)
@@ -1110,20 +1107,20 @@ putchar(' ');
}
/*:67*/
-#line 1018 "common.w"
+#line 1015 "common.w"
update_terminal();mark_error();
}
/*:66*//*68:*/
-#line 1064 "common.w"
+#line 1063 "common.w"
int wrap_up(void){
-if(show_progress)new_line();
+if(show_progress||show_happiness||history!=spotless)new_line();
if(show_stats)
print_stats();
/*69:*/
-#line 1074 "common.w"
+#line 1073 "common.w"
switch(history){
case spotless:
@@ -1137,25 +1134,25 @@ puts("(That was a fatal error, my friend.)");
}
/*:69*/
-#line 1069 "common.w"
+#line 1068 "common.w"
if(history> harmless_message)return EXIT_FAILURE;
else return EXIT_SUCCESS;
}
/*:68*//*70:*/
-#line 1092 "common.w"
+#line 1091 "common.w"
void
fatal(
const char*s,const char*t)
{
-if(*s)err_print(s);
+if(*s)printf("%s",s);
err_print(t);
history= fatal_message;exit(wrap_up());
}
/*:70*//*71:*/
-#line 1103 "common.w"
+#line 1102 "common.w"
void
overflow(
const char*t)
@@ -1165,7 +1162,7 @@ printf("\n! Sorry, %s capacity exceeded",t);fatal("","");
/*:71*//*75:*/
-#line 1156 "common.w"
+#line 1155 "common.w"
static void
scan_args(void)
@@ -1179,13 +1176,13 @@ boolean found_web= false,found_change= false,found_out= false;
strcpy(change_file_name,"/dev/null");
while(--argc> 0){
if((**(++argv)=='-'||**argv=='+')&&*(*argv+1))/*80:*/
-#line 1244 "common.w"
+#line 1245 "common.w"
for(dot_pos= *argv+1;*dot_pos> '\0';dot_pos++)
flags[(eight_bits)*dot_pos]= flag_change;
/*:80*/
-#line 1168 "common.w"
+#line 1167 "common.w"
else{
s= name_pos= *argv;dot_pos= NULL;
@@ -1194,17 +1191,17 @@ if(*s=='.')dot_pos= s++;
else if(*s=='/')dot_pos= NULL,name_pos= ++s;
else s++;
if(!found_web)/*77:*/
-#line 1194 "common.w"
+#line 1193 "common.w"
{
if(s-*argv> max_file_name_length-5)
/*82:*/
-#line 1260 "common.w"
+#line 1261 "common.w"
fatal("! Filename too long\n",*argv);
/*:82*/
-#line 1197 "common.w"
+#line 1196 "common.w"
if(dot_pos==NULL)
sprintf(web_file_name,"%s.w",*argv);
@@ -1214,28 +1211,30 @@ strcpy(web_file_name,*argv);
}
sprintf(alt_web_file_name,"%s.web",*argv);
sprintf(tex_file_name,"%s.tex",name_pos);
+if(make_xrefs){
sprintf(idx_file_name,"%s.idx",name_pos);
sprintf(scn_file_name,"%s.scn",name_pos);
+}
sprintf(C_file_name,"%s.c",name_pos);
found_web= true;
}
/*:77*/
-#line 1176 "common.w"
+#line 1175 "common.w"
else if(!found_change)/*78:*/
-#line 1212 "common.w"
+#line 1213 "common.w"
{
if(strcmp(*argv,"-")!=0){
if(s-*argv> max_file_name_length-4)
/*82:*/
-#line 1260 "common.w"
+#line 1261 "common.w"
fatal("! Filename too long\n",*argv);
/*:82*/
-#line 1216 "common.w"
+#line 1217 "common.w"
if(dot_pos==NULL)
sprintf(change_file_name,"%s.ch",*argv);
@@ -1245,20 +1244,20 @@ found_change= true;
}
/*:78*/
-#line 1177 "common.w"
+#line 1176 "common.w"
else if(!found_out)/*79:*/
-#line 1224 "common.w"
+#line 1225 "common.w"
{
if(s-*argv> max_file_name_length-5)
/*82:*/
-#line 1260 "common.w"
+#line 1261 "common.w"
fatal("! Filename too long\n",*argv);
/*:82*/
-#line 1227 "common.w"
+#line 1228 "common.w"
if(dot_pos==NULL){
sprintf(tex_file_name,"%s.tex",*argv);
@@ -1276,10 +1275,10 @@ found_out= true;
}
/*:79*/
-#line 1178 "common.w"
+#line 1177 "common.w"
else/*81:*/
-#line 1248 "common.w"
+#line 1249 "common.w"
{
if(program==ctangle)
@@ -1293,12 +1292,12 @@ else fatal(
}
/*:81*/
-#line 1179 "common.w"
+#line 1178 "common.w"
}
}
if(!found_web)/*81:*/
-#line 1248 "common.w"
+#line 1249 "common.w"
{
if(program==ctangle)
@@ -1312,7 +1311,7 @@ else fatal(
}
/*:81*/
-#line 1182 "common.w"
+#line 1181 "common.w"
}
diff --git a/web/c_cpp/cweb/common.h b/web/c_cpp/cweb/common.h
index 4104965917..97fda82e75 100644
--- a/web/c_cpp/cweb/common.h
+++ b/web/c_cpp/cweb/common.h
@@ -2,7 +2,7 @@
% This program by Silvio Levy and Donald E. Knuth
% is based on a program by Knuth.
% It is distributed WITHOUT ANY WARRANTY, express or implied.
-% Version 4.10 --- August 2023 (works also with later versions)
+% Version 4.11 --- December 2023 (works also with later versions)
% Copyright (C) 1987,1990,1993 Silvio Levy and Donald E. Knuth
@@ -41,7 +41,7 @@ extern int phase; /* which phase are we in? */
@ The procedure that gets everything rolling:
@<Predecl...@>=
-extern void common_init(void);@/
+extern void common_init(void);
@ Interface to the standard \CEE/ library:
@@ -166,7 +166,7 @@ extern name_pointer name_dir_end; /* end of |name_dir| */
extern name_pointer name_ptr; /* first unused position in |name_dir| */
extern name_pointer hash[]; /* heads of hash lists */
extern hash_pointer hash_end; /* end of |hash| */
-extern hash_pointer h; /* index into hash-head array */
+extern hash_pointer hash_ptr; /* index into hash-head array */
@ @<Predecl...@>=
extern name_pointer id_lookup(const char *,const char *,eight_bits);
diff --git a/web/c_cpp/cweb/common.w b/web/c_cpp/cweb/common.w
index dbcd57e31f..88932f3118 100644
--- a/web/c_cpp/cweb/common.w
+++ b/web/c_cpp/cweb/common.w
@@ -2,7 +2,7 @@
% This program by Silvio Levy and Donald E. Knuth
% is based on a program by Knuth.
% It is distributed WITHOUT ANY WARRANTY, express or implied.
-% Version 4.10 --- August 2023
+% Version 4.11 --- December 2023
% Copyright (C) 1987,1990,1993,2000 Silvio Levy and Donald E. Knuth
@@ -22,12 +22,12 @@
\def\v{\char'174} % vertical (|) in typewriter font
-\def\title{Common code for CTANGLE and CWEAVE (Version 4.10)}
+\def\title{Common code for CTANGLE and CWEAVE (Version 4.11)}
\def\topofcontents{\null\vfill
\centerline{\titlefont Common code for {\ttitlefont CTANGLE} and
{\ttitlefont CWEAVE}}
\vskip 15pt
- \centerline{(Version 4.10)}
+ \centerline{(Version 4.11)}
\vfill}
\def\botofcontents{\vfill
\noindent
@@ -619,15 +619,12 @@ it is inserted into the table.
@d hash_size 353 /* should be prime */
@<Global var...@>=
-name_pointer hash[hash_size]; /* heads of hash lists */
+name_pointer hash[hash_size]={NULL}; /* heads of hash lists */
hash_pointer hash_end = hash+hash_size-1; /* end of |hash| */
-hash_pointer h; /* index into hash-head array */
+hash_pointer hash_ptr; /* index into hash-head array */
@ Initially all the hash lists are empty.
-@<Init...@>=
-for (h=hash; h<=hash_end; *h++=NULL) ;
-
@ Here is the main procedure for finding identifiers:
@c
@@ -638,7 +635,7 @@ const char *last, /* last character of string plus one */
eight_bits t) /* the |ilk|; used by \.{CWEAVE} only */
{
const char *i=first; /* position in |buffer| */
- int h; /* hash code; shadows |hash_pointer h| */
+ int h; /* hash code */
size_t l; /* length of the given identifier */
name_pointer p; /* where the identifier is being sought */
if (last==NULL) for (last=first; *last!='\0'; last++);
@@ -883,10 +880,10 @@ while (p) { /* compare shortest prefix of |p| with new name */
p=(c==less?p->llink:p->rlink);
} else { /* new name matches |p| */
if (r!=NULL) { /* and also |r|: illegal */
- fputs("\n! Ambiguous prefix: matches <",stdout);
+ printf("%s","\n! Ambiguous prefix: matches <");
@.Ambiguous prefix ... @>
print_prefix_name(p);
- fputs(">\n and <",stdout);
+ printf("%s",">\n and <");
print_prefix_name(r);
err_print(">");
return name_dir; /* the unsection */
@@ -912,7 +909,7 @@ switch(section_name_cmp(&first,name_len,r)) {
/* compare all of |r| with new name */
case prefix:
if (!ispref) {
- fputs("\n! New name is a prefix of <",stdout);
+ printf("%s","\n! New name is a prefix of <");
@.New name is a prefix...@>
print_section_name(r);
err_print(">");
@@ -924,16 +921,16 @@ switch(section_name_cmp(&first,name_len,r)) {
extend_section_name(r,first,last+1,ispref);
break;
case bad_extension:
- fputs("\n! New name extends <",stdout);
+ printf("%s","\n! New name extends <");
@.New name extends...@>
print_section_name(r);
err_print(">");
break;
default: /* no match: illegal */
- fputs("\n! Section name incompatible with <",stdout);
+ printf("%s","\n! Section name incompatible with <");
@.Section name incompatible...@>
print_prefix_name(r);
- fputs(">,\n which abbreviates <",stdout);
+ printf("%s",">,\n which abbreviates <");
print_section_name(r);
err_print(">");
}
@@ -1014,7 +1011,7 @@ void
err_print( /* prints `\..' and location of error message */
const char *s)
{
- *s=='!'? printf("\n%s",s) : printf("%s",s);
+ printf(*s=='!' ? "\n%s" : "%s",s);
if (web_file_open) @<Print error location based on input buffer@>@;
update_terminal(); mark_error();
}
@@ -1030,10 +1027,12 @@ has special line-numbering conventions.
@<Print error location based on input buffer@>=
{char *k,*l; /* pointers into |buffer| */
-if (changing && include_depth==change_depth)
+if (changing && include_depth==change_depth && change_line>0)
printf(". (l. %d of change file)\n", change_line);
-else if (include_depth==0) printf(". (l. %d)\n", cur_line);
+else if (cur_line>0) {
+ if (include_depth==0) printf(". (l. %d)\n", cur_line);
else printf(". (l. %d of include file %s)\n", cur_line, cur_file_name);
+}
l= (loc>=limit? limit: loc);
if (l>buffer) {
for (k=buffer; k<l; k++)
@@ -1063,7 +1062,7 @@ a status of |EXIT_SUCCESS| if and only if only harmless messages were printed.
@c
int wrap_up(void) {
- if (show_progress) new_line();
+ if (show_progress || show_happiness || history != spotless) new_line();
if (show_stats)
print_stats(); /* print statistics about memory usage */
@<Print the job |history|@>@;
@@ -1093,7 +1092,7 @@ concatenated to print the final error message.
fatal(
const char *s,const char *t)
{
- if (*s) err_print(s);
+ if (*s) printf("%s",s);
err_print(t);
history=fatal_message; exit(wrap_up());
}
@@ -1203,8 +1202,10 @@ after the dot. We must check that there is enough room in
}
sprintf(alt_web_file_name,"%s.web",*argv);
sprintf(tex_file_name,"%s.tex",name_pos); /* strip off directory name */
- sprintf(idx_file_name,"%s.idx",name_pos);
- sprintf(scn_file_name,"%s.scn",name_pos);
+ if (make_xrefs) { /* indexes will be generated */
+ sprintf(idx_file_name,"%s.idx",name_pos);
+ sprintf(scn_file_name,"%s.scn",name_pos);
+ }
sprintf(C_file_name,"%s.c",name_pos);
found_web=true;
}
diff --git a/web/c_cpp/cweb/ctang-bs.ch b/web/c_cpp/cweb/ctang-bs.ch
index 6c6331c0c7..c70a87fe1d 100644
--- a/web/c_cpp/cweb/ctang-bs.ch
+++ b/web/c_cpp/cweb/ctang-bs.ch
@@ -17,12 +17,12 @@ by using "huge" pointers.
The ``banner line'' defined here should be changed whenever \.{CTANGLE}
is modified.
-@d banner "This is CTANGLE (Version 4.10)"
+@d banner "This is CTANGLE (Version 4.11)"
@y
The ``banner line'' defined here should be changed whenever \.{CTANGLE}
is modified.
-@d banner "This is CTANGLE (Version 4.10pc/big)"
+@d banner "This is CTANGLE (Version 4.11pc/big)"
@z
@@ -48,9 +48,6 @@ extern char *byte_ptr; /* first unused position in |byte_mem| */
extern name_info name_dir[]; /* information about names */
extern name_pointer name_dir_end; /* end of |name_dir| */
extern name_pointer name_ptr; /* first unused position in |name_dir| */
-extern name_pointer hash[]; /* heads of hash lists */
-extern hash_pointer hash_end; /* end of |hash| */
-extern hash_pointer h; /* index into hash-head array */
@y
@d ilk dummy.Ilk /* used by \.{CWEAVE} only */
@@ -78,9 +75,6 @@ extern name_info name_dir[]; /* information about names */
extern name_pointer name_dir_end; /* end of |name_dir| */
extern name_pointer name_ptr; /* first unused position in |name_dir| */
extern char huge* byte_ptr; /* first unused position in |byte_mem| */
-extern name_pointer hash[]; /* heads of hash lists */
-extern hash_pointer hash_end; /* end of |hash| */
-extern hash_pointer h; /* index into hash-head array */
@z
diff --git a/web/c_cpp/cweb/ctang-pc.ch b/web/c_cpp/cweb/ctang-pc.ch
index 25d62cdb6b..3e6e7ac5ef 100644
--- a/web/c_cpp/cweb/ctang-pc.ch
+++ b/web/c_cpp/cweb/ctang-pc.ch
@@ -9,9 +9,9 @@ that allows >64K arrays. If you need lots of bytes and toks, try the
alternate change files with -bs suffix instead of -pc.
@x section 1
-@d banner "This is CTANGLE (Version 4.10)"
+@d banner "This is CTANGLE (Version 4.11)"
@y
-@d banner "This is CTANGLE (Version 4.10pc)"
+@d banner "This is CTANGLE (Version 4.11pc)"
@z
@x section 17
@d max_bytes 100000 /* the number of bytes in identifiers,
diff --git a/web/c_cpp/cweb/ctang-ql.ch b/web/c_cpp/cweb/ctang-ql.ch
index 91aa24fff2..8072aff51a 100644
--- a/web/c_cpp/cweb/ctang-ql.ch
+++ b/web/c_cpp/cweb/ctang-ql.ch
@@ -7,15 +7,15 @@ ex <dev_>cc;"-v -h -c -=500000 ctangle_c"
@x
-\def\title{CTANGLE (Version 4.10)}
+\def\title{CTANGLE (Version 4.11)}
@y
-\def\title{CTANGLE (QL Version 4.10)}
+\def\title{CTANGLE (QL Version 4.11)}
@z
@x section 1
-@d banner "This is CTANGLE (Version 4.10)"
+@d banner "This is CTANGLE (Version 4.11)"
@y
-@d banner "This is CTANGLE (QL Version 4.10)"
+@d banner "This is CTANGLE (QL Version 4.11)"
@z
@x
diff --git a/web/c_cpp/cweb/ctang-vms.ch b/web/c_cpp/cweb/ctang-vms.ch
index 9e311d3aa3..2c4df3bf60 100644
--- a/web/c_cpp/cweb/ctang-vms.ch
+++ b/web/c_cpp/cweb/ctang-vms.ch
@@ -10,9 +10,9 @@ created:
(these changes not necessary for initial bootstrapping)
@x section 1 (01-FEB-1992 ST)
-@d banner "This is CTANGLE (Version 4.10)"
+@d banner "This is CTANGLE (Version 4.11)"
@y
-@d banner "This is CTANGLE (VAX/VMS Version 4.10)"
+@d banner "This is CTANGLE (VAX/VMS Version 4.11)"
@z
@x section 5 (01-FEB-1992 ST)
diff --git a/web/c_cpp/cweb/ctang-w32.ch b/web/c_cpp/cweb/ctang-w32.ch
index 51d3212b13..c0384b4888 100644
--- a/web/c_cpp/cweb/ctang-w32.ch
+++ b/web/c_cpp/cweb/ctang-w32.ch
@@ -4,9 +4,9 @@ This is the change file for CWEB's CTANGLE under Win32
Changes necessary for compiling with Borland C/C++
@x section 1
-@d banner "This is CTANGLE (Version 4.10)"
+@d banner "This is CTANGLE (Version 4.11)"
@y
-@d banner "This is CTANGLE (Version 4.10win32)"
+@d banner "This is CTANGLE (Version 4.11win32)"
@z
@x section 24
diff --git a/web/c_cpp/cweb/ctangle.c b/web/c_cpp/cweb/ctangle.c
index 2c31732e22..58e37b27b4 100644
--- a/web/c_cpp/cweb/ctangle.c
+++ b/web/c_cpp/cweb/ctangle.c
@@ -15,7 +15,7 @@
/*:5*/
#line 67 "ctangle.w"
-#define banner "This is CTANGLE (Version 4.10)" \
+#define banner "This is CTANGLE (Version 4.11)" \
#define ctangle false
#define cweave true \
@@ -230,7 +230,7 @@ extern name_pointer name_dir_end;
extern name_pointer name_ptr;
extern name_pointer hash[];
extern hash_pointer hash_end;
-extern hash_pointer h;
+extern hash_pointer hash_ptr;
/*:11*//*13:*/
#line 193 "common.h"
@@ -305,53 +305,53 @@ static output_state stack[stack_size+2];
static stack_pointer stack_end= stack+stack_size;
static stack_pointer stack_ptr;
-/*:32*//*37:*/
-#line 357 "ctangle.w"
+/*:32*//*38:*/
+#line 367 "ctangle.w"
static int cur_val;
-/*:37*//*42:*/
-#line 449 "ctangle.w"
+/*:38*//*42:*/
+#line 457 "ctangle.w"
static eight_bits out_state;
static boolean protect;
/*:42*//*45:*/
-#line 480 "ctangle.w"
+#line 488 "ctangle.w"
static name_pointer output_files[max_files];
static name_pointer*cur_out_file,*end_output_files,*an_output_file;
static char cur_section_name_char;
static char output_file_name[longest_name+1];
-/*:45*//*52:*/
-#line 573 "ctangle.w"
+/*:45*//*53:*/
+#line 584 "ctangle.w"
static boolean output_defs_seen= false;
-/*:52*//*57:*/
-#line 687 "ctangle.w"
+/*:53*//*57:*/
+#line 694 "ctangle.w"
static char translit[0200][translit_length];
/*:57*//*62:*/
-#line 763 "ctangle.w"
+#line 770 "ctangle.w"
-static eight_bits ccode[256];
+static eight_bits ccode[256]= {ignore};
/*:62*//*66:*/
-#line 823 "ctangle.w"
+#line 827 "ctangle.w"
static boolean comment_continues= false;
/*:66*//*68:*/
-#line 860 "ctangle.w"
+#line 864 "ctangle.w"
static name_pointer cur_section_name;
static boolean no_where;
/*:68*//*82:*/
-#line 1177 "ctangle.w"
+#line 1182 "ctangle.w"
static text_pointer cur_text;
static eight_bits next_control;
@@ -399,54 +399,48 @@ extern void print_stats(void);
#line 242 "ctangle.w"
static void store_two_bytes(sixteen_bits);
-/*:30*//*35:*/
-#line 321 "ctangle.w"
+/*:30*//*37:*/
+#line 347 "ctangle.w"
static void push_level(name_pointer);
static void pop_level(boolean);
-
-/*:35*//*39:*/
-#line 394 "ctangle.w"
static void get_output(void);
-/*:39*//*44:*/
-#line 470 "ctangle.w"
+/*:37*//*44:*/
+#line 478 "ctangle.w"
static void flush_buffer(void);
/*:44*//*49:*/
-#line 541 "ctangle.w"
-static void phase_two(void);
-
-/*:49*//*53:*/
-#line 576 "ctangle.w"
+#line 547 "ctangle.w"
+static void phase_two(void);
static void output_defs(void);
static void out_char(eight_bits);
-/*:53*//*65:*/
-#line 803 "ctangle.w"
+/*:49*//*65:*/
+#line 807 "ctangle.w"
static eight_bits skip_ahead(void);
static boolean skip_comment(boolean);
/*:65*//*70:*/
-#line 910 "ctangle.w"
+#line 915 "ctangle.w"
static eight_bits get_next(void);
/*:70*//*84:*/
-#line 1203 "ctangle.w"
+#line 1208 "ctangle.w"
static void scan_repl(eight_bits);
/*:84*//*91:*/
-#line 1395 "ctangle.w"
+#line 1399 "ctangle.w"
static void scan_section(void);
/*:91*//*99:*/
-#line 1472 "ctangle.w"
+#line 1476 "ctangle.w"
static void phase_one(void);
/*:99*//*101:*/
-#line 1505 "ctangle.w"
+#line 1509 "ctangle.w"
static void skip_limbo(void);
/*:101*/
@@ -479,12 +473,12 @@ init_node(name_dir);
last_unnamed= text_info;text_info->text_link= macro;
/*:27*//*46:*/
-#line 490 "ctangle.w"
+#line 498 "ctangle.w"
cur_out_file= end_output_files= output_files+max_files;
/*:46*//*58:*/
-#line 690 "ctangle.w"
+#line 697 "ctangle.w"
{int i;
for(i= 0;i<0200;i++)
@@ -492,11 +486,8 @@ snprintf(translit[i],translit_length,"X%02X",(unsigned int)(0200+i));
}
/*:58*//*63:*/
-#line 766 "ctangle.w"
-{
-int c;
-for(c= 0;c<256;c++)ccode[c]= ignore;
-}
+#line 773 "ctangle.w"
+
ccode[' ']= ccode['\t']= ccode['\n']= ccode['\v']= ccode['\r']= ccode['\f']
= ccode['*']= new_section;
ccode['@']= (eight_bits)'@';ccode['=']= string;
@@ -512,7 +503,7 @@ ccode['<']= ccode['(']= section_name;
ccode['\'']= ord;
/*:63*//*78:*/
-#line 1098 "ctangle.w"
+#line 1103 "ctangle.w"
section_text[0]= ' ';
/*:78*/
@@ -559,8 +550,8 @@ if(tok_ptr+2> tok_mem_end)overflow("token");
*tok_ptr++= x&0377;
}
-/*:29*//*34:*/
-#line 307 "ctangle.w"
+/*:29*//*35:*/
+#line 315 "ctangle.w"
static void
push_level(
@@ -575,8 +566,9 @@ cur_byte= cur_repl->tok_start;cur_section= 0;
}
}
-/*:34*//*36:*/
-#line 329 "ctangle.w"
+
+/*:35*//*36:*/
+#line 334 "ctangle.w"
static void
pop_level(
@@ -590,8 +582,8 @@ stack_ptr--;
if(stack_ptr> stack)cur_state= *stack_ptr;
}
-/*:36*//*38:*/
-#line 364 "ctangle.w"
+/*:36*//*39:*/
+#line 374 "ctangle.w"
static void
get_output(void)
@@ -614,13 +606,13 @@ switch(a/024000){
case 0:cur_val= (int)a;out_char(identifier);break;
case 1:if(a==output_defs_flag)output_defs();
else/*40:*/
-#line 399 "ctangle.w"
+#line 407 "ctangle.w"
{
a-= 024000;
if((a+name_dir)->equiv!=(void*)text_info)push_level(a+name_dir);
else if(a!=0){
-fputs("\n! Not present: <",stdout);
+printf("%s","\n! Not present: <");
print_section_name(a+name_dir);err_print(">");
}
@@ -628,7 +620,7 @@ goto restart;
}
/*:40*/
-#line 385 "ctangle.w"
+#line 395 "ctangle.w"
break;
default:cur_val= (int)a-050000;
@@ -638,8 +630,8 @@ out_char(section_number);
}
}
-/*:38*//*43:*/
-#line 457 "ctangle.w"
+/*:39*//*43:*/
+#line 465 "ctangle.w"
static void
flush_buffer(void)
@@ -654,7 +646,7 @@ cur_line++;
}
/*:43*//*48:*/
-#line 509 "ctangle.w"
+#line 517 "ctangle.w"
static void
phase_two(void){
@@ -664,23 +656,24 @@ cur_line= 1;
/*33:*/
#line 296 "ctangle.w"
-stack_ptr= stack+1;cur_name= name_dir;cur_repl= text_info->text_link+text_info;
+stack_ptr= stack+1;cur_name= name_dir;
+cur_repl= text_info->text_link+text_info;
cur_byte= cur_repl->tok_start;cur_section= 0;
/*:33*/
-#line 515 "ctangle.w"
+#line 523 "ctangle.w"
-/*51:*/
-#line 569 "ctangle.w"
+/*52:*/
+#line 580 "ctangle.w"
if(!output_defs_seen)
output_defs();
-/*:51*/
-#line 516 "ctangle.w"
+/*:52*/
+#line 524 "ctangle.w"
if(text_info->text_link==macro&&cur_out_file==end_output_files){
-fputs("\n! No program text was specified.",stdout);mark_harmless();
+printf("%s","\n! No program text was specified.");mark_harmless();
}
else{
@@ -691,12 +684,20 @@ printf(cur_out_file==end_output_files?
update_terminal();
}
-if(text_info->text_link!=macro){
+if(text_info->text_link!=macro)
+/*51:*/
+#line 570 "ctangle.w"
+
+{
while(stack_ptr> stack)get_output();
flush_buffer();
}
+
+/*:51*/
+#line 538 "ctangle.w"
+
/*50:*/
-#line 547 "ctangle.w"
+#line 556 "ctangle.w"
for(an_output_file= end_output_files;an_output_file> cur_out_file;){
an_output_file--;
@@ -707,26 +708,41 @@ fatal("! Cannot open output file ",output_file_name);
if(show_progress){printf("\n(%s)",output_file_name);update_terminal();}
cur_line= 1;
-stack_ptr= stack+1;
-cur_name= *an_output_file;
+/*34:*/
+#line 303 "ctangle.w"
+
+stack_ptr= stack+1;cur_name= *an_output_file;
cur_repl= (text_pointer)cur_name->equiv;
cur_byte= cur_repl->tok_start;
+
+/*:34*/
+#line 566 "ctangle.w"
+
+/*51:*/
+#line 570 "ctangle.w"
+
+{
while(stack_ptr> stack)get_output();
flush_buffer();
}
+/*:51*/
+#line 567 "ctangle.w"
+
+}
+
/*:50*/
-#line 533 "ctangle.w"
+#line 539 "ctangle.w"
if(show_happiness){
if(show_progress)new_line();
-fputs("Done.",stdout);
+printf("%s","Done.");
}
}
}
/*:48*//*54:*/
-#line 585 "ctangle.w"
+#line 592 "ctangle.w"
static void
output_defs(void)
@@ -766,7 +782,7 @@ pop_level(false);
}
/*:54*//*55:*/
-#line 628 "ctangle.w"
+#line 635 "ctangle.w"
static void
out_char(
@@ -779,7 +795,7 @@ case'\n':if(protect&&out_state!=verbatim)C_putc(' ');
if(protect||out_state==verbatim)C_putc('\\');
flush_buffer();if(out_state!=verbatim)out_state= normal;break;
/*59:*/
-#line 696 "ctangle.w"
+#line 703 "ctangle.w"
case identifier:
if(out_state==num_or_id)C_putc(' ');
@@ -791,10 +807,10 @@ else C_printf("%s",translit[(eight_bits)(*j)-0200]);
out_state= num_or_id;break;
/*:59*/
-#line 639 "ctangle.w"
+#line 646 "ctangle.w"
/*60:*/
-#line 706 "ctangle.w"
+#line 713 "ctangle.w"
case section_number:
if(cur_val> 0)C_printf("/*%d:*/",cur_val);
@@ -821,10 +837,10 @@ C_putc('"');C_putc('\n');
break;
/*:60*/
-#line 640 "ctangle.w"
+#line 647 "ctangle.w"
/*56:*/
-#line 658 "ctangle.w"
+#line 665 "ctangle.w"
case plus_plus:C_putc('+');C_putc('+');out_state= normal;break;
case minus_minus:C_putc('-');C_putc('-');out_state= normal;break;
@@ -845,7 +861,7 @@ case minus_gt_ast:C_putc('-');C_putc('>');C_putc('*');out_state= normal;
break;
/*:56*/
-#line 641 "ctangle.w"
+#line 648 "ctangle.w"
case'=':case'>':C_putc(cur_char);C_putc(' ');
out_state= normal;break;
@@ -864,7 +880,7 @@ default:C_putc(cur_char);out_state= normal;break;
}
/*:55*//*64:*/
-#line 787 "ctangle.w"
+#line 791 "ctangle.w"
static eight_bits
skip_ahead(void)
@@ -882,7 +898,7 @@ if(c!=ignore||*(loc-1)=='>')return c;
}
/*:64*//*67:*/
-#line 826 "ctangle.w"
+#line 830 "ctangle.w"
static boolean skip_comment(
boolean is_long_comment)
@@ -916,7 +932,7 @@ else loc++;
}
/*:67*//*69:*/
-#line 867 "ctangle.w"
+#line 871 "ctangle.w"
static eight_bits
get_next(void)
@@ -928,12 +944,12 @@ if(loc> limit){
if(preprocessing&&*(limit-1)!='\\')preprocessing= false;
if(get_line()==false)return new_section;
else if(print_where&&!no_where){
+sixteen_bits a;
print_where= false;
/*85:*/
-#line 1213 "ctangle.w"
+#line 1218 "ctangle.w"
{
-eight_bits a;
store_two_bytes(0150000);
if(changing&&include_depth==change_depth){
id_first= change_file_name;
@@ -947,7 +963,7 @@ store_id(a);
}
/*:85*/
-#line 879 "ctangle.w"
+#line 884 "ctangle.w"
}
else return(eight_bits)'\n';
@@ -960,7 +976,7 @@ else continue;
}
loc++;
if(xisdigit(c)||c=='.')/*73:*/
-#line 951 "ctangle.w"
+#line 956 "ctangle.w"
{
boolean hex_flag= false;
id_first= loc-1;
@@ -994,13 +1010,13 @@ return constant;
}
/*:73*/
-#line 890 "ctangle.w"
+#line 895 "ctangle.w"
else if(c=='\''||c=='"'
||((c=='L'||c=='u'||c=='U')&&(*loc=='\''||*loc=='"'))
||((c=='u'&&*loc=='8')&&(*(loc+1)=='\''||*(loc+1)=='"')))
/*74:*/
-#line 988 "ctangle.w"
+#line 993 "ctangle.w"
{
char delim= (char)c;
id_first= section_text+1;
@@ -1034,7 +1050,7 @@ c= (eight_bits)*loc++;
if(++id_loc<=section_text_end)*id_loc= (char)c;
}
if(id_loc>=section_text_end){
-fputs("\n! String too long: ",stdout);
+printf("%s","\n! String too long: ");
term_write(section_text+1,25);
err_print("...");
@@ -1044,11 +1060,11 @@ return string;
}
/*:74*/
-#line 894 "ctangle.w"
+#line 899 "ctangle.w"
else if(isalpha((int)c)||isxalpha(c)||ishigh(c))
/*72:*/
-#line 942 "ctangle.w"
+#line 947 "ctangle.w"
{
id_first= --loc;
do
@@ -1059,10 +1075,10 @@ id_loc= loc;return identifier;
}
/*:72*/
-#line 896 "ctangle.w"
+#line 901 "ctangle.w"
else if(c=='@')/*75:*/
-#line 1033 "ctangle.w"
+#line 1038 "ctangle.w"
switch(c= ccode[(eight_bits)*loc++]){
case ignore:continue;
@@ -1077,11 +1093,11 @@ continue;
case section_name:
cur_section_name_char= *(loc-1);
/*77:*/
-#line 1078 "ctangle.w"
+#line 1083 "ctangle.w"
{
char*k= section_text;
/*79:*/
-#line 1100 "ctangle.w"
+#line 1105 "ctangle.w"
while(true){
if(loc> limit&&get_line()==false){
@@ -1091,7 +1107,7 @@ loc= buffer+1;break;
}
c= (eight_bits)*loc;
/*80:*/
-#line 1123 "ctangle.w"
+#line 1128 "ctangle.w"
if(c=='@'){
c= (eight_bits)*(loc+1);
@@ -1110,7 +1126,7 @@ err_print("! Nesting of section names not allowed");break;
}
/*:80*/
-#line 1108 "ctangle.w"
+#line 1113 "ctangle.w"
loc++;if(k<section_text_end)k++;
if(xisspace(c)){
@@ -1119,7 +1135,7 @@ c= (eight_bits)' ';if(*(k-1)==' ')k--;
*k= (char)c;
}
if(k>=section_text_end){
-fputs("\n! Section name too long: ",stdout);
+printf("%s","\n! Section name too long: ");
term_write(section_text+1,25);
printf("...");mark_harmless();
@@ -1127,7 +1143,7 @@ printf("...");mark_harmless();
if(*k==' '&&k> section_text)k--;
/*:79*/
-#line 1080 "ctangle.w"
+#line 1085 "ctangle.w"
if(k-section_text> 3&&strncmp(k-2,"...",3)==0)
cur_section_name= section_lookup(section_text+1,k-3,true);
@@ -1136,7 +1152,7 @@ else cur_section_name= section_lookup(section_text+1,k,false);
if(cur_section_name_char=='(')
/*47:*/
-#line 494 "ctangle.w"
+#line 502 "ctangle.w"
{
for(an_output_file= cur_out_file;
@@ -1150,16 +1166,16 @@ else overflow("output files");
}
/*:47*/
-#line 1088 "ctangle.w"
+#line 1093 "ctangle.w"
return section_name;
}
/*:77*/
-#line 1046 "ctangle.w"
+#line 1051 "ctangle.w"
case string:/*81:*/
-#line 1145 "ctangle.w"
+#line 1150 "ctangle.w"
id_first= loc++;*(limit+1)= '@';*(limit+2)= '>';
while(*loc!='@'||*(loc+1)!='>')loc++;
@@ -1169,10 +1185,10 @@ id_loc= loc;loc+= 2;
return string;
/*:81*/
-#line 1047 "ctangle.w"
+#line 1052 "ctangle.w"
case ord:/*76:*/
-#line 1058 "ctangle.w"
+#line 1063 "ctangle.w"
id_first= loc;
if(*loc=='\\')
@@ -1194,13 +1210,13 @@ loc++;
return ord;
/*:76*/
-#line 1048 "ctangle.w"
+#line 1053 "ctangle.w"
default:return c;
}
/*:75*/
-#line 897 "ctangle.w"
+#line 902 "ctangle.w"
else if(xisspace(c)){
if(!preprocessing||loc> limit)continue;
@@ -1210,7 +1226,7 @@ else return(eight_bits)' ';
}
else if(c=='#'&&loc==buffer+1)preprocessing= true;
mistake:/*71:*/
-#line 919 "ctangle.w"
+#line 924 "ctangle.w"
switch(c){
case'+':if(*loc=='+')compress(plus_plus);break;
@@ -1235,14 +1251,14 @@ case'!':if(*loc=='=')compress(non_eq);break;
}
/*:71*/
-#line 905 "ctangle.w"
+#line 910 "ctangle.w"
return c;
}
}
/*:69*//*83:*/
-#line 1181 "ctangle.w"
+#line 1186 "ctangle.w"
static void
scan_repl(
@@ -1250,10 +1266,9 @@ eight_bits t)
{
sixteen_bits a;
if(t==section_name)/*85:*/
-#line 1213 "ctangle.w"
+#line 1218 "ctangle.w"
{
-eight_bits a;
store_two_bytes(0150000);
if(changing&&include_depth==change_depth){
id_first= change_file_name;
@@ -1267,11 +1282,11 @@ store_id(a);
}
/*:85*/
-#line 1187 "ctangle.w"
+#line 1192 "ctangle.w"
while(true)switch(a= get_next()){
/*86:*/
-#line 1228 "ctangle.w"
+#line 1232 "ctangle.w"
case identifier:store_id(a);
if(*buffer=='#'&&(
@@ -1284,7 +1299,7 @@ break;
case section_name:if(t!=section_name)goto done;
else{
/*87:*/
-#line 1269 "ctangle.w"
+#line 1273 "ctangle.w"
{
char*try_loc= loc;
while(*try_loc==' '&&try_loc<limit)try_loc++;
@@ -1297,16 +1312,15 @@ if(*try_loc=='=')err_print("! Missing `@ ' before a named section");
}
/*:87*/
-#line 1239 "ctangle.w"
+#line 1243 "ctangle.w"
a= cur_section_name-name_dir;
app_repl((a/0400)+0250);
app_repl(a%0400);
/*85:*/
-#line 1213 "ctangle.w"
+#line 1218 "ctangle.w"
{
-eight_bits a;
store_two_bytes(0150000);
if(changing&&include_depth==change_depth){
id_first= change_file_name;
@@ -1320,7 +1334,7 @@ store_id(a);
}
/*:85*/
-#line 1243 "ctangle.w"
+#line 1247 "ctangle.w"
}
break;
@@ -1332,10 +1346,9 @@ a= output_defs_flag;
app_repl((a/0400)+0200);
app_repl(a%0400);
/*85:*/
-#line 1213 "ctangle.w"
+#line 1218 "ctangle.w"
{
-eight_bits a;
store_two_bytes(0150000);
if(changing&&include_depth==change_depth){
id_first= change_file_name;
@@ -1349,13 +1362,13 @@ store_id(a);
}
/*:85*/
-#line 1253 "ctangle.w"
+#line 1257 "ctangle.w"
}
break;
case constant:case string:
/*88:*/
-#line 1286 "ctangle.w"
+#line 1290 "ctangle.w"
app_repl(a);
while(id_first<id_loc){
@@ -1371,12 +1384,12 @@ app_repl(*id_first++);
app_repl(a);
/*:88*/
-#line 1257 "ctangle.w"
+#line 1261 "ctangle.w"
break;
case ord:
/*89:*/
-#line 1304 "ctangle.w"
+#line 1308 "ctangle.w"
{
int c= (int)((eight_bits)*id_first);
if(c=='\\'){
@@ -1426,7 +1439,7 @@ app_repl(constant);
}
/*:89*/
-#line 1260 "ctangle.w"
+#line 1264 "ctangle.w"
break;
case definition:case format_code:case begin_C:if(t!=section_name)goto done;
@@ -1437,7 +1450,7 @@ err_print("! @d, @f and @c are ignored in C text");continue;
case new_section:goto done;
/*:86*/
-#line 1192 "ctangle.w"
+#line 1197 "ctangle.w"
case')':app_repl(a);
if(t==macro)app_repl(' ');
@@ -1450,7 +1463,7 @@ cur_text= text_ptr;(++text_ptr)->tok_start= tok_ptr;
}
/*:83*//*90:*/
-#line 1362 "ctangle.w"
+#line 1366 "ctangle.w"
static void
scan_section(void)
@@ -1465,7 +1478,7 @@ printf("*%d",(int)section_count);update_terminal();
next_control= ignore;
while(true){
/*92:*/
-#line 1403 "ctangle.w"
+#line 1407 "ctangle.w"
while(next_control<definition)
@@ -1474,11 +1487,11 @@ loc-= 2;next_control= get_next();
}
/*:92*/
-#line 1376 "ctangle.w"
+#line 1380 "ctangle.w"
if(next_control==definition){
/*93:*/
-#line 1410 "ctangle.w"
+#line 1414 "ctangle.w"
while((next_control= get_next())=='\n');
if(next_control!=identifier){
@@ -1494,7 +1507,7 @@ scan_repl(macro);
cur_text->text_link= macro;
/*:93*/
-#line 1378 "ctangle.w"
+#line 1382 "ctangle.w"
continue;
}
@@ -1504,14 +1517,14 @@ p= name_dir;break;
if(next_control==section_name){
p= cur_section_name;
/*94:*/
-#line 1432 "ctangle.w"
+#line 1436 "ctangle.w"
while((next_control= get_next())=='+');
if(next_control!='='&&next_control!=eq_eq)
continue;
/*:94*/
-#line 1386 "ctangle.w"
+#line 1390 "ctangle.w"
break;
}
@@ -1519,20 +1532,20 @@ return;
}
no_where= print_where= false;
/*95:*/
-#line 1437 "ctangle.w"
+#line 1441 "ctangle.w"
/*96:*/
-#line 1442 "ctangle.w"
+#line 1446 "ctangle.w"
store_two_bytes((sixteen_bits)(0150000+section_count));
/*:96*/
-#line 1438 "ctangle.w"
+#line 1442 "ctangle.w"
scan_repl(section_name);
/*97:*/
-#line 1446 "ctangle.w"
+#line 1450 "ctangle.w"
if(p==name_dir||p==NULL){
last_unnamed->text_link= cur_text-text_info;last_unnamed= cur_text;
@@ -1549,16 +1562,16 @@ cur_text->text_link= section_flag;
/*:97*/
-#line 1440 "ctangle.w"
+#line 1444 "ctangle.w"
/*:95*/
-#line 1392 "ctangle.w"
+#line 1396 "ctangle.w"
}
/*:90*//*98:*/
-#line 1461 "ctangle.w"
+#line 1465 "ctangle.w"
static void
phase_one(void){
@@ -1571,7 +1584,7 @@ check_complete();
}
/*:98*//*100:*/
-#line 1477 "ctangle.w"
+#line 1481 "ctangle.w"
static void
skip_limbo(void)
@@ -1585,7 +1598,7 @@ char c= *loc++;
switch(ccode[(eight_bits)c]){
case new_section:return;
case translit_code:/*102:*/
-#line 1507 "ctangle.w"
+#line 1511 "ctangle.w"
while(xisspace(*loc)&&loc<limit)loc++;
loc+= 3;
@@ -1610,7 +1623,7 @@ translit[i-0200][loc-beg]= '\0';
}
/*:102*/
-#line 1489 "ctangle.w"
+#line 1493 "ctangle.w"
break;
case format_code:case'@':break;
case control_text:if(c=='q'||c=='Q'){
@@ -1628,7 +1641,7 @@ default:err_print("! Double @ should be used in limbo");
}
/*:100*//*103:*/
-#line 1533 "ctangle.w"
+#line 1537 "ctangle.w"
void
print_stats(void){
diff --git a/web/c_cpp/cweb/ctangle.w b/web/c_cpp/cweb/ctangle.w
index c8ae55df85..37b09e7fc0 100644
--- a/web/c_cpp/cweb/ctangle.w
+++ b/web/c_cpp/cweb/ctangle.w
@@ -2,7 +2,7 @@
% This program by Silvio Levy and Donald E. Knuth
% is based on a program by Knuth.
% It is distributed WITHOUT ANY WARRANTY, express or implied.
-% Version 4.10 --- August 2023
+% Version 4.11 --- December 2023
% Copyright (C) 1987,1990,1993,2000 Silvio Levy and Donald E. Knuth
@@ -27,11 +27,11 @@
\mathchardef\RA="3221 % right arrow
\mathchardef\BA="3224 % double arrow
-\def\title{CTANGLE (Version 4.10)}
+\def\title{CTANGLE (Version 4.11)}
\def\topofcontents{\null\vfill
\centerline{\titlefont The {\ttitlefont CTANGLE} processor}
\vskip 15pt
- \centerline{(Version 4.10)}
+ \centerline{(Version 4.11)}
\vfill}
\def\botofcontents{\vfill
\noindent
@@ -61,7 +61,7 @@ Joachim Schrod, Lee Wittenberg, and others who have contributed improvements.
The ``banner line'' defined here should be changed whenever \.{CTANGLE}
is modified.
-@d banner "This is CTANGLE (Version 4.10)"
+@d banner "This is CTANGLE (Version 4.11)"
@c
@<Include files@>@/
@@ -294,9 +294,17 @@ code; if there are no such sections, there is nothing to output, and an
error message will have been generated before we do any of the initialization.
@<Initialize the output stacks@>=
-stack_ptr=stack+1; cur_name=name_dir; cur_repl=text_info->text_link+text_info;
+stack_ptr=stack+1; cur_name=name_dir;
+cur_repl=text_info->text_link+text_info;
cur_byte=cur_repl->tok_start; cur_section=0;
+@ Similar settings are used for secondary output files.
+
+@<Initialize the secondary output@>=
+stack_ptr=stack+1; cur_name=*an_output_file;
+cur_repl=(text_pointer)cur_name->equiv;
+cur_byte=cur_repl->tok_start;
+
@ When the replacement text for name |p| is to be inserted into the output,
the following subroutine is called to save the old level of output and get
the new one going.
@@ -318,9 +326,6 @@ name_pointer p)
}
}
-@ @<Predecl...@>=
-static void push_level(name_pointer);@/
-static void pop_level(boolean);
@ When we come to the end of a replacement text, the |pop_level| subroutine
does the right thing: It either moves to the continuation of this replacement
@@ -339,6 +344,11 @@ boolean flag) /* |flag==false| means we are in |output_defs| */
if (stack_ptr>stack) cur_state=*stack_ptr;@^system dependencies@>
}
+@ @<Predecl...@>=
+static void push_level(name_pointer);@/
+static void pop_level(boolean);@/
+static void get_output(void);
+
@ The heart of the output procedure is the function |get_output|,
which produces the next token of output and sends it on to the lower-level
function |out_char|. The main purpose of |get_output| is to handle the
@@ -391,8 +401,6 @@ get_output(void) /* sends next token to |out_char| */
}
}
-@ @<Predecl...@>=@+static void get_output(void);
-
@ The user may have forgotten to give any \CEE/ text for a section name,
or the \CEE/ text may have been associated with a different name by mistake.
@@ -401,7 +409,7 @@ or the \CEE/ text may have been associated with a different name by mistake.
a-=024000;
if ((a+name_dir)->equiv!=(void *)text_info) push_level(a+name_dir);
else if (a!=0) {
- fputs("\n! Not present: <",stdout);
+ printf("%s","\n! Not present: <");
print_section_name(a+name_dir); err_print(">");
@.Not present: <section name>@>
}
@@ -515,7 +523,7 @@ phase_two (void) {
@<Initialize the output stacks@>@;
@<Output macro definitions if appropriate@>@;
if (text_info->text_link==macro && cur_out_file==end_output_files) {
- fputs("\n! No program text was specified.",stdout); mark_harmless();
+ printf("%s","\n! No program text was specified."); mark_harmless();
@.No program text...@>
}
else {
@@ -526,19 +534,20 @@ phase_two (void) {
@.Writing the output...@>
update_terminal();
}
- if (text_info->text_link!=macro) {
- while (stack_ptr>stack) get_output();
- flush_buffer();
- }
+ if (text_info->text_link!=macro)
+ @<Output material...@>@;
@<Write all the named output files@>@;
if (show_happiness) {
if (show_progress) new_line();
- fputs("Done.",stdout);
+ printf("%s","Done.");
}
}
}
-@ @<Predecl...@>=@+static void phase_two(void);
+@ @<Predecl...@>=
+static void phase_two(void);@/
+static void output_defs(void);@/
+static void out_char(eight_bits);
@ To write the named output files, we proceed as for the unnamed
section.
@@ -554,12 +563,14 @@ for (an_output_file=end_output_files; an_output_file>cur_out_file;) {
@.Cannot open output file@>
if (show_progress) { printf("\n(%s)",output_file_name); update_terminal(); }
cur_line=1;
- stack_ptr=stack+1;
- cur_name=*an_output_file;
- cur_repl=(text_pointer)cur_name->equiv;
- cur_byte=cur_repl->tok_start;
- while (stack_ptr > stack) get_output();
- flush_buffer();
+ @<Initialize the secondary output@>@;
+ @<Output material...@>@;
+}
+
+@ @<Output material from |stack|@>=
+{
+ while (stack_ptr>stack) get_output();
+ flush_buffer();
}
@ If a \.{@@h} was not encountered in the input,
@@ -573,10 +584,6 @@ that refer to macros, preceded by the \.{\#define} preprocessor command.
@ @<Private...@>=
static boolean output_defs_seen=false;
-@ @<Predecl...@>=
-static void output_defs(void);@/
-static void out_char(eight_bits);
-
@ @d macro_end (cur_text+1)->tok_start /* end of |macro| replacement text */
@#
@d C_printf(c,a) fprintf(C_file,c,a)
@@ -761,12 +768,9 @@ milestones.
@d new_section 0312 /* control code for `\.{@@\ }' and `\.{@@*}' */
@<Private...@>=
-static eight_bits ccode[256]; /* meaning of a char following \.{@@} */
+static eight_bits ccode[256]={ignore}; /* meaning of a char following \.{@@} */
-@ @<Set ini...@>= {
- int c; /* must be |int| so the |for| loop will end */
- for (c=0; c<256; c++) ccode[c]=ignore;
-}
+@ @<Set ini...@>=
ccode[' ']=ccode['\t']=ccode['\n']=ccode['\v']=ccode['\r']=ccode['\f']
=ccode['*']=new_section;
ccode['@@']=(eight_bits)'@@'; ccode['=']=string;
@@ -875,6 +879,7 @@ get_next(void) /* produces the next input token */
if (preprocessing && *(limit-1)!='\\') preprocessing=false;
if (get_line()==false) return new_section;
else if (print_where && !no_where) {
+ sixteen_bits a;
print_where=false;
@<Insert the line number into |tok_mem|@>@;
}
@@ -1018,7 +1023,7 @@ convention, but do not allow the string to be longer than |longest_name|.
if (++id_loc<=section_text_end) *id_loc=(char)c;
}
if (id_loc>=section_text_end) {
- fputs("\n! String too long: ",stdout);
+ printf("%s","\n! String too long: ");
@.String too long@>
term_write(section_text+1,25);
err_print("...");
@@ -1113,7 +1118,7 @@ while (true) {
*k=(char)c;
}
if (k>=section_text_end) {
- fputs("\n! Section name too long: ",stdout);
+ printf("%s","\n! Section name too long: ");
@.Section name too long@>
term_write(section_text+1,25);
printf("..."); mark_harmless();
@@ -1212,7 +1217,6 @@ file name.
@<Insert the line...@>=
{
- eight_bits a; /* shadow variable |a| */
store_two_bytes(0150000);
if (changing && include_depth==change_depth) { /* correction made Feb 2017 */
id_first=change_file_name;
diff --git a/web/c_cpp/cweb/cweav-bs.ch b/web/c_cpp/cweb/cweav-bs.ch
index 1d541d536b..c2f3214c79 100644
--- a/web/c_cpp/cweb/cweav-bs.ch
+++ b/web/c_cpp/cweb/cweav-bs.ch
@@ -20,12 +20,12 @@ This file contributed by Barry Schwartz, trashman@crud.mn.org, 28 Jun 94.
The ``banner line'' defined here should be changed whenever \.{CWEAVE}
is modified.
-@d banner "This is CWEAVE (Version 4.10)"
+@d banner "This is CWEAVE (Version 4.11)"
@y
The ``banner line'' defined here should be changed whenever \.{CWEAVE}
is modified.
-@d banner "This is CWEAVE (Version 4.10pc/big)"
+@d banner "This is CWEAVE (Version 4.11pc/big)"
@z
@@ -51,9 +51,6 @@ extern char *byte_ptr; /* first unused position in |byte_mem| */
extern name_info name_dir[]; /* information about names */
extern name_pointer name_dir_end; /* end of |name_dir| */
extern name_pointer name_ptr; /* first unused position in |name_dir| */
-extern name_pointer hash[]; /* heads of hash lists */
-extern hash_pointer hash_end; /* end of |hash| */
-extern hash_pointer h; /* index into hash-head array */
@y
@d ilk dummy.Ilk /* used by \.{CWEAVE} only */
@@ -81,9 +78,6 @@ extern name_info name_dir[]; /* information about names */
extern name_pointer name_dir_end; /* end of |name_dir| */
extern name_pointer name_ptr; /* first unused position in |name_dir| */
extern char huge* byte_ptr; /* first unused position in |byte_mem| */
-extern name_pointer hash[]; /* heads of hash lists */
-extern hash_pointer hash_end; /* end of |hash| */
-extern hash_pointer h; /* index into hash-head array */
@z
diff --git a/web/c_cpp/cweb/cweav-pc.ch b/web/c_cpp/cweb/cweav-pc.ch
index 76173410af..165b8a54ee 100644
--- a/web/c_cpp/cweb/cweav-pc.ch
+++ b/web/c_cpp/cweb/cweav-pc.ch
@@ -11,9 +11,9 @@ that allows >64K arrays. (If you need lots more bytes, try the alternate
change files that have -bs in their name instead of -pc.)
@x section 1
-@d banner "This is CWEAVE (Version 4.10)"
+@d banner "This is CWEAVE (Version 4.11)"
@y
-@d banner "This is CWEAVE (Version 4.10pc)"
+@d banner "This is CWEAVE (Version 4.11pc)"
@z
@x section 17
diff --git a/web/c_cpp/cweb/cweav-ql.ch b/web/c_cpp/cweb/cweav-ql.ch
index 8f40a9dca6..31bd6138a2 100644
--- a/web/c_cpp/cweb/cweav-ql.ch
+++ b/web/c_cpp/cweb/cweav-ql.ch
@@ -7,15 +7,15 @@ ex <dev_>cc;"-v -h -c =500000 cweave_c"
@x
-\def\title{CWEAVE (Version 4.10)}
+\def\title{CWEAVE (Version 4.11)}
@y
-\def\title{CWEAVE (QL Version 4.10)}
+\def\title{CWEAVE (QL Version 4.11)}
@z
@x section 1
-@d banner "This is CWEAVE (Version 4.10)"
+@d banner "This is CWEAVE (Version 4.11)"
@y
-@d banner "This is CWEAVE (QL Version 4.10)"
+@d banner "This is CWEAVE (QL Version 4.11)"
@z
@x
diff --git a/web/c_cpp/cweb/cweav-vms.ch b/web/c_cpp/cweb/cweav-vms.ch
index d2cef52379..b944f83815 100644
--- a/web/c_cpp/cweb/cweav-vms.ch
+++ b/web/c_cpp/cweb/cweav-vms.ch
@@ -13,9 +13,9 @@ modified:
(also modified by Don Knuth to keep version numbers uptodate)
@x section 1 (01-FEB-1992 ST)
-@d banner "This is CWEAVE (Version 4.10)"
+@d banner "This is CWEAVE (Version 4.11)"
@y
-@d banner "This is CWEAVE (VAX/VMS Version 4.10)"
+@d banner "This is CWEAVE (VAX/VMS Version 4.11)"
@z
@x section 5 (01-FEB-1992 ST)
diff --git a/web/c_cpp/cweb/cweav-w32.ch b/web/c_cpp/cweb/cweav-w32.ch
index 94f4c39aa6..1bf1471e18 100644
--- a/web/c_cpp/cweb/cweav-w32.ch
+++ b/web/c_cpp/cweb/cweav-w32.ch
@@ -2,9 +2,9 @@ This is the change file for CWEB's CWEAVE under Win32
(Contributed by Fabrice Popineau, February 2002)
@x section 1
-@d banner "This is CWEAVE (Version 4.10)"
+@d banner "This is CWEAVE (Version 4.11)"
@y
-@d banner "This is CWEAVE (Version 4.10win32)"
+@d banner "This is CWEAVE (Version 4.11win32)"
@z
@x section 32
diff --git a/web/c_cpp/cweb/cweave.w b/web/c_cpp/cweb/cweave.w
index 70654828c1..2048c6bb2f 100644
--- a/web/c_cpp/cweb/cweave.w
+++ b/web/c_cpp/cweb/cweave.w
@@ -2,7 +2,7 @@
% This program by Silvio Levy and Donald E. Knuth
% is based on a program by Knuth.
% It is distributed WITHOUT ANY WARRANTY, express or implied.
-% Version 4.10 --- August 2023
+% Version 4.11 --- December 2023
% Copyright (C) 1987,1990,1993,2000 Silvio Levy and Donald E. Knuth
@@ -32,11 +32,11 @@
\def\skipxTeX{\\{skip\_\TEX/}}
\def\copyxTeX{\\{copy\_\TEX/}}
-\def\title{CWEAVE (Version 4.10)}
+\def\title{CWEAVE (Version 4.11)}
\def\topofcontents{\null\vfill
\centerline{\titlefont The {\ttitlefont CWEAVE} processor}
\vskip 15pt
- \centerline{(Version 4.10)}
+ \centerline{(Version 4.11)}
\vfill}
\def\botofcontents{\vfill
\noindent
@@ -67,7 +67,7 @@ Crusius, and others who have contributed improvements.
The ``banner line'' defined here should be changed whenever \.{CWEAVE}
is modified.
-@d banner "This is CWEAVE (Version 4.10)"
+@d banner "This is CWEAVE (Version 4.11)"
@c
@<Include files@>@/
@@ -564,12 +564,9 @@ scanning routines.
representation by means of the table |ccode|.
@<Private...@>=
-static eight_bits ccode[256]; /* meaning of a char following \.{@@} */
+static eight_bits ccode[256]={ignore}; /* meaning of a char following \.{@@} */
-@ @<Set ini...@>= {
- int c; /* must be |int| so the |for| loop will end */
- for (c=0; c<256; c++) ccode[c]=ignore;
-}
+@ @<Set ini...@>=
ccode[' ']=ccode['\t']=ccode['\n']=ccode['\v']=ccode['\r']=ccode['\f']
=ccode['*']=new_section;
ccode['@@']='@@'; /* `quoted' at sign */
@@ -646,7 +643,7 @@ skip_TeX(void) /* skip past pure \TEX/ code */
}
}
-@*1 Inputting the next token.
+@* Inputting the next token.
As stated above, \.{CWEAVE}'s most interesting lexical scanning routine is the
|get_next| function that inputs the next token of \CEE/ input. However,
|get_next| is not especially complicated.
@@ -911,7 +908,7 @@ convention, but do not allow the string to be longer than |longest_name|.
if (++id_loc<=section_text_end) *id_loc=c;
}
if (id_loc>=section_text_end) {
- fputs("\n! String too long: ",stdout);
+ printf("%s","\n! String too long: ");
@.String too long@>
term_write(section_text+1,25);
printf("..."); mark_error();
@@ -981,7 +978,7 @@ while (true) {
*k=c;
}
if (k>=section_text_end) {
- fputs("\n! Section name too long: ",stdout);
+ printf("%s","\n! Section name too long: ");
@.Section name too long@>
term_write(section_text+1,25);
printf("..."); mark_harmless();
@@ -1302,13 +1299,13 @@ name_pointer p) /* print anomalies in subtree |p| */
cur_xref=(xref_pointer)p->xref;
if ((an_output=(cur_xref->num==file_flag))==true) cur_xref=cur_xref->xlink;
if (cur_xref->num <def_flag) {
- fputs("\n! Never defined: <",stdout);
+ printf("%s","\n! Never defined: <");
print_section_name(p); putchar('>'); mark_harmless();
@.Never defined: <section name>@>
}
while (cur_xref->num >=cite_flag) cur_xref=cur_xref->xlink;
if (cur_xref==xmem && !an_output) {
- fputs("\n! Never used: <",stdout);
+ printf("%s","\n! Never used: <");
print_section_name(p); putchar('>'); mark_harmless();
@.Never used: <section name>@>
}
@@ -3195,7 +3192,8 @@ static void reduce(scrap_pointer,short,eight_bits,short,short);@/
static void squash(scrap_pointer,short,eight_bits,short,short);
@ Now here's the |reduce| procedure used in our code for productions,
-which takes advantage of the simplification that occurs when |k==0|.
+which takes advantage of the simplifications that occur when |k==0|
+or |k==1|.
@c
static void
@@ -3204,7 +3202,7 @@ scrap_pointer j, short k,
eight_bits c,
short d, short n)
{
- scrap_pointer i, i1; /* pointers into scrap memory */
+ scrap_pointer i; /* pointer into scrap memory */
j->cat=c;
if (k>0) {
j->trans=text_ptr;
@@ -3212,10 +3210,8 @@ short d, short n)
freeze_text();
}
if (k>1) {
- for (i=j+k, i1=j+1; i<=lo_ptr; i++, i1++) {
- i1->cat=i->cat; i1->trans=i->trans;
- i1->mathness=i->mathness;
- }
+ for (i=j+k; i<=lo_ptr; i++)
+ *(i-k+1)=*i;@^system dependencies@>
lo_ptr=lo_ptr-k+1;
}
pp=(pp+d<scrap_base? scrap_base: pp+d);
@@ -3243,6 +3239,32 @@ short d, short n)
reduce(j,k,c,d,n);
}
+@ If \.{CWEAVE} is being run in debugging mode, the production numbers and
+current stack categories will be printed out when |tracing| is set to |fully|;
+a sequence of two or more irreducible scraps will be printed out when
+|tracing| is set to |partly|.
+
+@d off 0
+@d partly 1
+@d fully 2
+
+@<Private...@>=
+static int tracing=off; /* can be used to show parsing details */
+
+@ @<Print a snapsh...@>=
+if (tracing==fully) {
+ printf("\n%d:",n);
+ for (i=scrap_base; i<=lo_ptr; i++) {
+ putchar(i==pp?'*':' ');
+ if (i->mathness %4 == yes_math) putchar('+');
+ else if (i->mathness %4 == no_math) putchar('-');
+ print_cat(i->cat);
+ if (i->mathness /4 == yes_math) putchar('+');
+ else if (i->mathness /4 == no_math) putchar('-');
+ }
+ if (hi_ptr<=scrap_ptr) printf("..."); /* indicate that more is coming */
+}
+
@ And here now is the code that applies productions as long as possible.
Before applying the production mechanism, we must make sure
it has good input (at least four scraps, the length of the lhs of the
@@ -3277,38 +3299,9 @@ stored, since zero does not match anything in a production.
@<Make sure the entries...@>=
if (lo_ptr<pp+3) {
- while (hi_ptr<=scrap_ptr && lo_ptr!=pp+3) {
- (++lo_ptr)->cat=hi_ptr->cat; lo_ptr->mathness=hi_ptr->mathness;
- lo_ptr->trans=(hi_ptr++)->trans;
- }
- for (i=lo_ptr+1;i<=pp+3;i++) i->cat=0;
-}
-
-@ If \.{CWEAVE} is being run in debugging mode, the production numbers and
-current stack categories will be printed out when |tracing| is set to |fully|;
-a sequence of two or more irreducible scraps will be printed out when
-|tracing| is set to |partly|.
-
-@d off 0
-@d partly 1
-@d fully 2
-
-@<Private...@>=
-static int tracing=off; /* can be used to show parsing details */
-
-@ @<Print a snapsh...@>=
-if (tracing==fully) {
- scrap_pointer k; /* pointer into |scrap_info|; shadows |short k| */
- printf("\n%d:",n);
- for (k=scrap_base; k<=lo_ptr; k++) {
- if (k==pp) putchar('*'); else putchar(' ');
- if (k->mathness %4 == yes_math) putchar('+');
- else if (k->mathness %4 == no_math) putchar('-');
- print_cat(k->cat);
- if (k->mathness /4 == yes_math) putchar('+');
- else if (k->mathness /4 == no_math) putchar('-');
- }
- if (hi_ptr<=scrap_ptr) printf("..."); /* indicate that more is coming */
+ while (hi_ptr<=scrap_ptr && lo_ptr!=pp+3)
+ *(++lo_ptr)=*(hi_ptr++);@^system dependencies@>
+ for (j=lo_ptr+1;j<=pp+3;j++) j->cat=0;
}
@ The |translate| function assumes that scraps have been stored in
@@ -3328,7 +3321,6 @@ for overflow.
static text_pointer
translate(void) /* converts a sequence of scraps */
{
- scrap_pointer i; /* index into |cat| */
scrap_pointer j; /* runs through final scraps */
pp=scrap_base; lo_ptr=pp-1; hi_ptr=pp;
@<If tracing, print an indication of where we are@>@;
@@ -4130,7 +4122,7 @@ while (k<k_limit) {
@ @<Skip next char...@>=
if (*k++!='@@') {
- fputs("\n! Illegal control code in section name: <",stdout);
+ printf("%s","\n! Illegal control code in section name: <");
@.Illegal control code...@>
print_section_name(cur_section_name); printf("> "); mark_error();
}
@@ -4145,7 +4137,7 @@ equals the delimiter that began the string being copied.
j=limit+1; *j='|'; delim=0;
while (true) {
if (k>=k_limit) {
- fputs("\n! C text in section name didn't end: <",stdout);
+ printf("%s","\n! C text in section name didn't end: <");
@.C text...didn't end@>
print_section_name(cur_section_name); printf("> "); mark_error(); break;
}
@@ -4180,7 +4172,7 @@ actually output the \TEX/ material instead of merely looking at the
static void
phase_two(void) {
phase=2; reset_input();
-if (show_progress) fputs("\nWriting the output file...",stdout);
+if (show_progress) printf("%s","\nWriting the output file...");
@.Writing the output file...@>
section_count=0; format_visible=true; copy_limbo();
finish_line(); flush_buffer(out_buf,false,false);
@@ -4249,8 +4241,10 @@ else {
out_str("\\N");
@.\\N@>
{@+ char s[32];@+snprintf(s,32,"{%d}",sec_depth+1);@+out_str(s);@+}
- if (show_progress)
- printf("*%d",(int)section_count); update_terminal(); /* print a progress report */
+ if (show_progress) {
+ printf("*%d",(int)section_count);
+ update_terminal(); /* print a progress report */
+ }
}
out('{'); out_section(section_count); out('}');
@@ -4531,7 +4525,7 @@ if (no_xref)
out_str("\\end");
@.\\end@>
else {
- if (show_progress) fputs("\nWriting the index...",stdout);
+ if (show_progress) printf("%s","\nWriting the index...");
@.Writing the index...@>
if (change_exists) {
@<Tell about changed sections@>@;
@@ -4569,7 +4563,7 @@ finish_line();
fclose(active_file);
if (show_happiness) {
if (show_progress) new_line();
- fputs("Done.",stdout);
+ printf("%s","Done.");
}
check_complete(); /* was all of the change file used? */
}
@@ -4579,12 +4573,9 @@ check_complete(); /* was all of the change file used? */
@ Just before the index comes a list of all the changed sections, including
the index section itself.
-@<Private...@>=
-static sixteen_bits k_section; /* runs through the sections */
-
-@ @<Tell about changed sections@>=
+@<Tell about changed sections@>=
/* remember that the index is already marked as changed */
-k_section=0;
+sixteen_bits k_section=0; /* runs through the sections */
while (!changed_section[++k_section]);
out_str("\\ch ");
@.\\ch@>
@@ -4605,28 +4596,25 @@ list for character |c| begins at location |bucket[c]| and continues through
the |blink| array.
@<Private...@>=
-static name_pointer bucket[256];
+static name_pointer bucket[256]={NULL};
static name_pointer next_name; /* successor of |cur_name| when sorting */
static name_pointer blink[max_names]; /* links in the buckets */
@ To begin the sorting, we go through all the hash lists and put each entry
having a nonempty cross-reference list into the proper bucket.
-@<Do the first pass...@>= {
-int c;
-for (c=0; c<256; c++) bucket[c]=NULL;
-for (h=hash; h<=hash_end; h++) {
- next_name=*h;
+@<Do the first pass...@>=
+for (hash_ptr=hash; hash_ptr<=hash_end; hash_ptr++) {
+ next_name=*hash_ptr;
while (next_name) {
cur_name=next_name; next_name=cur_name->link;
if (cur_name->xref!=(void *)xmem) {
- c=(cur_name->byte_start)[0];
+ int c=(cur_name->byte_start)[0];
if (xisupper(c)) c=tolower(c);
blink[cur_name-name_dir]=bucket[c]; bucket[c]=cur_name;
}
}
}
-}
@ During the sorting phase we shall use the |cat| and |trans| arrays from
\.{CWEAVE}'s parsing algorithm and rename them |depth| and |head|. They now
@@ -4754,11 +4742,8 @@ while (sort_ptr>scrap_info) {
cur_name=next_name; next_name=blink[cur_name-name_dir];
cur_byte=cur_name->byte_start+cur_depth;
if (cur_byte==(cur_name+1)->byte_start) c=0; /* hit end of the name */
- else {
- c=*cur_byte;
- if (xisupper(c)) c=tolower(c);
- }
- blink[cur_name-name_dir]=bucket[c]; bucket[c]=cur_name;
+ else if (xisupper(c=*cur_byte)) c=tolower(c);
+ blink[cur_name-name_dir]=bucket[c]; bucket[c]=cur_name;
} while (next_name);
--sort_ptr; unbucket(cur_depth+1);
}
diff --git a/web/c_cpp/cweb/cweb.1 b/web/c_cpp/cweb/cweb.1
index 4c35edb754..192c7c9597 100644
--- a/web/c_cpp/cweb/cweb.1
+++ b/web/c_cpp/cweb/cweb.1
@@ -1,4 +1,4 @@
-.TH CWEB 1 2021-Apr-24
+.TH CWEB 1 2023-Aug-20
.
.SH NAME
ctangle, cweave \- translate CWEB to C and/or TeX
@@ -108,7 +108,7 @@ means treat 'typename' in templates like 'typedef'.
.SH FILES
The location of the files mentioned below varies from system to system.
.TP
-cwebmac.tex
+cwebmac.tex, cwebacromac.tex
TeX macros used by cweave output.
.TP
cwebman.tex
diff --git a/web/c_cpp/cweb/cwebacromac.tex b/web/c_cpp/cweb/cwebacromac.tex
new file mode 100644
index 0000000000..4c12e41382
--- /dev/null
+++ b/web/c_cpp/cweb/cwebacromac.tex
@@ -0,0 +1,175 @@
+% hypertext macros for CWEB listings (in addition to cwebmac.tex)
+% Version 1.1 --- September 2023
+\ifx\ifacrohint\undefined\endinput\fi % these are not standalone macros
+\ifluatex % LuaTeX is almost like pdfTeX
+\protected\def\pdfliteral {\pdfextension literal}
+\protected\def\pdfstartlink {\pdfextension startlink\space}
+\protected\def\pdfendlink {\pdfextension endlink}
+\protected\def\pdfoutline {\pdfextension outline\space}
+\protected\def\pdfdest {\pdfextension dest\space}
+\protected\def\pdfcatalog {\pdfextension catalog}
+\edef\pdfhorigin {\pdfvariable horigin}
+\edef\pdfvorigin {\pdfvariable vorigin}
+\let\pdfpagewidth=\pagewidth
+\let\pdfpageheight=\pageheight
+\let\pdfoutput=\outputmode
+\fi % end of LuaTeX->pdfTeX redirection macros
+
+\ifacro % The following are general pdf macros
+\def\thewidth{\the\wd0 \space}
+\def\theheight{\the\ht\strutbox\space}
+\def\thedepth{\the\dp\strutbox\space}
+\ifpdflua
+ \ifx\pdfannotlink\undefined\let\pdfannotlink\pdfstartlink\fi% for pdfTeX 0.14
+ \def\pdflink#1#2{\hbox{\pdfannotlink height \theheight depth \thedepth
+ attr{/Border [0 0 0]} goto num #1 \Blue #1\Black\pdfendlink}} % changed 3.69
+\else\def\pdflink#1#2{\setbox0=\hbox{\special{pdf: bc [ \pdflinkcolor ]}{#1}%
+ \special{pdf: ec}}\special{pdf: ann width \thewidth height \theheight
+ depth \thedepth << /Type /Annot /Subtype /Link
+ /Border [0 0 0] /A << /S /GoTo /D (#2) >> >>}\box0\relax}\fi
+\def\sanitizecommand#1#2{\addtokens\usersanitizer
+ {\noexpand\dosanitizecommand\noexpand#1{#2}}}
+\def\dosanitizecommand#1#2{\ifx\nxt#1\addF{#2}\fi}
+
+\catcode`\[=1 \catcode`\]=2 \catcode`\{=12 \catcode`\}=12
+ \def\lbchar[{] \def\rbchar[}]
+\catcode`\[=12 \catcode`\]=12 \catcode`\{=1 \catcode`\}=2
+\catcode`\~=12 \def\tildechar{~} \catcode`\~=13
+\catcode`\|=0 |catcode`|\=12 |def|bschar{\} |catcode`|\=0 \catcode`\|=12
+\def\makeoutlinetoks{\Tnumfalse\afterassignment\makeolproctok\let\nxt= }
+\def\makeolnexttok{\afterassignment\makeolproctok\let\nxt= }
+\def\makeolgobbletok{\afterassignment\makeolnexttok\let\nxt= }
+\def\addF#1{\addtokens\toksF{#1}\tokprocessedtrue}
+% now comes a routine to "sanitize" section names, for pdf outlines
+\def\makeolproctok{\tokprocessedfalse
+ \let\next\makeolnexttok % default
+ \ifx\nxt\outlinedone\let\next\outlinedone
+ \else\ifx{\nxt \else\ifx}\nxt \Tnumfalse \instrfalse % skip braces
+ \else\ifx$\nxt % or a $ sign
+ \else\ifx^\nxt \addF^\else\ifx_\nxt \addF_% sanitize ^ and _
+ \else\ifx\nxt\spacechar \addF\space
+ \else\if\noexpand\nxt\relax % we have a control sequence; is it one we know?
+ \ifx\nxt~\addF\space
+ \else\ifx\nxt\onespace\addF\space
+ \else\the\usersanitizer
+ \iftokprocessed\else\makeolproctokctli
+ \iftokprocessed\else\makeolproctokctlii
+ \iftokprocessed\else\makeolproctokctliii % if not recognised, skip it
+ \fi\fi\fi
+ \fi\fi
+ \else % we don't have a control sequence, it's an ordinary char
+ \ifx/\nxt \addF{\string\/}% quote chars special to PDF with backslash
+ \else\ifx(\nxt \addF{\string\(}\else\ifx)\nxt \addF{\string\)}%
+ \else\ifx[\nxt \addF{\string\[}\else\ifx]\nxt \addF{\string\]}%
+ \else\expandafter\makeolproctokchar\meaning\nxt
+ \fi\fi\fi\fi\fi
+ \fi\fi\fi\fi\fi \fi\fi\fi
+ \next
+}
+\def\makeolproctokchar#1 #2 #3{\addF{#3}}
+\def\makeolproctokctli{%
+ \ifx\nxt\CEE\addF{C}\let\next\makeolgobbletok % \CEE/
+ \else\ifx\nxt\UNIX\addF{UNIX}\let\next\makeolgobbletok % \UNIX/
+ \else\ifx\nxt\TEX\addF{TeX}\let\next\makeolgobbletok % \TEX/
+ \else\ifx\nxt\TeX\addF{TeX}\else\ifx\nxt\LaTeX\addF{LaTeX}%
+ \else\ifx\nxt\CPLUSPLUS\addF{C++}\let\next\makeolgobbletok % \CPLUSPLUS/
+ \else\ifx\nxt\Cee\addF{C}%
+ \else\ifx\nxt\PB \let\next\makeolgobbletok \tokprocessedtrue % \PB{...}
+ \else\ifx\nxt\.\tokprocessedtrue\instrtrue % \.{...}
+ % skip \|
+ \else\ifx\nxt\\\ifinstr\addF{\bschar\bschar}\else\tokprocessedtrue\fi
+ \else\ifx\nxt\&\ifinstr\addF&\else\tokprocessedtrue\fi
+ \else\ifx\nxt\~\ifTnum\addF{0}\else\addF\tildechar\fi % 077->\T{\~77}
+ \else\ifx\nxt\_\ifTnum\addF{E}\else\addF_\fi % 0.1E5->\T{0.1\_5}
+ \else\ifx\nxt\^\ifTnum\addF{0x}\else\addF^\fi % 0x77 -> \T{\^77}
+ \else\ifx\nxt\\\\\ifTnum\addF{0b}\else\addF\\\fi % 0b10111 -> \T{\\10111}
+ \else\ifx\nxt\$\ifTnum\tokprocessedtrue\else\addF$\fi %$% \T{77\$L}
+ \else\ifx\nxt\{\addF\lbchar\else\ifx\nxt\}\addF\rbchar
+ \else\ifx\nxt\ \addF\space\else\ifx\nxt\#\addF{\string\#}%
+ \else\ifx\nxt\PP\addF{++}\else\ifx\nxt\MM\addF{--}%
+ \fi\fi\fi\fi\fi \fi\fi\fi\fi\fi
+ \fi\fi\fi\fi\fi \fi\fi\fi\fi\fi
+ \fi\fi
+}
+\def\makeolproctokctlii{%
+ \ifx\nxt\MG\addF{->}\else\ifx\nxt\GG\addF{>>}%
+ \else\ifx\nxt\LL\addF{<<}\else\ifx\nxt\NULL\addF{NULL}%
+ \else\ifx\nxt\AND\addF&\else\ifx\nxt\OR\addF|%
+ \else\ifx\nxt\XOR\addF^\else\ifx\nxt\CM\addF\tildechar
+ \else\ifx\nxt\MOD\addF{\string\%}\else\ifx\nxt\DC\addF{::}%
+ \else\ifx\nxt\PA\addF{.*}\else\ifx\nxt\MGA\addF{->*}%
+ \else\ifx\nxt\this\addF{this}\else\ifx\nxt\?\addF?%
+ \else\ifx\nxt\E\addF{==}\else\ifx\nxt\G\addF{>=}%
+ \else\ifx\nxt\I\addF{!=}\else\ifx\nxt\K\addF{=}%
+ \else\ifx\nxt\l\addF{l}\else\ifx\nxt\L\addF{L}%
+ \else\ifx\nxt\o\addF{o}\else\ifx\nxt\O\addF{O}%
+ \else\ifx\nxt\R\addF!%
+ \else\ifx\nxt\T \Tnumtrue \let\next\makeolgobbletok
+ \tokprocessedtrue % \T{number}
+ \else\ifx\nxt\AM\addF&\else\ifx\nxt\%\addF{\string\%}%
+ \fi\fi\fi\fi\fi \fi\fi\fi\fi\fi
+ \fi\fi\fi\fi\fi \fi\fi\fi\fi\fi
+ \fi\fi\fi\fi\fi \fi
+}
+\def\makeolproctokctliii{%
+ \ifx\nxt\V\addF{||}\else\ifx\nxt\W\addF{&&}\else\ifx\nxt\Z\addF{<=}%
+ \else\ifx\nxt\*\addF*\else\ifx\nxt\Xand\addF{\space and\space}%
+ \else\ifx\nxt\Xandxeq\addF{\space and_eq\space}%
+ \else\ifx\nxt\Xbitand\addF{\space bitand\space}%
+ \else\ifx\nxt\Xbitor\addF{\space bitor\space}%
+ \else\ifx\nxt\Xcompl\addF{\space compl\space}%
+ \else\ifx\nxt\Xnot\addF{\space not\space}%
+ \else\ifx\nxt\Xnotxeq\addF{\space not_eq\space}%
+ \else\ifx\nxt\Xor\addF{\space or\space}%
+ \else\ifx\nxt\Xorxeq\addF{\space or_eq\space}%
+ \else\ifx\nxt\Xxor\addF{\space xor\space}%
+ \else\ifx\nxt\Xxorxeq\addF{\space xor_eq\space}%
+ \fi\fi\fi\fi\fi \fi\fi\fi\fi\fi
+ \fi\fi\fi\fi\fi
+}
+\def\outlinedone{\edef\outlinest{\global\noexpand\toksE={\the\toksF}}%
+ \outlinest\let\outlinedone=\relax}
+\fi % End of pdf macros
+
+\ifhint
+% The following uses HINT primitives to implement:
+% \HINThome to mark the position of the home page
+% \HINTlabel to attach a label to the top of a section
+% \HINTlink to link a section number to the section label
+% \HINTcontents to produce an 'outline' item
+% These are the top level HINT macros that are used in this file
+% No HINT primitives are used directly.
+\def\HINThome{\HINTdest name {HINT.home}%
+ \HINToutline goto name {HINT.home} depth 1 {Table of Contents}}
+\def\HINTlabel{{\let\*=\empty\HINTdest num \secstar top}}
+\def\HINTlink#1#2{\HINTstartlink goto num #1 {#1}\HINTendlink}% #2 not used ???
+\def\HINTcontents#1#2#3{\HINToutline goto num #3 depth #2 {#1}}
+\let\pdflink=\HINTlink
+\fi % End of HINT macros
+
+% Common macros for \ifacro and \ifhint
+\ifacrohint
+\def\pdfnote#1.{\setbox0=\hbox{\toksA={#1.}\toksB={}\maketoks}\the\toksA}
+\def\firstsecno#1.{\setbox0=\hbox{\toksA={#1.}\toksB={}%
+ \def\makenote{\addtokens\toksB{\the\toksC}\def\makenote{\toksD={}
+ \toksC={}\let\space\empty}\makenote}\maketoks}}
+\def\addtokens#1#2{\edef\addtoks{\noexpand#1={\the#1#2}}\addtoks}
+\def\poptoks#1#2|ENDTOKS|{\let\first=#1\toksD={#1}%
+ \ifcat\noexpand\first0\countB=`#1\else\countB=0\fi\toksA={#2}}
+\def\maketoks{\expandafter\poptoks\the\toksA|ENDTOKS|%
+ \ifnum\countB>`9 \countB=0 \fi
+ \ifnum\countB<`0
+ \ifnum0=\countC\else\makenote\fi
+ \ifx\first.\let\next=\maketoksdone\else
+ \let\next=\maketoks
+ \addtokens\toksB{\the\toksD}
+ \ifx\first,\addtokens\toksB{\space}\fi
+ \fi
+ \else \addtokens\toksC{\the\toksD}\global\countC=1\let\next=\maketoks
+ \fi
+ \next
+}
+\def\makenote{\addtokens\toksB
+ {\noexpand\pdflink{\the\toksC}{\romannumeral\the\toksC}}\toksC={}\global\countC=0}
+\def\maketoksdone{\edef\st{\global\noexpand\toksA={\the\toksB}}\st}
+\fi % End of common macros
diff --git a/web/c_cpp/cweb/cwebmac.tex b/web/c_cpp/cweb/cwebmac.tex
index 382400a3f7..e079a80ef5 100644
--- a/web/c_cpp/cweb/cwebmac.tex
+++ b/web/c_cpp/cweb/cwebmac.tex
@@ -1,20 +1,8 @@
% standard macros for CWEB listings (in addition to plain.tex)
-% Version 4.10 --- August 2023
+% Version 4.11 --- October 2023
\ifx\renewenvironment\undefined\else\endinput\fi % LaTeX will use other macros
-\xdef\fmtversion{\fmtversion+CWEB4.10}
-\chardef\cwebversion=4 \chardef\cwebrevision=10
-\input iftex.sty % TeX engine tests
-\ifx\pdf+\pdftrue\fi % for plain TeX in combination with dvipdfm
-% Uncomment the following line if you want PDF goodies to be the default
-%\ifx\pdf-\else\pdftrue\fi
-\def\pdflinkcolor{0 0 1} % the RGB values for hyperlink color
-\ifxetex\pdftrue\fi % XeTeX produces PDF output
-\ifpdftex % pdfTeX produces PDF output if \pdfoutput>0
- \def\Black{\pdfliteral{0 g 0 G}} % use rgb colors for direct PDF output too
- \def\Blue{\pdfliteral{\pdflinkcolor\space rg \pdflinkcolor\space RG}}
-\fi
-\let\ifacro=\ifpdf
-\newif\ifacrohint \ifacro\acrohinttrue\fi \ifhint\acrohinttrue\fi
+\xdef\fmtversion{\fmtversion+CWEB4.11}
+\chardef\cwebversion=4 \chardef\cwebrevision=11
\let\:=\. % preserve a way to get the dot accent
% (all other accents will still work as usual)
@@ -134,162 +122,22 @@
\newif\iftokprocessed \newif\ifTnum \newif\ifinstr
{\def\\{\global\let\spacechar= }\\ }
-\ifacro % The following are pdf macros
-\def\thewidth{\the\wd0 \space}
-\def\theheight{\the\ht\strutbox\space}
-\def\thedepth{\the\dp\strutbox\space}
-\ifpdftex
- \ifx\pdfannotlink\undefined\let\pdfannotlink\pdfstartlink\fi% for pdfTeX 0.14
- \def\pdflink#1#2{\hbox{\pdfannotlink height \theheight depth \thedepth
- attr{/Border [0 0 0]} goto num #1 \Blue #1\Black\pdfendlink}} % changed 3.69
-\else\def\pdflink#1#2{\setbox0=\hbox{\special{pdf: bc [ \pdflinkcolor ]}{#1}%
- \special{pdf: ec}}\special{pdf: ann width \thewidth height \theheight
- depth \thedepth << /Type /Annot /Subtype /Link
- /Border [0 0 0] /A << /S /GoTo /D (#2) >> >>}\box0\relax}\fi
-\def\sanitizecommand#1#2{\addtokens\usersanitizer
- {\noexpand\dosanitizecommand\noexpand#1{#2}}}
-\def\dosanitizecommand#1#2{\ifx\nxt#1\addF{#2}\fi}
-
-\catcode`\[=1 \catcode`\]=2 \catcode`\{=12 \catcode`\}=12
- \def\lbchar[{] \def\rbchar[}]
-\catcode`\[=12 \catcode`\]=12 \catcode`\{=1 \catcode`\}=2
-\catcode`\~=12 \def\tildechar{~} \catcode`\~=13
-\catcode`\|=0 |catcode`|\=12 |def|bschar{\} |catcode`|\=0 \catcode`\|=12
-\def\makeoutlinetoks{\Tnumfalse\afterassignment\makeolproctok\let\nxt= }
-\def\makeolnexttok{\afterassignment\makeolproctok\let\nxt= }
-\def\makeolgobbletok{\afterassignment\makeolnexttok\let\nxt= }
-\def\addF#1{\addtokens\toksF{#1}\tokprocessedtrue}
-% now comes a routine to "sanitize" section names, for pdf outlines
-\def\makeolproctok{\tokprocessedfalse
- \let\next\makeolnexttok % default
- \ifx\nxt\outlinedone\let\next\outlinedone
- \else\ifx{\nxt \else\ifx}\nxt \Tnumfalse \instrfalse % skip braces
- \else\ifx$\nxt % or a $ sign
- \else\ifx^\nxt \addF^\else\ifx_\nxt \addF_% sanitize ^ and _
- \else\ifx\nxt\spacechar \addF\space
- \else\if\noexpand\nxt\relax % we have a control sequence; is it one we know?
- \ifx\nxt~\addF\space
- \else\ifx\nxt\onespace\addF\space
- \else\the\usersanitizer
- \iftokprocessed\else\makeolproctokctli
- \iftokprocessed\else\makeolproctokctlii
- \iftokprocessed\else\makeolproctokctliii % if not recognised, skip it
- \fi\fi\fi\fi\fi
- \else % we don't have a control sequence, it's an ordinary char
- \ifx/\nxt \addF{\string\/}% quote chars special to PDF with backslash
- \else\ifx(\nxt \addF{\string\(}\else\ifx)\nxt \addF{\string\)}%
- \else\ifx[\nxt \addF{\string\[}\else\ifx]\nxt \addF{\string\]}%
- \else\expandafter\makeolproctokchar\meaning\nxt
- \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi
- \next
-}
-\def\makeolproctokchar#1 #2 #3{\addF{#3}}
-\def\makeolproctokctli{%
- \ifx\nxt\CEE\addF{C}\let\next\makeolgobbletok % \CEE/
- \else\ifx\nxt\UNIX\addF{UNIX}\let\next\makeolgobbletok % \UNIX/
- \else\ifx\nxt\TEX\addF{TeX}\let\next\makeolgobbletok % \TEX/
- \else\ifx\nxt\TeX\addF{TeX}\else\ifx\nxt\LaTeX\addF{LaTeX}%
- \else\ifx\nxt\CPLUSPLUS\addF{C++}\let\next\makeolgobbletok % \CPLUSPLUS/
- \else\ifx\nxt\Cee\addF{C}%
- \else\ifx\nxt\PB \let\next\makeolgobbletok \tokprocessedtrue % \PB{...}
- \else\ifx\nxt\.\tokprocessedtrue\instrtrue % \.{...}
- % skip \|
- \else\ifx\nxt\\\ifinstr\addF{\bschar\bschar}\else\tokprocessedtrue\fi
- \else\ifx\nxt\&\ifinstr\addF&\else\tokprocessedtrue\fi
- \else\ifx\nxt\~\ifTnum\addF{0}\else\addF\tildechar\fi % 077->\T{\~77}
- \else\ifx\nxt\_\ifTnum\addF{E}\else\addF_\fi % 0.1E5->\T{0.1\_5}
- \else\ifx\nxt\^\ifTnum\addF{0x}\else\addF^\fi % 0x77 -> \T{\^77}
- \else\ifx\nxt\\\\\ifTnum\addF{0b}\else\addF\\\fi % 0b10111 -> \T{\\10111}
- \else\ifx\nxt\$\ifTnum\tokprocessedtrue\else\addF$\fi %$% \T{77\$L}
- \else\ifx\nxt\{\addF\lbchar \else\ifx\nxt\}\addF\rbchar
- \else\ifx\nxt\ \addF\space \else\ifx\nxt\#\addF{\string\#}%
- \else\ifx\nxt\PP\addF{++}\else\ifx\nxt\MM\addF{--}%
- \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi
-}
-\def\makeolproctokctlii{%
- \ifx\nxt\MG\addF{->}\else\ifx\nxt\GG\addF{>>}%
- \else\ifx\nxt\LL\addF{<<}\else\ifx\nxt\NULL\addF{NULL}%
- \else\ifx\nxt\AND\addF&\else\ifx\nxt\OR\addF|%
- \else\ifx\nxt\XOR\addF^\else\ifx\nxt\CM\addF\tildechar
- \else\ifx\nxt\MOD\addF{\string\%}\else\ifx\nxt\DC\addF{::}%
- \else\ifx\nxt\PA\addF{.*}\else\ifx\nxt\MGA\addF{->*}%
- \else\ifx\nxt\this\addF{this}\else\ifx\nxt\?\addF?%
- \else\ifx\nxt\E\addF{==}\else\ifx\nxt\G\addF{>=}%
- \else\ifx\nxt\I\addF{!=}\else\ifx\nxt\K\addF{=}%
- \else\ifx\nxt\l\addF{l}\else\ifx\nxt\L\addF{L}%
- \else\ifx\nxt\o\addF{o}\else\ifx\nxt\O\addF{O}%
- \else\ifx\nxt\R\addF!%
- \else\ifx\nxt\T \Tnumtrue \let\next\makeolgobbletok
- \tokprocessedtrue % \T{number}
- \else\ifx\nxt\AM\addF&\else\ifx\nxt\%\addF{\string\%}%
- \fi\fi\fi\fi\fi \fi\fi\fi\fi\fi
- \fi\fi\fi\fi\fi \fi\fi\fi\fi\fi
- \fi\fi\fi\fi\fi\fi
-}
-\def\makeolproctokctliii{%
- \ifx\nxt\V\addF{||}\else\ifx\nxt\W\addF{&&}\else\ifx\nxt\Z\addF{<=}%
- \else\ifx\nxt\*\addF*\else\ifx\nxt\Xand\addF{\space and\space}%
- \else\ifx\nxt\Xandxeq\addF{\space and_eq\space}%
- \else\ifx\nxt\Xbitand\addF{\space bitand\space}%
- \else\ifx\nxt\Xbitor\addF{\space bitor\space}%
- \else\ifx\nxt\Xcompl\addF{\space compl\space}%
- \else\ifx\nxt\Xnot\addF{\space not\space}%
- \else\ifx\nxt\Xnotxeq\addF{\space not_eq\space}%
- \else\ifx\nxt\Xor\addF{\space or\space}%
- \else\ifx\nxt\Xorxeq\addF{\space or_eq\space}%
- \else\ifx\nxt\Xxor\addF{\space xor\space}%
- \else\ifx\nxt\Xxorxeq\addF{\space xor_eq\space}%
- \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi
- \fi\fi\fi\fi\fi
-}
-\def\outlinedone{\edef\outlinest{\global\noexpand\toksE={\the\toksF}}%
- \outlinest\let\outlinedone=\relax}
-\fi % End of pdf macros
-
-\ifhint
-% The following uses HINT primitives to implement:
-% \HINThome to mark the position of the home page
-% \HINTlabel to attach a label to the top of a section
-% \HINTlink to link a section number to the section label
-% \HINTcontents to produce an 'outline' item
-% These are the top level HINT macros that are used in this file
-% No HINT primitives are used directly.
-\def\HINThome{\HINTdest name {HINT.home}%
- \HINToutline goto name {HINT.home} depth 1 {Table of Contents}}
-\def\HINTlabel{{\let\*=\empty\HINTdest num \secstar top}}
-\def\HINTlink#1#2{\HINTstartlink goto num #1 {#1}\HINTendlink}% #2 not used ???
-\def\HINTcontents#1#2#3{\HINToutline goto num #3 depth #2 {#1}}
-\let\pdflink=\HINTlink
-\fi % End of HINT macros
-
-% Common macros for \ifacro and \ifhint
-\ifacrohint
-\def\pdfnote#1.{\setbox0=\hbox{\toksA={#1.}\toksB={}\maketoks}\the\toksA}
-\def\firstsecno#1.{\setbox0=\hbox{\toksA={#1.}\toksB={}%
- \def\makenote{\addtokens\toksB{\the\toksC}\def\makenote{\toksD={}
- \toksC={}\let\space\empty}\makenote}\maketoks}}
-\def\addtokens#1#2{\edef\addtoks{\noexpand#1={\the#1#2}}\addtoks}
-\def\poptoks#1#2|ENDTOKS|{\let\first=#1\toksD={#1}%
- \ifcat\noexpand\first0\countB=`#1\else\countB=0\fi\toksA={#2}}
-\def\maketoks{\expandafter\poptoks\the\toksA|ENDTOKS|%
- \ifnum\countB>`9 \countB=0 \fi
- \ifnum\countB<`0
- \ifnum0=\countC\else\makenote\fi
- \ifx\first.\let\next=\maketoksdone\else
- \let\next=\maketoks
- \addtokens\toksB{\the\toksD}
- \ifx\first,\addtokens\toksB{\space}\fi
- \fi
- \else \addtokens\toksC{\the\toksD}\global\countC=1\let\next=\maketoks
- \fi
- \next
-}
-\def\makenote{\addtokens\toksB
- {\noexpand\pdflink{\the\toksC}{\romannumeral\the\toksC}}\toksC={}\global\countC=0}
-\def\maketoksdone{\edef\st{\global\noexpand\toksA={\the\toksB}}\st}
-\fi % End of common macros
-
-\def\pdfURL#1#2{\ifpdf \ifpdftex\pdfannotlink height \theheight depth \thedepth
+% Here we decide the output format, depending on the TeX engine in use:
+\input iftex.sty % TeX engine tests
+\ifx\pdf+\pdftrue\fi % for plain TeX in combination with dvipdfm
+% Uncomment the following line if you want PDF goodies to be the default
+%\ifx\pdf-\else\pdftrue\fi
+\ifxetex\pdftrue\fi % XeTeX produces PDF output
+\ifpdf \def\pdflinkcolor{0 0 1} \fi % the RGB values for hyperlink color
+\let\ifacro=\ifpdf
+\newif\ifacrohint \ifacro\acrohinttrue\fi \ifhint\acrohinttrue\fi
+\newif\ifpdflua \ifluatex\pdfluatrue\fi \ifpdftex\pdfluatrue\fi
+\ifpdflua % luaTeX and pdfTeX produce PDF output if \pdfoutput>0 (default)
+ \def\Black{\pdfliteral{0 g 0 G}} % use rgb colors for direct PDF output too
+ \def\Blue{\pdfliteral{\pdflinkcolor\space rg \pdflinkcolor\space RG}}
+\fi
+\ifacrohint \input cwebacromac \fi % load hypertext macros
+\def\pdfURL#1#2{\ifpdf \ifpdflua\pdfannotlink height \theheight depth \thedepth
attr {/Border [0 0 0]} user { /Type /Annot /Subtype /Link /A
<< /S /URI /URI (#2) >>}\Blue #1\Black \pdfendlink % changed in 3.69
\else {\setbox0=\hbox{\special{pdf: bc [ \pdflinkcolor ]}{#1}%
@@ -306,7 +154,7 @@
\ifhint\HINTlabel\fi% Start page before section
\noindent{\let\*=\lapstar\bf\secstar.\quad}%
\ifacro \smash{\raise\baselineskip\hbox to0pt{\let\*=\empty
- \ifpdftex \pdfdest num \secstar fith%
+ \ifpdflua \pdfdest num \secstar fith%
\else \special{pdf: dest (\romannumeral\secstar)
[ @thispage /FitH @ypos ]}\fi}}\fi}
\let\startsection=\stsec
@@ -347,7 +195,7 @@
\edef\gtitletoks{\expandafter\stripprefix\meaning\gtitletoks}%
\edef\next{\write\cont{\ZZ{\gtitletoks}{#1}{\secno}% write to contents file
{\noexpand\the\pageno}{\the\toksE}}}\next % \ZZ{title}{depth}{sec}{page}{ss}
- \ifpdf \ifpdftex\expandafter\xdef\csname curr#1\endcsname{\secno}
+ \ifpdf \ifpdflua\expandafter\xdef\csname curr#1\endcsname{\secno}
\ifnum#1>0\countB=#1 \advance\countB by-1
\advancenumber{chunk\the\countB.\expnumber{curr\the\countB}}\fi
\else \special{pdf: outline #1 << /Title (\the\toksE)
@@ -428,7 +276,7 @@
\def\title{\expandafter\uppercase\expandafter{\jobname}}
\def\topofcontents{\centerline{\titlefont\title}\vskip.7in
\vfill} % this material will start the table of contents page
-\def\startpdf{\ifpdf \ifpdftex\pdfcatalog{/PageMode /UseOutlines}
+\def\startpdf{\ifpdf \ifpdflua\pdfcatalog{/PageMode /UseOutlines}
\else {\special{pdf: docview << /PageMode /UseOutlines >>}}\fi\fi}
\def\botofcontents{\vfill
\centerline{\covernote}} % this material will end the table of contents page
@@ -450,7 +298,7 @@
\newwrite\cont
\output{\setbox0=\page % the first page is garbage
\openout\cont=\contentsfile
- \write\cont{\catcode `\noexpand\@=11\relax} % \makeatletter
+ \write\cont{\catcode `\noexpand\@=11\relax} % \makeatletter
\global\output{\normaloutput\page\lheader\rheader}}
\setpage
\vbox to \vsize{} % the first \topmark won't be null
@@ -462,7 +310,7 @@
\def\inx{\par\vskip6pt plus 1fil % we are beginning the index
\def\page{\box255 } \normalbottom
\write\cont{} % ensure that the contents file isn't empty
- \write\cont{\catcode `\noexpand\@=12\relax} % \makeatother
+ \write\cont{\catcode `\noexpand\@=12\relax} % \makeatother
\closeout\cont % the contents information has been fully gathered
\output{\ifpagesaved\normaloutput{\box\sbox}\lheader\rheader\fi
\global\setbox\sbox=\page \global\pagesavedtrue \mark{\topmark}}
@@ -490,7 +338,7 @@
\def\fin{\par\vfill\eject % this is done when we are ending the index
\ifpagesaved\null\vfill\eject\fi % output a null index column
\if L\lr\else\null\vfill\eject\fi % finish the current page
- \ifpdf \ifpdftex \makebookmarks % added in Version 3.68
+ \ifpdf \ifpdflua \makebookmarks % added in Version 3.68
\countsections \fi\fi % and in Version 4.9
\parfillskip 0pt plus 1fil
\def\grouptitle{NAMES OF THE SECTIONS}
@@ -505,8 +353,8 @@
\def\Us{\note{Used in sections}} % crossref for uses of a section
\def\I{\par\hangindent 2em}\let\*=*
\ifacro \def\outsecname{Names of the sections} \let\Xpdf\X
-% \ifpdftex \makebookmarks \pdfdest name {NOS} fitb % in versions < 3.68
- \ifpdftex \pdfdest name {NOS} fith % changed in version 3.69
+% \ifpdflua \makebookmarks \pdfdest name {NOS} fitb % in versions < 3.68
+ \ifpdflua \pdfdest name {NOS} fith % changed in version 3.69
\pdfoutline goto name {NOS} count -\the\countD {\outsecname}
\def\X##1:##2\X{\Xpdf##1:##2\X \firstsecno##1.%
{\toksF={}\makeoutlinetoks##2\outlinedone\outlinedone}%
diff --git a/web/c_cpp/cweb/cwebman.pdf b/web/c_cpp/cweb/cwebman.pdf
index 8cfef0ea10..8201815b56 100644
--- a/web/c_cpp/cweb/cwebman.pdf
+++ b/web/c_cpp/cweb/cwebman.pdf
Binary files differ
diff --git a/web/c_cpp/cweb/cwebman.tex b/web/c_cpp/cweb/cwebman.tex
index 108bd32f88..7a906cc954 100644
--- a/web/c_cpp/cweb/cwebman.tex
+++ b/web/c_cpp/cweb/cwebman.tex
@@ -35,7 +35,7 @@
\def\lheader{\mainfont\the\pageno\hfill\sc\runninghead\hfill}
\def\rheader{\hfill\sc\runninghead\hfill\mainfont\the\pageno}
-\def\runninghead{{\tentt CWEB} USER MANUAL (VERSION 4.10)}
+\def\runninghead{{\tentt CWEB} USER MANUAL (VERSION 4.11)}
% This verbatim mode assumes that ! marks are !! in the text being copied.
\def\verbatim{\begingroup
@@ -49,7 +49,7 @@
\null\vfill
\centerline{\titlefont The {\ttitlefont CWEB} System of
Structured Documentation}
-\vskip 18pt\centerline{(Version 4.10 --- August 2023)}
+\vskip 18pt\centerline{(Version 4.11 --- December 2023)}
\vskip 24pt
\centerline{\authorfont Donald E. Knuth and Silvio Levy}
\vfill
@@ -57,9 +57,6 @@
\noindent
\TeX\ is a trademark of the American Mathematical Society.
-\noindent
-Acrobat Reader is a trademark of Adobe Systems Incorporated.
-
\bigskip\noindent
The printed form of this manual is copyright \copyright\ 1994
by Addison-Wesley Publishing Company, Inc. All rights reserved.
@@ -1147,29 +1144,27 @@ the `\.{@\#}' will put extra space after `$\langle\,$Other locals$\,\rangle$'.
Many people have of course noticed analogies between \.{CWEB} and the
World Wide Web. The \.{CWEB} macros are in fact set up so that the output of
-\.{CWEAVE} can be converted easily into Portable Document Format,
-with clickable hyperlinks that can be read with Adobe's Acrobat Reader,
-using a widely available open-source program called \.{dvipdfm} developed
-by Mark~A. Wicks. After using \.{CWEAVE} to convert \.{cob.w} into
-\.{cob.tex}, you can prepare and view a hypertext version of the program
-by giving the commands
+\.{CWEAVE} can be converted easily into Portable Document Format, with
+clickable hyperlinks that can be read with your favorite {\mc PDF} viewer,
+using a widely available open-source program called \.{dvipdfm} developed by
+Mark~A. Wicks. After using \.{CWEAVE} to convert \.{cob.w} into \.{cob.tex},
+you can prepare a hypertext version of the program by giving the commands
$$\vbox{\halign{\.{#}\hfil\cr
tex "\\let\\pdf+ \\input cob"\cr
-dvipdfm cob\cr
-acroread cob.pdf\cr}}$$
+dvipdfm cob\cr}}$$
instead of invoking \TeX\ in the normal way. (Thanks to Hans Hagen,
C\'esar Augusto Rorato Crusius, and Julian Gilbey
for the macros that make this work.)
Alternatively, thanks to H\`an Th\^e\kern-.3em\raise.3ex\hbox{\'{}} Th\`anh
and Andreas Scherer, you can generate \.{cob.pdf} in one step by simply
saying `\.{pdftex}~\.{cob}'.
-And a third way to create PDF output from \.{CWEB} input is to say
-`\.{xetex}~\.{cob}'.
+Alternative ways to create {\mc PDF} output from \.{CWEB} input are to say
+`\.{xetex}~\.{cob}' or `\.{luatex}~\.{cob}'.
Similar output for ``smart'' devices can be created with Martin Ruckert's
Hi\TeX\ and its dynamic \.{HINT} format; just say `\.{hitex}~\.{cob}'.
\.{HINT} files can be viewed with the \.{hintview} program, which is available
-for {\mc GNU}/Linux, {\mc MS}~Windows, and Android.
+from \.{https://hint.userweb.mwn.de/hint/hintview.html}.
A more elaborate system called \.{CTWILL}, which extends the usual cross
references of \.{CWEAVE} by preparing links from the uses of identifiers
@@ -1187,7 +1182,7 @@ contains an excerpt from the \.{CWEB} program itself. The reader who
examines the listings in this appendix carefully will get a good
feeling for the basic ideas of \.{CWEB}.
-Appendix B is the file that sets \TEX/ up to accept
+Appendix B displays the files that set \TEX/ up to accept
the output of \.{CWEAVE}, and Appendix~C discusses how to use some of those
macros to vary the output formats.
@@ -1524,20 +1519,28 @@ features needed by the output of \.{CWEAVE}.
\vskip6pt
\begingroup \def\tt{\eighttt} \baselineskip9pt
-\def\printmacs{\begingroup
+\def\printmacs#1{\begingroup
\def\do##1{\catcode`##1=12 } \dospecials
\parskip 0pt \parindent 0pt
\catcode`\ =13 \catcode`\^^M=13
- \tt \verbatimdefs \input cwebmac \endgroup}
-\printmacs
+ \tt \verbatimdefs \input cweb#1mac \endgroup}
+\printmacs{\empty}
+
+\vskip6pt \baselineskip12pt
+\noindent And here comes the file that extends \.{cwebmac.tex} in order to
+support the ``hypertext'' features needed by the enhanced \TEX/ engines when
+processing the output of \.{CWEAVE}.
+
+\vskip6pt \baselineskip9pt
+\printmacs{acro}
\endgroup
\vfill\eject
\def\runninghead{APPENDIX C --- NOTES ON FORMATTING}
\section Appendix C: How to use \.{CWEB} macros.
-The macros in \.{cwebmac} make it possible to produce a variety of formats
-without editing the output of \.{CWEAVE}, and the purpose of this appendix
-is to explain some of the possibilities.
+The macros in \.{cwebmac} and \.{cwebacromac} make it possible to produce a
+variety of formats without editing the output of \.{CWEAVE}, and the purpose
+of this appendix is to explain some of the possibilities.
\def\point#1.{\yskip\indent#1.\quad\ignorespaces}
@@ -1607,7 +1610,7 @@ $$\lpile{\.{\\def\\topofcontents\{\\null\\vfill}\cr
\.{ { }\\titlefalse \% include headline on the contents page}\cr
\.{ { }\\def\\rheader\{\\mainfont The \{\\tt CWEAVE\}{ }processor\\hfil\}}\cr
\.{ { }\\centerline\{\\titlefont The \{\\ttitlefont CWEAVE\}{ }processor\}}\cr
- \.{ { }\\vskip 15pt \\centerline\{(Version 4.10)\}{ }\\vfill\}}\cr}$$
+ \.{ { }\\vskip 15pt \\centerline\{(Version 4.11)\}{ }\\vfill\}}\cr}$$
Redefining \.{\\rheader}, which is the headline for right-hand pages,
suffices in this case to put the desired information at the top of the
contents page.
@@ -1615,8 +1618,8 @@ contents page.
\point 9. Data for the table of contents is written to a file that
is read after the indexes have been \TEX/ed; there's one line of data
for every starred section. The file \.{common.toc} might look like this:
-$$\lpile{\.{\\ZZ \{Introduction\}\{0\}\{1\}\{29\}\{\}}\cr
- \.{\\ZZ \{The character set\}\{1\}\{21\}\{35\}\{\}}\cr}$$
+$$\lpile{\.{\\ZZ \{Introduction\}\{1\}\{1\}\{30\}\{\}}\cr
+ \.{\\ZZ \{The character set\}\{1\}\{21\}\{36\}\{\}}\cr}$$
and so on. The \.{\\topofcontents} macro could
redefine \.{\\ZZ} so that the information appears in any desired format.
(See also point~19 below.)
@@ -1735,9 +1738,9 @@ You can send email to
\\pdfURL\{the author\}\{mailto:andreas\\UNDER/github@@freenet.de\}\cr
or visit \\pdfURL\{his home page\}\{https://github.com/ascherer\}\cr}}$$
In a {\mc PDF} document, the first argument will appear in blue as
-clickable text; the Acrobat reader, if correctly configured, will then
-redirect those links to the user's browser and open either the
-email client or the HTML viewer. In a hardcopy document, both arguments
+clickable text; the {\mc PDF} viewer, if correctly configured, will then
+redirect those links to the user's browser and open either the email client
+or the {\mc HTML} viewer. In a hardcopy document, both arguments
will be printed ({\tt the second in parentheses and typewriter type}).
Certain special characters in an Internet address need to be handled
in a somewhat awkward way, so that \.{CWEAVE} and/or \TeX\
@@ -1749,10 +1752,10 @@ titles in the table of contents, some of which will be subsidiary to
others if the depth feature of \.{@*} has been used.
Such bookmark entries are also known as ``outlines.''
Moreover, the final group title, `Names of the sections',
-can be opened up to list every section name; Acrobat users can therefore
+can be opened up to list every section name; users can therefore
navigate easily to any desired section.
-The macros of \.{cwebmac.tex} are careful to ``sanitize'' all the names
+The macros of \.{cwebacromac.tex} are careful to ``sanitize'' all the names
that appear as bookmarks, by removing special characters and
formatting codes that are inappropriate for the limited typographic
capabilities of {\mc PDF} outlines. For example, one section of \.{CWEAVE}
diff --git a/web/c_cpp/cweb/prod.w b/web/c_cpp/cweb/prod.w
index c7254cc4ee..711d6477e7 100644
--- a/web/c_cpp/cweb/prod.w
+++ b/web/c_cpp/cweb/prod.w
@@ -2,7 +2,7 @@
% This program by Silvio Levy and Donald E. Knuth
% is based on a program by Knuth.
% It is distributed WITHOUT ANY WARRANTY, express or implied.
-% Version 4.10 --- August 2023
+% Version 4.11 --- December 2023
%
@ Here is a table of all the productions. Each production that
combines two or more consecutive scraps implicitly inserts a {\tt \$}
diff --git a/web/pwebmac/README.md b/web/pwebmac/README.md
index cfd364de09..e85b89cbc4 100644
--- a/web/pwebmac/README.md
+++ b/web/pwebmac/README.md
@@ -1,7 +1,7 @@
# pwebmac – Consolidated WEB macros for DVI, PDF, and HINT output
The original [WEB](https://ctan.org/pkg/web) system by Donald Knuth has the
-macros `webmac.tex` that produce DVI output only; for historic reasons, it
+macros `webmac.tex` that produce DVI output only; for historic reasons, they
will never be modified (apart from catastrophic errors).
Hàn Thế Thành has extended these macros in his (outdated?) `pdfwebmac.tex` for
PDF output (only) with [pdfTeX](https://ctan.org/pkg/pdftex).
@@ -19,7 +19,7 @@ for Martin Ruckert's “[HiTeX](https://ctan.org/pkg/hitex)” engine and its
Its initial application is the production of PDF and HINT files for all major
WEB programs for “TeX and friends” as distributed in
[TeX Live](https://www.tug.org/texlive). For this purpose, the shell script
-`makeall` was whipped together; it provides various commandline options and
+`makeall` was whipped together; it provides various command-line options and
works around several “quirks” in the WEB sources. The resulting collections
of PDF and HINT documents can be browsed in the
[`knuth-pdf`](https://ctan.org/pkg/knuth-pdf) and
@@ -27,13 +27,15 @@ of PDF and HINT documents can be browsed in the
WEB programmers who want to use `pwebmac.tex` instead of the default
`webmac.tex` in their programs have to change the first line in the TeX file
-created by `weave`. From there, all depends on the “TeX engine” you use:
-“plain TeX” by default creates DVI output, “plain TeX” with the invocation
-`tex "\let\pdf+\input…"`, `pdftex`, `luatex`, and `xetex` create PDF output
-with clickable links and bookmarks (depending on your PDF viewer), and `hitex`
-creates HINT output that can be viewed with the
+created by `WEAVE` (try `weave -p`). From there, all depends on the “TeX
+engine” you use: “plain TeX” by default creates DVI output, “plain TeX” with
+the invocation `tex "\let\pdf+\input…"`, as well as `pdftex`, `luatex`, and
+`xetex` create PDF output with clickable links and bookmarks (with `pdftex`
+and `luatex` you are advised to apply the “`--shell-escape`” command-line
+option in order to avoid an internal miscalculation in the resulting PDF
+file), and `hitex` creates HINT output that can be viewed with the
[`hintview`](https://hint.userweb.mwn.de/hint/hintview.html) program.
The `pwebmac` package is free software and may be used without constraints.
-This is version **4.10** of the `pwebmac` package — 2023-10-07, Andreas Scherer.
+This is version **4.11** of the `pwebmac` package — 2023-12-02, Andreas Scherer.
diff --git a/web/pwebmac/index.md b/web/pwebmac/index.md
index a580c752a6..90ddc7d131 100644
--- a/web/pwebmac/index.md
+++ b/web/pwebmac/index.md
@@ -108,4 +108,4 @@ directly.
## Happy C/WEB Programming!
-2023-06-11 Andreas Scherer
+2023-12-02 Andreas Scherer
diff --git a/web/pwebmac/makeall b/web/pwebmac/makeall
index 602f2377c5..b5b53ff72e 100755
--- a/web/pwebmac/makeall
+++ b/web/pwebmac/makeall
@@ -86,60 +86,48 @@ do
esac
done
-CWEAVE="cweave -f +lX"
-CTWILL="ctwill -f +lpdf"
+CWEAVE="cweave -f +lX +bph"
+CTWILL="ctwill -f +lpdf +bph"
+HITEX="hitex --compress"
PAX="pax -wvzf"
-SED_I="sed -i" # non-GNU-sed requires an extra '' argument for '-i' option.
PDF=pdf # default extension for 'knuth-pdf'
-HITEX="hitex --compress"
+SED_I="sed -i" # non-GNU-sed requires an extra '' argument for '-i' option.
+WEAVE="weave"
-# HINT format
-if [ hitex = "$TEX" ]
-then
- CTWILL="$CTWILL +P"
- TEX="$HITEX"
- PDF=hnt # default extension for 'knuth-hint'
- PDFTOCFRONT=false # use 'hintview -h' to start with TOC page
- VALID=false # HiTeX has no command-line option '--shell-escape'
-fi
+case "$TEX" in
+ hitex ) # HINT format
+ CTWILL="$CTWILL +P"
+ TEX="$HITEX"
+ PDF=hnt # default extension for 'knuth-hint'
+ PDFTOCFRONT=false # use 'hintview -h' to start with TOC page
+ VALID=false ;; # HiTeX has no command-line option '--shell-escape'
+
+ pdftex | luatex ) # actually only necessary for 'pwebmac.tex'
+ VALID=true ;;
+
+ * ) VALID=false ;; # plain TeX and XeTeX use different approach
+esac
# Valid PDF output from 'pdftex' and 'luatex': In 'pwebmac.tex' set '\countD'
# to the actual number of @<named modules@>, not the number of all sections.
-if ( $VALID )
+if $VALID
then
+ NEW=true # PDF output requires 'pwebmac.tex'
TEX="$TEX --shell-escape"
fi
+# Use alternative TeX macros more suited for PDF output.
+if $NEW
+then WEAVE="$WEAVE -p"
+fi
+
# WEB and CWEB programs we want to get formatted
for f in $FILES
do
f=$(basename $f .web)
- if [ ctwill = $f ]
- then
- # apply tons of editorial changes to 'ctwill.w'
- if [ "$HITEX" = "$TEX" ]
- then ctie -m $f.w cweave.w $f-w2c.ch $f-hint.ch
- else ctie -m $f.w cweave.w $f-w2c.ch $f-mini.ch
- fi
- cp -an $KNUTHWARE/cwebdir/*.bux .
- $CTWILL $f # prime the pump
- $CTWILL $f # get decent answers
-
- elif [ twill = $f ]
- then
- tie -m $f.web weave.web weave.ch weav-$f.ch
- weave $f
-
- elif [ glue = $f ]
- then
- weave $f # no 'glue.ch' at this time
-
- elif [ hitex = $f ]
- then
- cweave $f # no 'hitex.ch' at this time
-
- elif $CHANGES
+ if $CHANGES && echo $f | grep -v -q -E 'twill|glue|hitex'
+ # These are changes in and of themselves
then
case $f in
# CWEB programs have individual changefiles
@@ -153,49 +141,48 @@ do
# main WEB programs have complex change files
tex | mf | pdftex | xetex )
WEBINPUTS=$KNUTHWARE/../../Work//:$WEBINPUTS: \
- weave $f $f-final ;;
-
- # TWILL is a change in and of itself
- twill ) ;;
+ $WEAVE $f $f-final
- # HiTeX is a stand-alone version of TeX
- hitex ) ;;
+ # FIX: XeTeX uses '\pdfTeX' from section 114,
+ # which is not changed and thus 'disappears';
+ # repeat in preamble.
+ if [ xetex = $f ]
+ then $SED_I -e "s/\(\\\\let\\\\maybe\)/\\\\def\\\\pdfTeX{pdf\\\\TeX}\n\1/" $f.tex
+ fi ;;
# all other WEB codes have singular changefiles
- * ) weave $f $f ;;
+ * ) $WEAVE $f $f ;;
esac
- # FIX: XeTeX uses '\pdfTeX' from section 114, which is not
- # changed and thus 'disappears'; repeat in preamble.
- if [ xetex = $f ]
- then
- $SED_I -e "s/\(\\\\let\\\\maybe\)/\\\\def\\\\pdfTeX{pdf\\\\TeX}\n\1/" \
- $f.tex
- fi
-
# only document changed modules/sections
$SED_I -e "s/\(\\\\let\\\\maybe=\)\\\\iftrue/\1\\\\iffalse/" \
$f.tex
else
case $f in
+ ctwill )
+ # apply tons of editorial changes to 'ctwill.w'
+ if [ "$HITEX" = "$TEX" ]
+ then ctie -m $f.w cweave.w $f-w2c.ch $f-hint.ch
+ else ctie -m $f.w cweave.w $f-w2c.ch $f-mini.ch
+ fi
+ $CTWILL $f # prime the pump
+ $CTWILL $f ;; # get decent answers
+
c* | refsort | twinx | tie | hitex ) $CWEAVE $f ;;
- * ) weave $f ;;
+
+ twill )
+ tie -m $f.web weave.web weave.ch weav-$f.ch
+ $WEAVE $f ;;
+
+ * ) $WEAVE $f ;;
esac
fi
- if $NEW
+ # 'pwebmac' is for WEB only; do nothing for CWEB programs
+ if $NEW && echo $f | grep -v -q -E '^c|refsort|twinx|tie|hitex'
then
- # use extended WEB macros for TeX Live PDF documentation
- $SED_I -e "1 s/\\\\input webmac/\\\\input pwebmac/" $f.tex
-
# timestamp on table-of-contents page or the first page
case $f in
- # do nothing for CWEB programs
- c* | refsort | twinx | tie ) ;;
-
- hitex )
- $SED_I -e "s/\(\\\\def\\\\topofcontents\)/\\\\datethis\n\\\\emergencystretch=.1\\\\hsize\n\1/" $f.tex ;;
-
bibtex | patgen | tangle | weave )
$SED_I -e "s/\(\\\\def\\\\title\)/\\\\datecontentspage\n\1/" $f.tex ;;
@@ -247,8 +234,7 @@ FI
# FIX: don't wait for Oren Patashnik.
bibtex ) $SED_I -e "s/\\\\def\\\\titlepage{F}/\\\\titletrue/" $f.tex
if ! $CHANGES
- then
- $SED_I -e "71,78d" $f.tex
+ then $SED_I -e "71,78d" $f.tex
fi ;;
# FIX: 'glue.web' obviously uses an old 'webmac.tex'.
@@ -259,29 +245,27 @@ FI
# appear correctly in the bookmarks, too.
pdftex )
if $NEW && [ tex != "$TEX" ] && [ "$HITEX" != "$TEX" ]
- then
- $SED_I -e "s/\(\\\\def\\\\pdfTeX{pdf\\\\TeX}\)/\1 \\\\sanitizecommand\\\\pdfTeX{pdfTeX}\\\\sanitizecommand\\\\eTeX{e-TeX}/" \
- $f.tex
+ then $SED_I -e "s/\(\\\\def\\\\pdfTeX{pdf\\\\TeX}\)/\1 \\\\sanitizecommand\\\\pdfTeX{pdfTeX}\\\\sanitizecommand\\\\eTeX{e-TeX}/" $f.tex
fi ;;
# FIX: weave uses '\max' in name of module 173; this should
# appear correctly in the bookmarks, too.
weave )
if $NEW && [ tex != "$TEX" ] && [ "$HITEX" != "$TEX" ]
- then
- $SED_I -e "s/\(\\\\def\\\\({}\)/\\\\sanitizecommand\\\\max{max}\n\1/" \
- $f.tex
+ then $SED_I -e "s/\(\\\\def\\\\({}\)/\\\\sanitizecommand\\\\max{max}\n\1/" $f.tex
fi ;;
# FIX: purge obsolete macros from XeTeX.
xetex ) $SED_I -e "/\\\\input xewebmac/d" $f.tex ;;
+
+ # timestamp on table-of-contents page or the first page
+ hitex ) $SED_I -e "s/\(\\\\def\\\\topofcontents\)/\\\\datethis\n\\\\emergencystretch=.1\\\\hsize\n\1/" $f.tex ;;
esac
# shift table-of-contents pages to the front in PDF
- if $PDFTOCFRONT && [ ctwill != $f ] && [ hitex != $f ]
+ if $PDFTOCFRONT && echo $f | grep -v -q -E 'ctwill|hitex'
then
- $SED_I -e "0,/\\\\N[1{]/s/\(\\\\N[1{]\)/\\\\input pdfwebtocfront\n\n\1/" \
- $f.tex
+ $SED_I -e "0,/\\\\N[1{]/s/\(\\\\N[1{]\)/\\\\input pdfwebtocfront\n\n\1/" $f.tex
# only XeTeX can process XETEX.WEB
if [ xetex = $f ]
@@ -295,24 +279,24 @@ FI
fi
fi
- if [ xetex = $f ] # only XeTeX can process XETEX.WEB
- then $f $f
- elif [ ctwill = $f ] # gives two different outcomes
- then
- # sort mini-indexes
- if [ "$HITEX" = "$TEX" ]
- then # directly in the TeX file
- proofsort $f.tex > $f-sorted.tex
- mv $f-sorted.tex $f.tex
- else # in the TeX-created .ref file
- $TEX $f
- ctwill-refsort < $f.ref > $f.sref
- fi
- $TEX $f
- elif [ refsort = $f ]
- then $TEX -interaction nonstopmode $f
- else $TEX $f
- fi
+ case $f in
+ xetex ) $f $f ;; # only XeTeX can process XETEX.WEB
+
+ ctwill ) # gives two different outcomes
+ if [ "$HITEX" = "$TEX" ] # sort mini-indexes
+ then # directly in the TeX file
+ ctwill-proofsort < $f.tex > $f-sorted.tex
+ mv $f-sorted.tex $f.tex
+ else # in the TeX-created .ref file
+ $TEX $f
+ ctwill-refsort < $f.ref > $f.sref
+ fi
+ $TEX $f ;;
+
+ refsort ) $TEX -interaction nonstopmode $f ;;
+
+ * ) $TEX $f ;;
+ esac
done
if ( $PDFTOCFRONT || [ "$HITEX" = "$TEX" ] ) && ! $FILESELECT
@@ -385,9 +369,7 @@ then
f=$(kpsewhich -engine tex cwebman)
tie -m $(basename $f) $f $(basename $f .tex)-w2c.ch
if [ "$HITEX" = "$TEX" ]
- then
- $SED_I -e "s/\(\\\\input cwebmac\)/\1\n\\\\input hiplainpage/" \
- cwebman.tex
+ then $SED_I -e "s/\(\\\\input cwebmac\)/\1\n\\\\input hiplainpage/" cwebman.tex
fi
touch pages.tex # let 'manmac' produce output at all
diff --git a/web/pwebmac/pwebmac.tex b/web/pwebmac/pwebmac.tex
index 880075cb2a..a7bdc717b9 100644
--- a/web/pwebmac/pwebmac.tex
+++ b/web/pwebmac/pwebmac.tex
@@ -5,19 +5,7 @@
% macro integration \`a la CWEB by Andreas Scherer <andreas_tex@freenet.de>.
% This file is not copyrighted and can be used freely.
\ifx\renewenvironment\undefined\else\endinput\fi % LaTeX will use other macros
-\xdef\fmtversion{\fmtversion+WEBMAC4.10}
-\input iftex.sty % TeX engine tests
-\ifx\pdf+\pdftrue\fi
-% Uncomment the following line if you want PDF goodies to be the default
-%\ifx\pdf-\else\pdftrue\fi
-\def\pdflinkcolor{0 0 1} % the RGB values for hyperlink color
-\ifxetex\pdftrue\fi % XeTeX produces PDF output
-\newif\ifacrohint \ifpdf\acrohinttrue\fi \ifhint\acrohinttrue\fi
-\newif\ifpdflua \ifluatex\pdfluatrue\fi \ifpdftex\pdfluatrue\fi
-\ifpdflua % pdfTeX and luaTeX produce PDF output if \pdfoutput>0
- \def\Black{\pdfliteral{0 g 0 G}} % use rgb colors for direct PDF output too
- \def\Blue{\pdfliteral{\pdflinkcolor\space rg \pdflinkcolor\space RG}}
-\fi
+\xdef\fmtversion{\fmtversion+PWEBMAC4.11}
\parskip 0pt % no stretch between paragraphs
\parindent 1em % for paragraphs and for the first line of Pascal text
@@ -90,6 +78,20 @@
\newif\iftokprocessed \newif\ifTnum \newif\ifinstr
{\def\\{\global\let\spacechar= }\\ }
+% Here we decide the output format, depending on the TeX engine in use:
+\input iftex.sty % TeX engine tests
+\ifx\pdf+\pdftrue\fi % for plain TeX in combination with dvipdfm
+% Uncomment the following line if you want PDF goodies to be the default
+%\ifx\pdf-\else\pdftrue\fi
+\ifxetex\pdftrue\fi % XeTeX produces PDF output
+\ifpdf \def\pdflinkcolor{0 0 1} \fi % the RGB values for hyperlink color
+\newif\ifacrohint \ifpdf\acrohinttrue\fi \ifhint\acrohinttrue\fi
+\newif\ifpdflua \ifluatex\pdfluatrue\fi \ifpdftex\pdfluatrue\fi
+\ifpdflua % pdfTeX and luaTeX produce PDF output if \pdfoutput>0 (default)
+ \def\Black{\pdfliteral{0 g 0 G}} % use rgb colors for direct PDF output too
+ \def\Blue{\pdfliteral{\pdflinkcolor\space rg \pdflinkcolor\space RG}}
+\fi
+
\ifluatex % LuaTeX is almost like pdfTeX
\protected\def\pdfliteral {\pdfextension literal}
\protected\def\pdfstartlink {\pdfextension startlink\space}
@@ -97,7 +99,7 @@
\protected\def\pdfoutline {\pdfextension outline\space}
\protected\def\pdfdest {\pdfextension dest\space}
\protected\def\pdfcatalog {\pdfextension catalog}
-\chardef\pdfshellescape
+\chardef\pdfshellescape % excerpt from 'shellesc.sty'
\directlua{tex.sprint((status.shell_escape or os.execute()) .. " ")}
\edef\pdfhorigin {\pdfvariable horigin}
\edef\pdfvorigin {\pdfvariable vorigin}
@@ -106,7 +108,7 @@
\let\pdfoutput=\outputmode
\fi % end of LuaTeX->pdfTeX redirection macros
-\ifpdf % The following are pdf macros from 'cwebmac.tex 3.70'
+\ifpdf % The following are general pdf macros from 'cwebmac.tex 3.70'
\def\thewidth{\the\wd0 \space}
\def\theheight{\the\ht\strutbox\space}
\def\thedepth{\the\dp\strutbox\space}
@@ -190,7 +192,7 @@
\def\makeolproctokchar#1 #2 #3{\addF{#3}}
\def\outlinedone{\edef\outlinest{\global\noexpand\toksE={\the\toksF}}%
\outlinest\let\outlinedone=\relax}
-\fi % End of pdf macros
+\fi % End of general pdf macros
\ifhint
% The following uses HINT primitives to implement:
@@ -232,9 +234,10 @@
\next
}
\def\makenote{\addtokens\toksB
- {\noexpand\pdflink{\the\toksC}{\romannumeral\the\toksC}}\toksC={}\global\countC=0}
+ {\noexpand\pdflink{\the\toksC}{\romannumeral\the\toksC}}%
+ \toksC={}\global\countC=0}
\def\maketoksdone{\edef\st{\global\noexpand\toksA={\the\toksB}}\st}
-\fi % End of common macros
+\fi % End of common pdf/hint macros
\def\pdfURL#1#2{\ifpdf \ifpdflua\pdfannotlink height \theheight depth \thedepth
attr {/Border [0 0 0]} user { /Type /Annot /Subtype /Link /A
diff --git a/web/pwebmac/webman.ch b/web/pwebmac/webman.ch
index 1663836f42..1817ab4665 100644
--- a/web/pwebmac/webman.ch
+++ b/web/pwebmac/webman.ch
@@ -20,8 +20,8 @@
\def\bkminfo{}
\outer\def\section #1.{\penalty-50\vskip 12pt plus 3pt minus 3pt
\noindent\ifpdf\vbox to 0pt{\kern-2.5ex\relax
- \ifpdflua\pdfdest num \destcount fitbh\relax
- \else\special{pdf: dest (\the\destcount) [ @thispage /FitBH @ypos ]}\fi
+ \ifpdflua\pdfdest num \destcount fith\relax
+ \else\special{pdf: dest (\the\destcount) [ @thispage /FitH @ypos ]}\fi
\def\.##1{##1}%
\ifx\bkminfo\empty\def\sectitle{#1}\else\def\sectitle{#1 (\bkminfo)}\fi
\ifpdflua\pdfoutline goto num \destcount {\sectitle}\relax
@@ -82,6 +82,13 @@ This memo describes how to write programs in the
\itemitem{3)} A \PASCAL\ part, containing a piece of the program that
@z
+@x l.304
+`\.{\\input webmac}'; this will cause \TeX\ to read in the macros that
+@y
+`\.{\\input webmac}'---or, if you invoke `\.{weave -p}',
+`\.{\\input pwebmac}'---; this will cause \TeX\ to read in the macros that
+@z
+
@x l.358
\.{which is a \\\&\{packed\}{ }\\\&\{array\}{ }\$
@y
@@ -131,8 +138,10 @@ Finally, Appendix F is the `\.{webmac}' file that sets \TeX\ up to accept
the output of \.{WEAVE}; Appendix~G discusses how to use some of its macros
to vary the output formats; and Appendix~H discusses what needs to be done
@y
-Finally, \Appendix F is the `\.{webmac}' file that sets \TeX\ up to accept
-the output of \.{WEAVE}; \Appendix G discusses how to use some of its macros
+Finally, \Appendix F shows the `\.{webmac.tex}' file that sets \TeX\ up to
+accept the output of \.{WEAVE}; it also shows the `\.{pwebmac.tex}' file that
+provides alternative macros more suited for {\mc PDF} output with modern \TeX\
+engines; \Appendix G discusses how to use some of these macros
to vary the output formats; and \Appendix H discusses what needs to be done
@z
@@ -261,77 +270,277 @@ XREF[P]:=0;END{:62};IDLOOKUP:=P;END;
{:58}{66:}FUNCTION MODLOOKUP(L:SIXTEENBITS):NAMEPOINTER;LABEL 31;
@z
-@x l.1208
-\verbatim
+@x l.1203
+\section Appendix F: The \.{webmac.tex} file.
+This is the file that extends ``plain \TeX'' format in order to support the
@y
-\begingroup \def\tt{\ninett} \baselineskip10pt
-\verbatim
+\section Appendix F: Macros for formatting.
+The \.{webmac.tex} file extends ``plain \TeX'' format in order to support the
@z
-@x l.1210
+@x l.1208
+\verbatim
+% standard macros for WEB listings (in addition to PLAIN.TEX)
\xdef\fmtversion{\fmtversion+WEBMAC4.0} % identifies current set of macros
-@y
-\xdef\fmtversion{\fmtversion+WEBMAC4.2} % identifies current set of macros
-@z
+\parskip 0pt % no stretch between paragraphs
+\parindent 1em % for paragraphs and for the first line of Pascal text
-@x l.1218
-\font\tentex=cmtex10 % TeX extended character set (used in strings)
-@y
+\font\eightrm=cmr8 \let\sc=\eightrm % NOT a caps-and-small-caps font!
+\let\mainfont=\tenrm
+\font\titlefont=cmr7 scaled\magstep4 % title on the contents page
+\font\ttitlefont=cmtt10 scaled\magstep2 % typewriter type in title
\font\tentex=cmtex10 % TeX extended character set (used in strings)
-\fontdimen7\tentex=0pt % no extra space after punctuation
-@z
-@x l.1294
+\def\\#1{\hbox{\it#1\/\kern.05em}} % italic type for identifiers
+\def\|#1{\hbox{$#1$}} % one-letter identifiers look a bit better this way
+\def\&#1{\hbox{\bf#1\/}} % boldface type for reserved words
+\def\.#1{\hbox{\tentex % typewriter type for strings
+ \let\\=\BS % backslash in a string
+ \let\'=\RQ % right quote in a string
+ \let\`=\LQ % left quote in a string
+ \let\{=\LB % left brace in a string
+ \let\}=\RB % right brace in a string
+ \let\~=\TL % tilde in a string
+ \let\ =\SP % space in a string
+ \let\_=\UL % underline in a string
+ \let\&=\AM % ampersand in a string
+ #1}}
+\def\#{\hbox{\tt\char`\#}} % parameter sign
+\def\${\hbox{\tt\char`\$}} % dollar sign
+\def\%{\hbox{\tt\char`\%}} % percent sign
+\def\^{\ifmmode\mathchar"222 \else\char`^ \fi} % pointer or hat
+% circumflex accents can be obtained from \^^D instead of \^
+\def\AT!{@} % at sign for control text
+
+\chardef\AM=`\& % ampersand character in a string
+\chardef\BS=`\\ % backslash in a string
+\chardef\LB=`\{ % left brace in a string
+\def\LQ{{\tt\char'22}} % left quote in a string
+\chardef\RB=`\} % right brace in a string
+\def\RQ{{\tt\char'23}} % right quote in a string
+\def\SP{{\tt\char`\ }} % (visible) space in a string
+\chardef\TL=`\~ % tilde in a string
+\chardef\UL=`\_ % underline character in a string
+
+\newbox\bak \setbox\bak=\hbox to -1em{} % backspace one em
+\newbox\bakk\setbox\bakk=\hbox to -2em{} % backspace two ems
+
+\newcount\ind % current indentation in ems
+\def\1{\global\advance\ind by1\hangindent\ind em} % indent one more notch
+\def\2{\global\advance\ind by-1} % indent one less notch
+\def\3#1{\hfil\penalty#10\hfilneg} % optional break within a statement
+\def\4{\copy\bak} % backspace one notch
+\def\5{\hfil\penalty-1\hfilneg\kern2.5em\copy\bakk\ignorespaces}% optional break
+\def\6{\ifmmode\else\par % forced break
+ \hangindent\ind em\noindent\kern\ind em\copy\bakk\ignorespaces\fi}
+\def\7{\Y\6} % forced break and a little extra space
+
+\let\yskip=\smallskip
+\def\to{\mathrel{.\,.}} % double dot, used only in math mode
+\def\note#1#2.{\Y\noindent{\hangindent2em\baselineskip10pt\eightrm#1~#2.\par}}
+\def\lapstar{\rlap{*}}
+\def\startsection{\Q\noindent{\let\*=\lapstar\bf\modstar.\quad}}
+\def\defin#1{\global\advance\ind by 2 \1\&{#1 }} % begin `define' or `format'
+\def\A{\note{See also section}} % crossref for doubly defined section name
+\def\As{\note{See also sections}} % crossref for multiply defined section name
+\def\B{\mathopen{\.{@\{}}} % begin controlled comment
+\def\C#1{\ifmmode\gdef\XX{\null$\null}\else\gdef\XX{}\fi % Pascal comments
+ \XX\hfil\penalty-1\hfilneg\quad$\{\,$#1$\,\}$\XX}
+\def\D{\defin{define}} % macro definition
+\def\E{\cdot10^} % exponent in floating point constant
+\def\ET{ and~} % conjunction between two section numbers
+\def\ETs{, and~} % conjunction between the last two of several section numbers
+\def\F{\defin{format}} % format definition
+\let\G=\ge % greater than or equal sign
+\def\H#1{\hbox{\rm\char"7D\tt#1}} % hexadecimal constant
+\let\I=\ne % unequal sign
+\def\J{\.{@\&}} % TANGLE's join operation
+\let\K=\gets % left arrow
+\let\L=\le % less than or equal sign
+\outer\def\M#1.{\MN#1.\ifon\vfil\penalty-100\vfilneg % beginning of section
+ \vskip12ptminus3pt\startsection\ignorespaces}
+\outer\def\N#1.#2.{\MN#1.\vfil\eject % beginning of starred section
+ \def\rhead{\uppercase{\ignorespaces#2}} % define running headline
+ \message{*\modno} % progress report
+ \edef\next{\write\cont{\Z{#2}{\modno}{\the\pageno}}}\next % to contents file
+ \ifon\startsection{\bf\ignorespaces#2.\quad}\ignorespaces}
+\def\MN#1.{\par % common code for \M, \N
{\xdef\modstar{#1}\let\*=\empty\xdef\modno{#1}}
\ifx\modno\modstar \onmaybe \else\ontrue \fi \mark{\modno}}
-@y
- {\xdef\modstar{#1}\let\*=\empty\xdef\modno{#1}}% remove \* from section name
- \ifx\modno\modstar \onmaybe \else\ontrue \fi
- \mark{{{\tensy x}\modno}{\rhead}}}
- % each \mark is {section reference or null}{group title}
-@z
-
-@x l.1325
+\def\O#1{\hbox{\rm\char'23\kern-.2em\it#1\/\kern.05em}} % octal constant
+\def\P{\rightskip=0pt plus 100pt minus 10pt % go into Pascal mode
+ \sfcode`;=3000
+ \pretolerance 10000
+ \hyphenpenalty 10000 \exhyphenpenalty 10000
+ \global\ind=2 \1\ \unskip}
+\def\Q{\rightskip=0pt % get out of Pascal mode
+ \sfcode`;=1500 \pretolerance 200 \hyphenpenalty 50 \exhyphenpenalty 50 }
+\let\R=\lnot % logical not
+\let\S=\equiv % equivalence sign
+\def\T{\mathclose{\.{@\}}}} % terminate controlled comment
+\def\U{\note{This code is used in section}} % crossref for use of a section
+\def\Us{\note{This code is used in sections}} % crossref for uses of a section
+\let\V=\lor % logical or
+\let\W=\land % logical and
+\def\X#1:#2\X{\ifmmode\gdef\XX{\null$\null}\else\gdef\XX{}\fi % section name
+ \XX$\langle\,$#2{\eightrm\kern.5em#1}$\,\rangle$\XX}
+\def\Y{\par\yskip}
+\let\Z=\let % now you can \send the control sequence \Z
+\def\){\hbox{\.{@\$}}} % sign for string pool check sum
+\def\]{\hbox{\.{@\\}}} % sign for forced line break
+\def\=#1{\kern2pt\hbox{\vrule\vtop{\vbox{\hrule
+ \hbox{\strut\kern2pt\.{#1}\kern2pt}}
+ \hrule}\vrule}\kern2pt} % verbatim string
+\let\~=\ignorespaces
+\let\*=*
+
+\def\onmaybe{\let\ifon=\maybe} \let\maybe=\iftrue
+\newif\ifon \newif\iftitle \newif\ifpagesaved
\def\lheader{\mainfont\the\pageno\eightrm\qquad\rhead\hfill\title\qquad
\tensy x\mainfont\topmark} % top line on left-hand pages
\def\rheader{\tensy x\mainfont\topmark\eightrm\qquad\title\hfill\rhead
\qquad\mainfont\the\pageno} % top line on right-hand pages
-@y
-\def\lheader{\mainfont\the\pageno\eightrm\qquad\rhead
- \hfill\title\qquad\mainfont\topsecno} % top line on left-hand pages
-\def\rheader{\mainfont\topsecno\eightrm\qquad\title\hfill
- \rhead\qquad\mainfont\the\pageno} % top line on right-hand pages
-\def\topsecno{\expandafter\takeone\topmark}
-\def\takeone#1#2{#1}
-\def\taketwo#1#2{#2}
-\def\nullsec{\eightrm\kern-2em} % the \kern-2em cancels \qquad in headers
-@z
+\def\page{\box255 }
+\def\normaloutput#1#2#3{\ifodd\pageno\hoffset=\pageshift\fi
+ \shipout\vbox{
+ \vbox to\fullpageheight{
+ \iftitle\global\titlefalse
+ \else\hbox to\pagewidth{\vbox to10pt{}\ifodd\pageno #3\else#2\fi}\fi
+ \vfill#1}} % parameter #1 is the page itself
+ \global\advance\pageno by1}
-@x l.1336
\def\rhead{\.{WEB} OUTPUT} % this running head is reset by starred sections
-@y
-\def\rhead{\.{WEB} OUTPUT} % this running head is reset by starred sections
-\mark{\noexpand\nullsec{\rhead}}
-@z
-
-@x l.1392
+\def\title{} % an optional title can be set by the user
+\def\topofcontents{\centerline{\titlefont\title}
+ \vfill} % this material will start the table of contents page
+\def\botofcontents{\vfill} % this material will end the table of contents page
+\def\contentspagenumber{0} % default page number for table of contents
+\newdimen\pagewidth \pagewidth=6.5in % the width of each page
+\newdimen\pageheight \pageheight=8.7in % the height of each page
+\newdimen\fullpageheight \fullpageheight=9in % page height including headlines
+\newdimen\pageshift \pageshift=0in % shift righthand pages wrt lefthand ones
+\def\magnify#1{\mag=#1\pagewidth=6.5truein\pageheight=8.7truein
+ \fullpageheight=9truein\setpage}
+\def\setpage{\hsize\pagewidth\vsize\pageheight} % use after changing page size
+\def\contentsfile{CONTENTS} % file that gets table of contents info
+\def\readcontents{\input CONTENTS}
+
+\newwrite\cont
+\output{\setbox0=\page % the first page is garbage
+ \openout\cont=\contentsfile
+ \global\output{\normaloutput\page\lheader\rheader}}
+\setpage
+\vbox to \vsize{} % the first \topmark won't be null
+
+\def\ch{\note{The following sections were changed by the change file:}
+ \let\*=\relax}
+\newbox\sbox % saved box preceding the index
+\newbox\lbox % lefthand column in the index
+\def\inx{\par\vskip6pt plus 1fil % we are beginning the index
+ \write\cont{} % ensure that the contents file isn't empty
+ \closeout\cont % the contents information has been fully gathered
+ \output{\ifpagesaved\normaloutput{\box\sbox}\lheader\rheader\fi
+ \global\setbox\sbox=\page \global\pagesavedtrue}
+ \pagesavedfalse \eject % eject the page-so-far and predecessors
+ \setbox\sbox\vbox{\unvbox\sbox} % take it out of its box
+ \vsize=\pageheight \advance\vsize by -\ht\sbox % the remaining height
+ \hsize=.5\pagewidth \advance\hsize by -10pt
+ % column width for the index (20pt between cols)
+ \parfillskip 0pt plus .6\hsize % try to avoid almost empty lines
+ \def\lr{L} % this tells whether the left or right column is next
+ \output{\if L\lr\global\setbox\lbox=\page \gdef\lr{R}
+ \else\normaloutput{\vbox to\pageheight{\box\sbox\vss
+ \hbox to\pagewidth{\box\lbox\hfil\page}}}\lheader\rheader
+ \global\vsize\pageheight\gdef\lr{L}\global\pagesavedfalse\fi}
+ \message{Index:}
+ \parskip 0pt plus .5pt
+ \outer\def\:##1, {\par\hangindent2em\noindent##1:\kern1em} % index entry
+ \let\ttentry=\. \def\.##1{\ttentry{##1\kern.2em}} % give \tt a little room
+ \def\[##1]{$\underline{##1}$} % underlined index item
+ \rm \rightskip0pt plus 2.5em \tolerance 10000 \let\*=\lapstar
+ \hyphenpenalty 10000 \parindent0pt}
+\def\fin{\par\vfill\eject % this is done when we are ending the index
+ \ifpagesaved\null\vfill\eject\fi % output a null index column
+ \if L\lr\else\null\vfill\eject\fi % finish the current page
+ \parfillskip 0pt plus 1fil
\def\rhead{NAMES OF THE SECTIONS}
-@y
- \def\rhead{NAMES OF THE SECTIONS}
- \let\topsecno=\nullsec
-@z
-
-@x l.1395
+ \message{Section names:}
+ \output{\normaloutput\page\lheader\rheader}
+ \setpage
\def\note##1##2.{\hfil\penalty-1\hfilneg\quad{\eightrm##1 ##2.}}
+ \linepenalty=10 % try to conserve lines
+ \def\U{\note{Used in section}} % crossref for use of a section
+ \def\Us{\note{Used in sections}} % crossref for uses of a section
+ \def\:{\par\hangindent 2em}\let\*=*\let\.=\ttentry}
+\def\con{\par\vfill\eject % finish the section names
+ \rightskip 0pt \hyphenpenalty 50 \tolerance 200
+ \setpage
+ \output{\normaloutput\page\lheader\rheader}
+ \titletrue % prepare to output the table of contents
+ \pageno=\contentspagenumber \def\rhead{TABLE OF CONTENTS}
+ \message{Table of contents:}
+ \topofcontents
+ \line{\hfil Section\hbox to3em{\hss Page}}
+ \def\Z##1##2##3{\line{\ignorespaces##1
+ \leaders\hbox to .5em{.\hfil}\hfil\ ##2\hbox to3em{\hss##3}}}
+ \readcontents\relax % read the contents info
+ \botofcontents \end} % print the contents page(s) and terminate
+?endgroup
@y
- \def\note##1##2.{\hfil\penalty-1\hfilneg\quad{\eightrm##1~##2.}}
+\begingroup \def\tt{\eighttt} \baselineskip9pt
+\def\printmacs#1{\begingroup
+ \def\do##1{\catcode`##1=12 } \dospecials
+ \parskip 0pt \parindent 0pt
+ \catcode`\ =13 \catcode`\^^M=13
+ \tt \verbatimdefs \input #1 \endgroup}
+\printmacs{webmac}
+\vskip6pt \baselineskip12pt
+ \section Hypertext and hyperdocumentation.
+Many people have of course noticed analogies between \.{WEB} and the
+World Wide Web. The following \.{WEB} macros \.{pwebmac.tex} are in fact
+set up so that the output of \.{WEAVE} can be converted easily into
+Portable Document Format, with clickable hyperlinks that can be read
+with your favorite {\mc PDF} viewer.
+After using \.{WEAVE} with command line option `\.{-p}' to convert
+\.{cob.web} into \.{cob.tex}, you can prepare a hypertext version of
+the program by giving the commands
+$$\vbox{\halign{\.{#}\hfil\cr
+tex "\\let\\pdf+ \\input cob"\cr
+dvipdfm cob\cr}}$$
+instead of invoking \TeX\ in the normal way.
+Alternatively you can generate \.{cob.pdf} in one step by simply saying
+`\.{pdftex}~\.{cob}' or `\.{xetex}~\.{cob}' or `\.{luatex}~\.{cob}'.
+(You are advised to use the command line option `\.{--shell-escape}' with
+\.{pdftex} and \.{luatex} in order to receive ``valid'' {\mc PDF} output;
+otherwise, the internal counter for the ``Names of the sections'' part
+in the {\mc PDF} ``bookmarks'' will be incorrect.)
+
+Similar output for ``smart'' devices can be created with Martin Ruckert's
+Hi\TeX\ and its dynamic \.{HINT} format; just say `\.{hitex}~\.{cob}'.
+\.{HINT} files can be viewed with the \.{hintview} program, which is
+available from
+\pdfURL{\.{https://hint.userweb.mwn.de/hint/hintview.html}}%
+ {https://hint.userweb.mwn.de/hint/hintview.html}.%
+
+A more elaborate system called \.{TWILL}, which extends the usual cross
+references of \.{WEAVE} by preparing links from the uses of identifiers
+to their definitions, is also available---provided that you are willing
+to work a bit harder in cases where an identifier is multiply defined.
+\.{TWILL} is intended primarily for hardcopy output, but its principles
+could be used for hypertext as well. It uses its own set of macros
+`\.{twimac-web.tex}'.
+
+\vskip6pt \baselineskip9pt
+\printmacs{pwebmac}
+\endgroup
+\vfill\eject
@z
-@x l.1414
-?endgroup
+@x l.1418
+The macros in \.{webmac} make it possible to produce a variety of formats
@y
-?endgroup
-\endgroup
+The macros in \.{webmac} and \.{pwebmac} make it possible to produce
+a variety of formats
@z
@x l.1425
@@ -362,6 +571,17 @@ for every starred module. For example, when \pdfURL{Appendix~D}{weave.pdf}
was being generated,
@z
+@x l.569
+\.{\\ch}, \.{\\fin}, and \.{\\con}. \.{WEAVE} itself need not be changed.
+@y
+\.{\\ch}, \.{\\fin}, and \.{\\con}. \.{WEAVE} itself need not be changed.
+
+\point 15. In conjunction with `\.{weave -p}' and the \.{pwebmac} macros you
+can say `\.{\\input pdfwebtocfront}' as the last command in the limbo section
+and run \TeX\ \\{twice} on your woven \.{WEB} document, in order to shift the
+table-of-contents to the front of the {\mc PDF} output.
+@z
+
@x l.1583
dependencies'' in the index of Appendix~E above, and figure out what changes
@y