diff options
Diffstat (limited to 'web/c_cpp')
27 files changed, 794 insertions, 835 deletions
diff --git a/web/c_cpp/cweb/Makefile b/web/c_cpp/cweb/Makefile index e3db8819c6..c547ef9154 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.8 --- June 2022 +# Version 4.10 --- August 2023 # Copyright (C) 1987,1990,1993,2000 Silvio Levy and Donald E. Knuth @@ -203,3 +203,8 @@ tarfile: $(ALL) examples tarball: tar zcvhf /tmp/cweb.tgz $(ALL) examples + +ctan: + git archive -o ~/cweb-4.10.zip --prefix=cweb/ cweb-4.10 + make PDF=pdf usermanual + cd ..; zip -r ~/cweb-4.10.zip cweb/cwebman.pdf diff --git a/web/c_cpp/cweb/comm-bs.ch b/web/c_cpp/cweb/comm-bs.ch index b5e1d21b9b..ac2e26e9bd 100644 --- a/web/c_cpp/cweb/comm-bs.ch +++ b/web/c_cpp/cweb/comm-bs.ch @@ -15,8 +15,8 @@ by using "huge" pointers. (Update attempt by Andreas Scherer, 31 Jan 2021. Good luck!) -@x Section 9. - for section names */ +@x Section 10. +@d ilk dummy.Ilk /* used by \.{CWEAVE} only */ @<Common code...@>= typedef struct name_info { @@ -25,7 +25,7 @@ typedef struct name_info { union { struct name_info *Rlink; /* right link in binary search tree for section names */ - char Ilk; /* used by identifiers in \.{CWEAVE} only */ + eight_bits Ilk; /* used by identifiers in \.{CWEAVE} only */ } dummy; void *equiv_or_xref; /* info corresponding to names */ } name_info; /* contains information about an identifier or section name */ @@ -34,7 +34,7 @@ typedef name_pointer *hash_pointer; extern char byte_mem[]; /* characters of names */ extern char *byte_mem_end; /* end of |byte_mem| */ @y - for section names */ +@d ilk dummy.Ilk /* used by \.{CWEAVE} only */ @f huge extern @@ -45,7 +45,7 @@ typedef struct name_info { union { struct name_info *Rlink; /* right link in binary search tree for section names */ - char Ilk; /* used by identifiers in \.{CWEAVE} only */ + eight_bits Ilk; /* used by identifiers in \.{CWEAVE} only */ } dummy; union { void huge* equiv_member; @@ -59,7 +59,7 @@ extern char huge* byte_mem_end; /* end of |byte_mem| */ @z -@x Section 39. +@x Section 36. cur_file_name[l]='/'; /* \UNIX/ pathname separator */ @y cur_file_name[l]='/'; /* A valid {\mc MSDOS} pathname separator */ diff --git a/web/c_cpp/cweb/comm-mac.ch b/web/c_cpp/cweb/comm-mac.ch index 6bad610d1b..83df560cb4 100644 --- a/web/c_cpp/cweb/comm-mac.ch +++ b/web/c_cpp/cweb/comm-mac.ch @@ -4,29 +4,29 @@ 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.8)} + \centerline{(Version 4.10)} @y - \centerline{(Version 4.8 for MacOS)} + \centerline{(Version 4.10 for MacOS)} @z @x section 23: Make input_ln accept \n, \r, \n\r, or \r\n as line endings @ In the unlikely event that your standard I/O library does not -support |feof|, |getc|, and |ungetc| you may have to change things here. +support |feof| and |getc| you may have to change things here. @^system dependencies@> @c static boolean input_ln( /* copies a line into |buffer| or returns |false| */ FILE *fp) /* what file to read from */ { - register int c=EOF; /* character read; initialized so some compilers won't complain */ - register char *k; /* where next character goes */ + int c=EOF; /* character read; initialized so some compilers won't complain */ + char *k; /* where next character goes */ if (feof(fp)) return false; /* we have hit end-of-file */ limit = k = buffer; /* beginning of buffer */ while (k<=buffer_end && (c=getc(fp)) != EOF && c!='\n') if ((*(k++) = c) != ' ') limit = k; - if (k>buffer_end) - if ((c=getc(fp))!=EOF && c!='\n') { - ungetc(c,fp); loc=buffer; err_print("! Input line too long"); + if (k>buffer_end) { + while ((c=getc(fp))!=EOF && c!='\n'); /* discard rest of line */ + loc=buffer; err_print("! Input line too long"); @.Input line too long@> } if (c==EOF && limit==buffer) return false; /* there was nothing after @@ -46,8 +46,8 @@ line endings, so that \.{CWEB} will works with ASCII files stored in static boolean input_ln( /* copies a line into |buffer| or returns |false| */ FILE *fp) /* what file to read from */ { - register int c=EOF; /* character read; initialized so some compilers won't complain */ - register char *k; /* where next character goes */ + int c=EOF; /* character read; initialized so some compilers won't complain */ + char *k; /* where next character goes */ if (feof(fp)) return false; /* we have hit end-of-file */ limit = k = buffer; /* beginning of buffer */ while (true) { @@ -61,7 +61,7 @@ FILE *fp) /* what file to read from */ return true; } else if (k>buffer_end) { - ungetc(c,fp); loc=buffer; err_print("! Input line too long"); + while ((c=getc(fp))!=EOF && c!='\n' && c!='\r'); /* discard rest of line */ return true; @.Input line too long@> } @@ -81,17 +81,7 @@ FILE *fp) /* what file to read from */ @<Skip over comment lines in the change file; |return| if end of file@>@; @z -@x section 36, don't try to open a change file if none was specified -if ((change_file=fopen(change_file_name,"r"))==NULL) - fatal("! Cannot open change file ", change_file_name); -@y -if (change_file_name[0] == '\0') /* no change file specified */ - change_file = NULL; /* reset at least the |change_file| */ -else if ((change_file=fopen(change_file_name,"r"))==NULL) - fatal("! Cannot open change file ", change_file_name); -@z - -@x section 39, declare colon as Mac's path separator +@x section 36, declare colon as Mac's path separator (Colon-separated paths are not supported.) The remainder of the \.{@@i} line after the file name is ignored. @@ -104,12 +94,22 @@ The remainder of the \.{@@i} line after the file name is ignored. @d PATH_SEP ':' /* MacOS pathname separator */ @^system dependencies@> @z -@x section 39, use the path separator constant +@x section 36, use the path separator constant cur_file_name[l]='/'; /* \UNIX/ pathname separator */ @y cur_file_name[l]=PATH_SEP; /* pathname separator */ @z +@x section 41, don't try to open a change file if none was specified +if ((change_file=fopen(change_file_name,"r"))==NULL) + fatal("! Cannot open change file ", change_file_name); +@y +if (change_file_name[0] == '\0') /* no change file specified */ + change_file = NULL; /* reset at least the |change_file| */ +else if ((change_file=fopen(change_file_name,"r"))==NULL) + fatal("! Cannot open change file ", change_file_name); +@z + @x section 75, explain the convention for omitted change files An omitted change file argument means that |"/dev/null"| should be used, @y @@ -134,7 +134,7 @@ An omitted change file argument means that no change file should be used, @z @x section 85, insert an extra module before the index -@** Index. +@* Index. @y by putting the new module here, we preserve all the previous section numbers @ We assume an interface to \CEE/ command-line emulation as supplied by the |ccommand| function of Metrowerks CodeWarrior, as defined in @@ -144,5 +144,5 @@ the header file \.{console.h}. #include <console.h> @^system dependencies@> -@** Index. +@* Index. @z diff --git a/web/c_cpp/cweb/comm-ql.ch b/web/c_cpp/cweb/comm-ql.ch index 52c4834bed..592c7e04a1 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.8)} +\def\title{Common code for CTANGLE and CWEAVE (Version 4.10)} \def\topofcontents{\null\vfill \centerline{\titlefont Common code for {\ttitlefont CTANGLE} and {\ttitlefont CWEAVE}} \vskip 15pt - \centerline{(Version 4.8)} + \centerline{(Version 4.10)} \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.8)} +\def\title{Common code for CTANGLE and CWEAVE (QL Version 4.10)} \def\topofcontents{\null\vfill \centerline{\titlefont Common code for {\ttitlefont CTANGLE} and {\ttitlefont CWEAVE}} \vskip 15pt - \centerline{(Version 4.8)} + \centerline{(Version 4.10)} \vfill} \def\botofcontents{\vfill \noindent @@ -212,17 +212,15 @@ the routine as if it would work. @<Complain about argument length@>@; if (dot_pos==NULL) { sprintf(tex_file_name,"%s.tex",*argv); - sprintf(idx_file_name,"%s.idx",*argv); - sprintf(scn_file_name,"%s.scn",*argv); sprintf(C_file_name,"%s.c",*argv); } else { strcpy(tex_file_name,*argv); strcpy(C_file_name,*argv); - if (make_xrefs) { /* indexes will be generated */ - *dot_pos='\0'; - sprintf(idx_file_name,"%s.idx",*argv); - sprintf(scn_file_name,"%s.scn",*argv); - } + *dot_pos='\0'; /* string now ends where the dot was */ + } + if (make_xrefs) { /* indexes will be generated */ + sprintf(idx_file_name,"%s.idx",*argv); + sprintf(scn_file_name,"%s.scn",*argv); } found_out=true; } @@ -233,17 +231,15 @@ the routine as if it would work. @<Complain about argument length@>; if (dot_pos==NULL) { sprintf(tex_file_name,"%s_tex",*argv); - sprintf(idx_file_name,"%s_idx",*argv); - sprintf(scn_file_name,"%s_scn",*argv); sprintf(C_file_name,"%s_c",*argv); } else { strcpy(tex_file_name,*argv); strcpy(C_file_name,*argv); - if (make_xrefs) { /* indexes will be generated */ - *dot_pos='\0'; - sprintf(idx_file_name,"%s_idx",*argv); - sprintf(scn_file_name,"%s_scn",*argv); - } + *dot_pos='\0'; /* string now ends where the dot was */ + } + if (make_xrefs) { /* indexes will be generated */ + sprintf(idx_file_name,"%s_idx",*argv); + sprintf(scn_file_name,"%s_scn",*argv); } found_out=true; } diff --git a/web/c_cpp/cweb/comm-vms.ch b/web/c_cpp/cweb/comm-vms.ch index a5ddc252f3..fe72d604fd 100644 --- a/web/c_cpp/cweb/comm-vms.ch +++ b/web/c_cpp/cweb/comm-vms.ch @@ -75,7 +75,7 @@ null device |"NL:"| should be used, when no changes are desired. @z @x section 85 (01-FEB-1992 ST) -@** Index. +@* Index. @y @* VAX/VMS specific code. We have used |SS$_NORMAL| and |SS$_ABORT| as return codes, @@ -84,5 +84,5 @@ so we have to include the system message codes. @<Include files@>= #include ssdef /* we need VAX/VMS system messages */ -@** Index. +@* Index. @z diff --git a/web/c_cpp/cweb/comm-w32.ch b/web/c_cpp/cweb/comm-w32.ch index 38c209981a..cf5d63c9c1 100644 --- a/web/c_cpp/cweb/comm-w32.ch +++ b/web/c_cpp/cweb/comm-w32.ch @@ -34,16 +34,10 @@ header files to be safe. Admittedly, this is not vital for cweb, except that I build the whole texlive set of programs using the __fastcall convention. -@x -extern boolean names_match(name_pointer,const char *,size_t,eight_bits);@/ +@x section 11 +extern boolean names_match(name_pointer,const char *,size_t,eight_bits); @y -extern boolean __cdecl names_match(name_pointer,const char *,size_t,eight_bits);@/ -@z - -@x -extern void init_p(name_pointer,eight_bits);@/ -@y -extern void __cdecl init_p(name_pointer,eight_bits);@/ +extern boolean __cdecl names_match(name_pointer,const char *,size_t,eight_bits); @z @x section 75 diff --git a/web/c_cpp/cweb/common.c b/web/c_cpp/cweb/common.c index 2b5c7c9ccc..ccedc5e914 100644 --- a/web/c_cpp/cweb/common.c +++ b/web/c_cpp/cweb/common.c @@ -1,8 +1,8 @@ /*1:*/ #line 62 "common.w" -/*3:*/ -#line 44 "common.h" +/*4:*/ +#line 48 "common.h" #include <ctype.h> #include <stdbool.h> @@ -12,7 +12,7 @@ #include <stdlib.h> #include <string.h> -/*:3*/ +/*:4*/ #line 63 "common.w" #define ctangle false @@ -61,14 +61,15 @@ #define llink link #define rlink dummy.Rlink #define root name_dir->rlink \ - \ + +#define ilk dummy.Ilk \ #define spotless 0 #define harmless_message 1 #define error_message 2 #define fatal_message 3 -#define mark_harmless if(history==spotless) history= harmless_message -#define mark_error history= error_message +#define mark_harmless() if(history==spotless) history= harmless_message +#define mark_error() history= error_message #define confusion(s) fatal("! This can't happen: ",s) \ \ @@ -78,8 +79,8 @@ #define show_stats flags['s'] #define make_xrefs flags['x'] \ -#define update_terminal fflush(stdout) -#define new_line putchar('\n') +#define update_terminal() fflush(stdout) +#define new_line() putchar('\n') #define term_write(a,b) fflush(stdout) ,fwrite(a,sizeof(char) ,b,stdout) \ #define buf_size 200 @@ -133,24 +134,24 @@ typedef uint16_t sixteen_bits; extern boolean program; extern int phase; -/*:2*//*4:*/ -#line 74 "common.h" +/*:2*//*5:*/ +#line 78 "common.h" extern char section_text[]; extern char*section_text_end; extern char*id_first; extern char*id_loc; -/*:4*//*5:*/ -#line 92 "common.h" +/*:5*//*6:*/ +#line 96 "common.h" extern char buffer[]; extern char*buffer_end; extern char*loc; extern char*limit; -/*:5*//*6:*/ -#line 109 "common.h" +/*:6*//*7:*/ +#line 113 "common.h" extern int include_depth; extern FILE*file[]; @@ -165,16 +166,16 @@ extern boolean input_has_ended; extern boolean changing; extern boolean web_file_open; -/*:6*//*8:*/ -#line 129 "common.h" +/*:7*//*9:*/ +#line 133 "common.h" extern sixteen_bits section_count; extern boolean changed_section[]; extern boolean change_pending; extern boolean print_where; -/*:8*//*9:*/ -#line 143 "common.h" +/*:9*//*10:*/ +#line 148 "common.h" typedef struct name_info{ char*byte_start; @@ -182,7 +183,7 @@ struct name_info*link; union{ struct name_info*Rlink; -char Ilk; +eight_bits Ilk; }dummy; void*equiv_or_xref; }name_info; @@ -198,13 +199,13 @@ extern name_pointer hash[]; extern hash_pointer hash_end; extern hash_pointer h; -/*:9*//*11:*/ -#line 187 "common.h" +/*:10*//*12:*/ +#line 193 "common.h" extern int history; -/*:11*//*13:*/ -#line 203 "common.h" +/*:12*//*14:*/ +#line 211 "common.h" extern int argc; extern char**argv; @@ -214,8 +215,8 @@ extern char idx_file_name[]; extern char scn_file_name[]; extern boolean flags[]; -/*:13*//*14:*/ -#line 217 "common.h" +/*:14*//*15:*/ +#line 225 "common.h" extern FILE*C_file; extern FILE*tex_file; @@ -223,7 +224,7 @@ extern FILE*idx_file; extern FILE*scn_file; extern FILE*active_file; -/*:14*/ +/*:15*/ #line 65 "common.w" /*18:*/ @@ -275,8 +276,8 @@ boolean web_file_open= false; static char change_buffer[buf_size]; static char*change_limit; -/*:26*//*37:*/ -#line 393 "common.w" +/*:26*//*42:*/ +#line 545 "common.w" sixteen_bits section_count; boolean changed_section[max_sections]; @@ -284,7 +285,7 @@ boolean change_pending; boolean print_where= false; -/*:37*//*43:*/ +/*:42*//*43:*/ #line 590 "common.w" char byte_mem[max_bytes]; @@ -306,12 +307,12 @@ hash_pointer hash_end= hash+hash_size-1; hash_pointer h; /*:46*//*65:*/ -#line 1003 "common.w" +#line 1002 "common.w" int history= spotless; /*:65*//*73:*/ -#line 1126 "common.w" +#line 1125 "common.w" int argc; char**argv; @@ -322,7 +323,7 @@ char scn_file_name[max_file_name_length]; boolean flags[128]; /*:73*//*83:*/ -#line 1269 "common.w" +#line 1266 "common.w" FILE*C_file; FILE*tex_file; @@ -333,41 +334,43 @@ FILE*active_file; /*:83*/ #line 66 "common.w" -/*7:*/ -#line 123 "common.h" +/*3:*/ +#line 43 "common.h" + +extern void common_init(void); + +/*:3*//*8:*/ +#line 127 "common.h" extern boolean get_line(void); extern void check_complete(void); extern void reset_input(void); -/*:7*//*10:*/ -#line 166 "common.h" +/*:8*//*11:*/ +#line 171 "common.h" -extern boolean names_match(name_pointer,const char*,size_t,eight_bits); extern name_pointer id_lookup(const char*,const char*,eight_bits); extern name_pointer section_lookup(char*,char*,boolean); -extern void init_node(name_pointer); -extern void init_p(name_pointer,eight_bits); extern void print_prefix_name(name_pointer); extern void print_section_name(name_pointer); extern void sprint_section_name(char*,name_pointer); -/*:10*//*12:*/ -#line 190 "common.h" +extern boolean names_match(name_pointer,const char*,size_t,eight_bits); + +extern void init_node(name_pointer); + +/*:11*//*13:*/ +#line 196 "common.h" extern int wrap_up(void); extern void err_print(const char*); extern void fatal(const char*,const char*); extern void overflow(const char*); -/*:12*//*15:*/ -#line 225 "common.h" - -extern void common_init(void); extern void print_stats(void); -/*:15*//*24:*/ +/*:13*//*24:*/ #line 176 "common.w" static boolean input_ln(FILE*); @@ -380,18 +383,18 @@ static void prime_the_change_buffer(void); static void check_change(void); /*:33*//*55:*/ -#line 764 "common.w" +#line 763 "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 991 "common.w" +#line 990 "common.w" static int section_name_cmp(char**,size_t,name_pointer); /*:64*//*76:*/ -#line 1186 "common.w" +#line 1185 "common.w" static void scan_args(void); /*:76*/ @@ -421,7 +424,7 @@ for(h= hash;h<=hash_end;*h++= NULL); #line 99 "common.w" /*74:*/ -#line 1139 "common.w" +#line 1138 "common.w" show_banner= show_happiness= show_progress= make_xrefs= true; @@ -429,7 +432,7 @@ show_banner= show_happiness= show_progress= make_xrefs= true; #line 100 "common.w" /*84:*/ -#line 1276 "common.w" +#line 1273 "common.w" scan_args(); if(program==ctangle){ @@ -453,15 +456,15 @@ fatal("! Cannot open output file ",tex_file_name); static boolean input_ln( FILE*fp) { -register int c= EOF; -register char*k; +int c= EOF; +char*k; if(feof(fp))return false; limit= k= buffer; while(k<=buffer_end&&(c= getc(fp))!=EOF&&c!='\n') if((*(k++)= c)!=' ')limit= k; -if(k> buffer_end) -if((c= getc(fp))!=EOF&&c!='\n'){ -ungetc(c,fp);loc= buffer;err_print("! Input line too long"); +if(k> buffer_end){ +while((c= getc(fp))!=EOF&&c!='\n'); +loc= buffer;err_print("! Input line too long"); } if(c==EOF&&limit==buffer)return false; @@ -544,15 +547,15 @@ change_limit= change_buffer;changing= false; return; } if(limit> buffer+1&&buffer[0]=='@'){ -char xyz_code= xisupper(buffer[1])?tolower((int)buffer[1]):buffer[1]; +if(xisupper(buffer[1]))buffer[1]= tolower((int)buffer[1]); /*34:*/ #line 336 "common.w" -if(xyz_code=='x'||xyz_code=='z'){ +if(buffer[1]=='x'||buffer[1]=='z'){ loc= buffer+2;err_print("! Where is the matching @y?"); } -else if(xyz_code=='y'){ +else if(buffer[1]=='y'){ if(n> 0){ loc= buffer+2; printf("\n! Hmm... %d ",n); @@ -590,44 +593,14 @@ if(lines_dont_match)n++; } /*:32*//*35:*/ -#line 356 "common.w" - -void -reset_input(void) -{ -limit= buffer;loc= buffer+1;buffer[0]= ' '; -/*36:*/ -#line 371 "common.w" - -if((web_file= fopen(web_file_name,"r"))==NULL){ -strcpy(web_file_name,alt_web_file_name); -if((web_file= fopen(web_file_name,"r"))==NULL) -fatal("! Cannot open input file ",web_file_name); -} - - -web_file_open= true; -if((change_file= fopen(change_file_name,"r"))==NULL) -fatal("! Cannot open change file ",change_file_name); - -/*:36*/ -#line 361 "common.w" - -include_depth= cur_line= change_line= 0; -change_depth= include_depth; -changing= true;prime_the_change_buffer();changing= !changing; -limit= buffer;loc= buffer+1;buffer[0]= ' ';input_has_ended= false; -} - -/*:35*//*38:*/ -#line 400 "common.w" +#line 362 "common.w" boolean get_line(void) { restart: if(changing&&include_depth==change_depth) -/*41:*/ -#line 508 "common.w" +/*38:*/ +#line 470 "common.w" { change_line++; if(!input_ln(change_file)){ @@ -657,12 +630,12 @@ prime_the_change_buffer();changing= !changing;print_where= true; } } -/*:41*/ -#line 405 "common.w" +/*:38*/ +#line 367 "common.w" if(!changing||include_depth> change_depth){ -/*40:*/ -#line 491 "common.w" +/*37:*/ +#line 453 "common.w" { cur_line++; while(!input_ln(cur_file)){ @@ -680,8 +653,8 @@ if(buffer[0]==change_buffer[0]) if(change_limit> change_buffer)check_change(); } -/*:40*/ -#line 407 "common.w" +/*:37*/ +#line 369 "common.w" if(changing&&include_depth==change_depth)goto restart; } @@ -701,8 +674,8 @@ err_print("! Too many nested includes"); goto restart; } include_depth++; -/*39:*/ -#line 445 "common.w" +/*36:*/ +#line 407 "common.w" { char temp_file_name[max_file_name_length]; char*cur_file_name_end= cur_file_name+max_file_name_length-1; @@ -723,7 +696,6 @@ cur_line= 0;print_where= true; goto restart; } if((kk= getenv("CWEBINPUTS"))!=NULL){ - if((l= strlen(kk))> max_file_name_length-2)too_long(); strcpy(temp_file_name,kk); } @@ -732,10 +704,10 @@ else{ if((l= strlen(CWEBINPUTS))> max_file_name_length-2)too_long(); strcpy(temp_file_name,CWEBINPUTS); #else -#line 474 "common.w" +#line 435 "common.w" l= 0; #endif -#line 476 "common.w" +#line 437 "common.w" } if(l> 0){ if(k+l+2>=cur_file_name_end)too_long(); @@ -743,6 +715,7 @@ if(k+l+2>=cur_file_name_end)too_long(); for(;k>=cur_file_name;k--)*(k+l+1)= *k; strcpy(cur_file_name,temp_file_name); cur_file_name[l]= '/'; + if((cur_file= fopen(cur_file_name,"r"))!=NULL){ cur_line= 0;print_where= true; goto restart; @@ -751,15 +724,15 @@ goto restart; include_depth--;err_print("! Cannot open include file");goto restart; } -/*:39*/ -#line 426 "common.w" +/*:36*/ +#line 388 "common.w" } return true; } -/*:38*//*42:*/ -#line 540 "common.w" +/*:35*//*39:*/ +#line 502 "common.w" void check_complete(void){ @@ -772,7 +745,37 @@ err_print("! Change file entry did not match"); } } -/*:42*//*48:*/ +/*:39*//*40:*/ +#line 518 "common.w" + +void +reset_input(void) +{ +limit= buffer;loc= buffer+1;buffer[0]= ' '; +/*41:*/ +#line 533 "common.w" + +if((web_file= fopen(web_file_name,"r"))==NULL){ +strcpy(web_file_name,alt_web_file_name); +if((web_file= fopen(web_file_name,"r"))==NULL) +fatal("! Cannot open input file ",web_file_name); +} + + +web_file_open= true; +if((change_file= fopen(change_file_name,"r"))==NULL) +fatal("! Cannot open change file ",change_file_name); + +/*:41*/ +#line 523 "common.w" + +include_depth= cur_line= change_line= 0; +change_depth= include_depth; +changing= true;prime_the_change_buffer();changing= !changing; +limit= buffer;loc= buffer+1;buffer[0]= ' ';input_has_ended= false; +} + +/*:40*//*48:*/ #line 633 "common.w" name_pointer @@ -811,13 +814,13 @@ p->link= hash[h];hash[h]= p; #line 647 "common.w" if(p==name_ptr)/*51:*/ -#line 676 "common.w" +#line 675 "common.w" { if(byte_ptr+l> byte_mem_end)overflow("byte memory"); if(name_ptr>=name_dir_end)overflow("name"); strncpy(byte_ptr,first,l); (++name_ptr)->byte_start= byte_ptr+= l; -init_p(p,t); +if(program==cweave)p->ilk= t,init_node(p); } /*:51*/ @@ -827,7 +830,7 @@ return p; } /*:48*//*52:*/ -#line 708 "common.w" +#line 707 "common.w" void print_section_name( @@ -846,7 +849,7 @@ if(q)term_write("...",3); } /*:52*//*53:*/ -#line 725 "common.w" +#line 724 "common.w" void sprint_section_name( @@ -866,7 +869,7 @@ s= p->byte_start; } /*:53*//*54:*/ -#line 743 "common.w" +#line 742 "common.w" void print_prefix_name( @@ -879,7 +882,7 @@ if(s+l<(p+1)->byte_start)term_write("...",3); } /*:54*//*56:*/ -#line 769 "common.w" +#line 768 "common.w" static int web_strcmp( char*j, @@ -897,7 +900,7 @@ else return greater; } /*:56*//*57:*/ -#line 798 "common.w" +#line 797 "common.w" static name_pointer add_section_name( @@ -927,7 +930,7 @@ return par==NULL?(root= p):c==less?(par->llink= p):(par->rlink= p); } /*:57*//*58:*/ -#line 826 "common.w" +#line 825 "common.w" static void extend_section_name( @@ -951,7 +954,7 @@ if(ispref)*(byte_ptr-1)= ' '; } /*:58*//*59:*/ -#line 854 "common.w" +#line 853 "common.w" name_pointer section_lookup( @@ -966,7 +969,7 @@ name_pointer par= NULL; size_t name_len= (size_t)(last-first+1); /*60:*/ -#line 878 "common.w" +#line 877 "common.w" while(p){ c= web_strcmp(first,name_len,first_chunk(p),prefix_length(p)); @@ -993,19 +996,19 @@ p= q,q= NULL; } /*:60*/ -#line 868 "common.w" +#line 867 "common.w" /*61:*/ -#line 903 "common.w" +#line 902 "common.w" if(r==NULL) return add_section_name(par,c,first,last+1,ispref); /*:61*/ -#line 869 "common.w" +#line 868 "common.w" /*62:*/ -#line 911 "common.w" +#line 910 "common.w" switch(section_name_cmp(&first,name_len,r)){ @@ -1039,12 +1042,12 @@ err_print(">"); return r; /*:62*/ -#line 870 "common.w" +#line 869 "common.w" } /*:59*//*63:*/ -#line 959 "common.w" +#line 958 "common.w" static int section_name_cmp( char**pfirst, @@ -1066,7 +1069,7 @@ if(ispref){ *pfirst= first+(ptrdiff_t)(ss-s); return extension; }else return equal; -else return(q->byte_start==(q+1)->byte_start)?equal:prefix; +else return length(q)==0?equal:prefix; case extension: if(!ispref)return bad_extension; first+= ss-s; @@ -1078,7 +1081,7 @@ default:return c; } /*:63*//*66:*/ -#line 1013 "common.w" +#line 1012 "common.w" void err_print( @@ -1086,7 +1089,7 @@ const char*s) { *s=='!'?printf("\n%s",s):printf("%s",s); if(web_file_open)/*67:*/ -#line 1032 "common.w" +#line 1031 "common.w" {char*k,*l; if(changing&&include_depth==change_depth) @@ -1098,7 +1101,7 @@ if(l> buffer){ for(k= buffer;k<l;k++) if(*k=='\t')putchar(' '); else putchar(*k); -new_line; +new_line(); for(k= buffer;k<l;k++)putchar(' '); } for(k= l;k<limit;k++)putchar(*k); @@ -1107,20 +1110,20 @@ putchar(' '); } /*:67*/ -#line 1019 "common.w" +#line 1018 "common.w" -update_terminal;mark_error; +update_terminal();mark_error(); } /*:66*//*68:*/ -#line 1065 "common.w" +#line 1064 "common.w" int wrap_up(void){ -if(show_progress)new_line; +if(show_progress)new_line(); if(show_stats) print_stats(); /*69:*/ -#line 1075 "common.w" +#line 1074 "common.w" switch(history){ case spotless: @@ -1134,14 +1137,14 @@ puts("(That was a fatal error, my friend.)"); } /*:69*/ -#line 1070 "common.w" +#line 1069 "common.w" if(history> harmless_message)return EXIT_FAILURE; else return EXIT_SUCCESS; } /*:68*//*70:*/ -#line 1093 "common.w" +#line 1092 "common.w" void fatal( const char*s,const char*t) @@ -1152,7 +1155,7 @@ history= fatal_message;exit(wrap_up()); } /*:70*//*71:*/ -#line 1104 "common.w" +#line 1103 "common.w" void overflow( const char*t) @@ -1162,27 +1165,27 @@ printf("\n! Sorry, %s capacity exceeded",t);fatal("",""); /*:71*//*75:*/ -#line 1157 "common.w" +#line 1156 "common.w" static void scan_args(void) { char*dot_pos; char*name_pos; -register char*s; +char*s; 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 1247 "common.w" +#line 1244 "common.w" for(dot_pos= *argv+1;*dot_pos> '\0';dot_pos++) flags[(eight_bits)*dot_pos]= flag_change; /*:80*/ -#line 1169 "common.w" +#line 1168 "common.w" else{ s= name_pos= *argv;dot_pos= NULL; @@ -1191,17 +1194,17 @@ if(*s=='.')dot_pos= s++; else if(*s=='/')dot_pos= NULL,name_pos= ++s; else s++; if(!found_web)/*77:*/ -#line 1195 "common.w" +#line 1194 "common.w" { if(s-*argv> max_file_name_length-5) /*82:*/ -#line 1263 "common.w" +#line 1260 "common.w" fatal("! Filename too long\n",*argv); /*:82*/ -#line 1198 "common.w" +#line 1197 "common.w" if(dot_pos==NULL) sprintf(web_file_name,"%s.w",*argv); @@ -1218,21 +1221,21 @@ found_web= true; } /*:77*/ -#line 1177 "common.w" +#line 1176 "common.w" else if(!found_change)/*78:*/ -#line 1213 "common.w" +#line 1212 "common.w" { if(strcmp(*argv,"-")!=0){ if(s-*argv> max_file_name_length-4) /*82:*/ -#line 1263 "common.w" +#line 1260 "common.w" fatal("! Filename too long\n",*argv); /*:82*/ -#line 1217 "common.w" +#line 1216 "common.w" if(dot_pos==NULL) sprintf(change_file_name,"%s.ch",*argv); @@ -1242,43 +1245,41 @@ found_change= true; } /*:78*/ -#line 1178 "common.w" +#line 1177 "common.w" else if(!found_out)/*79:*/ -#line 1225 "common.w" +#line 1224 "common.w" { if(s-*argv> max_file_name_length-5) /*82:*/ -#line 1263 "common.w" +#line 1260 "common.w" fatal("! Filename too long\n",*argv); /*:82*/ -#line 1228 "common.w" +#line 1227 "common.w" if(dot_pos==NULL){ sprintf(tex_file_name,"%s.tex",*argv); -sprintf(idx_file_name,"%s.idx",*argv); -sprintf(scn_file_name,"%s.scn",*argv); sprintf(C_file_name,"%s.c",*argv); }else{ strcpy(tex_file_name,*argv); strcpy(C_file_name,*argv); -if(make_xrefs){ *dot_pos= '\0'; +} +if(make_xrefs){ sprintf(idx_file_name,"%s.idx",*argv); sprintf(scn_file_name,"%s.scn",*argv); } -} found_out= true; } /*:79*/ -#line 1179 "common.w" +#line 1178 "common.w" else/*81:*/ -#line 1251 "common.w" +#line 1248 "common.w" { if(program==ctangle) @@ -1292,12 +1293,12 @@ else fatal( } /*:81*/ -#line 1180 "common.w" +#line 1179 "common.w" } } if(!found_web)/*81:*/ -#line 1251 "common.w" +#line 1248 "common.w" { if(program==ctangle) @@ -1311,7 +1312,7 @@ else fatal( } /*:81*/ -#line 1183 "common.w" +#line 1182 "common.w" } diff --git a/web/c_cpp/cweb/common.h b/web/c_cpp/cweb/common.h index 186e87fd63..4104965917 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.8 --- June 2022 (works also with later versions) +% Version 4.10 --- August 2023 (works also with later versions) % Copyright (C) 1987,1990,1993 Silvio Levy and Donald E. Knuth @@ -32,13 +32,17 @@ First comes general stuff: @d ctangle false @d cweave true -@<Common code...@>= +@<Common code...@>=@^system dependencies@> typedef bool boolean; typedef uint8_t eight_bits; typedef uint16_t sixteen_bits; extern boolean program; /* \.{CWEAVE} or \.{CTANGLE}? */ extern int phase; /* which phase are we in? */ +@ The procedure that gets everything rolling: +@<Predecl...@>= +extern void common_init(void);@/ + @ Interface to the standard \CEE/ library: @<Include files@>= @@ -139,6 +143,7 @@ extern boolean print_where; /* tells \.{CTANGLE} to print line and file info */ @d rlink dummy.Rlink /* right link in binary search tree for section names */ @d root name_dir->rlink /* the root of the binary search tree for section names */ +@d ilk dummy.Ilk /* used by \.{CWEAVE} only */ @<Common code...@>= typedef struct name_info { @@ -147,7 +152,7 @@ typedef struct name_info { union { struct name_info *Rlink; /* right link in binary search tree for section names */ - char Ilk; /* used by identifiers in \.{CWEAVE} only */ + eight_bits Ilk; /* used by identifiers in \.{CWEAVE} only */ } dummy; void *equiv_or_xref; /* info corresponding to names */ } name_info; /* contains information about an identifier or section name */ @@ -164,23 +169,24 @@ extern hash_pointer hash_end; /* end of |hash| */ extern hash_pointer h; /* index into hash-head array */ @ @<Predecl...@>= -extern boolean names_match(name_pointer,const char *,size_t,eight_bits);@/ extern name_pointer id_lookup(const char *,const char *,eight_bits); /* looks up a string in the identifier table */ extern name_pointer section_lookup(char *,char *,boolean); /* finds section name */ -extern void init_node(name_pointer);@/ -extern void init_p(name_pointer,eight_bits);@/ extern void print_prefix_name(name_pointer);@/ extern void print_section_name(name_pointer);@/ extern void sprint_section_name(char *,name_pointer); +@# +extern boolean names_match(name_pointer,const char *,size_t,eight_bits); +/* two routines defined in \.{ctangle.w} and \.{cweave.w} */ +extern void init_node(name_pointer); @ Code related to error handling: @d spotless 0 /* |history| value for normal jobs */ @d harmless_message 1 /* |history| value when non-serious info was printed */ @d error_message 2 /* |history| value when an error was noted */ @d fatal_message 3 /* |history| value when we had to stop prematurely */ -@d mark_harmless if (history==spotless) history=harmless_message -@d mark_error history=error_message +@d mark_harmless() if (history==spotless) history=harmless_message +@d mark_error() history=error_message @d confusion(s) fatal("! This can't happen: ",s) @.This can't happen@> @@ -192,6 +198,8 @@ extern int wrap_up(void); /* indicate |history| and exit */ extern void err_print(const char *); /* print error message and context */ extern void fatal(const char *,const char *); /* issue error message and die */ extern void overflow(const char *); /* succumb because a table has overflowed */ +@# +extern void print_stats(void); /* defined in \.{ctangle.w} and \.{cweave.w} */ @ Code related to command line arguments: @d show_banner flags['b'] /* should the banner line be printed? */ @@ -210,8 +218,8 @@ extern char scn_file_name[]; /* name of |scn_file| */ extern boolean flags[]; /* an option for each 7-bit code */ @ Code related to output: -@d update_terminal fflush(stdout) /* empty the terminal output buffer */ -@d new_line putchar('\n') +@d update_terminal() fflush(stdout) /* empty the terminal output buffer */ +@d new_line() putchar('\n') @d term_write(a,b) fflush(stdout),fwrite(a,sizeof(char),b,stdout) @<Common code...@>= @@ -221,11 +229,6 @@ extern FILE *idx_file; /* where index from \.{CWEAVE} goes */ extern FILE *scn_file; /* where list of sections from \.{CWEAVE} goes */ extern FILE *active_file; /* currently active file for \.{CWEAVE} output */ -@ The procedure that gets everything rolling: -@<Predecl...@>= -extern void common_init(void);@/ -extern void print_stats(void); - @ The following parameters are sufficient to handle \TEX/ (converted to \.{CWEB}), so they should be sufficient for most applications of \.{CWEB}. diff --git a/web/c_cpp/cweb/common.w b/web/c_cpp/cweb/common.w index 4ec17241c3..dbcd57e31f 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.8 --- June 2022 +% Version 4.10 --- August 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.8)} +\def\title{Common code for CTANGLE and CWEAVE (Version 4.10)} \def\topofcontents{\null\vfill \centerline{\titlefont Common code for {\ttitlefont CTANGLE} and {\ttitlefont CWEAVE}} \vskip 15pt - \centerline{(Version 4.8)} + \centerline{(Version 4.10)} \vfill} \def\botofcontents{\vfill \noindent @@ -47,7 +47,7 @@ under the terms of a permission notice identical to this one. \pageno=\contentspagenumber \advance\pageno by 1 \let\maybe=\iftrue -@** Introduction. This file contains code common +@* Introduction. This file contains code common to both \.{CTANGLE} and \.{CWEAVE}, which roughly concerns the following problems: character uniformity, input routines, error handling and parsing of command line. We have tried to concentrate in this file @@ -129,7 +129,7 @@ char *section_text_end = section_text+longest_name; /* end of |section_text| */ char *id_first; /* where the current identifier begins in the buffer */ char *id_loc; /* just after the current identifier in the buffer */ -@** Input routines. The lowest level of input to the \.{CWEB} programs +@* Input routines. The lowest level of input to the \.{CWEB} programs is performed by |input_ln|, which must be told which file to read from. The return value of |input_ln| is |true| if the read is successful and |false| if not (generally this means the file has ended). The conventions @@ -150,22 +150,22 @@ char *loc=buffer; /* points to the next character to be read from the buffer */ char *limit=buffer; /* points to the last character in the buffer */ @ In the unlikely event that your standard I/O library does not -support |feof|, |getc|, and |ungetc| you may have to change things here. +support |feof| and |getc| you may have to change things here. @^system dependencies@> @c static boolean input_ln( /* copies a line into |buffer| or returns |false| */ FILE *fp) /* what file to read from */ { - register int c=EOF; /* character read; initialized so some compilers won't complain */ - register char *k; /* where next character goes */ + int c=EOF; /* character read; initialized so some compilers won't complain */ + char *k; /* where next character goes */ if (feof(fp)) return false; /* we have hit end-of-file */ limit = k = buffer; /* beginning of buffer */ while (k<=buffer_end && (c=getc(fp)) != EOF && c!='\n') if ((*(k++) = c) != ' ') limit = k; - if (k>buffer_end) - if ((c=getc(fp))!=EOF && c!='\n') { - ungetc(c,fp); loc=buffer; err_print("! Input line too long"); + if (k>buffer_end) { + while ((c=getc(fp))!=EOF && c!='\n'); /* discard rest of line */ + loc=buffer; err_print("! Input line too long"); @.Input line too long@> } if (c==EOF && limit==buffer) return false; /* there was nothing after @@ -175,8 +175,8 @@ FILE *fp) /* what file to read from */ @ @<Predecl...@>=@+static boolean input_ln(FILE *); -@ Now comes the problem of deciding which file to read from next. -Recall that the actual text that \.{CWEB} should process comes from two +@* File handling. Now comes the problem of deciding which file to read from +next. Recall that the actual text that \.{CWEB} should process comes from two streams: a |web_file|, which can contain possibly nested include commands~\.{@@i}, and a |change_file|, which might also contain includes. The |web_file| together with the currently open include @@ -313,7 +313,7 @@ check_change(void) /* switches to |change_file| if the buffers match */ return; } if (limit>buffer+1 && buffer[0]=='@@') { - char xyz_code=xisupper(buffer[1])? tolower((int)buffer[1]): buffer[1]; + if (xisupper(buffer[1])) buffer[1]=tolower((int)buffer[1]); @<If the current line starts with \.{@@y}, report any discrepancies and |return|@>@; } @@ -334,11 +334,11 @@ check_change(void) /* switches to |change_file| if the buffers match */ @ @<Predecl...@>=@+static void check_change(void); @ @<If the current line starts with \.{@@y}...@>= -if (xyz_code=='x' || xyz_code=='z') { +if (buffer[1]=='x' || buffer[1]=='z') { loc=buffer+2; err_print("! Where is the matching @@y?"); @.Where is the match...@> } -else if (xyz_code=='y') { +else if (buffer[1]=='y') { if (n>0) { loc=buffer+2; printf("\n! Hmm... %d ",n); @@ -349,37 +349,6 @@ else if (xyz_code=='y') { return; } -@ The |reset_input| procedure, which gets \.{CWEB} ready to read the -user's \.{CWEB} input, is used at the beginning of phase one of \.{CTANGLE}, -phases one and two of \.{CWEAVE}. - -@c -void -reset_input(void) -{ - limit=buffer; loc=buffer+1; buffer[0]=' '; - @<Open input files@>@; - include_depth=cur_line=change_line=0; - change_depth=include_depth; - changing=true; prime_the_change_buffer(); changing=!changing; - limit=buffer; loc=buffer+1; buffer[0]=' '; input_has_ended=false; -} - -@ The following code opens the input files. -@^system dependencies@> - -@<Open input files@>= -if ((web_file=fopen(web_file_name,"r"))==NULL) { - strcpy(web_file_name,alt_web_file_name); - if ((web_file=fopen(web_file_name,"r"))==NULL) - fatal("! Cannot open input file ", web_file_name); -} -@.Cannot open input file@> -@.Cannot open change file@> -web_file_open=true; -if ((change_file=fopen(change_file_name,"r"))==NULL) - fatal("! Cannot open change file ", change_file_name); - @ The |get_line| procedure is called when |loc>limit|; it puts the next line of merged input into the buffer and updates the other variables appropriately. A space is placed at the right end of the line. @@ -390,14 +359,7 @@ If we've just changed from the |cur_file| to the |change_file|, or if the |cur_file| has changed, we tell \.{CTANGLE} to print this information in the \CEE/ file by means of the |print_where| flag. -@<Global var...@>= -sixteen_bits section_count; /* the current section number */ -boolean changed_section[max_sections]; /* is the section changed? */ -boolean change_pending; /* if the current change is not yet recorded in - |changed_section[section_count]| */ -boolean print_where=false; /* should \.{CTANGLE} print line and file info? */ - -@ @c +@c boolean get_line(void) /* inputs the next line */ { restart: @@ -432,7 +394,7 @@ boolean get_line(void) /* inputs the next line */ stop reading it and start reading from the named include file. The \.{@@i} line should give a complete file name with or without double quotes. -If the environment variable \.{CWEBINPUTS} is set, or if the compiler flag +If the environment variable |CWEBINPUTS| is set, or if the compiler flag of the same name was defined at compile time, \.{CWEB} will look for include files in the directory thus named, if it cannot find them in the current directory. @@ -462,7 +424,6 @@ The remainder of the \.{@@i} line after the file name is ignored. goto restart; /* success */ } if ((kk=getenv("CWEBINPUTS"))!=NULL) { -@.CWEBINPUTS@> if ((l=strlen(kk))>max_file_name_length-2) too_long(); strcpy(temp_file_name,kk); } @@ -480,6 +441,7 @@ The remainder of the \.{@@i} line after the file name is ignored. for (; k>=cur_file_name; k--) *(k+l+1)=*k; strcpy(cur_file_name,temp_file_name); cur_file_name[l]='/'; /* \UNIX/ pathname separator */ +@^system dependencies@> if ((cur_file=fopen(cur_file_name,"r"))!=NULL) { cur_line=0; print_where=true; goto restart; /* success */ @@ -549,7 +511,45 @@ check_complete(void) { } } -@** Storage of names and strings. +@ The |reset_input| procedure, which gets \.{CWEB} ready to read the +user's \.{CWEB} input, is used at the beginning of phase one of \.{CTANGLE}, +phases one and two of \.{CWEAVE}. + +@c +void +reset_input(void) +{ + limit=buffer; loc=buffer+1; buffer[0]=' '; + @<Open input files@>@; + include_depth=cur_line=change_line=0; + change_depth=include_depth; + changing=true; prime_the_change_buffer(); changing=!changing; + limit=buffer; loc=buffer+1; buffer[0]=' '; input_has_ended=false; +} + +@ The following code opens the input files. +@^system dependencies@> + +@<Open input files@>= +if ((web_file=fopen(web_file_name,"r"))==NULL) { + strcpy(web_file_name,alt_web_file_name); + if ((web_file=fopen(web_file_name,"r"))==NULL) + fatal("! Cannot open input file ", web_file_name); +} +@.Cannot open input file@> +@.Cannot open change file@> +web_file_open=true; +if ((change_file=fopen(change_file_name,"r"))==NULL) + fatal("! Cannot open change file ", change_file_name); + +@ @<Global var...@>= +sixteen_bits section_count; /* the current section number */ +boolean changed_section[max_sections]; /* is the section changed? */ +boolean change_pending; /* if the current change is not yet recorded in + |changed_section[section_count]| */ +boolean print_where=false; /* should \.{CTANGLE} print line and file info? */ + +@* Storage of names and strings. Both \.{CWEAVE} and \.{CTANGLE} store identifiers, section names and other strings in a large array of |char|s, called |byte_mem|. Information about the names is kept in the array |name_dir|, whose @@ -670,15 +670,14 @@ if (p==NULL) { } @ The information associated with a new identifier must be initialized -in a slightly different way in \.{CWEAVE} than in \.{CTANGLE}; hence the -|init_p| procedure. +in a slightly different way in \.{CWEAVE} than in \.{CTANGLE}. @<Enter a new name...@>= { if (byte_ptr+l>byte_mem_end) overflow("byte memory"); if (name_ptr>=name_dir_end) overflow("name"); strncpy(byte_ptr,first,l); (++name_ptr)->byte_start=byte_ptr+=l; - init_p(p,t); + if (program==cweave) p->ilk=t, init_node(p); } @ If |p| is a |name_pointer| variable, as we have seen, @@ -977,7 +976,7 @@ name_pointer r) /* section name being compared */ *pfirst=first+(ptrdiff_t)(ss-s); return extension; /* null extension */ } else return equal; - else return (q->byte_start==(q+1)->byte_start)? equal: prefix; + else return length(q)==0? equal: prefix; case extension: if (!ispref) return bad_extension; first += ss-s; @@ -990,7 +989,7 @@ name_pointer r) /* section name being compared */ @ @<Predec...@>=@+static int section_name_cmp(char **,size_t,name_pointer); -@** Reporting errors to the user. +@* Reporting errors to the user. A global variable called |history| will contain one of four values at the end of every run: |spotless| means that no unusual messages were printed; |harmless_message| means that a message of possible interest @@ -1017,7 +1016,7 @@ const char *s) { *s=='!'? printf("\n%s",s) : printf("%s",s); if (web_file_open) @<Print error location based on input buffer@>@; - update_terminal; mark_error; + update_terminal(); mark_error(); } @ The error locations can be indicated by using the global variables @@ -1040,7 +1039,7 @@ if (l>buffer) { for (k=buffer; k<l; k++) if (*k=='\t') putchar(' '); else putchar(*k); /* print the characters already read */ - new_line; + new_line(); for (k=buffer; k<l; k++) putchar(' '); /* space out the next line */ } for (k=l; k<limit; k++) putchar(*k); /* print the part not yet read */ @@ -1064,7 +1063,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) new_line(); if (show_stats) print_stats(); /* print statistics about memory usage */ @<Print the job |history|@>@; @@ -1114,7 +1113,7 @@ and \.{CWEB} prints an error message that is really for the \.{CWEB} maintenance person, not the user. In such cases the program says |confusion("indication of where we are")|. -@** Command line arguments. +@* Command line arguments. The user calls \.{CWEAVE} and \.{CTANGLE} with arguments on the command line. These are either file names or flags to be turned off (beginning with |"-"|) or flags to be turned on (beginning with |"+"|). @@ -1160,7 +1159,7 @@ scan_args(void) { char *dot_pos; /* position of |'.'| in the argument */ char *name_pos; /* file name beginning, sans directory */ - register char *s; /* register for scanning strings */ + char *s; /* pointer for scanning strings */ boolean found_web=false,found_change=false,found_out=false; /* have these names been seen? */ @@ -1228,17 +1227,15 @@ after the dot. We must check that there is enough room in @<Complain about argument length@>@; if (dot_pos==NULL) { sprintf(tex_file_name,"%s.tex",*argv); - sprintf(idx_file_name,"%s.idx",*argv); - sprintf(scn_file_name,"%s.scn",*argv); sprintf(C_file_name,"%s.c",*argv); } else { strcpy(tex_file_name,*argv); strcpy(C_file_name,*argv); - if (make_xrefs) { /* indexes will be generated */ - *dot_pos='\0'; - sprintf(idx_file_name,"%s.idx",*argv); - sprintf(scn_file_name,"%s.scn",*argv); - } + *dot_pos='\0'; /* string now ends where the dot was */ + } + if (make_xrefs) { /* indexes will be generated */ + sprintf(idx_file_name,"%s.idx",*argv); + sprintf(scn_file_name,"%s.scn",*argv); } found_out=true; } @@ -1263,7 +1260,7 @@ else fatal( @ @<Complain about arg...@>= fatal("! Filename too long\n", *argv); @.Filename too long@> -@** Output. Here is the code that opens the output file: +@* Output. Here is the code that opens the output file: @^system dependencies@> @<Global var...@>= @@ -1285,4 +1282,4 @@ else { fatal("! Cannot open output file ", tex_file_name); } -@** Index. +@* Index. diff --git a/web/c_cpp/cweb/ctang-bs.ch b/web/c_cpp/cweb/ctang-bs.ch index 911d7d5dcf..6c6331c0c7 100644 --- a/web/c_cpp/cweb/ctang-bs.ch +++ b/web/c_cpp/cweb/ctang-bs.ch @@ -17,17 +17,17 @@ by using "huge" pointers. The ``banner line'' defined here should be changed whenever \.{CTANGLE} is modified. -@d banner "This is CTANGLE (Version 4.8)" +@d banner "This is CTANGLE (Version 4.10)" @y The ``banner line'' defined here should be changed whenever \.{CTANGLE} is modified. -@d banner "This is CTANGLE (Version 4.8pc/big)" +@d banner "This is CTANGLE (Version 4.10pc/big)" @z -@x Section 10. - for section names */ +@x Section 11. +@d ilk dummy.Ilk /* used by \.{CWEAVE} only */ @<Common code...@>= typedef struct name_info { @@ -36,7 +36,7 @@ typedef struct name_info { union { struct name_info *Rlink; /* right link in binary search tree for section names */ - char Ilk; /* used by identifiers in \.{CWEAVE} only */ + eight_bits Ilk; /* used by identifiers in \.{CWEAVE} only */ } dummy; void *equiv_or_xref; /* info corresponding to names */ } name_info; /* contains information about an identifier or section name */ @@ -52,7 +52,7 @@ 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 - for section names */ +@d ilk dummy.Ilk /* used by \.{CWEAVE} only */ @f huge extern @@ -63,7 +63,7 @@ typedef struct name_info { union { struct name_info *Rlink; /* right link in binary search tree for section names */ - char Ilk; /* used by identifiers in \.{CWEAVE} only */ + eight_bits Ilk; /* used by identifiers in \.{CWEAVE} only */ } dummy; union { char *equiv_member; @@ -144,10 +144,8 @@ text_ptr=text_info+1; text_ptr->tok_start=tok_mem; @x Section 31. - eight_bits *end_field; /* ending location of replacement text */ eight_bits *byte_field; /* present location within replacement text */ @y - eight_bits huge* end_field; /* ending location of replacement text */ eight_bits huge* byte_field; /* present location within replacement text */ @z @@ -156,10 +154,10 @@ text_ptr=text_info+1; text_ptr->tok_start=tok_mem; out_char( eight_bits cur_char) { - char *j, *k; /* pointer into |byte_mem| */ + char *j; /* pointer into |byte_mem| */ @y out_char(cur_char) eight_bits cur_char; { - char huge* j, huge* k; /* pointer into |byte_mem| */ + char huge* j; /* pointer into |byte_mem| */ @z diff --git a/web/c_cpp/cweb/ctang-pc.ch b/web/c_cpp/cweb/ctang-pc.ch index 00c1937307..25d62cdb6b 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.8)" +@d banner "This is CTANGLE (Version 4.10)" @y -@d banner "This is CTANGLE (Version 4.8pc)" +@d banner "This is CTANGLE (Version 4.10pc)" @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 809dff497d..91aa24fff2 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.8)} +\def\title{CTANGLE (Version 4.10)} @y -\def\title{CTANGLE (QL Version 4.8)} +\def\title{CTANGLE (QL Version 4.10)} @z @x section 1 -@d banner "This is CTANGLE (Version 4.8)" +@d banner "This is CTANGLE (Version 4.10)" @y -@d banner "This is CTANGLE (QL Version 4.8)" +@d banner "This is CTANGLE (QL Version 4.10)" @z @x diff --git a/web/c_cpp/cweb/ctang-vms.ch b/web/c_cpp/cweb/ctang-vms.ch index a928d912cf..9e311d3aa3 100644 --- a/web/c_cpp/cweb/ctang-vms.ch +++ b/web/c_cpp/cweb/ctang-vms.ch @@ -10,12 +10,12 @@ created: (these changes not necessary for initial bootstrapping) @x section 1 (01-FEB-1992 ST) -@d banner "This is CTANGLE (Version 4.8)" +@d banner "This is CTANGLE (Version 4.10)" @y -@d banner "This is CTANGLE (VAX/VMS Version 4.8)" +@d banner "This is CTANGLE (VAX/VMS Version 4.10)" @z -@x section 4 (01-FEB-1992 ST) +@x section 5 (01-FEB-1992 ST) #include <ctype.h> /* definition of |@!isalpha|, |@!isdigit| and so on */ #include <stdbool.h> /* definition of |@!bool|, |@!true| and |@!false| */ #include <stddef.h> /* definition of |@!ptrdiff_t| */ diff --git a/web/c_cpp/cweb/ctang-w32.ch b/web/c_cpp/cweb/ctang-w32.ch index ab76415410..51d3212b13 100644 --- a/web/c_cpp/cweb/ctang-w32.ch +++ b/web/c_cpp/cweb/ctang-w32.ch @@ -4,12 +4,12 @@ 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.8)" +@d banner "This is CTANGLE (Version 4.10)" @y -@d banner "This is CTANGLE (Version 4.8win32)" +@d banner "This is CTANGLE (Version 4.10win32)" @z -@x +@x section 24 boolean names_match( name_pointer p, /* points to the proposed match */ const char *first, /* position of first character of string */ @@ -23,15 +23,13 @@ size_t l, /* length of identifier */ eight_bits t) /* not used by \.{CTANGLE} */ @z -@x +@x section 25 void init_node( name_pointer node) { node->equiv=(void *)text_info; } -void -init_p(name_pointer p,eight_bits t) {@+(void)p;@+(void)t;@+} @y void init_node( @@ -39,6 +37,4 @@ name_pointer node) { node->equiv=(void *)text_info; } -void __cdecl -init_p(name_pointer p,eight_bits t) {@+(void)p;@+(void)t;@+} @z diff --git a/web/c_cpp/cweb/ctangle.c b/web/c_cpp/cweb/ctangle.c index 262469d611..2c31732e22 100644 --- a/web/c_cpp/cweb/ctangle.c +++ b/web/c_cpp/cweb/ctangle.c @@ -1,8 +1,8 @@ /*1:*/ #line 66 "ctangle.w" -/*4:*/ -#line 44 "common.h" +/*5:*/ +#line 48 "common.h" #include <ctype.h> #include <stdbool.h> @@ -12,10 +12,10 @@ #include <stdlib.h> #include <string.h> -/*:4*/ +/*:5*/ #line 67 "ctangle.w" -#define banner "This is CTANGLE (Version 4.8)" \ +#define banner "This is CTANGLE (Version 4.10)" \ #define ctangle false #define cweave true \ @@ -63,14 +63,15 @@ #define llink link #define rlink dummy.Rlink #define root name_dir->rlink \ - \ + +#define ilk dummy.Ilk \ #define spotless 0 #define harmless_message 1 #define error_message 2 #define fatal_message 3 -#define mark_harmless if(history==spotless) history= harmless_message -#define mark_error history= error_message +#define mark_harmless() if(history==spotless) history= harmless_message +#define mark_error() history= error_message #define confusion(s) fatal("! This can't happen: ",s) \ \ @@ -80,8 +81,8 @@ #define show_stats flags['s'] #define make_xrefs flags['x'] \ -#define update_terminal fflush(stdout) -#define new_line putchar('\n') +#define update_terminal() fflush(stdout) +#define new_line() putchar('\n') #define term_write(a,b) fflush(stdout) ,fwrite(a,sizeof(char) ,b,stdout) \ #define buf_size 200 @@ -107,11 +108,13 @@ #define output_defs_flag (2*024000-1) \ #define stack_size 50 -#define cur_end cur_state.end_field +#define cur_state stack[stack_size+1] \ + #define cur_byte cur_state.byte_field #define cur_name cur_state.name_field #define cur_repl cur_state.repl_field -#define cur_section cur_state.section_field \ +#define cur_section cur_state.section_field +#define cur_end (cur_repl+1) ->tok_start \ #define section_number 0201 #define identifier 0202 \ @@ -123,8 +126,10 @@ #define verbatim 4 \ #define max_files 256 +#define macro_end (cur_text+1) ->tok_start \ + #define C_printf(c,a) fprintf(C_file,c,a) -#define C_putc(c) putc((int) (c) ,C_file) \ +#define C_putc(c) fputc((int) (c) ,C_file) \ #define translit_length 10 \ @@ -162,24 +167,24 @@ typedef uint16_t sixteen_bits; extern boolean program; extern int phase; -/*:3*//*5:*/ -#line 74 "common.h" +/*:3*//*6:*/ +#line 78 "common.h" extern char section_text[]; extern char*section_text_end; extern char*id_first; extern char*id_loc; -/*:5*//*6:*/ -#line 92 "common.h" +/*:6*//*7:*/ +#line 96 "common.h" extern char buffer[]; extern char*buffer_end; extern char*loc; extern char*limit; -/*:6*//*7:*/ -#line 109 "common.h" +/*:7*//*8:*/ +#line 113 "common.h" extern int include_depth; extern FILE*file[]; @@ -194,16 +199,16 @@ extern boolean input_has_ended; extern boolean changing; extern boolean web_file_open; -/*:7*//*9:*/ -#line 129 "common.h" +/*:8*//*10:*/ +#line 133 "common.h" extern sixteen_bits section_count; extern boolean changed_section[]; extern boolean change_pending; extern boolean print_where; -/*:9*//*10:*/ -#line 143 "common.h" +/*:10*//*11:*/ +#line 148 "common.h" typedef struct name_info{ char*byte_start; @@ -211,7 +216,7 @@ struct name_info*link; union{ struct name_info*Rlink; -char Ilk; +eight_bits Ilk; }dummy; void*equiv_or_xref; }name_info; @@ -227,13 +232,13 @@ extern name_pointer hash[]; extern hash_pointer hash_end; extern hash_pointer h; -/*:10*//*12:*/ -#line 187 "common.h" +/*:11*//*13:*/ +#line 193 "common.h" extern int history; -/*:12*//*14:*/ -#line 203 "common.h" +/*:13*//*15:*/ +#line 211 "common.h" extern int argc; extern char**argv; @@ -243,8 +248,8 @@ extern char idx_file_name[]; extern char scn_file_name[]; extern boolean flags[]; -/*:14*//*15:*/ -#line 217 "common.h" +/*:15*//*16:*/ +#line 225 "common.h" extern FILE*C_file; extern FILE*tex_file; @@ -252,7 +257,7 @@ extern FILE*idx_file; extern FILE*scn_file; extern FILE*active_file; -/*:15*/ +/*:16*/ #line 69 "ctangle.w" /*19:*/ @@ -265,10 +270,9 @@ sixteen_bits text_link; typedef text*text_pointer; /*:19*//*31:*/ -#line 274 "ctangle.w" +#line 267 "ctangle.w" typedef struct{ -eight_bits*end_field; eight_bits*byte_field; name_pointer name_field; text_pointer repl_field; @@ -290,32 +294,30 @@ static eight_bits*tok_mem_end= tok_mem+max_toks-1; static eight_bits*tok_ptr; /*:20*//*26:*/ -#line 200 "ctangle.w" +#line 196 "ctangle.w" static text_pointer last_unnamed; /*:26*//*32:*/ -#line 291 "ctangle.w" +#line 285 "ctangle.w" -static output_state cur_state; - -static output_state stack[stack_size+1]; +static output_state stack[stack_size+2]; static stack_pointer stack_end= stack+stack_size; static stack_pointer stack_ptr; /*:32*//*37:*/ -#line 367 "ctangle.w" +#line 357 "ctangle.w" static int cur_val; /*:37*//*42:*/ -#line 459 "ctangle.w" +#line 449 "ctangle.w" static eight_bits out_state; static boolean protect; /*:42*//*45:*/ -#line 490 "ctangle.w" +#line 480 "ctangle.w" static name_pointer output_files[max_files]; static name_pointer*cur_out_file,*end_output_files,*an_output_file; @@ -323,33 +325,33 @@ static char cur_section_name_char; static char output_file_name[longest_name+1]; /*:45*//*52:*/ -#line 590 "ctangle.w" +#line 573 "ctangle.w" static boolean output_defs_seen= false; /*:52*//*57:*/ -#line 703 "ctangle.w" +#line 687 "ctangle.w" -static char translit[128][translit_length]; +static char translit[0200][translit_length]; /*:57*//*62:*/ -#line 779 "ctangle.w" +#line 763 "ctangle.w" static eight_bits ccode[256]; /*:62*//*66:*/ -#line 839 "ctangle.w" +#line 823 "ctangle.w" static boolean comment_continues= false; /*:66*//*68:*/ -#line 876 "ctangle.w" +#line 860 "ctangle.w" static name_pointer cur_section_name; static boolean no_where; /*:68*//*82:*/ -#line 1193 "ctangle.w" +#line 1177 "ctangle.w" static text_pointer cur_text; static eight_bits next_control; @@ -357,92 +359,94 @@ static eight_bits next_control; /*:82*/ #line 71 "ctangle.w" -/*8:*/ -#line 123 "common.h" +/*4:*/ +#line 43 "common.h" + +extern void common_init(void); + +/*:4*//*9:*/ +#line 127 "common.h" extern boolean get_line(void); extern void check_complete(void); extern void reset_input(void); -/*:8*//*11:*/ -#line 166 "common.h" +/*:9*//*12:*/ +#line 171 "common.h" -extern boolean names_match(name_pointer,const char*,size_t,eight_bits); extern name_pointer id_lookup(const char*,const char*,eight_bits); extern name_pointer section_lookup(char*,char*,boolean); -extern void init_node(name_pointer); -extern void init_p(name_pointer,eight_bits); extern void print_prefix_name(name_pointer); extern void print_section_name(name_pointer); extern void sprint_section_name(char*,name_pointer); -/*:11*//*13:*/ -#line 190 "common.h" +extern boolean names_match(name_pointer,const char*,size_t,eight_bits); + +extern void init_node(name_pointer); + +/*:12*//*14:*/ +#line 196 "common.h" extern int wrap_up(void); extern void err_print(const char*); extern void fatal(const char*,const char*); extern void overflow(const char*); -/*:13*//*16:*/ -#line 225 "common.h" - -extern void common_init(void); extern void print_stats(void); -/*:16*//*30:*/ -#line 246 "ctangle.w" +/*:14*//*30:*/ +#line 242 "ctangle.w" static void store_two_bytes(sixteen_bits); /*:30*//*35:*/ -#line 330 "ctangle.w" +#line 321 "ctangle.w" static void push_level(name_pointer); static void pop_level(boolean); /*:35*//*39:*/ -#line 404 "ctangle.w" +#line 394 "ctangle.w" static void get_output(void); /*:39*//*44:*/ -#line 480 "ctangle.w" +#line 470 "ctangle.w" static void flush_buffer(void); /*:44*//*49:*/ -#line 557 "ctangle.w" +#line 541 "ctangle.w" static void phase_two(void); /*:49*//*53:*/ -#line 593 "ctangle.w" +#line 576 "ctangle.w" static void output_defs(void); static void out_char(eight_bits); /*:53*//*65:*/ -#line 819 "ctangle.w" +#line 803 "ctangle.w" static eight_bits skip_ahead(void); static boolean skip_comment(boolean); /*:65*//*70:*/ -#line 926 "ctangle.w" +#line 910 "ctangle.w" static eight_bits get_next(void); /*:70*//*84:*/ -#line 1219 "ctangle.w" +#line 1203 "ctangle.w" static void scan_repl(eight_bits); /*:84*//*91:*/ -#line 1411 "ctangle.w" +#line 1395 "ctangle.w" static void scan_section(void); /*:91*//*99:*/ -#line 1488 "ctangle.w" +#line 1472 "ctangle.w" static void phase_one(void); /*:99*//*101:*/ -#line 1521 "ctangle.w" +#line 1505 "ctangle.w" static void skip_limbo(void); /*:101*/ @@ -471,24 +475,24 @@ text_ptr= text_info+1;text_ptr->tok_start= tok_mem; init_node(name_dir); /*:23*//*27:*/ -#line 203 "ctangle.w" +#line 199 "ctangle.w" last_unnamed= text_info;text_info->text_link= macro; /*:27*//*46:*/ -#line 500 "ctangle.w" +#line 490 "ctangle.w" cur_out_file= end_output_files= output_files+max_files; /*:46*//*58:*/ -#line 706 "ctangle.w" +#line 690 "ctangle.w" -{ -int i; -for(i= 0;i<128;i++)sprintf(translit[i],"X%02X",(unsigned int)(128+i)); +{int i; +for(i= 0;i<0200;i++) +snprintf(translit[i],translit_length,"X%02X",(unsigned int)(0200+i)); } /*:58*//*63:*/ -#line 782 "ctangle.w" +#line 766 "ctangle.w" { int c; for(c= 0;c<256;c++)ccode[c]= ignore; @@ -508,7 +512,7 @@ ccode['<']= ccode['(']= section_name; ccode['\'']= ord; /*:63*//*78:*/ -#line 1114 "ctangle.w" +#line 1098 "ctangle.w" section_text[0]= ' '; /*:78*/ @@ -534,7 +538,7 @@ return length(p)==l&&strncmp(first,p->byte_start,l)==0; } /*:24*//*25:*/ -#line 170 "ctangle.w" +#line 168 "ctangle.w" void init_node( @@ -542,11 +546,9 @@ name_pointer node) { node->equiv= (void*)text_info; } -void -init_p(name_pointer p,eight_bits t){(void)p;(void)t;} /*:25*//*29:*/ -#line 236 "ctangle.w" +#line 232 "ctangle.w" static void store_two_bytes( @@ -558,7 +560,7 @@ if(tok_ptr+2> tok_mem_end)overflow("token"); } /*:29*//*34:*/ -#line 315 "ctangle.w" +#line 307 "ctangle.w" static void push_level( @@ -569,13 +571,12 @@ if(stack_ptr==stack_end)overflow("stack"); stack_ptr++; if(p!=NULL){ cur_name= p;cur_repl= (text_pointer)p->equiv; -cur_byte= cur_repl->tok_start;cur_end= (cur_repl+1)->tok_start; -cur_section= 0; +cur_byte= cur_repl->tok_start;cur_section= 0; } } /*:34*//*36:*/ -#line 338 "ctangle.w" +#line 329 "ctangle.w" static void pop_level( @@ -583,15 +584,14 @@ boolean flag) { if(flag&&cur_repl->text_link<section_flag){ cur_repl= cur_repl->text_link+text_info; -cur_byte= cur_repl->tok_start;cur_end= (cur_repl+1)->tok_start; -return; +cur_byte= cur_repl->tok_start;return; } stack_ptr--; if(stack_ptr> stack)cur_state= *stack_ptr; } /*:36*//*38:*/ -#line 374 "ctangle.w" +#line 364 "ctangle.w" static void get_output(void) @@ -614,7 +614,7 @@ 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 409 "ctangle.w" +#line 399 "ctangle.w" { a-= 024000; @@ -628,7 +628,7 @@ goto restart; } /*:40*/ -#line 395 "ctangle.w" +#line 385 "ctangle.w" break; default:cur_val= (int)a-050000; @@ -639,7 +639,7 @@ out_char(section_number); } /*:38*//*43:*/ -#line 467 "ctangle.w" +#line 457 "ctangle.w" static void flush_buffer(void) @@ -648,13 +648,13 @@ C_putc('\n'); if(cur_line%100==0&&show_progress){ putchar('.'); if(cur_line%500==0)printf("%d",cur_line); -update_terminal; +update_terminal(); } cur_line++; } /*:43*//*48:*/ -#line 519 "ctangle.w" +#line 509 "ctangle.w" static void phase_two(void){ @@ -662,47 +662,41 @@ phase= 2; web_file_open= false; cur_line= 1; /*33:*/ -#line 304 "ctangle.w" +#line 296 "ctangle.w" stack_ptr= stack+1;cur_name= name_dir;cur_repl= text_info->text_link+text_info; -cur_byte= cur_repl->tok_start;cur_end= (cur_repl+1)->tok_start;cur_section= 0; +cur_byte= cur_repl->tok_start;cur_section= 0; /*:33*/ -#line 525 "ctangle.w" +#line 515 "ctangle.w" /*51:*/ -#line 586 "ctangle.w" +#line 569 "ctangle.w" if(!output_defs_seen) output_defs(); /*:51*/ -#line 526 "ctangle.w" +#line 516 "ctangle.w" if(text_info->text_link==macro&&cur_out_file==end_output_files){ -fputs("\n! No program text was specified.",stdout);mark_harmless; +fputs("\n! No program text was specified.",stdout);mark_harmless(); } else{ -if(cur_out_file==end_output_files){ if(show_progress){ -printf("\nWriting the output file (%s):",C_file_name); -update_terminal; -} -} -else{ -if(show_progress){ -fputs("\nWriting the output files:",stdout); +printf(cur_out_file==end_output_files? +"\nWriting the output file (%s):": +"\nWriting the output files: (%s)",C_file_name); -printf(" (%s)",C_file_name); -update_terminal; -} -if(text_info->text_link==macro)goto writeloop; +update_terminal(); } +if(text_info->text_link!=macro){ while(stack_ptr> stack)get_output(); flush_buffer(); -writeloop:/*50:*/ -#line 563 "ctangle.w" +} +/*50:*/ +#line 547 "ctangle.w" for(an_output_file= end_output_files;an_output_file> cur_out_file;){ an_output_file--; @@ -711,29 +705,28 @@ fclose(C_file); if((C_file= fopen(output_file_name,"wb"))==NULL) fatal("! Cannot open output file ",output_file_name); -if(show_progress){printf("\n(%s)",output_file_name);update_terminal;} +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; -cur_end= (cur_repl+1)->tok_start; while(stack_ptr> stack)get_output(); flush_buffer(); } /*:50*/ -#line 549 "ctangle.w" +#line 533 "ctangle.w" if(show_happiness){ -if(show_progress)new_line; +if(show_progress)new_line(); fputs("Done.",stdout); } } } /*:48*//*54:*/ -#line 600 "ctangle.w" +#line 585 "ctangle.w" static void output_defs(void) @@ -743,13 +736,12 @@ push_level(NULL); for(cur_text= text_info+1;cur_text<text_ptr;cur_text++) if(cur_text->text_link==macro){ cur_byte= cur_text->tok_start; -cur_end= (cur_text+1)->tok_start; C_printf("%s","#define "); out_state= normal; protect= true; -while(cur_byte<cur_end){ +while(cur_byte<macro_end){ a= *cur_byte++; -if(cur_byte==cur_end&&a=='\n')break; +if(cur_byte==macro_end&&a=='\n')break; if(out_state==verbatim&&a!=string&&a!=constant&&a!='\n') C_putc(a); @@ -774,35 +766,35 @@ pop_level(false); } /*:54*//*55:*/ -#line 644 "ctangle.w" +#line 628 "ctangle.w" static void out_char( eight_bits cur_char) { -char*j,*k; +char*j; restart: switch(cur_char){ 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 712 "ctangle.w" +#line 696 "ctangle.w" case identifier: if(out_state==num_or_id)C_putc(' '); -for(j= (cur_val+name_dir)->byte_start,k= (cur_val+name_dir+1)->byte_start; -j<k;j++) +for(j= (cur_val+name_dir)->byte_start; +j<(cur_val+name_dir+1)->byte_start;j++) if((eight_bits)(*j)<0200)C_putc(*j); else C_printf("%s",translit[(eight_bits)(*j)-0200]); out_state= num_or_id;break; /*:59*/ -#line 655 "ctangle.w" +#line 639 "ctangle.w" /*60:*/ -#line 722 "ctangle.w" +#line 706 "ctangle.w" case section_number: if(cur_val> 0)C_printf("/*%d:*/",cur_val); @@ -819,8 +811,8 @@ C_printf("\n#line %d \"",(int)a); cur_val= (int)(*cur_byte++-0200)*0400; cur_val+= *cur_byte++; -for(j= (cur_val+name_dir)->byte_start,k= (cur_val+name_dir+1)->byte_start; -j<k;j++){ +for(j= (cur_val+name_dir)->byte_start; +j<(cur_val+name_dir+1)->byte_start;j++){ if(*j=='\\'||*j=='"')C_putc('\\'); C_putc(*j); } @@ -829,10 +821,10 @@ C_putc('"');C_putc('\n'); break; /*:60*/ -#line 656 "ctangle.w" +#line 640 "ctangle.w" /*56:*/ -#line 674 "ctangle.w" +#line 658 "ctangle.w" case plus_plus:C_putc('+');C_putc('+');out_state= normal;break; case minus_minus:C_putc('-');C_putc('-');out_state= normal;break; @@ -853,7 +845,7 @@ case minus_gt_ast:C_putc('-');C_putc('>');C_putc('*');out_state= normal; break; /*:56*/ -#line 657 "ctangle.w" +#line 641 "ctangle.w" case'=':case'>':C_putc(cur_char);C_putc(' '); out_state= normal;break; @@ -872,7 +864,7 @@ default:C_putc(cur_char);out_state= normal;break; } /*:55*//*64:*/ -#line 803 "ctangle.w" +#line 787 "ctangle.w" static eight_bits skip_ahead(void) @@ -890,7 +882,7 @@ if(c!=ignore||*(loc-1)=='>')return c; } /*:64*//*67:*/ -#line 842 "ctangle.w" +#line 826 "ctangle.w" static boolean skip_comment( boolean is_long_comment) @@ -924,7 +916,7 @@ else loc++; } /*:67*//*69:*/ -#line 883 "ctangle.w" +#line 867 "ctangle.w" static eight_bits get_next(void) @@ -938,7 +930,7 @@ if(get_line()==false)return new_section; else if(print_where&&!no_where){ print_where= false; /*85:*/ -#line 1229 "ctangle.w" +#line 1213 "ctangle.w" { eight_bits a; @@ -955,7 +947,7 @@ store_id(a); } /*:85*/ -#line 895 "ctangle.w" +#line 879 "ctangle.w" } else return(eight_bits)'\n'; @@ -968,7 +960,7 @@ else continue; } loc++; if(xisdigit(c)||c=='.')/*73:*/ -#line 967 "ctangle.w" +#line 951 "ctangle.w" { boolean hex_flag= false; id_first= loc-1; @@ -1002,13 +994,13 @@ return constant; } /*:73*/ -#line 906 "ctangle.w" +#line 890 "ctangle.w" else if(c=='\''||c=='"' ||((c=='L'||c=='u'||c=='U')&&(*loc=='\''||*loc=='"')) ||((c=='u'&&*loc=='8')&&(*(loc+1)=='\''||*(loc+1)=='"'))) /*74:*/ -#line 1004 "ctangle.w" +#line 988 "ctangle.w" { char delim= (char)c; id_first= section_text+1; @@ -1052,11 +1044,11 @@ return string; } /*:74*/ -#line 910 "ctangle.w" +#line 894 "ctangle.w" else if(isalpha((int)c)||isxalpha(c)||ishigh(c)) /*72:*/ -#line 958 "ctangle.w" +#line 942 "ctangle.w" { id_first= --loc; do @@ -1067,10 +1059,10 @@ id_loc= loc;return identifier; } /*:72*/ -#line 912 "ctangle.w" +#line 896 "ctangle.w" else if(c=='@')/*75:*/ -#line 1049 "ctangle.w" +#line 1033 "ctangle.w" switch(c= ccode[(eight_bits)*loc++]){ case ignore:continue; @@ -1085,11 +1077,11 @@ continue; case section_name: cur_section_name_char= *(loc-1); /*77:*/ -#line 1094 "ctangle.w" +#line 1078 "ctangle.w" { char*k= section_text; /*79:*/ -#line 1116 "ctangle.w" +#line 1100 "ctangle.w" while(true){ if(loc> limit&&get_line()==false){ @@ -1099,7 +1091,7 @@ loc= buffer+1;break; } c= (eight_bits)*loc; /*80:*/ -#line 1139 "ctangle.w" +#line 1123 "ctangle.w" if(c=='@'){ c= (eight_bits)*(loc+1); @@ -1118,7 +1110,7 @@ err_print("! Nesting of section names not allowed");break; } /*:80*/ -#line 1124 "ctangle.w" +#line 1108 "ctangle.w" loc++;if(k<section_text_end)k++; if(xisspace(c)){ @@ -1130,12 +1122,12 @@ if(k>=section_text_end){ fputs("\n! Section name too long: ",stdout); term_write(section_text+1,25); -printf("...");mark_harmless; +printf("...");mark_harmless(); } if(*k==' '&&k> section_text)k--; /*:79*/ -#line 1096 "ctangle.w" +#line 1080 "ctangle.w" if(k-section_text> 3&&strncmp(k-2,"...",3)==0) cur_section_name= section_lookup(section_text+1,k-3,true); @@ -1144,7 +1136,7 @@ else cur_section_name= section_lookup(section_text+1,k,false); if(cur_section_name_char=='(') /*47:*/ -#line 504 "ctangle.w" +#line 494 "ctangle.w" { for(an_output_file= cur_out_file; @@ -1158,16 +1150,16 @@ else overflow("output files"); } /*:47*/ -#line 1104 "ctangle.w" +#line 1088 "ctangle.w" return section_name; } /*:77*/ -#line 1062 "ctangle.w" +#line 1046 "ctangle.w" case string:/*81:*/ -#line 1161 "ctangle.w" +#line 1145 "ctangle.w" id_first= loc++;*(limit+1)= '@';*(limit+2)= '>'; while(*loc!='@'||*(loc+1)!='>')loc++; @@ -1177,10 +1169,10 @@ id_loc= loc;loc+= 2; return string; /*:81*/ -#line 1063 "ctangle.w" +#line 1047 "ctangle.w" case ord:/*76:*/ -#line 1074 "ctangle.w" +#line 1058 "ctangle.w" id_first= loc; if(*loc=='\\') @@ -1202,13 +1194,13 @@ loc++; return ord; /*:76*/ -#line 1064 "ctangle.w" +#line 1048 "ctangle.w" default:return c; } /*:75*/ -#line 913 "ctangle.w" +#line 897 "ctangle.w" else if(xisspace(c)){ if(!preprocessing||loc> limit)continue; @@ -1218,7 +1210,7 @@ else return(eight_bits)' '; } else if(c=='#'&&loc==buffer+1)preprocessing= true; mistake:/*71:*/ -#line 935 "ctangle.w" +#line 919 "ctangle.w" switch(c){ case'+':if(*loc=='+')compress(plus_plus);break; @@ -1243,14 +1235,14 @@ case'!':if(*loc=='=')compress(non_eq);break; } /*:71*/ -#line 921 "ctangle.w" +#line 905 "ctangle.w" return c; } } /*:69*//*83:*/ -#line 1197 "ctangle.w" +#line 1181 "ctangle.w" static void scan_repl( @@ -1258,7 +1250,7 @@ eight_bits t) { sixteen_bits a; if(t==section_name)/*85:*/ -#line 1229 "ctangle.w" +#line 1213 "ctangle.w" { eight_bits a; @@ -1275,11 +1267,11 @@ store_id(a); } /*:85*/ -#line 1203 "ctangle.w" +#line 1187 "ctangle.w" while(true)switch(a= get_next()){ /*86:*/ -#line 1244 "ctangle.w" +#line 1228 "ctangle.w" case identifier:store_id(a); if(*buffer=='#'&&( @@ -1292,7 +1284,7 @@ break; case section_name:if(t!=section_name)goto done; else{ /*87:*/ -#line 1285 "ctangle.w" +#line 1269 "ctangle.w" { char*try_loc= loc; while(*try_loc==' '&&try_loc<limit)try_loc++; @@ -1305,13 +1297,13 @@ if(*try_loc=='=')err_print("! Missing `@ ' before a named section"); } /*:87*/ -#line 1255 "ctangle.w" +#line 1239 "ctangle.w" a= cur_section_name-name_dir; app_repl((a/0400)+0250); app_repl(a%0400); /*85:*/ -#line 1229 "ctangle.w" +#line 1213 "ctangle.w" { eight_bits a; @@ -1328,7 +1320,7 @@ store_id(a); } /*:85*/ -#line 1259 "ctangle.w" +#line 1243 "ctangle.w" } break; @@ -1340,7 +1332,7 @@ a= output_defs_flag; app_repl((a/0400)+0200); app_repl(a%0400); /*85:*/ -#line 1229 "ctangle.w" +#line 1213 "ctangle.w" { eight_bits a; @@ -1357,13 +1349,13 @@ store_id(a); } /*:85*/ -#line 1269 "ctangle.w" +#line 1253 "ctangle.w" } break; case constant:case string: /*88:*/ -#line 1302 "ctangle.w" +#line 1286 "ctangle.w" app_repl(a); while(id_first<id_loc){ @@ -1379,12 +1371,12 @@ app_repl(*id_first++); app_repl(a); /*:88*/ -#line 1273 "ctangle.w" +#line 1257 "ctangle.w" break; case ord: /*89:*/ -#line 1320 "ctangle.w" +#line 1304 "ctangle.w" { int c= (int)((eight_bits)*id_first); if(c=='\\'){ @@ -1434,7 +1426,7 @@ app_repl(constant); } /*:89*/ -#line 1276 "ctangle.w" +#line 1260 "ctangle.w" break; case definition:case format_code:case begin_C:if(t!=section_name)goto done; @@ -1445,7 +1437,7 @@ err_print("! @d, @f and @c are ignored in C text");continue; case new_section:goto done; /*:86*/ -#line 1208 "ctangle.w" +#line 1192 "ctangle.w" case')':app_repl(a); if(t==macro)app_repl(' '); @@ -1458,7 +1450,7 @@ cur_text= text_ptr;(++text_ptr)->tok_start= tok_ptr; } /*:83*//*90:*/ -#line 1378 "ctangle.w" +#line 1362 "ctangle.w" static void scan_section(void) @@ -1468,12 +1460,12 @@ text_pointer q; sixteen_bits a; section_count++;no_where= true; if(*(loc-1)=='*'&&show_progress){ -printf("*%d",(int)section_count);update_terminal; +printf("*%d",(int)section_count);update_terminal(); } next_control= ignore; while(true){ /*92:*/ -#line 1419 "ctangle.w" +#line 1403 "ctangle.w" while(next_control<definition) @@ -1482,11 +1474,11 @@ loc-= 2;next_control= get_next(); } /*:92*/ -#line 1392 "ctangle.w" +#line 1376 "ctangle.w" if(next_control==definition){ /*93:*/ -#line 1426 "ctangle.w" +#line 1410 "ctangle.w" while((next_control= get_next())=='\n'); if(next_control!=identifier){ @@ -1502,7 +1494,7 @@ scan_repl(macro); cur_text->text_link= macro; /*:93*/ -#line 1394 "ctangle.w" +#line 1378 "ctangle.w" continue; } @@ -1512,14 +1504,14 @@ p= name_dir;break; if(next_control==section_name){ p= cur_section_name; /*94:*/ -#line 1448 "ctangle.w" +#line 1432 "ctangle.w" while((next_control= get_next())=='+'); if(next_control!='='&&next_control!=eq_eq) continue; /*:94*/ -#line 1402 "ctangle.w" +#line 1386 "ctangle.w" break; } @@ -1527,20 +1519,20 @@ return; } no_where= print_where= false; /*95:*/ -#line 1453 "ctangle.w" +#line 1437 "ctangle.w" /*96:*/ -#line 1458 "ctangle.w" +#line 1442 "ctangle.w" store_two_bytes((sixteen_bits)(0150000+section_count)); /*:96*/ -#line 1454 "ctangle.w" +#line 1438 "ctangle.w" scan_repl(section_name); /*97:*/ -#line 1462 "ctangle.w" +#line 1446 "ctangle.w" if(p==name_dir||p==NULL){ last_unnamed->text_link= cur_text-text_info;last_unnamed= cur_text; @@ -1557,16 +1549,16 @@ cur_text->text_link= section_flag; /*:97*/ -#line 1456 "ctangle.w" +#line 1440 "ctangle.w" /*:95*/ -#line 1408 "ctangle.w" +#line 1392 "ctangle.w" } /*:90*//*98:*/ -#line 1477 "ctangle.w" +#line 1461 "ctangle.w" static void phase_one(void){ @@ -1579,7 +1571,7 @@ check_complete(); } /*:98*//*100:*/ -#line 1493 "ctangle.w" +#line 1477 "ctangle.w" static void skip_limbo(void) @@ -1593,7 +1585,7 @@ char c= *loc++; switch(ccode[(eight_bits)c]){ case new_section:return; case translit_code:/*102:*/ -#line 1523 "ctangle.w" +#line 1507 "ctangle.w" while(xisspace(*loc)&&loc<limit)loc++; loc+= 3; @@ -1607,7 +1599,7 @@ char*beg; sscanf(loc-3,"%x",&i); while(xisspace(*loc)&&loc<limit)loc++; beg= loc; -while(loc<limit&&(xisalpha(*loc)||xisdigit(*loc)||*loc=='_'))loc++; +while(loc<limit&&(xisalpha(*loc)||xisdigit(*loc)||isxalpha(*loc)))loc++; if(loc-beg>=translit_length) err_print("! Replacement string in @l too long"); @@ -1618,7 +1610,7 @@ translit[i-0200][loc-beg]= '\0'; } /*:102*/ -#line 1505 "ctangle.w" +#line 1489 "ctangle.w" break; case format_code:case'@':break; case control_text:if(c=='q'||c=='Q'){ @@ -1636,7 +1628,7 @@ default:err_print("! Double @ should be used in limbo"); } /*:100*//*103:*/ -#line 1549 "ctangle.w" +#line 1533 "ctangle.w" void print_stats(void){ diff --git a/web/c_cpp/cweb/ctangle.w b/web/c_cpp/cweb/ctangle.w index 0c372e59ed..c8ae55df85 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.8 --- June 2022 +% Version 4.10 --- August 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.8)} +\def\title{CTANGLE (Version 4.10)} \def\topofcontents{\null\vfill \centerline{\titlefont The {\ttitlefont CTANGLE} processor} \vskip 15pt - \centerline{(Version 4.8)} + \centerline{(Version 4.10)} \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.8)" +@d banner "This is CTANGLE (Version 4.10)" @c @<Include files@>@/ @@ -162,10 +162,8 @@ eight_bits t) /* not used by \.{CTANGLE} */ return length(p)==l && strncmp(first,p->byte_start,l)==0; } -@ The common lookup routine refers to separate routines |init_node| and -|init_p| when the data structure grows. Actually |init_p| is called only by -\.{CWEAVE}, but we need to declare a dummy version so that -the loader won't complain of its absence. +@ The common lookup routine |id_lookup| refers to a separate routine +|init_node| when the data structure grows. @c void @@ -174,8 +172,6 @@ name_pointer node) { node->equiv=(void *)text_info; } -void -init_p(name_pointer p,eight_bits t) {@+(void)p;@+(void)t;@+} @* Tokens. Replacement texts, which represent \CEE/ code in a compressed format, @@ -247,13 +243,10 @@ sixteen_bits x) @** Stacks for output. The output process uses a stack to keep track of what is going on at different ``levels'' as the sections are being -written out. Entries on this stack have five parts: - -\yskip\hang |end_field| is the |tok_mem| location where the replacement -text of a particular level will end; +written out. Entries on this stack have four parts: -\hang |byte_field| is the |tok_mem| location from which the next token -on a particular level will be read; +\yskip\hang |byte_field| is the |tok_mem| location from which the next +token on a particular level will be read; \hang |name_field| points to the name corresponding to a particular level; @@ -262,10 +255,10 @@ at a particular level; \hang |section_field| is the section number, or zero if this is a macro. -\yskip\noindent The current values of these five quantities are referred to -quite frequently, so they are stored in a separate place instead of in -the |stack| array. We call the current values |cur_end|, |cur_byte|, -|cur_name|, |cur_repl|, and |cur_section|. +\yskip\noindent The current values of these four quantities are referred to +quite frequently, so they are stored in an extra slot at the very end of the +|stack| array. We call the current values |cur_byte|, |cur_name|, |cur_repl|, +and |cur_section|. The global variable |stack_ptr| tells how many levels of output are currently in progress. The end of all output occurs when the stack is @@ -273,7 +266,6 @@ empty, i.e., when |stack_ptr==stack|. @<Typed...@>= typedef struct { - eight_bits *end_field; /* ending location of replacement text */ eight_bits *byte_field; /* present location within replacement text */ name_pointer name_field; /* |byte_start| index for text being output */ text_pointer repl_field; /* |tok_start| index for text being output */ @@ -282,16 +274,16 @@ typedef struct { typedef output_state *stack_pointer; @ @d stack_size 50 /* number of simultaneous levels of macro expansion */ -@d cur_end cur_state.end_field /* current ending location in |tok_mem| */ +@d cur_state stack[stack_size+1] /* |cur_byte|, |cur_name|, |cur_repl|, + and |cur_section| */ @d cur_byte cur_state.byte_field /* location of next output byte in |tok_mem|*/ @d cur_name cur_state.name_field /* pointer to current name being expanded */ @d cur_repl cur_state.repl_field /* pointer to current replacement text */ @d cur_section cur_state.section_field /* current section number being expanded */ +@d cur_end (cur_repl+1)->tok_start /* current ending location in |tok_mem| */ @<Private...@>= -static output_state cur_state; /* |cur_end|, |cur_byte|, |cur_name|, |cur_repl|, - and |cur_section| */ -static output_state stack[stack_size+1]; /* info for non-current levels */ +static output_state stack[stack_size+2]; /* info for non-current levels */ static stack_pointer stack_end=stack+stack_size; /* end of |stack| */ static stack_pointer stack_ptr; /* first unused location in the output state stack */ @@ -303,7 +295,7 @@ 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; -cur_byte=cur_repl->tok_start; cur_end=(cur_repl+1)->tok_start; cur_section=0; +cur_byte=cur_repl->tok_start; cur_section=0; @ 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 @@ -322,8 +314,7 @@ name_pointer p) stack_ptr++; if (p!=NULL) { /* |p==NULL| means we are in |output_defs| */ cur_name=p; cur_repl=(text_pointer)p->equiv; - cur_byte=cur_repl->tok_start; cur_end=(cur_repl+1)->tok_start; - cur_section=0; + cur_byte=cur_repl->tok_start; cur_section=0; } } @@ -342,11 +333,10 @@ boolean flag) /* |flag==false| means we are in |output_defs| */ { if (flag && cur_repl->text_link<section_flag) { /* link to a continuation */ cur_repl=cur_repl->text_link+text_info; /* stay on the same level */ - cur_byte=cur_repl->tok_start; cur_end=(cur_repl+1)->tok_start; - return; + cur_byte=cur_repl->tok_start; return; } stack_ptr--; /* go down to the previous level */ - if (stack_ptr>stack) cur_state=*stack_ptr; + if (stack_ptr>stack) cur_state=*stack_ptr;@^system dependencies@> } @ The heart of the output procedure is the function |get_output|, @@ -472,7 +462,7 @@ flush_buffer(void) /* writes one line to output file */ if (cur_line % 100 == 0 && show_progress) { putchar('.'); if (cur_line % 500 == 0) printf("%d",cur_line); - update_terminal; /* progress report */ + update_terminal(); /* progress report */ } cur_line++; } @@ -525,30 +515,24 @@ 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; + fputs("\n! No program text was specified.",stdout); mark_harmless(); @.No program text...@> } else { - if (cur_out_file==end_output_files) { - if (show_progress) { - printf("\nWriting the output file (%s):",C_file_name); - update_terminal; - } - } - else { - if (show_progress) { - fputs("\nWriting the output files:",stdout); + if (show_progress) { + printf(cur_out_file==end_output_files ? @| + "\nWriting the output file (%s):" : @| + "\nWriting the output files: (%s)",C_file_name); @.Writing the output...@> - printf(" (%s)",C_file_name); - update_terminal; - } - if (text_info->text_link==macro) goto writeloop; + update_terminal(); } - while (stack_ptr>stack) get_output(); - flush_buffer(); -writeloop: @<Write all the named output files@>@; + if (text_info->text_link!=macro) { + while (stack_ptr>stack) get_output(); + flush_buffer(); + } + @<Write all the named output files@>@; if (show_happiness) { - if (show_progress) new_line; + if (show_progress) new_line(); fputs("Done.",stdout); } } @@ -568,13 +552,12 @@ for (an_output_file=end_output_files; an_output_file>cur_out_file;) { if ((C_file=fopen(output_file_name,"wb"))==NULL) fatal("! Cannot open output file ",output_file_name); @.Cannot open output file@> - if (show_progress) { printf("\n(%s)",output_file_name); update_terminal; } + 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; - cur_end=(cur_repl+1)->tok_start; while (stack_ptr > stack) get_output(); flush_buffer(); } @@ -594,8 +577,10 @@ static boolean output_defs_seen=false; static void output_defs(void);@/ static void out_char(eight_bits); -@ @d C_printf(c,a) fprintf(C_file,c,a) -@d C_putc(c) putc((int)(c),C_file) /* isn't \CEE/ wonderfully consistent? */ +@ @d macro_end (cur_text+1)->tok_start /* end of |macro| replacement text */ +@# +@d C_printf(c,a) fprintf(C_file,c,a) +@d C_putc(c) fputc((int)(c),C_file) /* isn't \CEE/ wonderfully consistent? */ @c static void @@ -606,13 +591,12 @@ output_defs(void) for (cur_text=text_info+1; cur_text<text_ptr; cur_text++) if (cur_text->text_link==macro) { /* |cur_text| is the text for a |macro| */ cur_byte=cur_text->tok_start; - cur_end=(cur_text+1)->tok_start; C_printf("%s","#define "); out_state=normal; protect=true; /* newlines should be preceded by |'\\'| */ - while (cur_byte<cur_end) { + while (cur_byte<macro_end) { a=*cur_byte++; - if (cur_byte==cur_end && a=='\n') break; /* disregard a final newline */ + if (cur_byte==macro_end && a=='\n') break; /* disregard a final newline */ if (out_state==verbatim && a!=string && a!=constant && a!='\n') C_putc(a); /* a high-bit character can occur in a string */ @^high-bit character handling@> @@ -646,7 +630,7 @@ static void out_char( eight_bits cur_char) { - char *j, *k; /* pointer into |byte_mem| */ + char *j; /* pointer into |byte_mem| */ restart: switch (cur_char) { case '\n': if (protect && out_state!=verbatim) C_putc(' '); @@ -690,8 +674,8 @@ case period_ast: C_putc('.');@+C_putc('*'); out_state=normal; break; case minus_gt_ast: C_putc('-');@+C_putc('>');@+C_putc('*'); out_state=normal; break; -@ When an identifier is output to the \CEE/ file, characters in the -range 128--255 must be changed into something else, so the \CEE/ +@ When an identifier is output to the \CEE/ file, characters in the range +128--255 (|0200|--|0377|) must be changed into something else, so the \CEE/ compiler won't complain. By default, \.{CTANGLE} converts the character with code $16 x+y$ to the three characters `\.X$xy$', but a different transliteration table can be specified. Thus a German @@ -701,19 +685,19 @@ This makes debugging a lot less confusing. @d translit_length 10 @<Private...@>= -static char translit[128][translit_length]; +static char translit[0200][translit_length]; @ @<Set init...@>= -{ - int i; - for (i=0;i<128;i++) sprintf(translit[i],"X%02X",(unsigned int)(128+i)); +{ int i; + for (i=0;i<0200;i++) + snprintf(translit[i],translit_length,"X%02X",(unsigned int)(0200+i)); } @ @<Case of an identifier@>=@t\1\quad@> case identifier: if (out_state==num_or_id) C_putc(' '); - for (j=(cur_val+name_dir)->byte_start, k=(cur_val+name_dir+1)->byte_start; - j<k; j++) + for (j=(cur_val+name_dir)->byte_start; + j<(cur_val+name_dir+1)->byte_start; j++) if ((eight_bits)(*j)<0200) C_putc(*j); @^high-bit character handling@> else C_printf("%s",translit[(eight_bits)(*j)-0200]); @@ -735,8 +719,8 @@ case section_number: @:line}{\.{\#line}@> cur_val=(int)(*cur_byte++-0200)*0400; cur_val+=*cur_byte++; /* points to the file name */ - for (j=(cur_val+name_dir)->byte_start, k=(cur_val+name_dir+1)->byte_start; - j<k; j++) { + for (j=(cur_val+name_dir)->byte_start; + j<(cur_val+name_dir+1)->byte_start; j++) { if (*j=='\\' || *j=='"') C_putc('\\'); C_putc(*j); } @@ -1132,7 +1116,7 @@ if (k>=section_text_end) { fputs("\n! Section name too long: ",stdout); @.Section name too long@> term_write(section_text+1,25); - printf("..."); mark_harmless; + printf("..."); mark_harmless(); } if (*k==' ' && k>section_text) k--; @@ -1384,7 +1368,7 @@ scan_section(void) sixteen_bits a; /* token for left-hand side of definition */ section_count++; @+ no_where=true; if (*(loc-1)=='*' && show_progress) { /* starred section */ - printf("*%d",(int)section_count); update_terminal; + printf("*%d",(int)section_count); update_terminal(); } next_control=ignore; while (true) { @@ -1533,7 +1517,7 @@ skip_limbo(void) sscanf(loc-3,"%x",&i); while(xisspace(*loc)&&loc<limit) loc++; beg=loc; - while(loc<limit&&(xisalpha(*loc)||xisdigit(*loc)||*loc=='_')) loc++; + while(loc<limit&&(xisalpha(*loc)||xisdigit(*loc)||isxalpha(*loc))) loc++; if (loc-beg>=translit_length) err_print("! Replacement string in @@l too long"); @.Replacement string in @@l...@> @@ -1550,7 +1534,7 @@ but not an |int|, we use \.{\%td} to print these quantities. void print_stats(void) { puts("\nMemory usage statistics:"); - printf("%td names (out of %ld)\n", + printf("%td names (out of %ld)\n",@^system dependencies@> (ptrdiff_t)(name_ptr-name_dir),(long)max_names); printf("%td replacement texts (out of %ld)\n", (ptrdiff_t)(text_ptr-text_info),(long)max_texts); diff --git a/web/c_cpp/cweb/cweav-bs.ch b/web/c_cpp/cweb/cweav-bs.ch index 5a53a8ad0a..1d541d536b 100644 --- a/web/c_cpp/cweb/cweav-bs.ch +++ b/web/c_cpp/cweb/cweav-bs.ch @@ -20,17 +20,17 @@ 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.8)" +@d banner "This is CWEAVE (Version 4.10)" @y The ``banner line'' defined here should be changed whenever \.{CWEAVE} is modified. -@d banner "This is CWEAVE (Version 4.8pc/big)" +@d banner "This is CWEAVE (Version 4.10pc/big)" @z -@x Section 10. - for section names */ +@x Section 11. +@d ilk dummy.Ilk /* used by \.{CWEAVE} only */ @<Common code...@>= typedef struct name_info { @@ -39,7 +39,7 @@ typedef struct name_info { union { struct name_info *Rlink; /* right link in binary search tree for section names */ - char Ilk; /* used by identifiers in \.{CWEAVE} only */ + eight_bits Ilk; /* used by identifiers in \.{CWEAVE} only */ } dummy; void *equiv_or_xref; /* info corresponding to names */ } name_info; /* contains information about an identifier or section name */ @@ -55,7 +55,7 @@ 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 - for section names */ +@d ilk dummy.Ilk /* used by \.{CWEAVE} only */ @f huge extern @@ -66,7 +66,7 @@ typedef struct name_info { union { struct name_info *Rlink; /* right link in binary search tree for section names */ - char Ilk; /* used by identifiers in \.{CWEAVE} only */ + eight_bits Ilk; /* used by identifiers in \.{CWEAVE} only */ } dummy; union { char *equiv_member; @@ -146,6 +146,7 @@ static text_pointer tok_start_end; /* end of |tok_start| */ static text_pointer text_ptr; /* first unused position in |tok_start| */ @z + @x Section 31. (goes with the previous change) tok_ptr=max_tok_ptr=tok_mem+1;@/ tok_start[0]=tok_start[1]=tok_mem+1;@/ @@ -187,39 +188,35 @@ max_tok_ptr=tok_mem+1; max_text_ptr=tok_start+1; @x Section 97. - char *k, *k_end=(p+1)->byte_start; /* pointers into |byte_mem| */ - out('{'); - for (k=p->byte_start; k<k_end; k++) { + char *k; /* pointer into |byte_mem| */ @y - char huge* k, huge* k_end=(p+1)->byte_start; /* pointers into |byte_mem| */ - out('{'); - for (k=p->byte_start; k<k_end; k++) { + char huge* *k; /* pointer into |byte_mem| */ @z -@x Section 218. +@x Section 217. char *p; /* index into |byte_mem| */ @y char huge *p; /* index into |byte_mem| */ @z -@x Section 253. +@x Section 252. if (cur_name->xref!=(void *)xmem) { @y if (cur_name->xref!=(void huge*)xmem) { @z -@x Section 255. +@x Section 254. static char *cur_byte; /* index into |byte_mem| */ @y static char huge* cur_byte; /* index into |byte_mem| */ @z -@x Section 264. -switch (cur_name->ilk) {@+char *j;@+@t}\6{\4@> +@x Section 263. +switch (cur_name->ilk) {@+char *p; /* index into |byte_mem| */@+@t}\6{\4@> @y -switch (cur_name->ilk) {@+char huge* j;@+@t}\6{\4@> +switch (cur_name->ilk) {@+char huge* p; /* index into |byte_mem| */@+@t}\6{\4@> @z diff --git a/web/c_cpp/cweb/cweav-pc.ch b/web/c_cpp/cweb/cweav-pc.ch index eb2e394265..76173410af 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.8)" +@d banner "This is CWEAVE (Version 4.10)" @y -@d banner "This is CWEAVE (Version 4.8pc)" +@d banner "This is CWEAVE (Version 4.10pc)" @z @x section 17 @@ -21,8 +21,9 @@ change files that have -bs in their name instead of -pc.) @y @d max_bytes (unsigned)60000 /* the number of bytes in identifiers, @z -@x -@d max_refs 30000 /* number of cross-references; must be less than 65536 */ + +@x section 23 +@ @d max_refs 30000 /* number of cross-references; must be less than 65536 */ @y -@d max_refs 10000 /* number of cross-references; must be less than 65536 */ +@ @d max_refs 10000 /* number of cross-references; must be less than 65536 */ @z diff --git a/web/c_cpp/cweb/cweav-ql.ch b/web/c_cpp/cweb/cweav-ql.ch index 94e1f54304..8f40a9dca6 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.8)} +\def\title{CWEAVE (Version 4.10)} @y -\def\title{CWEAVE (QL Version 4.8)} +\def\title{CWEAVE (QL Version 4.10)} @z @x section 1 -@d banner "This is CWEAVE (Version 4.8)" +@d banner "This is CWEAVE (Version 4.10)" @y -@d banner "This is CWEAVE (QL Version 4.8)" +@d banner "This is CWEAVE (QL Version 4.10)" @z @x diff --git a/web/c_cpp/cweb/cweav-vms.ch b/web/c_cpp/cweb/cweav-vms.ch index 5debd4bd92..d2cef52379 100644 --- a/web/c_cpp/cweb/cweav-vms.ch +++ b/web/c_cpp/cweb/cweav-vms.ch @@ -13,12 +13,12 @@ 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.8)" +@d banner "This is CWEAVE (Version 4.10)" @y -@d banner "This is CWEAVE (VAX/VMS Version 4.8)" +@d banner "This is CWEAVE (VAX/VMS Version 4.10)" @z -@x section 4 (01-FEB-1992 ST) +@x section 5 (01-FEB-1992 ST) #include <ctype.h> /* definition of |@!isalpha|, |@!isdigit| and so on */ #include <stdbool.h> /* definition of |@!bool|, |@!true| and |@!false| */ #include <stddef.h> /* definition of |@!ptrdiff_t| */ diff --git a/web/c_cpp/cweb/cweav-w32.ch b/web/c_cpp/cweb/cweav-w32.ch index f40d6e3195..94f4c39aa6 100644 --- a/web/c_cpp/cweb/cweav-w32.ch +++ b/web/c_cpp/cweb/cweav-w32.ch @@ -2,12 +2,12 @@ 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.8)" +@d banner "This is CWEAVE (Version 4.10)" @y -@d banner "This is CWEAVE (Version 4.8win32)" +@d banner "This is CWEAVE (Version 4.10win32)" @z -@x +@x section 32 boolean names_match( name_pointer p, /* points to the proposed match */ const char *first, /* position of first character of string */ @@ -20,15 +20,3 @@ const char *first, /* position of first character of string */ size_t l, /* length of identifier */ eight_bits t) /* desired |ilk| */ @z - -@x -void -init_p( -name_pointer p, -eight_bits t) -@y -void __cdecl -init_p( -name_pointer p, -eight_bits t) -@z diff --git a/web/c_cpp/cweb/cweave.w b/web/c_cpp/cweb/cweave.w index 7de3b4d1d9..70654828c1 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.8 --- June 2022 +% Version 4.10 --- August 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.8)} +\def\title{CWEAVE (Version 4.10)} \def\topofcontents{\null\vfill \centerline{\titlefont The {\ttitlefont CWEAVE} processor} \vskip 15pt - \centerline{(Version 4.8)} + \centerline{(Version 4.10)} \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.8)" +@d banner "This is CWEAVE (Version 4.10)" @c @<Include files@>@/ @@ -100,7 +100,7 @@ char **av) /* argument values */ phase_one(); /* read all the user's text and store the cross-references */ phase_two(); /* read all the text again and translate it to \TEX/ form */ phase_three(); /* output the cross-reference index */ - if (tracing==fully && !show_progress) new_line; + if (tracing==fully && !show_progress) new_line(); return wrap_up(); /* and exit gracefully */ } @@ -111,13 +111,11 @@ possible changes from this \.{COMMON} interface consistently. @i common.h -@ The following parameters are sufficient to handle \TEX/ (converted to -\.{CWEB}), so they should be sufficient for most applications of \.{CWEAVE}. +@ \.{CWEAVE} will use the |INT_MAX| limit in section +|@<Output the code for the beginning...@>| below. -@d line_length 80 /* lines of \TEX/ output have at most this many characters; - should be less than 256 */ -@d max_refs 30000 /* number of cross-references; must be less than 65536 */ -@d max_scraps 5000 /* number of tokens in \CEE/ texts being parsed */ +@<Incl...@>= +#include <limits.h> @* Data structures exclusive to {\tt CWEAVE}. As explained in \.{common.w}, the field of a |name_info| structure @@ -147,7 +145,6 @@ identifiers are \CEE/ or \CPLUSPLUS/ reserved words whose |ilk| explains how they are to be treated when \CEE/ code is being formatted. -@d ilk dummy.Ilk @d normal 0 /* ordinary identifiers have |normal| ilk */ @d roman 1 /* normal index entries have |roman| ilk */ @d wildcard 2 /* user-formatted index entries have |wildcard| ilk */ @@ -217,7 +214,9 @@ typedef struct xref_info { } xref_info; typedef xref_info *xref_pointer; -@ @<Private...@>= +@ @d max_refs 30000 /* number of cross-references; must be less than 65536 */ + +@<Private...@>= static xref_info xmem[max_refs]; /* contains cross-reference information */ static xref_pointer xmem_end = xmem+max_refs-1; static xref_pointer xref_ptr; /* the largest occupied position in |xmem| */ @@ -242,7 +241,7 @@ to one-letter identifiers or \CEE/'s reserved words. If the user has sent the |no_xref| flag (the \.{-x} option of the command line), it is unnecessary to keep track of cross-references for identifiers. If one were careful, one could probably make more changes around section -115 to avoid a lot of identifier looking up. +|@<Match a prod...@>| to avoid a lot of identifier looking up. @d append_xref(c) if (xref_ptr==xmem_end) overflow("cross-reference"); else (++xref_ptr)->num=c @@ -355,7 +354,7 @@ tok_ptr=max_tok_ptr=tok_mem+1;@/ tok_start[0]=tok_start[1]=tok_mem+1;@/ text_ptr=max_text_ptr=tok_start+1; -@ Here are the three procedures needed to complete |id_lookup|: +@ Here are the two procedures needed to complete |id_lookup|: @c boolean names_match( name_pointer p, /* points to the proposed match */ @@ -369,14 +368,6 @@ eight_bits t) /* desired |ilk| */ } void -init_p( -name_pointer p, -eight_bits t) -{ - p->ilk=t; init_node(p); -} - -void init_node( name_pointer p) { @@ -923,7 +914,7 @@ convention, but do not allow the string to be longer than |longest_name|. fputs("\n! String too long: ",stdout); @.String too long@> term_write(section_text+1,25); - printf("..."); mark_error; + printf("..."); mark_error(); } id_loc++; return string; @@ -993,7 +984,7 @@ if (k>=section_text_end) { fputs("\n! Section name too long: ",stdout); @.Section name too long@> term_write(section_text+1,25); - printf("..."); mark_harmless; + printf("..."); mark_harmless(); } if (*k==' ' && k>section_text) k--; @@ -1087,7 +1078,7 @@ phase_one(void) { /* it will become |true| if any line changes */ if (*(loc-1)=='*' && show_progress) { printf("*%d",(int)section_count); - update_terminal; /* print a progress report */ + update_terminal(); /* print a progress report */ } @<Store cross-references in the \TEX/ part of a section@>@; @<Store cross-references in the definition part of a section@>@; @@ -1312,13 +1303,13 @@ name_pointer p) /* print anomalies in subtree |p| */ 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); - print_section_name(p); putchar('>'); mark_harmless; + 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); - print_section_name(p); putchar('>'); mark_harmless; + print_section_name(p); putchar('>'); mark_harmless(); @.Never used: <section name>@> } section_check(p->rlink); @@ -1335,6 +1326,9 @@ characters long, so we place it into an output buffer. During the output process, |out_line| will hold the current line number of the line about to be output. +@d line_length 80 /* lines of \TEX/ output have at most this many characters; + should be less than 256 */ + @<Private...@>= static char out_buf[line_length+1]; /* assembled characters */ static char *out_buf_end = out_buf+line_length; /* end of |out_buf| */ @@ -1353,9 +1347,8 @@ carried over to the next line (so that \TEX/ will ignore the completion of commented-out text). @d c_line_write(c) fflush(active_file),fwrite(out_buf+1,sizeof(char),c,active_file) -@d tex_putc(c) putc(c,active_file) -@d tex_new_line putc('\n',active_file) @d tex_printf(c) fprintf(active_file,"%s",c) +@d tex_putc(c) fputc(c,active_file) @d tex_puts(c) fputs(c,active_file) @<Predecl...@>= @@ -1373,7 +1366,7 @@ boolean per_cent,boolean carryover) while (j>out_buf && *j==' ') j--; c_line_write(j-out_buf); if (per_cent) tex_putc('%'); - tex_new_line; out_line++; + tex_putc('\n'); out_line++; if (carryover) while (j>out_buf) if (*j--=='%' && (j==out_buf || *j!='\\')) { @@ -1443,8 +1436,8 @@ to overflow. To make this routine a little faster, we initialize position out_buf[0]='\\'; @ A long line is broken at a blank space or just before a backslash that isn't -preceded by another backslash. In the latter case, a |'%'| is output at -the break. +preceded by another backslash or a \TeX\ comment marker. In the latter case, a +|'%'| is output at the break. @c static void @@ -1456,7 +1449,7 @@ break_out(void) /* finds a way to break the output line */ if (*k==' ') { flush_buffer(k,false,true); return; } - if (*(k--)=='\\' && *k!='\\') { /* we've decreased |k| */ + if (*(k--)=='\\' && *k!='\\' && *k!='%') { /* we've decreased |k| */ flush_buffer(k,true,true); return; } } @@ -1472,7 +1465,7 @@ line by putting a |'%'| just before the last character. printf("\n! Line had to be broken (output l. %d):\n",out_line); @.Line had to be broken@> term_write(out_buf+1, out_ptr-out_buf-1); - new_line; mark_harmless; + new_line(); mark_harmless(); flush_buffer(out_ptr-1,true,true); return; } @@ -1491,7 +1484,7 @@ out_section( sixteen_bits n) { char s[6]; - sprintf(s,"%d",(int)n); out_str(s); + snprintf(s,6,"%d",(int)n); out_str(s); if (changed_section[n]) out_str("\\*"); @.\\*@> } @@ -1505,9 +1498,9 @@ out_name( name_pointer p, boolean quote_xalpha) { - char *k, *k_end=(p+1)->byte_start; /* pointers into |byte_mem| */ + char *k; /* pointer into |byte_mem| */ out('{'); - for (k=p->byte_start; k<k_end; k++) { + for (k=p->byte_start; k<(p+1)->byte_start; k++) { if (isxalpha(*k) && quote_xalpha) out('\\'); @.\\\$@> @.\\\_@> @@ -2124,7 +2117,8 @@ identifier&|exp|: \.{\\\\\{}identifier with underlines and \.{\\X}$n$\.:translated section name\.{\\X}&maybe\cr \.{@@(@q)@>}\thinspace section name\thinspace\.{@@>}&|section_scrap|: \.{\\X}$n$\.{:\\.\{}section name with special characters - quoted\.{\ \}\\X}&maybe\cr + quoted\.{\\,\}\\X}\footnote*{The \.{\\,} (thin space) is omitted + in ``|inner| \TeX\ mode.''}&maybe\cr \.{/*}\thinspace comment\thinspace\.{*/}&|insert|: |cancel| \.{\\C\{}translated comment\.\} |force|&no\cr \.{//}\thinspace comment&|insert|: |cancel| @@ -2169,6 +2163,8 @@ blanks that will not match in any productions. Parsing stops when Since the |scrap| structure will later be used for other purposes, we declare its second element as a union. +@d trans trans_plus.Trans /* translation texts of scraps */ + @<Type...@>= typedef struct { eight_bits cat; @@ -2180,7 +2176,7 @@ typedef struct { } scrap; typedef scrap *scrap_pointer; -@ @d trans trans_plus.Trans /* translation texts of scraps */ +@ @d max_scraps 5000 /* number of tokens in \CEE/ texts being parsed */ @<Private...@>= static scrap scrap_info[max_scraps]; /* memory array for scraps */ @@ -2219,9 +2215,18 @@ translated without line-break controls. @d tok_flag (4*id_flag) /* signifies a token list */ @d inner_tok_flag (5*id_flag) /* signifies a token list in `\pb' */ +@<Predecl...@>= +#ifdef DEBUG +static void print_text(text_pointer p); +#endif + +@ This function prints a token list for debugging; +it is not used in |main| at this time. + @c +#ifdef DEBUG static void -print_text( /* prints a token list for debugging; not used in |main| */ +print_text( text_pointer p) { token_pointer j; /* index into |tok_mem| */ @@ -2244,10 +2249,9 @@ text_pointer p) default: @<Print token |r| in symbolic form@>@; } } - update_terminal; + update_terminal(); } - -@ @<Predecl...@>=@+static void print_text(text_pointer p); +#endif /* |DEBUG| */ @ @<Print token |r|...@>= switch (r) { @@ -2360,9 +2364,9 @@ static int cur_mathness, init_mathness; understanding the format by comparing the code with the symbolic productions as they were listed earlier. -@d begin_math if (cur_mathness==maybe_math) init_mathness=yes_math; +@d begin_math() if (cur_mathness==maybe_math) init_mathness=yes_math; else if (cur_mathness==no_math) app_str("${}") -@d end_math if (cur_mathness==maybe_math) init_mathness=no_math; +@d end_math() if (cur_mathness==maybe_math) init_mathness=no_math; else if (cur_mathness==yes_math) app_str("{}$") @c @@ -2379,10 +2383,10 @@ token a) { if (a==' ' || (a>=big_cancel && a<=big_force) || a==dindent) /* non-math token */ { - end_math; + end_math(); cur_mathness=no_math; } else { - begin_math; + begin_math(); cur_mathness=yes_math; } app(a); @@ -2394,11 +2398,11 @@ scrap_pointer a) { switch (a->mathness % 4) { /* left boundary */ case (no_math): - end_math; + end_math(); cur_mathness=a->mathness / 4; /* right boundary */ break; case (yes_math): - begin_math; + begin_math(); cur_mathness=a->mathness / 4; /* right boundary */ break; case (maybe_math): /* no changes */ break; @@ -3184,7 +3188,7 @@ current token list is empty and ready to be appended~to. Note that |freeze_text| does not check to see that |text_ptr| hasn't gotten too large, since it is assumed that this test was done beforehand. -@d freeze_text *(++text_ptr)=tok_ptr +@d freeze_text() *(++text_ptr)=tok_ptr @<Predecl...@>= static void reduce(scrap_pointer,short,eight_bits,short,short);@/ @@ -3205,7 +3209,7 @@ short d, short n) if (k>0) { j->trans=text_ptr; j->mathness=4*cur_mathness+init_mathness; - freeze_text; + freeze_text(); } if (k>1) { for (i=j+k, i1=j+1; i<=lo_ptr; i++, i1++) { @@ -3348,13 +3352,13 @@ for (j=scrap_base; j<=lo_ptr; j++) { if (j->mathness / 4 == yes_math) app('$'); if (tok_ptr+6>tok_mem_end) overflow("token"); } -freeze_text; return text_ptr-1; +freeze_text(); return text_ptr-1; @ @<If semi-tracing, show the irreducible scraps@>= if (lo_ptr>scrap_base && tracing==partly) { printf("\nIrreducible scrap sequence in section %d:",(int)section_count); @.Irreducible scrap sequence...@> - mark_harmless; + mark_harmless(); for (j=scrap_base; j<=lo_ptr; j++) { putchar(' '); print_cat(j->cat); } @@ -3362,7 +3366,7 @@ if (lo_ptr>scrap_base && tracing==partly) { @ @<If tracing,...@>= if (tracing==fully) { - printf("\nTracing after l. %d:\n",cur_line); mark_harmless; + printf("\nTracing after l. %d:\n",cur_line); mark_harmless(); @.Tracing after...@> if (loc>buffer+50) { printf("..."); @@ -3407,7 +3411,7 @@ been appended: @d app_scrap(c,b) { (++scrap_ptr)->cat=(c); scrap_ptr->trans=text_ptr; scrap_ptr->mathness=5*(b); /* no no, yes yes, or maybe maybe */ - freeze_text; + freeze_text(); } @ @<Append the scr...@>= @@ -3705,7 +3709,7 @@ outer_parse(void) /* makes scraps from \CEE/ tokens and comments */ @.\\SHC@> bal=copy_comment(is_long_comment,1); next_control=ignore; while (bal>0) { - p=text_ptr; freeze_text; q=C_translate(); + p=text_ptr; freeze_text(); q=C_translate(); /* at this point we have |tok_ptr+6<=max_toks| */ app(tok_flag+(int)(p-tok_start)); if (make_pb) app_str("\\PB{"); @@ -3753,8 +3757,8 @@ on a particular level will be read; \yskip\hang |mode_field| is the current mode, either |inner| or |outer|. \yskip\noindent The current values of these quantities are referred to -quite frequently, so they are stored in a separate place instead of in the -|stack| array. We call the current values |cur_end|, |cur_tok|, and +quite frequently, so they are stored in an extra slot at the very end of +the |stack| array. We call the current values |cur_end|, |cur_tok|, and |cur_mode|. The global variable |stack_ptr| tells how many levels of output are @@ -3762,26 +3766,28 @@ currently in progress. The end of output occurs when an |end_translation| token is found, so the stack is never empty except when we first begin the output process. -@d inner false /* value of |mode| for \CEE/ texts within \TEX/ texts */ -@d outer true /* value of |mode| for \CEE/ texts in sections */ - -@<Typed...@>= typedef int mode; +@s mode int +@<Typed...@>= +typedef enum { + @!inner, /* value of |mode| for \CEE/ texts within \TEX/ texts */ + @!outer /* value of |mode| for \CEE/ texts in sections */ +} mode; typedef struct { token_pointer end_field; /* ending location of token list */ token_pointer tok_field; /* present location within token list */ - boolean mode_field; /* interpretation of control tokens */ + mode mode_field; /* interpretation of control tokens */ } output_state; typedef output_state *stack_pointer; @ @d stack_size 2000 /* number of simultaneous output levels */ +@d cur_state stack[stack_size] /* |cur_end|, |cur_tok|, |cur_mode| */ @d cur_end cur_state.end_field /* current ending location in |tok_mem| */ @d cur_tok cur_state.tok_field /* location of next output token in |tok_mem| */ @d cur_mode cur_state.mode_field /* current mode of interpretation */ -@d init_stack stack_ptr=stack;cur_mode=outer /* initialize the stack */ +@d init_stack() stack_ptr=stack;cur_mode=outer /* initialize the stack */ @<Private...@>= -static output_state cur_state; /* |cur_end|, |cur_tok|, |cur_mode| */ -static output_state stack[stack_size]; /* info for non-current levels */ +static output_state stack[stack_size+1]; /* info for non-current levels */ static stack_pointer stack_end=stack+stack_size-1; /* end of |stack| */ static stack_pointer stack_ptr; /* first unused location in the output state stack */ static stack_pointer max_stack_ptr; /* largest value assumed by |stack_ptr| */ @@ -3789,25 +3795,21 @@ static stack_pointer max_stack_ptr; /* largest value assumed by |stack_ptr| */ @ @<Set init...@>= max_stack_ptr=stack; +@ @<Predecl...@>= +static void push_level(text_pointer); + @ To insert token-list |p| into the output, the |push_level| subroutine is called; it saves the old level of output and gets a new one going. The value of |cur_mode| is not changed. -@<Predecl...@>= -static void push_level(text_pointer);@/ -static void pop_level(void); - -@ @c +@c static void push_level( /* suspends the current level */ text_pointer p) { if (stack_ptr==stack_end) overflow("stack"); - if (stack_ptr>stack) { /* save current state */ - stack_ptr->end_field=cur_end; - stack_ptr->tok_field=cur_tok; - stack_ptr->mode_field=cur_mode; - } + if (stack_ptr>stack) /* save current state */ + *stack_ptr = cur_state;@^system dependencies@> stack_ptr++; if (stack_ptr>max_stack_ptr) max_stack_ptr=stack_ptr; cur_tok=*p; cur_end=*(p+1); @@ -3815,15 +3817,9 @@ text_pointer p) @ Conversely, the |pop_level| routine restores the conditions that were in force when the current level was begun. This subroutine will never be -called when |stack_ptr==1|. +called when |stack_ptr==1|. It is so simple, we declare it as a macro: -@c -static void -pop_level(void) -{ - cur_end=(--stack_ptr)->end_field; - cur_tok=stack_ptr->tok_field; cur_mode=stack_ptr->mode_field; -} +@d pop_level() cur_state = *(--stack_ptr)@^system dependencies@> @ The |get_output| function returns the next byte of output that is not a reference to a token list. It returns the values |identifier| or |res_word| @@ -3891,10 +3887,10 @@ output_C(void) /* outputs the current token list */ text_pointer p; /* translation of the \CEE/ text */ next_control=ignore; p=C_translate(); app(inner_tok_flag+(int)(p-tok_start)); - if (make_pb) { - out_str("\\PB{"); make_output(); out('}'); + if (make_pb) out_str("\\PB{"); @.\\PB@> - }@+else make_output(); /* output the list */ + make_output(); /* output the list */ + if (make_pb) out('}'); if (text_ptr>max_text_ptr) max_text_ptr=text_ptr; if (tok_ptr>max_tok_ptr) max_tok_ptr=tok_ptr; text_ptr=save_text_ptr; tok_ptr=save_tok_ptr; /* forget the tokens */ @@ -3920,7 +3916,7 @@ make_output(void) /* outputs the equivalents of tokens */ boolean save_mode; /* value of |cur_mode| before a sequence of breaks */ boolean dindent_pending=false; /* should a |dindent| be output? */ app(end_translation); /* append a sentinel */ - freeze_text; push_level(text_ptr-1); + freeze_text(); push_level(text_ptr-1); while (true) { a=get_output(); reswitch: switch(a) { @@ -4093,7 +4089,7 @@ out(':'); if (an_output) out_str("\\.{"@q}@>); @.\\.@> @<Output the text of the section name@>@; -if (an_output) out_str(@q{@>" }"); +if (an_output) cur_mode==inner?out_str(@q{@>"}"):out_str(@q{@>"\\,}"); out_str("\\X"); @ @<Output the text...@>= @@ -4136,7 +4132,7 @@ while (k<k_limit) { if (*k++!='@@') { fputs("\n! Illegal control code in section name: <",stdout); @.Illegal control code...@> - print_section_name(cur_section_name); printf("> "); mark_error; + print_section_name(cur_section_name); printf("> "); mark_error(); } @ The \CEE/ text enclosed in \pb\ should not contain `\.{\v}' characters, @@ -4151,7 +4147,7 @@ while (true) { if (k>=k_limit) { fputs("\n! C text in section name didn't end: <",stdout); @.C text...didn't end@> - print_section_name(cur_section_name); printf("> "); mark_error; break; + print_section_name(cur_section_name); printf("> "); mark_error(); break; } b=*(k++); if (b=='@@' || (b=='\\' && delim!=0)) @@ -4202,8 +4198,8 @@ within a single section. The variables |out_line| or |out_ptr| will change if a section is non-null, so the following macros `|save_position|' and `|emit_space_if_needed|' are able to handle the situation: -@d save_position save_line=out_line; save_place=out_ptr -@d emit_space_if_needed if (save_line!=out_line || save_place!=out_ptr) +@d save_position() save_line=out_line; save_place=out_ptr +@d emit_space_if_needed() if (save_line!=out_line || save_place!=out_ptr) out_str("\\Y"); space_checked=true; @.\\Y@> @@ -4220,7 +4216,7 @@ static boolean group_found=false; /* has a starred section occurred? */ @ @<Translate the current section@>= { section_count++; @<Output the code for the beginning of a new section@>@; - save_position; + save_position(); @<Translate the \TEX/ part of the current section@>@; @<Translate the definition part of the current section@>@; @<Translate the \CEE/ part of the current section@>@; @@ -4245,16 +4241,16 @@ else { loc++; } else { - for (sec_depth=0; xisdigit(*loc);loc++) - sec_depth = sec_depth*10 + (*loc) -'0'; + for (sec_depth=0; xisdigit(*loc);loc++)@^system dependencies@> + if (sec_depth < INT_MAX / 10) sec_depth = sec_depth*10 + (*loc) -'0'; } while (*loc == ' ') loc++; /* remove spaces before group title */ group_found=true; out_str("\\N"); @.\\N@> - {@+ char s[32];@+sprintf(s,"{%d}",sec_depth+1);@+out_str(s);@+} + {@+ 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 */ + printf("*%d",(int)section_count); update_terminal(); /* print a progress report */ } out('{'); out_section(section_count); out('}'); @@ -4263,7 +4259,7 @@ index entries are not copied and \CEE/ text within \pb\ is translated. @<Translate the \T...@>= do switch (next_control=copy_TeX()) { - case '|': init_stack; output_C(); break; + case '|': init_stack(); output_C(); break; case '@@': out('@@'); break; case TeX_string: case noop: case xref_roman: case xref_wildcard: case xref_typewriter: @@ -4286,7 +4282,7 @@ the token memory is in its initial empty state. @<Translate the d...@>= space_checked=false; while (next_control<=definition) { /* |format_code| or |definition| */ - init_stack; + init_stack(); if (next_control==definition) @<Start a macro definition@>@; else @<Start a format definition@>@; outer_parse(); finish_C(format_visible); format_visible=true; @@ -4343,16 +4339,15 @@ it starts after we scan the matching `\.)'. @<Start a macro...@>= { if (save_line!=out_line || save_place!=out_ptr || space_checked) app(backup); - if(!space_checked){emit_space_if_needed;save_position;} + if(!space_checked){emit_space_if_needed();save_position();} app_str("\\D"); /* this will produce `\#\&{define }' */ @.\\D@> if ((next_control=get_next())!=identifier) err_print("! Improper macro definition"); @.Improper macro definition@> else { - app_cur_id(false); + app('$'); app_cur_id(false); if (*loc=='(') { - app('$'); reswitch: switch (next_control=get_next()) { case '(': case ',': app(next_control); goto reswitch; case identifier: app_cur_id(false); goto reswitch; @@ -4364,10 +4359,9 @@ it starts after we scan the matching `\.)'. } @=/* otherwise fall through */@>@; default: err_print("! Improper macro definition"); break; } - app('$'); } else next_control=get_next(); - app(break_space); + app_str("$ "); app(break_space); app_scrap(dead,no_math); /* scrap won't take part in the parsing */ } } @@ -4375,7 +4369,7 @@ it starts after we scan the matching `\.)'. @ @<Start a format...@>= { doing_format=true; if(*(loc-1)=='s' || *(loc-1)=='S') format_visible=false; - if(!space_checked){emit_space_if_needed;save_position;} + if(!space_checked){emit_space_if_needed();save_position();} app_str("\\F"); /* this will produce `\&{format }' */ @.\\F@> next_control=get_next(); @@ -4403,7 +4397,7 @@ static name_pointer this_section; /* the current section name, or zero */ @ @<Translate the \CEE/...@>= this_section=name_dir; if (next_control<=section_name) { - emit_space_if_needed; init_stack; + emit_space_if_needed(); init_stack(); if (next_control==begin_C) next_control=get_next(); else { this_section=cur_section; @@ -4531,46 +4525,50 @@ contents. @c static void phase_three(void) { -if (no_xref) { - finish_line(); +phase=3; +finish_line(); /* the bulk of |tex_file| has been written */ +if (no_xref) out_str("\\end"); @.\\end@> - finish_line(); -} else { - phase=3; if (show_progress) fputs("\nWriting the index...",stdout); + if (show_progress) fputs("\nWriting the index...",stdout); @.Writing the index...@> - finish_line(); - if ((idx_file=fopen(idx_file_name,"wb"))==NULL) - fatal("! Cannot open index file ",idx_file_name); -@.Cannot open index file@> if (change_exists) { - @<Tell about changed sections@>@; finish_line(); finish_line(); + @<Tell about changed sections@>@; + finish_line(); flush_buffer(out_buf,false,false); + /* insert a blank line, it looks nice */ } out_str("\\inx"); finish_line(); @.\\inx@> +@# + if ((idx_file=fopen(idx_file_name,"wb"))==NULL) + fatal("! Cannot open index file ",idx_file_name); +@.Cannot open index file@> active_file=idx_file; /* change active file to the index file */ @<Do the first pass of sorting@>@; @<Sort and output the index@>@; finish_line(); fclose(active_file); /* finished with |idx_file| */ +@# active_file=tex_file; /* switch back to |tex_file| for a tic */ out_str("\\fin"); finish_line(); @.\\fin@> +@# if ((scn_file=fopen(scn_file_name,"wb"))==NULL) fatal("! Cannot open section file ",scn_file_name); @.Cannot open section file@> active_file=scn_file; /* change active file to section listing file */ @<Output all the section names@>@; finish_line(); fclose(active_file); /* finished with |scn_file| */ - active_file=tex_file; +@# + active_file=tex_file; /* switch back to |tex_file| for the last time */ if (group_found) out_str("\\con");@+else out_str("\\end"); @.\\con@> @.\\end@> - finish_line(); - fclose(active_file); } +finish_line(); +fclose(active_file); if (show_happiness) { - if (show_progress) new_line; + if (show_progress) new_line(); fputs("Done.",stdout); } check_complete(); /* was all of the change file used? */ @@ -4671,7 +4669,7 @@ needs to be changed if ASCII code is not being used. @^high-bit character handling@> We initialize |collate| by copying a few characters at a time, because -some \CEE/ compilers choke on long strings. +some \CEE/ compilers choke on long strings.@^system dependencies@> @<Set init...@>= collate[0]=0; @@ -4778,14 +4776,15 @@ while (sort_ptr>scrap_info) { } @ @<Output the name...@>= -switch (cur_name->ilk) {@+char *j;@+@t}\6{\4@> +switch (cur_name->ilk) {@+char *p; /* index into |byte_mem| */@+@t}\6{\4@> case normal: case func_template: if (is_tiny(cur_name)) out_str("\\|"); - else { - for (j=cur_name->byte_start;j<(cur_name+1)->byte_start;j++) - if (xislower(*j)) goto lowcase; - out_str("\\."); break; -lowcase: out_str("\\\\"); + else {@+boolean all_caps=true;@+@t}\6{@> + for (p=cur_name->byte_start;p<(cur_name+1)->byte_start;p++) + if (xislower(*p)) { /* not entirely uppercase */ + all_caps=false; break; + } + out_str(all_caps ? "\\." : "\\\\"); } break; @.\\|@> @@ -4793,14 +4792,13 @@ lowcase: out_str("\\\\"); @.\\\\@> case wildcard: out_str("\\9");@+ goto not_an_identifier; @.\\9@> - case typewriter: out_str("\\."); - @=/* fall through */@>@; + case typewriter: out_str("\\.");@+ goto not_an_identifier; @.\\.@> case roman: not_an_identifier: out_name(cur_name,false); goto name_done; case custom: out_str("$\\"); - for (j=cur_name->byte_start;j<(cur_name+1)->byte_start;j++) - out(*j=='_'? 'x': *j=='$'? 'X': *j); + for (p=cur_name->byte_start;p<(cur_name+1)->byte_start;p++) + out(*p=='_'? 'x': *p=='$'? 'X': *p); out('$'); goto name_done; default: out_str("\\&"); @@ -4850,7 +4848,7 @@ name_pointer p) if (p) { section_print(p->llink); out_str("\\I"); @.\\I@> - tok_ptr=tok_mem+1; text_ptr=tok_start+1; scrap_ptr=scrap_info; init_stack; + tok_ptr=tok_mem+1; text_ptr=tok_start+1; scrap_ptr=scrap_info; init_stack(); app(section_flag+(int)(p-name_dir)); make_output(); footnote(cite_flag); footnote(0); /* |cur_xref| was set by |make_output| */ @@ -4871,7 +4869,7 @@ void print_stats(void) { puts("\nMemory usage statistics:"); @.Memory usage statistics:@> - printf("%td names (out of %ld)\n", + printf("%td names (out of %ld)\n",@^system dependencies@> (ptrdiff_t)(name_ptr-name_dir),(long)max_names); printf("%td cross-references (out of %ld)\n", (ptrdiff_t)(xref_ptr-xmem),(long)max_refs); diff --git a/web/c_cpp/cweb/cwebmac.tex b/web/c_cpp/cweb/cwebmac.tex index e2d2ecb3a2..382400a3f7 100644 --- a/web/c_cpp/cweb/cwebmac.tex +++ b/web/c_cpp/cweb/cwebmac.tex @@ -1,24 +1,19 @@ % standard macros for CWEB listings (in addition to plain.tex) -% Version 4.8--- June 2022 +% Version 4.10 --- August 2023 \ifx\renewenvironment\undefined\else\endinput\fi % LaTeX will use other macros -\xdef\fmtversion{\fmtversion+CWEB4.8} -\chardef\cwebversion=4 \chardef\cwebrevision=7 -\newif\ifpdf -\ifx\pdf+\pdftrue\fi +\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 -\ifx\undefined\XeTeXrevision\else\pdftrue\fi % XeTeX produces PDF output -\newif\ifpdftex -\ifx\pdfoutput\undefined \pdftexfalse \else\ifnum\pdfoutput=0 \pdftexfalse -%\else \pdftextrue \pdfoutput=1 \input pdfcolor \let\setcolor\pdfsetcolor \fi\fi -\else \pdftextrue \pdfoutput=1 % changed in 3.69 +\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\fi -\newif\ifhint -\ifx\HINTversion\undefined \hintfalse \else \hinttrue \fi -\newif\ifacro \ifpdf\acrotrue\fi \ifpdftex\acrotrue\fi +\fi +\let\ifacro=\ifpdf \newif\ifacrohint \ifacro\acrohinttrue\fi \ifhint\acrohinttrue\fi \let\:=\. % preserve a way to get the dot accent @@ -135,7 +130,7 @@ \newtoks\toksA \newtoks\toksB \newtoks\toksC \newtoks\toksD \newtoks\toksE \newtoks\toksF \newtoks\usersanitizer \newcount\countA \countA=0 \newcount\countB \countB=0 -\newcount\countC \countC=0 +\newcount\countC \countC=0 \newcount\countD \countD=0 \newif\iftokprocessed \newif\ifTnum \newif\ifinstr {\def\\{\global\let\spacechar= }\\ } @@ -145,7 +140,7 @@ \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\ht\strutbox depth\dp\strutbox + \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 @@ -294,14 +289,14 @@ \def\maketoksdone{\edef\st{\global\noexpand\toksA={\the\toksB}}\st} \fi % End of common macros -\def\pdfURL#1#2{\ifpdftex\pdfannotlink height\ht\strutbox depth\dp\strutbox - attr {/Border [0 0 0]} user { /Type /Action /Subtype /Link /A +\def\pdfURL#1#2{\ifpdf \ifpdftex\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 \ifpdf{\setbox0=\hbox{\special{pdf: bc [ \pdflinkcolor ]}{#1}% - \special{pdf: ec}}\special{pdf: ann width \thewidth\space height \theheight - \space depth \thedepth\space << /Border [0 0 0] - /Type /Action /Subtype /Link /A << /S /URI /URI (#2) >> >>}\box0\relax}% - \else #1 ({\tt#2})\fi\fi} + \else {\setbox0=\hbox{\special{pdf: bc [ \pdflinkcolor ]}{#1}% + \special{pdf: ec}}\special{pdf: ann width \thewidth height \theheight + depth \thedepth << /Border [0 0 0] /Type /Annot /Subtype /Link /A + << /S /URI /URI (#2) >> >>}\box0\relax}\fi + \else #1 ({\tt#2})\fi} {\catcode`\~=12 \gdef\TILDE/{~}} % ~ in a URL {\catcode`\_=12 \gdef\UNDER/{_}} % _ in a URL @@ -352,11 +347,11 @@ \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} - \ifpdftex\expandafter\xdef\csname curr#1\endcsname{\secno} + \ifpdf \ifpdftex\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\fi - \ifpdf\special{pdf: outline #1 << /Title (\the\toksE) /Dest - [ @thispage /FitH @ypos ] >>}\fi + \advancenumber{chunk\the\countB.\expnumber{curr\the\countB}}\fi + \else \special{pdf: outline #1 << /Title (\the\toksE) + /Dest [ @thispage /FitH @ypos ] >>}\fi \fi \ifon\startsection{\bf#3.\quad}\ignorespaces} \def\MN#1{\par % common code for \M, \N {\xdef\secstar{#1}\let\*=\empty\xdef\secno{#1}}% remove \* from section name @@ -428,13 +423,13 @@ \vfill#1}} % parameter #1 is the page itself \global\advance\pageno by1} -\gtitle={\.{CWEB} output} % this running head is reset by starred sections +\gtitle={{\tentex CWEB} output} % this running head is reset by starred sections \mark{\noexpand\nullsec0{\the\gtitle}} \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{\ifpdftex\pdfcatalog{/PageMode /UseOutlines}\else - \ifpdf{\special{pdf: docview << /PageMode /UseOutlines >>}}\fi\fi} +\def\startpdf{\ifpdf \ifpdftex\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 \def\covernote{} @@ -495,7 +490,8 @@ \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 - \ifpdftex \makebookmarks \fi % added in Version 3.68 + \ifpdf \ifpdftex \makebookmarks % added in Version 3.68 + \countsections \fi\fi % and in Version 4.9 \parfillskip 0pt plus 1fil \def\grouptitle{NAMES OF THE SECTIONS} \let\topsecno=\nullsec @@ -511,7 +507,7 @@ \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 - \pdfoutline goto name {NOS} count -\secno {\outsecname} + \pdfoutline goto name {NOS} count -\the\countD {\outsecname} \def\X##1:##2\X{\Xpdf##1:##2\X \firstsecno##1.% {\toksF={}\makeoutlinetoks##2\outlinedone\outlinedone}% \pdfoutline goto num \the\toksA \expandafter{\the\toksE}} @@ -524,6 +520,10 @@ \fi\fi \readsections} \def\makebookmarks{\let\ZZ=\writebookmarkline \readcontents\relax} +\def\countsections{\message{Number of named sections:} + {\def\I{\global\advance\countD by 1}\def\X##1\X{\relax} + \def\Q##1.{\relax}\def\Qs##1.{\relax}\def\U##1.{\relax}\def\Us##1.{\relax} + \readsections\relax}\message{\the\countD}} \def\expnumber#1{\expandafter\ifx\csname#1\endcsname\relax 0% \else \csname#1\endcsname \fi} % Petr Olsak's macros from texinfo.tex \def\advancenumber#1{\countA=\expnumber{#1}\relax \advance\countA by1 diff --git a/web/c_cpp/cweb/cwebman.pdf b/web/c_cpp/cweb/cwebman.pdf Binary files differindex bed70a685f..8cfef0ea10 100644 --- a/web/c_cpp/cweb/cwebman.pdf +++ b/web/c_cpp/cweb/cwebman.pdf diff --git a/web/c_cpp/cweb/cwebman.tex b/web/c_cpp/cweb/cwebman.tex index 87523dbced..108bd32f88 100644 --- a/web/c_cpp/cweb/cwebman.tex +++ b/web/c_cpp/cweb/cwebman.tex @@ -2,7 +2,7 @@ \def\tangref{3} % where the main explanation of CTANGLing is given \input cwebmac -\acrofalse\pdffalse\pdftexfalse\hintfalse\acrohintfalse +\pdffalse\acrohintfalse \def\page{\box255 } \normalbottom \parskip 0pt plus 1pt \def\RA{\char'31 } % right arrow @@ -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.8)} +\def\runninghead{{\tentt CWEB} USER MANUAL (VERSION 4.10)} % 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.8 --- June 2022)} +\vskip 18pt\centerline{(Version 4.10 --- August 2023)} \vskip 24pt \centerline{\authorfont Donald E. Knuth and Silvio Levy} \vfill @@ -1345,7 +1345,7 @@ strncpy(change_buffer,buffer,(size_t)(limit-buffer+1)); \def\runninghead{APPENDIX A --- TRANSLATION BY {\tentt CWEAVE}} Here is the corresponding excerpt from \.{common.tex}. -(Code for section 31 is omitted for space reasons.) +\ifhint\relax\else(Code for section 31 is omitted for space reasons.)\fi \vskip6pt \begingroup \def\tt{\eighttt} \baselineskip9pt @@ -1370,7 +1370,7 @@ change file ends }\6 \4${}\}{}$\2\par \fi -\M{28}\B\X7:Predeclaration of procedures\X${}\mathrel+\E{}$\5 +\M{28}\B\X3:Predeclaration of procedures\X${}\mathrel+\E{}$\5 \&{static} \&{void} \\{prime\_the\_change\_buffer}(\&{void});\par \fi @@ -1418,6 +1418,15 @@ ${}\{{}$\1\6 \4${}\}{}$\2\5 \&{while} ${}(\\{limit}\E\\{buffer}){}$;\par \U27.\fi +!ifhint +\M{31}\B\X31:Move \PB{\\{buffer}} and \PB{\\{limit}} to \PB{\\{change\_buffer}} +and \PB{\\{change\_limit}}\X${}\E{}$\6 +$\\{change\_limit}\K\\{change\_buffer}+(\&{ptrdiff\_t})(\\{limit}-% +\\{buffer});{}$\6 +${}\\{strncpy}(\\{change\_buffer},\39\\{buffer},\39(\&{size\_t})(\\{limit}-% +\\{buffer}+\T{1})){}$;\par +\Us27\ET32.\fi +!fi !endgroup \endgroup \vfil\eject @@ -1448,7 +1457,7 @@ change file ends }\6 \4${}\}{}$\2\par \fi -\M{28}\B\X7:Predeclaration of procedures\X${}\mathrel+\E{}$\5 +\M{28}\B\X3:Predeclaration of procedures\X${}\mathrel+\E{}$\5 \&{static} \&{void} \\{prime\_the\_change\_buffer}(\&{void});\par \fi @@ -1598,7 +1607,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.8)\}{ }\\vfill\}}\cr}$$ + \.{ { }\\vskip 15pt \\centerline\{(Version 4.10)\}{ }\\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. diff --git a/web/c_cpp/cweb/examples/wordtest.w b/web/c_cpp/cweb/examples/wordtest.w index 98de5aedc6..000166815d 100644 --- a/web/c_cpp/cweb/examples/wordtest.w +++ b/web/c_cpp/cweb/examples/wordtest.w @@ -166,7 +166,7 @@ default: print_usage: fprintf(stderr, @*Treaps. The most interesting part of this program is its sorting algorithm, which is based on the ``treap'' data structure of Aragon and Seidel [{\sl 30th IEEE Symposium on Foundations of Computer Science\/} (1989), -540--546]. +540--545]. @^Aragon, Cecilia Rodriguez@>@^Seidel, Raimund@> A treap is a binary tree whose nodes have two key fields. The primary key, which in our application is a word from the input, obeys diff --git a/web/c_cpp/cweb/prod.w b/web/c_cpp/cweb/prod.w index 1e6cb6194c..c7254cc4ee 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.8 --- June 2022 +% Version 4.10 --- August 2023 % @ Here is a table of all the productions. Each production that combines two or more consecutive scraps implicitly inserts a {\tt \$} |