diff --git a/Makefile b/Makefile index 63dbd3d..0c20d83 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ # This file is part of CWEB. # It is distributed WITHOUT ANY WARRANTY, express or implied. -# Version 4.1 --- February 2021 +# Version 4.2 --- February 2021 # Copyright (C) 1987,1990,1993,2000 Silvio Levy and Donald E. Knuth @@ -63,8 +63,10 @@ RM= /bin/rm CP= /bin/cp # uncomment the second line if you use pdftex to bypass .dvi files +# uncomment the third line if you use xetex to bypass .dvi files PDFTEX = dvipdfm #PDFTEX = pdftex +#PDFTEX = xetex ########## You shouldn't have to change anything after this point ####### @@ -105,6 +107,7 @@ ALL = common.w ctangle.w cweave.w prod.w \ case "$(PDFTEX)" in \ dvipdfm ) tex "\let\pdf+ \input $*"; dvipdfm $* ;; \ pdftex ) pdftex $* ;; \ + xetex ) xetex $* ;; \ esac all: ctangle cweave diff --git a/README.md b/README.md index a4f5e8e..7b8177e 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# cweb 4.1 +# cweb 4.2 people have been accumulating several decades of experience with [cweb](http://www-cs-faculty.stanford.edu/~uno/cweb.html), and we know that @@ -16,7 +16,7 @@ in fact, now to be found in this cweb development project. besides for further development, this ‘project’ is used as an – obviously incomplete – repository of original release versions of levy/knuth [cweb](http://www-cs-faculty.stanford.edu/~uno/cweb.html). you can either -compile these sources directly or stick the recent version “cweb-4.1” into my +compile these sources directly or stick the recent version “cweb-4.2” into my [cwebbin](https://github.com/ascherer/cwebbin), which introduces convenient extensions and prepares cweb for inclusion in the “tex live” distribution. diff --git a/comm-mac.ch b/comm-mac.ch index 8af008e..aa3a77f 100644 --- a/comm-mac.ch +++ b/comm-mac.ch @@ -4,9 +4,9 @@ No changes to CTANGLE or CWEAVE are needed. (Contributed 13 Oct 2000 by AndPio@aol.com; slightly edited by Don Knuth) @x in limbo, change the title page document to specify Mac version - \centerline{(Version 4.1)} + \centerline{(Version 4.2)} @y - \centerline{(Version 4.1 for MacOS)} + \centerline{(Version 4.2 for MacOS)} @z @x sections 23/24: Make input_ln accept \n, \r, \n\r, or \r\n as line endings diff --git a/comm-ql.ch b/comm-ql.ch index f12bd12..c03b918 100644 --- a/comm-ql.ch +++ b/comm-ql.ch @@ -10,24 +10,24 @@ ex 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.1)} +\def\title{Common code for CTANGLE and CWEAVE (Version 4.2)} \def\topofcontents{\null\vfill \centerline{\titlefont Common code for {\ttitlefont CTANGLE} and {\ttitlefont CWEAVE}} \vskip 15pt - \centerline{(Version 4.1)} + \centerline{(Version 4.2)} \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.1)} +\def\title{Common code for CTANGLE and CWEAVE (QL Version 4.2)} \def\topofcontents{\null\vfill \centerline{\titlefont Common code for {\ttitlefont CTANGLE} and {\ttitlefont CWEAVE}} \vskip 15pt - \centerline{(Version 4.1)} + \centerline{(Version 4.2)} \vfill} \def\botofcontents{\vfill \noindent diff --git a/common.c b/common.c index 49b40d0..7dd0f0c 100644 --- a/common.c +++ b/common.c @@ -41,6 +41,15 @@ #define xisupper(c) (isupper((eight_bits) c) &&((eight_bits) c<0200) ) #define xisxdigit(c) (isxdigit((eight_bits) c) &&((eight_bits) c<0200) ) \ +#define max_include_depth 10 \ + +#define max_file_name_length 1024 +#define cur_file file[include_depth] +#define cur_file_name file_name[include_depth] +#define cur_line line[include_depth] +#define web_file file[0] +#define web_file_name file_name[0] \ + #define length(c) (size_t) ((c+1) ->byte_start-(c) ->byte_start) #define print_id(c) term_write((c) ->byte_start,length((c) ) ) #define llink link @@ -57,15 +66,6 @@ #define confusion(s) fatal("! This can't happen: ",s) \ \ -#define max_include_depth 10 \ - -#define max_file_name_length 1024 -#define cur_file file[include_depth] -#define cur_file_name file_name[include_depth] -#define cur_line line[include_depth] -#define web_file file[0] -#define web_file_name file_name[0] \ - #define show_banner flags['b'] #define show_progress flags['p'] #define show_stats flags['s'] @@ -149,7 +149,31 @@ extern char*loc; extern char*limit; /*:5*//*6:*/ -#line 102 "common.h" +#line 105 "common.h" + +extern int include_depth; +extern FILE*file[]; +extern FILE*change_file; +extern char file_name[][max_file_name_length]; + +extern char change_file_name[]; +extern int line[]; +extern int change_line; +extern int change_depth; +extern boolean input_has_ended; +extern boolean changing; +extern boolean web_file_open; + +/*:6*//*8:*/ +#line 125 "common.h" + +extern sixteen_bits section_count; +extern boolean changed_section[]; +extern boolean change_pending; +extern boolean print_where; + +/*:8*//*9:*/ +#line 139 "common.h" typedef struct name_info{ char*byte_start; @@ -173,44 +197,20 @@ extern name_pointer hash[]; extern hash_pointer hash_end; extern hash_pointer h; -/*:6*//*8:*/ -#line 146 "common.h" +/*:9*//*11:*/ +#line 183 "common.h" extern int history; -/*:8*//*10:*/ -#line 166 "common.h" +/*:11*//*13:*/ +#line 199 "common.h" -extern int include_depth; -extern FILE*file[]; -extern FILE*change_file; +extern int argc; +extern char**argv; extern char C_file_name[]; extern char tex_file_name[]; extern char idx_file_name[]; extern char scn_file_name[]; -extern char file_name[][max_file_name_length]; - -extern char change_file_name[]; -extern int line[]; -extern int change_line; -extern int change_depth; -extern boolean input_has_ended; -extern boolean changing; -extern boolean web_file_open; - -/*:10*//*12:*/ -#line 190 "common.h" - -extern sixteen_bits section_count; -extern boolean changed_section[]; -extern boolean change_pending; -extern boolean print_where; - -/*:12*//*13:*/ -#line 203 "common.h" - -extern int argc; -extern char**argv; extern boolean flags[]; /*:13*//*14:*/ @@ -232,10 +232,11 @@ boolean program; /*:18*//*19:*/ #line 92 "common.w" + int phase; /*:19*//*21:*/ -#line 129 "common.w" +#line 130 "common.w" char section_text[longest_name+1]; char*section_text_end= section_text+longest_name; @@ -243,12 +244,12 @@ char*id_first; char*id_loc; /*:21*//*22:*/ -#line 149 "common.w" +#line 150 "common.w" char buffer[long_buf_size]; char*buffer_end= buffer+buf_size-2; -char*limit= buffer; char*loc= buffer; +char*limit= buffer; /*:22*//*25:*/ #line 194 "common.w" @@ -259,7 +260,7 @@ FILE*change_file; char file_name[max_include_depth][max_file_name_length]; char change_file_name[max_file_name_length]; -char alt_web_file_name[max_file_name_length]; +static char alt_web_file_name[max_file_name_length]; int line[max_include_depth]; int change_line; int change_depth; @@ -270,11 +271,11 @@ boolean web_file_open= false; /*:25*//*26:*/ #line 220 "common.w" -char change_buffer[buf_size]; -char*change_limit; +static char change_buffer[buf_size]; +static char*change_limit; /*:26*//*37:*/ -#line 401 "common.w" +#line 399 "common.w" sixteen_bits section_count; boolean changed_section[max_sections]; @@ -283,7 +284,7 @@ boolean change_pending; boolean print_where= false; /*:37*//*43:*/ -#line 598 "common.w" +#line 596 "common.w" char byte_mem[max_bytes]; char*byte_mem_end= byte_mem+max_bytes-1; @@ -291,25 +292,25 @@ name_info name_dir[max_names]; name_pointer name_dir_end= name_dir+max_names-1; /*:43*//*44:*/ -#line 609 "common.w" +#line 607 "common.w" -name_pointer name_ptr; char*byte_ptr; +name_pointer name_ptr; /*:44*//*46:*/ -#line 629 "common.w" +#line 627 "common.w" name_pointer hash[hash_size]; hash_pointer hash_end= hash+hash_size-1; hash_pointer h; /*:46*//*65:*/ -#line 1017 "common.w" +#line 1014 "common.w" int history= spotless; /*:65*//*73:*/ -#line 1138 "common.w" +#line 1135 "common.w" int argc; char**argv; @@ -320,7 +321,7 @@ char scn_file_name[max_file_name_length]; boolean flags[128]; /*:73*//*83:*/ -#line 1286 "common.w" +#line 1282 "common.w" FILE*C_file; FILE*tex_file; @@ -332,7 +333,14 @@ FILE*active_file; #line 70 "common.w" /*7:*/ -#line 125 "common.h" +#line 119 "common.h" + +extern boolean get_line(void); +extern void check_complete(void); +extern void reset_input(void); + +/*:7*//*10:*/ +#line 162 "common.h" extern boolean names_match(name_pointer,const char*,size_t,eight_bits); extern name_pointer id_lookup(const char*,const char*,char); @@ -344,71 +352,59 @@ extern void print_prefix_name(name_pointer); extern void print_section_name(name_pointer); extern void sprint_section_name(char*,name_pointer); -/*:7*//*9:*/ -#line 149 "common.h" +/*:10*//*12:*/ +#line 186 "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*); -/*:9*//*11:*/ -#line 184 "common.h" - -extern boolean get_line(void); -extern void check_complete(void); -extern void reset_input(void); - -/*:11*//*15:*/ +/*:12*//*15:*/ #line 223 "common.h" extern void common_init(void); extern void print_stats(void); -/*:15*//*23:*/ -#line 159 "common.w" - +/*:15*//*24:*/ +#line 180 "common.w" static boolean input_ln(FILE*); -/*:23*//*27:*/ -#line 231 "common.w" - +/*:24*//*28:*/ +#line 241 "common.w" static void prime_the_change_buffer(void); -/*:27*//*32:*/ -#line 303 "common.w" - +/*:28*//*33:*/ +#line 340 "common.w" static void check_change(void); -/*:32*//*55:*/ -#line 776 "common.w" +/*:33*//*55:*/ +#line 774 "common.w" static int web_strcmp(char*,int,char*,int); static name_pointer add_section_name(name_pointer,int,char*,char*,int); static void extend_section_name(name_pointer,char*,char*,int); -/*:55*//*63:*/ -#line 972 "common.w" - +/*:55*//*64:*/ +#line 1002 "common.w" static int section_name_cmp(char**,int,name_pointer); -/*:63*//*75:*/ -#line 1170 "common.w" - +/*:64*//*76:*/ +#line 1197 "common.w" static void scan_args(void); -/*:75*/ +/*:76*/ #line 71 "common.w" /*:1*//*20:*/ -#line 98 "common.w" +#line 99 "common.w" void common_init(void) { /*45:*/ -#line 613 "common.w" +#line 611 "common.w" name_dir->byte_start= byte_ptr= byte_mem; name_ptr= name_dir+1; @@ -416,24 +412,24 @@ name_ptr->byte_start= byte_mem; root= NULL; /*:45*//*47:*/ -#line 636 "common.w" +#line 634 "common.w" for(h= hash;h<=hash_end;*h++= NULL); /*:47*/ -#line 102 "common.w" +#line 103 "common.w" /*74:*/ -#line 1151 "common.w" +#line 1148 "common.w" show_banner= show_happiness= show_progress= make_xrefs= true; show_stats= false; /*:74*/ -#line 103 "common.w" +#line 104 "common.w" /*84:*/ -#line 1293 "common.w" +#line 1289 "common.w" scan_args(); if(program==ctangle){ @@ -447,12 +443,12 @@ fatal("! Cannot open output file ",tex_file_name); } /*:84*/ -#line 104 "common.w" +#line 105 "common.w" } -/*:20*//*24:*/ -#line 162 "common.w" +/*:20*//*23:*/ +#line 160 "common.w" static boolean input_ln( FILE*fp) @@ -473,15 +469,15 @@ if(c==EOF&&limit==buffer)return false; return true; } -/*:24*//*28:*/ -#line 234 "common.w" +/*:23*//*27:*/ +#line 231 "common.w" static void prime_the_change_buffer(void) { change_limit= change_buffer; /*29:*/ -#line 248 "common.w" +#line 247 "common.w" while(true){ change_line++; @@ -498,10 +494,10 @@ err_print("! Missing @x in change file"); } /*:29*/ -#line 239 "common.w" +#line 236 "common.w" /*30:*/ -#line 265 "common.w" +#line 264 "common.w" do{ change_line++; @@ -513,10 +509,10 @@ return; }while(limit==buffer); /*:30*/ -#line 240 "common.w" +#line 237 "common.w" /*31:*/ -#line 275 "common.w" +#line 274 "common.w" { change_limit= change_buffer+(ptrdiff_t)(limit-buffer); @@ -524,12 +520,12 @@ strncpy(change_buffer,buffer,(size_t)(limit-buffer+1)); } /*:31*/ -#line 241 "common.w" +#line 238 "common.w" } -/*:28*//*33:*/ -#line 306 "common.w" +/*:27*//*32:*/ +#line 302 "common.w" static void check_change(void) @@ -552,7 +548,7 @@ return; if(limit> buffer+1&&buffer[0]=='@'){ char xyz_code= xisupper(buffer[1])?tolower((eight_bits)buffer[1]):buffer[1]; /*34:*/ -#line 344 "common.w" +#line 342 "common.w" if(xyz_code=='x'||xyz_code=='z'){ loc= buffer+2;err_print("! Where is the matching @y?"); @@ -570,11 +566,11 @@ return; } /*:34*/ -#line 328 "common.w" +#line 324 "common.w" } /*31:*/ -#line 275 "common.w" +#line 274 "common.w" { change_limit= change_buffer+(ptrdiff_t)(limit-buffer); @@ -582,7 +578,7 @@ strncpy(change_buffer,buffer,(size_t)(limit-buffer+1)); } /*:31*/ -#line 330 "common.w" +#line 326 "common.w" changing= false;cur_line++; while(!input_ln(cur_file)){ @@ -597,15 +593,15 @@ if(lines_dont_match)n++; } } -/*:33*//*35:*/ -#line 364 "common.w" +/*:32*//*35:*/ +#line 362 "common.w" void reset_input(void) { limit= buffer;loc= buffer+1;buffer[0]= ' '; /*36:*/ -#line 379 "common.w" +#line 377 "common.w" if((web_file= fopen(web_file_name,"r"))==NULL){ strcpy(web_file_name,alt_web_file_name); @@ -619,7 +615,7 @@ if((change_file= fopen(change_file_name,"r"))==NULL) fatal("! Cannot open change file ",change_file_name); /*:36*/ -#line 369 "common.w" +#line 367 "common.w" include_depth= 0;cur_line= 0;change_line= 0; change_depth= include_depth; @@ -628,14 +624,14 @@ limit= buffer;loc= buffer+1;buffer[0]= ' ';input_has_ended= false; } /*:35*//*38:*/ -#line 408 "common.w" +#line 406 "common.w" boolean get_line(void) { restart: if(changing&&include_depth==change_depth) /*41:*/ -#line 516 "common.w" +#line 514 "common.w" { change_line++; if(!input_ln(change_file)){ @@ -666,11 +662,11 @@ prime_the_change_buffer();changing= !changing;print_where= true; } /*:41*/ -#line 413 "common.w" +#line 411 "common.w" if(!changing||include_depth> change_depth){ /*40:*/ -#line 499 "common.w" +#line 497 "common.w" { cur_line++; while(!input_ln(cur_file)){ @@ -689,7 +685,7 @@ if(change_limit> change_buffer)check_change(); } /*:40*/ -#line 415 "common.w" +#line 413 "common.w" if(changing&&include_depth==change_depth)goto restart; } @@ -710,7 +706,7 @@ goto restart; } include_depth++; /*39:*/ -#line 453 "common.w" +#line 451 "common.w" { char temp_file_name[max_file_name_length]; char*cur_file_name_end= cur_file_name+max_file_name_length-1; @@ -758,14 +754,14 @@ include_depth--;err_print("! Cannot open include file");goto restart; } /*:39*/ -#line 434 "common.w" +#line 432 "common.w" } return true; } /*:38*//*42:*/ -#line 548 "common.w" +#line 546 "common.w" void check_complete(void){ @@ -779,7 +775,7 @@ err_print("! Change file entry did not match"); } /*:42*//*48:*/ -#line 641 "common.w" +#line 639 "common.w" name_pointer id_lookup( @@ -794,17 +790,17 @@ name_pointer p; if(last==NULL)for(last= first;*last!='\0';last++); l= (int)(last-first); /*49:*/ -#line 664 "common.w" +#line 662 "common.w" h= (eight_bits)*i; while(++ilink; @@ -814,10 +810,10 @@ p->link= hash[h];hash[h]= p; } /*:50*/ -#line 655 "common.w" +#line 653 "common.w" if(p==name_ptr)/*51:*/ -#line 683 "common.w" +#line 681 "common.w" { if(byte_ptr+l> byte_mem_end)overflow("byte memory"); if(name_ptr>=name_dir_end)overflow("name"); @@ -827,13 +823,13 @@ init_p(p,t); } /*:51*/ -#line 656 "common.w" +#line 654 "common.w" return p; } /*:48*//*52:*/ -#line 715 "common.w" +#line 713 "common.w" void print_section_name( @@ -854,7 +850,7 @@ if(q)term_write("...",3); } /*:52*//*53:*/ -#line 734 "common.w" +#line 732 "common.w" void sprint_section_name( @@ -877,7 +873,7 @@ s= p->byte_start; } /*:53*//*54:*/ -#line 755 "common.w" +#line 753 "common.w" void print_prefix_name( @@ -890,7 +886,7 @@ if(s+l<(p+1)->byte_start)term_write("...",3); } /*:54*//*56:*/ -#line 781 "common.w" +#line 779 "common.w" static int web_strcmp( char*j, @@ -908,7 +904,7 @@ else return greater; } /*:56*//*57:*/ -#line 810 "common.w" +#line 808 "common.w" static name_pointer add_section_name( @@ -939,7 +935,7 @@ return par==NULL?(root= p):c==less?(par->llink= p):(par->rlink= p); } /*:57*//*58:*/ -#line 839 "common.w" +#line 837 "common.w" static void extend_section_name( @@ -963,7 +959,7 @@ if(ispref)*(byte_ptr-1)= ' '; } /*:58*//*59:*/ -#line 867 "common.w" +#line 865 "common.w" name_pointer section_lookup( @@ -978,7 +974,7 @@ name_pointer par= NULL; int name_len= (int)(last-first)+1; /*60:*/ -#line 891 "common.w" +#line 889 "common.w" while(p){ c= web_strcmp(first,name_len,first_chunk(p),prefix_length(p)); @@ -1005,19 +1001,19 @@ p= q,q= NULL; } /*:60*/ -#line 881 "common.w" +#line 879 "common.w" /*61:*/ -#line 916 "common.w" +#line 914 "common.w" if(r==NULL) return add_section_name(par,c,first,last+1,ispref); /*:61*/ -#line 882 "common.w" +#line 880 "common.w" /*62:*/ -#line 924 "common.w" +#line 922 "common.w" switch(section_name_cmp(&first,name_len,r)){ @@ -1051,12 +1047,12 @@ return r; } /*:62*/ -#line 883 "common.w" +#line 881 "common.w" } -/*:59*//*64:*/ -#line 975 "common.w" +/*:59*//*63:*/ +#line 970 "common.w" static int section_name_cmp( char**pfirst, @@ -1089,8 +1085,8 @@ default:return c; } } -/*:64*//*66:*/ -#line 1027 "common.w" +/*:63*//*66:*/ +#line 1024 "common.w" void err_print( @@ -1099,7 +1095,7 @@ const char*s) char*k,*l; printf(*s=='!'?"\n%s":"%s",s); if(web_file_open)/*67:*/ -#line 1047 "common.w" +#line 1044 "common.w" {if(changing&&include_depth==change_depth) printf(". (l. %d of change file)\n",change_line); @@ -1119,20 +1115,20 @@ putchar(' '); } /*:67*/ -#line 1034 "common.w" +#line 1031 "common.w" update_terminal;mark_error; } /*:66*//*68:*/ -#line 1079 "common.w" +#line 1076 "common.w" int wrap_up(void){ if(show_progress)new_line; if(show_stats) print_stats(); /*69:*/ -#line 1089 "common.w" +#line 1086 "common.w" switch(history){ case spotless:if(show_happiness)puts("(No errors were found.)");break; @@ -1144,14 +1140,14 @@ case fatal_message:puts("(That was a fatal error, my friend.)"); } /*:69*/ -#line 1084 "common.w" +#line 1081 "common.w" if(history> harmless_message)return EXIT_FAILURE; else return EXIT_SUCCESS; } /*:68*//*70:*/ -#line 1105 "common.w" +#line 1102 "common.w" void fatal( const char*s,const char*t) @@ -1162,7 +1158,7 @@ history= fatal_message;exit(wrap_up()); } /*:70*//*71:*/ -#line 1116 "common.w" +#line 1113 "common.w" void overflow( const char*t) @@ -1171,8 +1167,8 @@ printf("\n! Sorry, %s capacity exceeded",t);fatal("",""); } -/*:71*//*76:*/ -#line 1173 "common.w" +/*:71*//*75:*/ +#line 1167 "common.w" static void scan_args(void) @@ -1186,7 +1182,7 @@ 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 1262 "common.w" +#line 1258 "common.w" { for(dot_pos= *argv+1;*dot_pos> '\0';dot_pos++) @@ -1194,7 +1190,7 @@ flags[(eight_bits)*dot_pos]= flag_change; } /*:80*/ -#line 1185 "common.w" +#line 1179 "common.w" else{ s= name_pos= *argv;dot_pos= NULL; @@ -1204,17 +1200,17 @@ else if(*s=='/')dot_pos= NULL,name_pos= ++s; else s++; } if(!found_web)/*77:*/ -#line 1210 "common.w" +#line 1206 "common.w" { if(s-*argv> max_file_name_length-5) /*82:*/ -#line 1280 "common.w" +#line 1276 "common.w" fatal("! Filename too long\n",*argv); /*:82*/ -#line 1213 "common.w" +#line 1209 "common.w" if(dot_pos==NULL) sprintf(web_file_name,"%s.w",*argv); @@ -1231,21 +1227,21 @@ found_web= true; } /*:77*/ -#line 1194 "common.w" +#line 1188 "common.w" else if(!found_change)/*78:*/ -#line 1228 "common.w" +#line 1224 "common.w" { if(strcmp(*argv,"-")!=0){ if(s-*argv> max_file_name_length-4) /*82:*/ -#line 1280 "common.w" +#line 1276 "common.w" fatal("! Filename too long\n",*argv); /*:82*/ -#line 1232 "common.w" +#line 1228 "common.w" if(dot_pos==NULL) sprintf(change_file_name,"%s.ch",*argv); @@ -1255,20 +1251,20 @@ found_change= true; } /*:78*/ -#line 1195 "common.w" +#line 1189 "common.w" else if(!found_out)/*79:*/ -#line 1240 "common.w" +#line 1236 "common.w" { if(s-*argv> max_file_name_length-5) /*82:*/ -#line 1280 "common.w" +#line 1276 "common.w" fatal("! Filename too long\n",*argv); /*:82*/ -#line 1243 "common.w" +#line 1239 "common.w" if(dot_pos==NULL){ sprintf(tex_file_name,"%s.tex",*argv); @@ -1288,10 +1284,10 @@ found_out= true; } /*:79*/ -#line 1196 "common.w" +#line 1190 "common.w" else/*81:*/ -#line 1268 "common.w" +#line 1264 "common.w" { if(program==ctangle) @@ -1305,12 +1301,12 @@ else fatal( } /*:81*/ -#line 1197 "common.w" +#line 1191 "common.w" } } if(!found_web)/*81:*/ -#line 1268 "common.w" +#line 1264 "common.w" { if(program==ctangle) @@ -1324,8 +1320,8 @@ else fatal( } /*:81*/ -#line 1200 "common.w" +#line 1194 "common.w" } -/*:76*/ +/*:75*/ diff --git a/common.h b/common.h index 40896f8..425239f 100644 --- a/common.h +++ b/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.1 --- February 2021 (works also with later versions) +% Version 4.2 --- February 2021 (works also with later versions) % Copyright (C) 1987,1990,1993 Silvio Levy and Donald E. Knuth @@ -91,6 +91,43 @@ extern char *buffer_end; /* end of |buffer| */ extern char *loc; /* points to the next character to be read from the buffer */ extern char *limit; /* points to the last character in the buffer */ +@ Code related to file handling: +@f line x /* make |line| an unreserved word */ +@d max_include_depth 10 /* maximum number of source files open + simultaneously, not counting the change file */ +@d max_file_name_length 1024 +@d cur_file file[include_depth] /* current file */ +@d cur_file_name file_name[include_depth] /* current file name */ +@d cur_line line[include_depth] /* number of current line in current file */ +@d web_file file[0] /* main source file */ +@d web_file_name file_name[0] /* main source file name */ + +@= +extern int include_depth; /* current level of nesting */ +extern FILE *file[]; /* stack of non-change files */ +extern FILE *change_file; /* change file */ +extern char file_name[][max_file_name_length]; + /* stack of non-change file names */ +extern char change_file_name[]; /* name of change file */ +extern int line[]; /* number of current line in the stacked files */ +extern int change_line; /* number of current line in change file */ +extern int change_depth; /* where \.{@@y} originated during a change */ +extern boolean input_has_ended; /* if there is no more input */ +extern boolean changing; /* if the current line is from |change_file| */ +extern boolean web_file_open; /* if the web file is being read */ + +@ @= +extern boolean get_line(void); /* inputs the next line */ +extern void check_complete(void); /* checks that all changes were picked up */ +extern void reset_input(void); /* initialize to read the web file and change file */ + +@ Code related to section numbers: +@= +extern sixteen_bits section_count; /* the current section number */ +extern boolean changed_section[]; /* is the section changed? */ +extern boolean change_pending; /* is a decision about change still unclear? */ +extern boolean print_where; /* tells \.{CTANGLE} to print line and file info */ + @ Code related to identifier and section name storage: @d length(c) (size_t)((c+1)->byte_start-(c)->byte_start) /* the length of a name */ @d print_id(c) term_write((c)->byte_start,length((c))) /* print identifier */ @@ -131,7 +168,7 @@ 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 void sprint_section_name(char *,name_pointer); @ Code related to error handling: @d spotless 0 /* |history| value for normal jobs */ @@ -152,47 +189,6 @@ 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 */ -@ Code related to file handling: -@f line x /* make |line| an unreserved word */ -@d max_include_depth 10 /* maximum number of source files open - simultaneously, not counting the change file */ -@d max_file_name_length 1024 -@d cur_file file[include_depth] /* current file */ -@d cur_file_name file_name[include_depth] /* current file name */ -@d cur_line line[include_depth] /* number of current line in current file */ -@d web_file file[0] /* main source file */ -@d web_file_name file_name[0] /* main source file name */ - -@= -extern int include_depth; /* current level of nesting */ -extern FILE *file[]; /* stack of non-change files */ -extern FILE *change_file; /* change file */ -extern char C_file_name[]; /* name of |C_file| */ -extern char tex_file_name[]; /* name of |tex_file| */ -extern char idx_file_name[]; /* name of |idx_file| */ -extern char scn_file_name[]; /* name of |scn_file| */ -extern char file_name[][max_file_name_length]; - /* stack of non-change file names */ -extern char change_file_name[]; /* name of change file */ -extern int line[]; /* number of current line in the stacked files */ -extern int change_line; /* number of current line in change file */ -extern int change_depth; /* where \.{@@y} originated during a change */ -extern boolean input_has_ended; /* if there is no more input */ -extern boolean changing; /* if the current line is from |change_file| */ -extern boolean web_file_open; /* if the web file is being read */ - -@ @= -extern boolean get_line(void); /* inputs the next line */ -extern void check_complete(void); /* checks that all changes were picked up */ -extern void reset_input(void); /* initialize to read the web file and change file */ - -@ Code related to section numbers: -@= -extern sixteen_bits section_count; /* the current section number */ -extern boolean changed_section[]; /* is the section changed? */ -extern boolean change_pending; /* is a decision about change still unclear? */ -extern boolean print_where; /* tells \.{CTANGLE} to print line and file info */ - @ Code related to command line arguments: @d show_banner flags['b'] /* should the banner line be printed? */ @d show_progress flags['p'] /* should progress reports be printed? */ @@ -203,9 +199,13 @@ extern boolean print_where; /* tells \.{CTANGLE} to print line and file info */ @= extern int argc; /* copy of |ac| parameter to |main| */ extern char **argv; /* copy of |av| parameter to |main| */ +extern char C_file_name[]; /* name of |C_file| */ +extern char tex_file_name[]; /* name of |tex_file| */ +extern char idx_file_name[]; /* name of |idx_file| */ +extern char scn_file_name[]; /* name of |scn_file| */ extern boolean flags[]; /* an option for each 7-bit code */ -@ Code relating to output: +@ Code related to output: @d update_terminal fflush(stdout) /* empty the terminal output buffer */ @d new_line putchar('\n') @d putxchar putchar @d term_write(a,b) fflush(stdout),fwrite(a,sizeof(char),b,stdout) @@ -222,7 +222,7 @@ extern FILE *active_file; /* currently active file for \.{CWEAVE} output */ @ The procedure that gets everything rolling: @= extern void common_init(void);@/ -extern void print_stats(void);@/ +extern void print_stats(void); @ The following parameters were sufficient in the original \.{WEB} to handle \TEX/, so they should be sufficient for most applications of diff --git a/common.w b/common.w index 377a796..15e93c2 100644 --- a/common.w +++ b/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.1 --- February 2021 +% Version 4.2 --- February 2021 % 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.1)} +\def\title{Common code for CTANGLE and CWEAVE (Version 4.2)} \def\topofcontents{\null\vfill \centerline{\titlefont Common code for {\ttitlefont CTANGLE} and {\ttitlefont CWEAVE}} \vskip 15pt - \centerline{(Version 4.1)} + \centerline{(Version 4.2)} \vfill} \def\botofcontents{\vfill \noindent @@ -68,7 +68,7 @@ The file begins with a few basic definitions. @h @@/ @@/ -@@/ +@ @ The details will be filled in due course. The interface of this module is included first. It is also used by the main programs. @@ -89,7 +89,8 @@ produces the \TEX/ output file, and finally it sorts and outputs the index. Similarly, \.{CTANGLE} operates in two phases. The global variable |phase| tells which phase we are in. -@= int phase; /* which phase are we in? */ +@= +int phase; /* which phase are we in? */ @ There's an initialization procedure that gets both \.{CTANGLE} and \.{CWEAVE} off to a good start. We will fill in the details of this @@ -149,17 +150,14 @@ some of \.{CWEB}'s routines use the fact that it is safe to refer to @= char buffer[long_buf_size]; /* where each line of input goes */ char *buffer_end=buffer+buf_size-2; /* end of |buffer| */ -char *limit=buffer; /* points to the last character in the buffer */ 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. @^system dependencies@> -@= -static boolean input_ln(FILE *);@/ - -@ @c +@c static boolean input_ln(@t\1\1@> /* copies a line into |buffer| or returns |false| */ FILE *fp@t\2\2@>) /* what file to read from */ { @@ -179,6 +177,8 @@ FILE *fp@t\2\2@>) /* what file to read from */ return true; } +@ @=@+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 streams: a |web_file|, which can contain possibly nested include @@ -198,7 +198,7 @@ FILE *change_file; /* change file */ char file_name[max_include_depth][max_file_name_length]; /* stack of non-change file names */ char change_file_name[max_file_name_length]; /* name of change file */ -char alt_web_file_name[max_file_name_length]; /* alternate name to try */ +static char alt_web_file_name[max_file_name_length]; /* alternate name to try */ int line[max_include_depth]; /* number of current line in the stacked files */ int change_line; /* number of current line in change file */ int change_depth; /* where \.{@@y} originated during a change */ @@ -218,8 +218,8 @@ Here's a shorthand expression for inequality between the two lines: strncmp(buffer, change_buffer, (size_t)(limit-buffer))) @= -char change_buffer[buf_size]; /* next line of |change_file| */ -char *change_limit; /* points to the last character in |change_buffer| */ +static char change_buffer[buf_size]; /* next line of |change_file| */ +static char *change_limit; /* points to the last character in |change_buffer| */ @ Procedure |prime_the_change_buffer| sets |change_buffer| in preparation for the next matching operation. @@ -228,10 +228,7 @@ Since blank lines in the change file are not used for matching, we have the change file is exhausted. This procedure is called only when |changing| is |true|; hence error messages will be reported correctly. -@= -static void prime_the_change_buffer(void);@/ - -@ @c +@c static void prime_the_change_buffer(void) { @@ -241,6 +238,8 @@ prime_the_change_buffer(void) @@; } +@ @=@+static void prime_the_change_buffer(void); + @ While looking for a line that begins with \.{@@x} in the change file, we allow lines that begin with \.{@@}, as long as they don't begin with \.{@@y}, \.{@@z}, or \.{@@i} (which would probably mean that the change file is fouled up). @@ -289,7 +288,7 @@ prepares to read the next line from |change_file|. When a match is found, the current section is marked as changed unless the first line after the \.{@@x} and after the \.{@@y} both start with -either |'@@*'| or |'@@ '| (possibly preceded by whitespace). +either `\.{@@*}' or `\.{@@\ }' (possibly preceded by whitespace). This procedure is called only when |buffer= -static void check_change(void);@/ - -@ @c +@c static void check_change(void) /* switches to |change_file| if the buffers match */ { @@ -341,6 +337,8 @@ check_change(void) /* switches to |change_file| if the buffers match */ } } +@ @=@+static void check_change(void); + @ @= if (xyz_code=='x' || xyz_code=='z') { loc=buffer+2; err_print("! Where is the matching @@y?"); @@ -607,8 +605,8 @@ usually have |name_ptr->byte_start==byte_ptr|, and certainly we want to keep |name_ptr<=name_dir_end| and |byte_ptr<=byte_mem_end|. @= -name_pointer name_ptr; /* first unused position in |name_dir| */ char *byte_ptr; /* first unused position in |byte_mem| */ +name_pointer name_ptr; /* first unused position in |name_dir| */ @ @= name_dir->byte_start=byte_ptr=byte_mem; /* position zero in both arrays */ @@ -776,7 +774,7 @@ are null-terminated, and we keep an eye open for prefixes and extensions. @= static int web_strcmp(char *,int,char *,int);@/ static name_pointer add_section_name(name_pointer,int,char *,char *,int);@/ -static void extend_section_name(name_pointer,char *,char *,int);@/ +static void extend_section_name(name_pointer,char *,char *,int); @ @c static int web_strcmp(@t\1\1@> /* fuller comparison than |strcmp| */ @@ -969,10 +967,7 @@ us to regard \.{@@} as an ``extension'' of itself. @d bad_extension 5 -@= -static int section_name_cmp(char **,int,name_pointer);@/ - -@ @c +@c static int section_name_cmp(@t\1\1@> char **pfirst, /* pointer to beginning of comparison string */ int len, /* length of string */ @@ -1004,6 +999,8 @@ name_pointer r@t\2\2@>) /* section name being compared */ } } +@ @=@+static int section_name_cmp(char **,int,name_pointer); + @** 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 @@ -1150,7 +1147,7 @@ should be set before calling |common_init|. @= show_banner=show_happiness=show_progress=make_xrefs=true;@/ -show_stats=false;@/ +show_stats=false; @ We now must look at the command line arguments and set the file names accordingly. At least one file name must be present: the \.{CWEB} @@ -1167,10 +1164,7 @@ when no changes are desired. If there's a third file name, it will be the output file. -@= -static void scan_args(void);@/ - -@ @c +@c static void scan_args(void) { @@ -1200,6 +1194,8 @@ scan_args(void) if (!found_web) @@; } +@ @=@+static void scan_args(void); + @ We use all of |*argv| for the |web_file_name| if there is a |'.'| in it, otherwise we add |".w"|. If this file can't be opened, we prepare an |alt_web_file_name| by adding |"web"| after the dot. diff --git a/ctang-bs.ch b/ctang-bs.ch index 22310b8..55cc27c 100644 --- a/ctang-bs.ch +++ b/ctang-bs.ch @@ -17,12 +17,12 @@ by using "huge" pointers. The ``banner line'' defined here should be changed whenever \.{CTANGLE} is modified. -@d banner "This is CTANGLE (Version 4.1)" +@d banner "This is CTANGLE (Version 4.2)" @y The ``banner line'' defined here should be changed whenever \.{CTANGLE} is modified. -@d banner "This is CTANGLE (Version 4.1pc/big)" +@d banner "This is CTANGLE (Version 4.2pc/big)" @z @@ -141,13 +141,13 @@ typedef text *text_pointer; @x Section 17. -eight_bits tok_mem[max_toks]; -eight_bits *tok_mem_end=tok_mem+max_toks-1; -eight_bits *tok_ptr; /* first unused position in |tok_mem| */ +static eight_bits tok_mem[max_toks]; +static eight_bits *tok_mem_end=tok_mem+max_toks-1; +static eight_bits *tok_ptr; /* first unused position in |tok_mem| */ @y -eight_bits huge tok_mem[max_toks]; -eight_bits huge* tok_mem_end; -eight_bits huge* tok_ptr; /* first unused position in |tok_mem| */ +static eight_bits huge tok_mem[max_toks]; +static eight_bits huge* tok_mem_end; +static eight_bits huge* tok_ptr; /* first unused position in |tok_mem| */ @z diff --git a/ctang-pc.ch b/ctang-pc.ch index 686a2b0..ddf281b 100644 --- a/ctang-pc.ch +++ b/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.1)" +@d banner "This is CTANGLE (Version 4.2)" @y -@d banner "This is CTANGLE (Version 4.1pc)" +@d banner "This is CTANGLE (Version 4.2pc)" @z @x section 4 @d max_bytes 1000000 /* the number of bytes in identifiers, diff --git a/ctang-ql.ch b/ctang-ql.ch index df4ca82..64f0e81 100644 --- a/ctang-ql.ch +++ b/ctang-ql.ch @@ -7,15 +7,15 @@ ex cc;"-v -h -c -=500000 ctangle_c" @x -\def\title{CTANGLE (Version 4.1)} +\def\title{CTANGLE (Version 4.2)} @y -\def\title{CTANGLE (QL Version 4.1)} +\def\title{CTANGLE (QL Version 4.2)} @z @x section 1 -@d banner "This is CTANGLE (Version 4.1)" +@d banner "This is CTANGLE (Version 4.2)" @y -@d banner "This is CTANGLE (QL Version 4.1)" +@d banner "This is CTANGLE (QL Version 4.2)" @z @x diff --git a/ctang-vms.ch b/ctang-vms.ch index 87acb6e..5686c66 100644 --- a/ctang-vms.ch +++ b/ctang-vms.ch @@ -10,9 +10,9 @@ created: (these changes not necessary for initial bootstrapping) @x section 1 (01-FEB-1992 ST) -@d banner "This is CTANGLE (Version 4.1)" +@d banner "This is CTANGLE (Version 4.2)" @y -@d banner "This is CTANGLE (VAX/VMS Version 4.1)" +@d banner "This is CTANGLE (VAX/VMS Version 4.2)" @z @x section 3 (01-FEB-1992 ST) diff --git a/ctang-w32.ch b/ctang-w32.ch index 896d086..1c687e5 100644 --- a/ctang-w32.ch +++ b/ctang-w32.ch @@ -4,9 +4,9 @@ This is the change file for CWEB's CTANGLE under Win32 Changes necessary for compiling with Borland C/C++ @x section 1 -@d banner "This is CTANGLE (Version 4.1)" +@d banner "This is CTANGLE (Version 4.2)" @y -@d banner "This is CTANGLE (Version 4.1win32)" +@d banner "This is CTANGLE (Version 4.2win32)" @z @x diff --git a/ctangle.c b/ctangle.c index 200d61a..d955da9 100644 --- a/ctangle.c +++ b/ctangle.c @@ -15,7 +15,7 @@ /*:4*/ #line 67 "ctangle.w" -#define banner "This is CTANGLE (Version 4.1)" \ +#define banner "This is CTANGLE (Version 4.2)" \ #define ctangle false #define cweave true \ @@ -43,6 +43,15 @@ #define xisupper(c) (isupper((eight_bits) c) &&((eight_bits) c<0200) ) #define xisxdigit(c) (isxdigit((eight_bits) c) &&((eight_bits) c<0200) ) \ +#define max_include_depth 10 \ + +#define max_file_name_length 1024 +#define cur_file file[include_depth] +#define cur_file_name file_name[include_depth] +#define cur_line line[include_depth] +#define web_file file[0] +#define web_file_name file_name[0] \ + #define length(c) (size_t) ((c+1) ->byte_start-(c) ->byte_start) #define print_id(c) term_write((c) ->byte_start,length((c) ) ) #define llink link @@ -59,15 +68,6 @@ #define confusion(s) fatal("! This can't happen: ",s) \ \ -#define max_include_depth 10 \ - -#define max_file_name_length 1024 -#define cur_file file[include_depth] -#define cur_file_name file_name[include_depth] -#define cur_line line[include_depth] -#define web_file file[0] -#define web_file_name file_name[0] \ - #define show_banner flags['b'] #define show_progress flags['p'] #define show_stats flags['s'] @@ -171,7 +171,31 @@ extern char*loc; extern char*limit; /*:6*//*7:*/ -#line 102 "common.h" +#line 105 "common.h" + +extern int include_depth; +extern FILE*file[]; +extern FILE*change_file; +extern char file_name[][max_file_name_length]; + +extern char change_file_name[]; +extern int line[]; +extern int change_line; +extern int change_depth; +extern boolean input_has_ended; +extern boolean changing; +extern boolean web_file_open; + +/*:7*//*9:*/ +#line 125 "common.h" + +extern sixteen_bits section_count; +extern boolean changed_section[]; +extern boolean change_pending; +extern boolean print_where; + +/*:9*//*10:*/ +#line 139 "common.h" typedef struct name_info{ char*byte_start; @@ -195,44 +219,20 @@ extern name_pointer hash[]; extern hash_pointer hash_end; extern hash_pointer h; -/*:7*//*9:*/ -#line 146 "common.h" +/*:10*//*12:*/ +#line 183 "common.h" extern int history; -/*:9*//*11:*/ -#line 166 "common.h" +/*:12*//*14:*/ +#line 199 "common.h" -extern int include_depth; -extern FILE*file[]; -extern FILE*change_file; +extern int argc; +extern char**argv; extern char C_file_name[]; extern char tex_file_name[]; extern char idx_file_name[]; extern char scn_file_name[]; -extern char file_name[][max_file_name_length]; - -extern char change_file_name[]; -extern int line[]; -extern int change_line; -extern int change_depth; -extern boolean input_has_ended; -extern boolean changing; -extern boolean web_file_open; - -/*:11*//*13:*/ -#line 190 "common.h" - -extern sixteen_bits section_count; -extern boolean changed_section[]; -extern boolean change_pending; -extern boolean print_where; - -/*:13*//*14:*/ -#line 203 "common.h" - -extern int argc; -extern char**argv; extern boolean flags[]; /*:14*//*15:*/ @@ -257,7 +257,7 @@ sixteen_bits text_link; typedef text*text_pointer; /*:19*//*31:*/ -#line 270 "ctangle.w" +#line 269 "ctangle.w" typedef struct{ eight_bits*end_field; @@ -274,83 +274,90 @@ typedef output_state*stack_pointer; /*20:*/ #line 129 "ctangle.w" -text text_info[max_texts]; -text_pointer text_info_end= text_info+max_texts-1; -text_pointer text_ptr; -eight_bits tok_mem[max_toks]; -eight_bits*tok_mem_end= tok_mem+max_toks-1; -eight_bits*tok_ptr; +static text text_info[max_texts]; +static text_pointer text_info_end= text_info+max_texts-1; +static text_pointer text_ptr; +static eight_bits tok_mem[max_toks]; +static eight_bits*tok_mem_end= tok_mem+max_toks-1; +static eight_bits*tok_ptr; /*:20*//*26:*/ #line 198 "ctangle.w" -text_pointer last_unnamed; +static text_pointer last_unnamed; /*:26*//*32:*/ -#line 286 "ctangle.w" +#line 285 "ctangle.w" -output_state cur_state; +static output_state cur_state; -output_state stack[stack_size+1]; -stack_pointer stack_end= stack+stack_size; -stack_pointer stack_ptr; +static output_state stack[stack_size+1]; +static stack_pointer stack_end= stack+stack_size; +static stack_pointer stack_ptr; /*:32*//*37:*/ -#line 362 "ctangle.w" +#line 361 "ctangle.w" -int cur_val; +static int cur_val; /*:37*//*42:*/ -#line 454 "ctangle.w" +#line 452 "ctangle.w" -eight_bits out_state; -boolean protect; +static eight_bits out_state; +static boolean protect; /*:42*//*45:*/ -#line 486 "ctangle.w" +#line 483 "ctangle.w" -name_pointer output_files[max_files]; -name_pointer*cur_out_file,*end_output_files,*an_output_file; -char cur_section_name_char; -char output_file_name[longest_name+1]; +static name_pointer output_files[max_files]; +static name_pointer*cur_out_file,*end_output_files,*an_output_file; +static char cur_section_name_char; +static char output_file_name[longest_name+1]; /*:45*//*52:*/ -#line 586 "ctangle.w" +#line 582 "ctangle.w" -boolean output_defs_seen= false; +static boolean output_defs_seen= false; /*:52*//*57:*/ -#line 695 "ctangle.w" +#line 691 "ctangle.w" -char translit[128][translit_length]; +static char translit[128][translit_length]; /*:57*//*62:*/ -#line 774 "ctangle.w" +#line 770 "ctangle.w" -eight_bits ccode[256]; +static eight_bits ccode[256]; /*:62*//*66:*/ -#line 834 "ctangle.w" +#line 830 "ctangle.w" -boolean comment_continues= false; +static boolean comment_continues= false; /*:66*//*68:*/ -#line 873 "ctangle.w" +#line 869 "ctangle.w" -name_pointer cur_section_name; -boolean no_where; +static name_pointer cur_section_name; +static boolean no_where; /*:68*//*82:*/ -#line 1187 "ctangle.w" +#line 1182 "ctangle.w" -text_pointer cur_text; -eight_bits next_control; +static text_pointer cur_text; +static eight_bits next_control; /*:82*/ #line 71 "ctangle.w" /*8:*/ -#line 125 "common.h" +#line 119 "common.h" + +extern boolean get_line(void); +extern void check_complete(void); +extern void reset_input(void); + +/*:8*//*11:*/ +#line 162 "common.h" extern boolean names_match(name_pointer,const char*,size_t,eight_bits); extern name_pointer id_lookup(const char*,const char*,char); @@ -362,91 +369,75 @@ extern void print_prefix_name(name_pointer); extern void print_section_name(name_pointer); extern void sprint_section_name(char*,name_pointer); -/*:8*//*10:*/ -#line 149 "common.h" +/*:11*//*13:*/ +#line 186 "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*); -/*:10*//*12:*/ -#line 184 "common.h" - -extern boolean get_line(void); -extern void check_complete(void); -extern void reset_input(void); - -/*:12*//*16:*/ +/*:13*//*16:*/ #line 223 "common.h" extern void common_init(void); extern void print_stats(void); -/*:16*//*29:*/ -#line 231 "ctangle.w" - +/*:16*//*30:*/ +#line 241 "ctangle.w" static void store_two_bytes(sixteen_bits); -/*:29*//*34:*/ -#line 310 "ctangle.w" +/*:30*//*35:*/ +#line 324 "ctangle.w" static void push_level(name_pointer); static void pop_level(boolean); -/*:34*//*38:*/ -#line 369 "ctangle.w" - +/*:35*//*39:*/ +#line 397 "ctangle.w" static void get_output(void); -/*:38*//*43:*/ -#line 462 "ctangle.w" - +/*:39*//*44:*/ +#line 473 "ctangle.w" static void flush_buffer(void); -/*:43*//*48:*/ -#line 517 "ctangle.w" - +/*:44*//*49:*/ +#line 549 "ctangle.w" static void phase_two(void); -/*:48*//*53:*/ -#line 589 "ctangle.w" +/*:49*//*53:*/ +#line 585 "ctangle.w" static void output_defs(void); static void out_char(eight_bits); -/*:53*//*64:*/ -#line 798 "ctangle.w" +/*:53*//*65:*/ +#line 810 "ctangle.w" static eight_bits skip_ahead(void); static boolean skip_comment(boolean); -/*:64*//*69:*/ -#line 885 "ctangle.w" - +/*:65*//*70:*/ +#line 924 "ctangle.w" static eight_bits get_next(void); -/*:69*//*83:*/ -#line 1191 "ctangle.w" - +/*:70*//*84:*/ +#line 1208 "ctangle.w" static void scan_repl(eight_bits); -/*:83*//*90:*/ -#line 1348 "ctangle.w" - +/*:84*//*91:*/ +#line 1379 "ctangle.w" static void scan_section(void); -/*:90*//*98:*/ -#line 1455 "ctangle.w" - +/*:91*//*99:*/ +#line 1460 "ctangle.w" static void phase_one(void); -/*:98*//*100:*/ -#line 1473 "ctangle.w" - +/*:99*//*101:*/ +#line 1494 "ctangle.w" static void skip_limbo(void); -/*:100*/ +/*:101*/ #line 72 "ctangle.w" @@ -476,12 +467,12 @@ init_node(name_dir); last_unnamed= text_info;text_info->text_link= 0; /*:27*//*46:*/ -#line 496 "ctangle.w" +#line 493 "ctangle.w" cur_out_file= end_output_files= output_files+max_files; /*:46*//*58:*/ -#line 698 "ctangle.w" +#line 694 "ctangle.w" { int i; @@ -489,7 +480,7 @@ for(i= 0;i<128;i++)sprintf(translit[i],"X%02X",(unsigned int)(128+i)); } /*:58*//*63:*/ -#line 777 "ctangle.w" +#line 773 "ctangle.w" { int c; for(c= 0;c<256;c++)ccode[c]= ignore; @@ -509,7 +500,7 @@ ccode['\'']= ord; } /*:63*//*78:*/ -#line 1108 "ctangle.w" +#line 1103 "ctangle.w" section_text[0]= ' '; /*:78*/ @@ -547,10 +538,10 @@ node->equiv= (void*)text_info; void init_p(name_pointer p,eight_bits t){(void)p;(void)t;} -/*:25*//*30:*/ -#line 234 "ctangle.w" +/*:25*//*29:*/ +#line 231 "ctangle.w" -void +static void store_two_bytes( sixteen_bits x) { @@ -559,8 +550,8 @@ if(tok_ptr+2> tok_mem_end)overflow("token"); *tok_ptr++= x&0377; } -/*:30*//*35:*/ -#line 314 "ctangle.w" +/*:29*//*34:*/ +#line 309 "ctangle.w" static void push_level( @@ -576,8 +567,8 @@ cur_section= 0; } } -/*:35*//*36:*/ -#line 333 "ctangle.w" +/*:34*//*36:*/ +#line 332 "ctangle.w" static void pop_level( @@ -592,8 +583,8 @@ stack_ptr--; if(stack_ptr> stack)cur_state= *stack_ptr; } -/*:36*//*39:*/ -#line 372 "ctangle.w" +/*:36*//*38:*/ +#line 368 "ctangle.w" static void get_output(void) @@ -616,7 +607,7 @@ switch(a/024000){ case 0:cur_val= a;out_char(identifier);break; case 1:if(a==output_defs_flag)output_defs(); else/*40:*/ -#line 404 "ctangle.w" +#line 402 "ctangle.w" { a-= 024000; @@ -630,7 +621,7 @@ goto restart; } /*:40*/ -#line 393 "ctangle.w" +#line 389 "ctangle.w" break; default:cur_val= a-050000;if(cur_val> 0)cur_section= cur_val; @@ -639,8 +630,8 @@ out_char(section_number); } } -/*:39*//*44:*/ -#line 465 "ctangle.w" +/*:38*//*43:*/ +#line 460 "ctangle.w" static void flush_buffer(void) @@ -654,30 +645,30 @@ update_terminal; cur_line++; } -/*:44*//*49:*/ -#line 520 "ctangle.w" +/*:43*//*48:*/ +#line 514 "ctangle.w" static void phase_two(void){ web_file_open= false; cur_line= 1; /*33:*/ -#line 299 "ctangle.w" +#line 298 "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; /*:33*/ -#line 525 "ctangle.w" +#line 519 "ctangle.w" /*51:*/ -#line 582 "ctangle.w" +#line 578 "ctangle.w" if(!output_defs_seen) output_defs(); /*:51*/ -#line 526 "ctangle.w" +#line 520 "ctangle.w" if(text_info->text_link==0&&cur_out_file==end_output_files){ fputs("\n! No program text was specified.",stdout);mark_harmless; @@ -700,7 +691,7 @@ if(text_info->text_link==0)goto writeloop; while(stack_ptr> stack)get_output(); flush_buffer(); writeloop:/*50:*/ -#line 559 "ctangle.w" +#line 555 "ctangle.w" for(an_output_file= end_output_files;an_output_file> cur_out_file;){ an_output_file--; @@ -721,7 +712,7 @@ flush_buffer(); } /*:50*/ -#line 547 "ctangle.w" +#line 541 "ctangle.w" if(show_happiness){ if(show_progress)new_line; @@ -730,8 +721,8 @@ fputs("Done.",stdout); } } -/*:49*//*54:*/ -#line 593 "ctangle.w" +/*:48*//*54:*/ +#line 589 "ctangle.w" static void output_defs(void) @@ -771,7 +762,7 @@ pop_level(false); } /*:54*//*55:*/ -#line 636 "ctangle.w" +#line 632 "ctangle.w" static void out_char( @@ -784,7 +775,7 @@ case'\n':if(protect&&out_state!=verbatim)C_putc(' '); if(protect||out_state==verbatim)C_putc('\\'); flush_buffer();if(out_state!=verbatim)out_state= normal;break; /*59:*/ -#line 704 "ctangle.w" +#line 700 "ctangle.w" case identifier: if(out_state==num_or_id)C_putc(' '); @@ -799,10 +790,10 @@ j++; out_state= num_or_id;break; /*:59*/ -#line 647 "ctangle.w" +#line 643 "ctangle.w" /*60:*/ -#line 717 "ctangle.w" +#line 713 "ctangle.w" case section_number: if(cur_val> 0)C_printf("/*%d:*/",cur_val); @@ -829,10 +820,10 @@ C_printf("%s","\"\n"); break; /*:60*/ -#line 648 "ctangle.w" +#line 644 "ctangle.w" /*56:*/ -#line 666 "ctangle.w" +#line 662 "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 +844,7 @@ case minus_gt_ast:C_putc('-');C_putc('>');C_putc('*');out_state= normal; break; /*:56*/ -#line 649 "ctangle.w" +#line 645 "ctangle.w" case'=':case'>':C_putc(cur_char);C_putc(' '); out_state= normal;break; @@ -871,8 +862,8 @@ default:C_putc(cur_char);out_state= normal;break; } } -/*:55*//*65:*/ -#line 802 "ctangle.w" +/*:55*//*64:*/ +#line 794 "ctangle.w" static eight_bits skip_ahead(void) @@ -889,8 +880,8 @@ if(c!=ignore||*(loc-1)=='>')return c; } } -/*:65*//*67:*/ -#line 837 "ctangle.w" +/*:64*//*67:*/ +#line 833 "ctangle.w" static boolean skip_comment( boolean is_long_comment) @@ -923,8 +914,8 @@ else loc++; } } -/*:67*//*70:*/ -#line 888 "ctangle.w" +/*:67*//*69:*/ +#line 881 "ctangle.w" static eight_bits get_next(void) @@ -938,7 +929,7 @@ if(get_line()==false)return new_section; else if(print_where&&!no_where){ print_where= false; /*85:*/ -#line 1220 "ctangle.w" +#line 1214 "ctangle.w" store_two_bytes(0150000); if(changing&&include_depth==change_depth){ @@ -953,7 +944,7 @@ id_loc= id_first+strlen(id_first); app_repl(a_l%0400);} /*:85*/ -#line 900 "ctangle.w" +#line 893 "ctangle.w" } else return'\n'; @@ -967,7 +958,7 @@ else continue; } loc++; if(xisdigit(c)||c=='.')/*73:*/ -#line 969 "ctangle.w" +#line 964 "ctangle.w" { id_first= loc-1; if(*id_first=='.'&&!xisdigit(*loc))goto mistake; @@ -992,13 +983,13 @@ return constant; } /*:73*/ -#line 912 "ctangle.w" +#line 905 "ctangle.w" else if(c=='\''||c=='"' ||((c=='L'||c=='u'||c=='U')&&(*loc=='\''||*loc=='"')) ||((c=='u'&&*loc=='8')&&(*(loc+1)=='\''||*(loc+1)=='"'))) /*74:*/ -#line 997 "ctangle.w" +#line 992 "ctangle.w" { char delim= c; id_first= section_text+1; @@ -1042,11 +1033,11 @@ return string; } /*:74*/ -#line 916 "ctangle.w" +#line 909 "ctangle.w" else if(isalpha(c)||isxalpha(c)||ishigh(c)) /*72:*/ -#line 962 "ctangle.w" +#line 957 "ctangle.w" { id_first= --loc; while(isalpha((eight_bits)*++loc)||isdigit((eight_bits)*loc) @@ -1055,10 +1046,10 @@ id_loc= loc;return identifier; } /*:72*/ -#line 918 "ctangle.w" +#line 911 "ctangle.w" else if(c=='@')/*75:*/ -#line 1042 "ctangle.w" +#line 1037 "ctangle.w" { c= ccode[(eight_bits)*loc++]; switch(c){ @@ -1074,11 +1065,11 @@ continue; case section_name: cur_section_name_char= *(loc-1); /*77:*/ -#line 1090 "ctangle.w" +#line 1085 "ctangle.w" { char*k; /*79:*/ -#line 1110 "ctangle.w" +#line 1105 "ctangle.w" k= section_text; while(true){ @@ -1089,7 +1080,7 @@ loc= buffer+1;break; } c= *loc; /*80:*/ -#line 1134 "ctangle.w" +#line 1129 "ctangle.w" if(c=='@'){ c= *(loc+1); @@ -1108,7 +1099,7 @@ err_print("! Nesting of section names not allowed");break; } /*:80*/ -#line 1119 "ctangle.w" +#line 1114 "ctangle.w" loc++;if(k section_text)k--; /*:79*/ -#line 1092 "ctangle.w" +#line 1087 "ctangle.w" if(k-section_text> 3&&strncmp(k-2,"...",3)==0) cur_section_name= section_lookup(section_text+1,k-3,1); else cur_section_name= section_lookup(section_text+1,k,0); if(cur_section_name_char=='(') /*47:*/ -#line 500 "ctangle.w" +#line 497 "ctangle.w" { for(an_output_file= cur_out_file; @@ -1148,16 +1139,16 @@ overflow("output files"); } /*:47*/ -#line 1098 "ctangle.w" +#line 1093 "ctangle.w" return section_name; } /*:77*/ -#line 1056 "ctangle.w" +#line 1051 "ctangle.w" case string:/*81:*/ -#line 1156 "ctangle.w" +#line 1151 "ctangle.w" { id_first= loc++;*(limit+1)= '@';*(limit+2)= '>'; while(*loc!='@'||*(loc+1)!='>')loc++; @@ -1168,10 +1159,10 @@ return string; } /*:81*/ -#line 1057 "ctangle.w" +#line 1052 "ctangle.w" case ord:/*76:*/ -#line 1069 "ctangle.w" +#line 1064 "ctangle.w" id_first= loc; if(*loc=='\\'){ @@ -1194,14 +1185,14 @@ loc++; return ord; /*:76*/ -#line 1058 "ctangle.w" +#line 1053 "ctangle.w" default:return c; } } /*:75*/ -#line 919 "ctangle.w" +#line 912 "ctangle.w" else if(xisspace(c)){ if(!preprocessing||loc> limit)continue; @@ -1210,7 +1201,7 @@ else return' '; } else if(c=='#'&&loc==buffer+1)preprocessing= 1; mistake:/*71:*/ -#line 940 "ctangle.w" +#line 935 "ctangle.w" switch(c){ case'+':if(*loc=='+')compress(plus_plus);break; @@ -1234,14 +1225,14 @@ case'!':if(*loc=='=')compress(non_eq);break; } /*:71*/ -#line 926 "ctangle.w" +#line 919 "ctangle.w" return c; } } -/*:70*//*84:*/ -#line 1194 "ctangle.w" +/*:69*//*83:*/ +#line 1186 "ctangle.w" static void scan_repl( @@ -1249,7 +1240,7 @@ eight_bits t) { sixteen_bits a; if(t==section_name){/*85:*/ -#line 1220 "ctangle.w" +#line 1214 "ctangle.w" store_two_bytes(0150000); if(changing&&include_depth==change_depth){ @@ -1264,11 +1255,11 @@ id_loc= id_first+strlen(id_first); app_repl(a_l%0400);} /*:85*/ -#line 1200 "ctangle.w" +#line 1192 "ctangle.w" } while(true)switch(a= get_next()){ /*86:*/ -#line 1233 "ctangle.w" +#line 1227 "ctangle.w" case identifier:a= id_lookup(id_first,id_loc,0)-name_dir; app_repl((a/0400)+0200); @@ -1276,7 +1267,7 @@ app_repl(a%0400);break; case section_name:if(t!=section_name)goto done; else{ /*87:*/ -#line 1266 "ctangle.w" +#line 1260 "ctangle.w" { char*try_loc= loc; while(*try_loc==' '&&try_loc text_info_end)overflow("text"); cur_text= text_ptr;(++text_ptr)->tok_start= tok_ptr; } -/*:84*//*91:*/ -#line 1355 "ctangle.w" +/*:83*//*90:*/ +#line 1346 "ctangle.w" static void scan_section(void) @@ -1449,7 +1440,7 @@ printf("*%d",section_count);update_terminal; next_control= 0; while(true){ /*92:*/ -#line 1394 "ctangle.w" +#line 1387 "ctangle.w" while(next_controltext_link= macro; } /*:93*/ -#line 1371 "ctangle.w" +#line 1362 "ctangle.w" continue; } @@ -1491,14 +1482,14 @@ p= name_dir;break; if(next_control==section_name){ p= cur_section_name; /*94:*/ -#line 1426 "ctangle.w" +#line 1419 "ctangle.w" while((next_control= get_next())=='+'); if(next_control!='='&&next_control!=eq_eq) continue; /*:94*/ -#line 1379 "ctangle.w" +#line 1370 "ctangle.w" break; } @@ -1506,20 +1497,20 @@ return; } no_where= print_where= false; /*95:*/ -#line 1431 "ctangle.w" +#line 1424 "ctangle.w" /*96:*/ -#line 1436 "ctangle.w" +#line 1429 "ctangle.w" store_two_bytes((sixteen_bits)(0150000+section_count)); /*:96*/ -#line 1432 "ctangle.w" +#line 1425 "ctangle.w" scan_repl(section_name); /*97:*/ -#line 1440 "ctangle.w" +#line 1433 "ctangle.w" if(p==name_dir||p==0){ (last_unnamed)->text_link= cur_text-text_info;last_unnamed= cur_text; @@ -1536,16 +1527,16 @@ cur_text->text_link= section_flag; /*:97*/ -#line 1434 "ctangle.w" +#line 1427 "ctangle.w" /*:95*/ -#line 1385 "ctangle.w" +#line 1376 "ctangle.w" } -/*:91*//*99:*/ -#line 1458 "ctangle.w" +/*:90*//*98:*/ +#line 1448 "ctangle.w" static void phase_one(void){ @@ -1558,8 +1549,8 @@ check_complete(); phase= 2; } -/*:99*//*101:*/ -#line 1476 "ctangle.w" +/*:98*//*100:*/ +#line 1465 "ctangle.w" static void skip_limbo(void) @@ -1574,7 +1565,7 @@ c= *loc++; if(ccode[(eight_bits)c]==new_section)break; switch(ccode[(eight_bits)c]){ case translit_code:/*102:*/ -#line 1505 "ctangle.w" +#line 1496 "ctangle.w" while(xisspace(*loc)&&loc@/ @h @@/ @@/ -@@/ -@@/ +@@/ +@ @ \.{CTANGLE} has a fairly straightforward outline. It operates in two phases: First it reads the source file, saving the \CEE/ code in @@ -126,13 +126,13 @@ typedef struct { } text; typedef text *text_pointer; -@ @= -text text_info[max_texts]; -text_pointer text_info_end=text_info+max_texts-1; -text_pointer text_ptr; /* first unused position in |text_info| */ -eight_bits tok_mem[max_toks]; -eight_bits *tok_mem_end=tok_mem+max_toks-1; -eight_bits *tok_ptr; /* first unused position in |tok_mem| */ +@ @= +static text text_info[max_texts]; +static text_pointer text_info_end=text_info+max_texts-1; +static text_pointer text_ptr; /* first unused position in |text_info| */ +static eight_bits tok_mem[max_toks]; +static eight_bits *tok_mem_end=tok_mem+max_toks-1; +static eight_bits *tok_ptr; /* first unused position in |tok_mem| */ @ @= text_info->tok_start=tok_ptr=tok_mem; @@ -195,8 +195,8 @@ The replacement text pointer for the first unnamed section appears in @d section_flag max_texts /* final |text_link| in section replacement texts */ -@= -text_pointer last_unnamed; /* most recent replacement text of unnamed section */ +@= +static text_pointer last_unnamed; /* most recent replacement text of unnamed section */ @ @= last_unnamed=text_info; text_info->text_link=0; @@ -228,11 +228,8 @@ construction or numerical constant. @ The following procedure is used to enter a two-byte value into |tok_mem| when a replacement text is being generated. -@= -static void store_two_bytes(sixteen_bits);@/ - -@ @c -void +@c +static void store_two_bytes( sixteen_bits x) { @@ -241,6 +238,8 @@ sixteen_bits x) *tok_ptr++=x&0377; /* store low byte */ } +@ @=@+static void store_two_bytes(sixteen_bits); + @** 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: @@ -283,12 +282,12 @@ typedef output_state *stack_pointer; @d cur_repl cur_state.repl_field /* pointer to current replacement text */ @d cur_section cur_state.section_field /* current section number being expanded */ -@= -output_state cur_state; /* |cur_end|, |cur_byte|, |cur_name|, |cur_repl|, +@= +static output_state cur_state; /* |cur_end|, |cur_byte|, |cur_name|, |cur_repl|, and |cur_section| */ -output_state stack[stack_size+1]; /* info for non-current levels */ -stack_pointer stack_end=stack+stack_size; /* end of |stack| */ -stack_pointer stack_ptr; /* first unused location in the output state stack */ +static output_state stack[stack_size+1]; /* 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 */ @ To get the output process started, we will perform the following initialization steps. We may assume that |text_info->text_link| is nonzero, @@ -307,11 +306,7 @@ the new one going. We assume that the \CEE/ compiler can copy structures. @^system dependencies@> -@= -static void push_level(name_pointer);@/ -static void pop_level(boolean);@/ - -@ @c +@c static void push_level(@t\1\1@> /* suspends the current level */ name_pointer p@t\2\2@>) @@ -326,6 +321,10 @@ name_pointer p@t\2\2@>) } } +@ @= +static void push_level(name_pointer);@/ +static void pop_level(boolean); + @ When we come to the end of a replacement text, the |pop_level| subroutine does the right thing: It either moves to the continuation of this replacement text or returns the state to the most recently stacked level. @@ -359,17 +358,14 @@ if the next output is an identifier, in which case @d section_number 0201 /* code returned by |get_output| for section numbers */ @d identifier 0202 /* code returned by |get_output| for identifiers */ -@= -int cur_val; /* additional information corresponding to output token */ +@= +static int cur_val; /* additional information corresponding to output token */ @ If |get_output| finds that no more output remains, it returns with |stack_ptr==stack|. @^high-bit character handling@> -@= -static void get_output(void);@/ - -@ @c +@c static void get_output(void) /* sends next token to |out_char| */ { @@ -398,6 +394,8 @@ get_output(void) /* sends next token to |out_char| */ } } +@ @=@+static void get_output(void); + @ The user may have forgotten to give any \CEE/ text for a section name, or the \CEE/ text may have been associated with a different name by mistake. @@ -451,18 +449,15 @@ are preceded by a `\.\\'. @d unbreakable 3 /* state associated with \.{@@\&} */ @d verbatim 4 /* state in the middle of a string */ -@= -eight_bits out_state; /* current status of partial output */ -boolean protect; /* should newline characters be quoted? */ +@= +static eight_bits out_state; /* current status of partial output */ +static boolean protect; /* should newline characters be quoted? */ @ Here is a routine that is invoked when we want to output the current line. During the output process, |cur_line| equals the number of the next line to be output. -@= -static void flush_buffer(void);@/ - -@ @c +@c static void flush_buffer(void) /* writes one line to output file */ { @@ -475,6 +470,8 @@ flush_buffer(void) /* writes one line to output file */ cur_line++; } +@ @=@+static void flush_buffer(void); + @ Second, we have modified the original \.{TANGLE} so that it will write output on multiple files. If a section name is introduced in at least one place by \.{@@(} @@ -483,11 +480,11 @@ All these special sections are saved on a stack, |output_files|. We write them out after we've done the unnamed section. @d max_files 256 -@= -name_pointer output_files[max_files]; -name_pointer *cur_out_file, *end_output_files, *an_output_file; -char cur_section_name_char; /* is it |'<'| or |'('| */ -char output_file_name[longest_name+1]; /* name of the file */ +@= +static name_pointer output_files[max_files]; +static name_pointer *cur_out_file, *end_output_files, *an_output_file; +static char cur_section_name_char; /* is it |'<'| or |'('| */ +static char output_file_name[longest_name+1]; /* name of the file */ @ We make |end_output_files| point just beyond the end of |output_files|. The stack pointer @@ -514,10 +511,7 @@ complain we're out of room@>= @* The big output switch. Here then is the routine that does the output. -@= -static void phase_two(void);@/ - -@ @c +@c static void phase_two (void) { web_file_open=false; @@ -552,6 +546,8 @@ writeloop: @@; } } +@ @=@+static void phase_two(void); + @ To write the named output files, we proceed as for the unnamed section. The only subtlety is that we have to open each one. @@ -583,12 +579,12 @@ that refer to macros, preceded by the \.{\#define} preprocessor command. if (!output_defs_seen) output_defs(); -@ @= -boolean output_defs_seen=false; +@ @= +static boolean output_defs_seen=false; @ @= static void output_defs(void);@/ -static void out_char(eight_bits);@/ +static void out_char(eight_bits); @ @c static void @@ -692,8 +688,8 @@ This makes debugging a lot less confusing. @d translit_length 10 -@= -char translit[128][translit_length]; +@= +static char translit[128][translit_length]; @ @= { @@ -771,8 +767,8 @@ milestones. @d section_name 0311 /* control code for `\.{@@<}' */ @d new_section 0312 /* control code for `\.{@@\ }' and `\.{@@*}' */ -@= -eight_bits ccode[256]; /* meaning of a char following \.{@@} */ +@= +static eight_bits ccode[256]; /* meaning of a char following \.{@@} */ @ @= { int c; /* must be |int| so the |for| loop will end */ @@ -795,11 +791,7 @@ eight_bits ccode[256]; /* meaning of a char following \.{@@} */ @ The |skip_ahead| procedure reads through the input at fairly high speed until finding the next non-ignorable control code, which it returns. -@= -static eight_bits skip_ahead(void);@/ -static boolean skip_comment(boolean);@/ - -@ @c +@c static eight_bits skip_ahead(void) /* skip to next control code */ { @@ -815,6 +807,10 @@ skip_ahead(void) /* skip to next control code */ } } +@ @= +static eight_bits skip_ahead(void);@/ +static boolean skip_comment(boolean); + @ The |skip_comment| procedure reads through the input at somewhat high speed in order to pass over comments, which \.{CTANGLE} does not transmit to the output. If the comment is introduced by \.{/*}, |skip_comment| @@ -831,8 +827,8 @@ the two types of comments. If |skip_comment| comes to the end of the section, it prints an error message. No comment, long or short, is allowed to contain `\.{@@\ }' or `\.{@@*}'. -@= -boolean comment_continues=false; /* are we scanning a comment? */ +@= +static boolean comment_continues=false; /* are we scanning a comment? */ @ @c static boolean skip_comment(@t\1\1@> /* skips over comments */ @@ -870,9 +866,9 @@ boolean is_long_comment@t\2\2@>) @d constant 03 -@= -name_pointer cur_section_name; /* name of section just scanned */ -boolean no_where; /* suppress |print_where|? */ +@= +static name_pointer cur_section_name; /* name of section just scanned */ +static boolean no_where; /* suppress |print_where|? */ @ As one might expect, |get_next| consists mostly of a big switch that branches to the various special cases that can arise. @@ -882,10 +878,7 @@ that branches to the various special cases that can arise. @d ishigh(c) ((eight_bits)(c)>0177) @^high-bit character handling@> -@= -static eight_bits get_next(void);@/ - -@ @c +@c static eight_bits get_next(void) /* produces the next input token */ { @@ -928,6 +921,8 @@ get_next(void) /* produces the next input token */ } } +@ @=@+static eight_bits get_next(void); + @ The following code assigns values to the combinations \.{++}, \.{--}, \.{->}, \.{>=}, \.{<=}, \.{==}, \.{<<}, \.{>>}, \.{!=}, \.{||} and \.{\&\&}, and to the \CPLUSPLUS/ @@ -1184,12 +1179,9 @@ acted, |cur_text| will point to the replacement text just generated, and @d macro 0 @d app_repl(c) {if (tok_ptr==tok_mem_end) overflow("token"); *tok_ptr++=c;} -@= -text_pointer cur_text; /* replacement text formed by |scan_repl| */ -eight_bits next_control; - -@ @= -static void scan_repl(eight_bits);@/ +@= +static text_pointer cur_text; /* replacement text formed by |scan_repl| */ +static eight_bits next_control; @ @c static void @@ -1213,6 +1205,8 @@ eight_bits t@t\2\2@>) cur_text=text_ptr; (++text_ptr)->tok_start=tok_ptr; } +@ @=@+static void scan_repl(eight_bits); + @ Here is the code for the line number: first a |sixteen_bits| equal to |0150000|; then the numeric line number; then a pointer to the file name. @@ -1236,7 +1230,7 @@ case identifier: a=id_lookup(id_first,id_loc,0)-name_dir; app_repl(a % 0400); break; case section_name: if (t!=section_name) goto done; else { - @@; + @@; a=cur_section_name-name_dir; app_repl((a / 0400)+0250); app_repl(a % 0400); @@ -1263,7 +1257,7 @@ case definition: case format_code: case begin_C: if (t!=section_name) goto done; } case new_section: goto done; -@ @= { +@ @= { char *try_loc=loc; while (*try_loc==' ' && try_loc= -static void scan_section(void);@/ - -@ The body of |scan_section| is a loop where we look for control codes +The body of |scan_section| is a loop where we look for control codes that are significant to \.{CTANGLE}: those that delimit a definition, the \CEE/ part of a module, or a new module. @@ -1385,6 +1376,8 @@ scan_section(void) @@; } +@ @=@+static void scan_section(void); + @ At the top of this loop, if |next_control==section_name|, the section name has already been scanned (see |@|). Thus, if we encounter |next_control==section_name| in the @@ -1452,9 +1445,6 @@ else { cur_text->text_link=section_flag; /* mark this replacement text as a nonmacro */ -@ @= -static void phase_one(void);@/ - @ @c static void phase_one(void) { @@ -1467,13 +1457,12 @@ phase_one(void) { phase=2; } +@ @=@+static void phase_one(void); + @ Only a small subset of the control codes is legal in limbo, so limbo processing is straightforward. -@= -static void skip_limbo(void);@/ - -@ @c +@c static void skip_limbo(void) { @@ -1502,6 +1491,8 @@ skip_limbo(void) } } +@ @=@+static void skip_limbo(void); + @ @= while(xisspace(*loc)&&locnum=0; /* sentinel value */ @x Section 30. (to please Borland's C++, version 4.02) -token tok_mem[max_toks]; /* tokens */ -token_pointer tok_mem_end = tok_mem+max_toks-1; /* end of |tok_mem| */ -token_pointer tok_ptr; /* first unused position in |tok_mem| */ -token_pointer max_tok_ptr; /* largest value of |tok_ptr| */ -token_pointer tok_start[max_texts]; /* directory into |tok_mem| */ -text_pointer tok_start_end = tok_start+max_texts-1; /* end of |tok_start| */ -text_pointer text_ptr; /* first unused position in |tok_start| */ -@y -token tok_mem[max_toks]; /* tokens */ -token_pointer tok_mem_end; /* end of |tok_mem| */ -token_pointer tok_ptr; /* first unused position in |tok_mem| */ -token_pointer max_tok_ptr; /* largest value of |tok_ptr| */ -token_pointer tok_start[max_texts]; /* directory into |tok_mem| */ -text_pointer tok_start_end; /* end of |tok_start| */ -text_pointer text_ptr; /* first unused position in |tok_start| */ +static token tok_mem[max_toks]; /* tokens */ +static token_pointer tok_mem_end = tok_mem+max_toks-1; /* end of |tok_mem| */ +static token_pointer tok_ptr; /* first unused position in |tok_mem| */ +static token_pointer max_tok_ptr; /* largest value of |tok_ptr| */ +static token_pointer tok_start[max_texts]; /* directory into |tok_mem| */ +static text_pointer tok_start_end = tok_start+max_texts-1; /* end of |tok_start| */ +static text_pointer text_ptr; /* first unused position in |tok_start| */ +@y +static token tok_mem[max_toks]; /* tokens */ +static token_pointer tok_mem_end; /* end of |tok_mem| */ +static token_pointer tok_ptr; /* first unused position in |tok_mem| */ +static token_pointer max_tok_ptr; /* largest value of |tok_ptr| */ +static token_pointer tok_start[max_texts]; /* directory into |tok_mem| */ +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) @@ -212,9 +212,9 @@ max_tok_ptr=tok_mem+1; max_text_ptr=tok_start+1; @x Section 246. -char *cur_byte; /* index into |byte_mem| */ +static char *cur_byte; /* index into |byte_mem| */ @y -char huge* cur_byte; /* index into |byte_mem| */ +static char huge* cur_byte; /* index into |byte_mem| */ @z diff --git a/cweav-man.ch b/cweav-man.ch index 83b14c9..b723609 100644 --- a/cweav-man.ch +++ b/cweav-man.ch @@ -16,7 +16,7 @@ under the terms of a permission notice identical to this one. } @y \def\botofcontents{\vfill\titlefalse} -\def\contentspagenumber{110} +\def\contentspagenumber{111} \def\title{APPENDIX F: CWEAVE} \let\K=\leftarrow @z diff --git a/cweav-pc.ch b/cweav-pc.ch index 2619998..b37f9f2 100644 --- a/cweav-pc.ch +++ b/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.1)" +@d banner "This is CWEAVE (Version 4.2)" @y -@d banner "This is CWEAVE (Version 4.1pc)" +@d banner "This is CWEAVE (Version 4.2pc)" @z @x section 4 diff --git a/cweav-ql.ch b/cweav-ql.ch index 28227af..28053eb 100644 --- a/cweav-ql.ch +++ b/cweav-ql.ch @@ -7,15 +7,15 @@ ex cc;"-v -h -c =500000 cweave_c" @x -\def\title{CWEAVE (Version 4.1)} +\def\title{CWEAVE (Version 4.2)} @y -\def\title{CWEAVE (QL Version 4.1)} +\def\title{CWEAVE (QL Version 4.2)} @z @x section 1 -@d banner "This is CWEAVE (Version 4.1)" +@d banner "This is CWEAVE (Version 4.2)" @y -@d banner "This is CWEAVE (QL Version 4.1)" +@d banner "This is CWEAVE (QL Version 4.2)" @z @x diff --git a/cweav-vms.ch b/cweav-vms.ch index ea35014..7d80d57 100644 --- a/cweav-vms.ch +++ b/cweav-vms.ch @@ -13,9 +13,9 @@ modified: (also modified by Don Knuth to keep version numbers uptodate) @x section 1 (01-FEB-1992 ST) -@d banner "This is CWEAVE (Version 4.1)" +@d banner "This is CWEAVE (Version 4.2)" @y -@d banner "This is CWEAVE (VAX/VMS Version 4.1)" +@d banner "This is CWEAVE (VAX/VMS Version 4.2)" @z @x section 3 (01-FEB-1992 ST) diff --git a/cweav-w32.ch b/cweav-w32.ch index 575387b..346d007 100644 --- a/cweav-w32.ch +++ b/cweav-w32.ch @@ -2,9 +2,9 @@ This is the change file for CWEB's CWEAVE under Win32 (Contributed by Fabrice Popineau, February 2002) @x section 1 -@d banner "This is CWEAVE (Version 4.1)" +@d banner "This is CWEAVE (Version 4.2)" @y -@d banner "This is CWEAVE (Version 4.1win32)" +@d banner "This is CWEAVE (Version 4.2win32)" @z @x diff --git a/cweave.w b/cweave.w index 8be3530..a8e3105 100644 --- a/cweave.w +++ b/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.1 --- February 2021 +% Version 4.2 --- February 2021 % 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.1)} +\def\title{CWEAVE (Version 4.2)} \def\topofcontents{\null\vfill \centerline{\titlefont The {\ttitlefont CWEAVE} processor} \vskip 15pt - \centerline{(Version 4.1)} + \centerline{(Version 4.2)} \vfill} \def\botofcontents{\vfill \noindent @@ -67,13 +67,13 @@ 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.1)" +@d banner "This is CWEAVE (Version 4.2)" @c @@/ @h @@/ @@/ -@@/ +@@/ @ @ \.{CWEAVE} has a fairly straightforward outline. It operates in @@ -99,6 +99,7 @@ char **av@t\2\2@>) /* 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==2 && !show_progress) new_line; return wrap_up(); /* and exit gracefully */ } @@ -181,8 +182,8 @@ is the total number of sections that have started. Sections which have been altered by a change file entry have their |changed_section| flag turned on during the first phase. -@= -boolean change_exists; /* has any section changed? */ +@= +static boolean change_exists; /* has any section changed? */ @ The other large memory area in \.{CWEAVE} keeps the cross-reference data. All uses of the name |p| are recorded in a linked list beginning at @@ -213,11 +214,11 @@ typedef struct xref_info { } xref_info; typedef xref_info *xref_pointer; -@ @= -xref_info xmem[max_refs]; /* contains cross-reference information */ -xref_pointer xmem_end = xmem+max_refs-1; -xref_pointer xref_ptr; /* the largest occupied position in |xmem| */ -sixteen_bits xref_switch,section_xref_switch; /* either zero or |def_flag| */ +@ @= +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| */ +static sixteen_bits xref_switch,section_xref_switch; /* either zero or |def_flag| */ @ A section that is used for multi-file output (with the \.{@@(} feature) has a special first cross-reference whose |num| field is |file_flag|. @@ -250,7 +251,7 @@ If one were careful, one could probably make more changes around section @= static void new_xref(name_pointer);@/ static void new_section_xref(name_pointer);@/ -static void set_file_flag(name_pointer);@/ +static void set_file_flag(name_pointer); @ @c static void @@ -332,15 +333,15 @@ that is unoccupied by replacement text is called |tok_ptr|, and the first unused location of |tok_start| is called |text_ptr|. Thus, we usually have |*text_ptr==tok_ptr|. -@= -token tok_mem[max_toks]; /* tokens */ -token_pointer tok_mem_end = tok_mem+max_toks-1; /* end of |tok_mem| */ -token_pointer tok_ptr; /* first unused position in |tok_mem| */ -token_pointer max_tok_ptr; /* largest value of |tok_ptr| */ -token_pointer tok_start[max_texts]; /* directory into |tok_mem| */ -text_pointer tok_start_end = tok_start+max_texts-1; /* end of |tok_start| */ -text_pointer text_ptr; /* first unused position in |tok_start| */ -text_pointer max_text_ptr; /* largest value of |text_ptr| */ +@= +static token tok_mem[max_toks]; /* tokens */ +static token_pointer tok_mem_end = tok_mem+max_toks-1; /* end of |tok_mem| */ +static token_pointer tok_ptr; /* first unused position in |tok_mem| */ +static token_pointer max_tok_ptr; /* largest value of |tok_ptr| */ +static token_pointer tok_start[max_texts]; /* directory into |tok_mem| */ +static text_pointer tok_start_end = tok_start+max_texts-1; /* end of |tok_start| */ +static text_pointer text_ptr; /* first unused position in |tok_start| */ +static text_pointer max_text_ptr; /* largest value of |text_ptr| */ @ @= tok_ptr=max_tok_ptr=tok_mem+1;@/ @@ -382,8 +383,7 @@ name_pointer p) p->xref=(void *)xref_ptr; } -@ @= -static void update_node(name_pointer p);@/ +@ @=@+static void update_node(name_pointer p); @ We have to get \CEE/'s reserved words into the hash table, and the simplest way to do this is @@ -489,8 +489,7 @@ id_lookup("volatile",NULL,const_like); id_lookup("wchar_t",NULL,raw_int); id_lookup("while",NULL,for_like); id_lookup("xor",NULL,alfop); -id_lookup("xor_eq",NULL,alfop); -res_wd_end=name_ptr; +id_lookup("xor_eq",NULL,alfop);@+ res_wd_end=name_ptr; id_lookup("TeX",NULL,custom); id_lookup("make_pair",NULL,func_template); @@ -546,8 +545,8 @@ scanning routines. @ Control codes are converted to \.{CWEAVE}'s internal representation by means of the table |ccode|. -@= -eight_bits ccode[256]; /* meaning of a char following \.{@@} */ +@= +static eight_bits ccode[256]; /* meaning of a char following \.{@@} */ @ @= {int c; for (c=0; c<256; c++) ccode[c]=0;} @@ -589,7 +588,7 @@ interpretation of identifiers. @= static void skip_limbo(void);@/ -static eight_bits skip_TeX(void);@/ +static eight_bits skip_TeX(void); @ @c static void @@ -597,7 +596,7 @@ skip_limbo(void) { while(true) { if (loc>limit && get_line()==false) return; *(limit+1)='@@'; - while (*loc!='@@') loc++; /* look for '@@', then skip two chars */ + while (*loc!='@@') loc++; /* look for `\.{@@}', then skip two chars */ if (loc++ <=limit) { int c=ccode[(eight_bits)*loc++]; if (c==new_section) return; if (c==noop) skip_restricted(); @@ -666,9 +665,9 @@ it sets |xref_switch| to |def_flag| and goes on to the next token. @d string 0201 /* \CEE/ string */ @d identifier 0202 /* \CEE/ identifier or reserved word */ -@= -name_pointer cur_section; /* name of section just scanned */ -char cur_section_char; /* the character just before that name */ +@= +static name_pointer cur_section; /* name of section just scanned */ +static char cur_section_char; /* the character just before that name */ @ As one might expect, |get_next| consists mostly of a big switch that branches to the various special cases that can arise. @@ -680,10 +679,7 @@ compilers even allow the dollar sign. @d ishigh(c) ((eight_bits)(c)>0177) @^high-bit character handling@> -@= -static eight_bits get_next(void);@/ - -@ @c +@c static eight_bits get_next(void) /* produces the next input token */ { @@ -708,6 +704,8 @@ get_next(void) /* produces the next input token */ } } +@ @=@+static eight_bits get_next(void); + @ Because preprocessor commands do not fit in with the rest of the syntax of \CEE/, we have to deal with them separately. One solution is to enclose such @@ -721,8 +719,8 @@ for |ord|, since |get_next| changes |ord| into a string. @d left_preproc ord /* begins a preprocessor command */ @d right_preproc 0217 /* ends a preprocessor command */ -@= -boolean preprocessing=false; /* are we scanning a preprocessor command? */ +@= +static boolean preprocessing=false; /* are we scanning a preprocessor command? */ @ @= { preprocessing=true; @@ -734,8 +732,8 @@ boolean preprocessing=false; /* are we scanning a preprocessor command? */ a file name in lines that start with \.{\#include}. We must treat this file name as a string. -@= -boolean sharp_include_line=false; /* are we scanning a |#include| line? */ +@= +static boolean sharp_include_line=false; /* are we scanning a \&{\#include} line? */ @ @= while (loc<=buffer_end-7 && xisspace(*loc)) loc++; @@ -844,7 +842,7 @@ convention, but do not allow the string to be longer than |longest_name|. if (delim=='u' && *loc=='8') { *++id_loc=*loc++; } delim=*loc++; *++id_loc=delim; } - if (delim=='<') delim='>'; /* for file names in |#include| lines */ + if (delim=='<') delim='>'; /* for file names in \&{\#include} lines */ while (true) { if (loc>=limit) { if(*(limit-1)!='\\') { @@ -960,10 +958,7 @@ if (c=='@@') { @ This function skips over a restricted context at relatively high speed. -@= -static void skip_restricted(void);@/ - -@ @c +@c static void skip_restricted(void) { @@ -983,6 +978,8 @@ false_alarm: } } +@ @=@+static void skip_restricted(void); + @ At the present point in the program we have |*(loc-1)==verbatim|; we set |id_first| to the beginning of the string itself, and |id_loc| to its ending-plus-one location in the @@ -1007,16 +1004,13 @@ The global variable |next_control| often contains the most recent output of |get_next|; in interesting cases, this will be the control code that ended a section or part of a section. -@= -eight_bits next_control; /* control code waiting to be acting upon */ +@= +static eight_bits next_control; /* control code waiting to be acting upon */ @ The overall processing strategy in phase one has the following straightforward outline. -@= -static void phase_one(void);@/ - -@ @c +@c static void phase_one(void) { phase=1; reset_input(); section_count=0; @@ -1029,6 +1023,8 @@ phase_one(void) { @@; } +@ @=@+static void phase_one(void); + @ @= { if (++section_count==max_sections) overflow("section number"); @@ -1067,7 +1063,7 @@ as well as |normal==0|. @= static void C_xref(eight_bits);@/ -static void outer_xref(void);@/ +static void outer_xref(void); @ @c static void @@ -1161,9 +1157,9 @@ entirely, even if it contains \pb\ constructions. The variables |lhs| and |rhs| point to the respective identifiers involved in a format definition. -@= -name_pointer lhs, rhs; /* pointers to |byte_start| for format identifiers */ -name_pointer res_wd_end; /* pointer to the first nonreserved identifier */ +@= +static name_pointer lhs, rhs; /* pointers to |byte_start| for format identifiers */ +static name_pointer res_wd_end; /* pointer to the first nonreserved identifier */ @ When we get to the following code we have |next_control>=format_code|. @@ -1245,18 +1241,15 @@ if (next_control<=section_name) { /* |begin_C| or |section_name| */ section name was both defined and used. The variable |cur_xref| will point to cross-references for the current section name of interest. -@= -xref_pointer cur_xref; /* temporary cross-reference pointer */ -boolean an_output; /* did |file_flag| precede |cur_xref|? */ +@= +static xref_pointer cur_xref; /* temporary cross-reference pointer */ +static boolean an_output; /* did |file_flag| precede |cur_xref|? */ @ The following recursive procedure walks through the tree of section names and prints out anomalies. @^recursion@> -@= -static void section_check(name_pointer);@/ - -@ @c +@c static void section_check( name_pointer p) /* print anomalies in subtree |p| */ @@ -1281,6 +1274,8 @@ name_pointer p) /* print anomalies in subtree |p| */ } } +@ @=@+static void section_check(name_pointer); + @ @=section_check(root); @* Low-level output routines. @@ -1289,11 +1284,11 @@ 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. -@= -char out_buf[line_length+1]; /* assembled characters */ -char *out_buf_end = out_buf+line_length; /* end of |out_buf| */ -char *out_ptr; /* last character in |out_buf| */ -int out_line; /* number of next line to be output */ +@= +static char out_buf[line_length+1]; /* assembled characters */ +static char *out_buf_end = out_buf+line_length; /* end of |out_buf| */ +static char *out_ptr; /* last character in |out_buf| */ +static int out_line; /* number of next line to be output */ @ The |flush_buffer| routine empties the buffer up to a given breakpoint, and moves any remaining characters to the beginning of the next line. @@ -1314,7 +1309,7 @@ of commented-out text). @= static void flush_buffer(char *,boolean,boolean);@/ -static void finish_line(void);@/ +static void finish_line(void); @ @c static void @@ -1379,7 +1374,7 @@ A line break will occur at a space or after a single-nonletter @= static void out_str(const char *);@/ -static void break_out(void);@/ +static void break_out(void); @ @c static void @@ -1437,7 +1432,7 @@ the section is changed, we output `\.{\\*}' just after the number. @= static void out_section(sixteen_bits);@/ -static void out_name(name_pointer,boolean);@/ +static void out_name(name_pointer,boolean); @ @c static void @@ -1484,7 +1479,7 @@ The use of `\.{@@}' signs is severely restricted in such material: @= static void copy_limbo(void);@/ static eight_bits copy_TeX(void);@/ -static int copy_comment(boolean,int);@/ +static int copy_comment(boolean,int); @ @c static void @@ -1716,8 +1711,8 @@ same initial letter; these subscripts are assigned from left to right. @d begin_arg 61 /* \.{@@[} */ @d end_arg 62 /* \.{@@]} */ -@= -char cat_name[256][12]; +@= +static char cat_name[256][12]; @ @= {int c; for (c=0;c<256;c++) strcpy(cat_name[c],"UNKNOWN");} @@ -1783,10 +1778,7 @@ char cat_name[256][12]; @ This code allows \.{CWEAVE} to display its parsing steps. -@= -static void print_cat(eight_bits);@/ - -@ @c +@c static void print_cat(@t\1\1@> /* symbolic printout of a category */ eight_bits c@t\2\2@>) @@ -1794,6 +1786,8 @@ eight_bits c@t\2\2@>) fputs(cat_name[c],stdout); } +@ @=@+static void print_cat(eight_bits); + @ The token lists for translated \TEX/ output contain some special control symbols as well as ordinary characters. These control symbols are interpreted by \.{CWEAVE} before they are written to the output file. @@ -2104,15 +2098,15 @@ typedef scrap *scrap_pointer; @ @d trans trans_plus.Trans /* translation texts of scraps */ -@= -scrap scrap_info[max_scraps]; /* memory array for scraps */ -scrap_pointer scrap_info_end=scrap_info+max_scraps-1; /* end of |scrap_info| */ -scrap_pointer scrap_base; /* beginning of the current scrap sequence */ -scrap_pointer scrap_ptr; /* ending of the current scrap sequence */ -scrap_pointer max_scr_ptr; /* largest value assumed by |scrap_ptr| */ -scrap_pointer pp; /* current position for reducing productions */ -scrap_pointer lo_ptr; /* last scrap that has been examined */ -scrap_pointer hi_ptr; /* first scrap that has not been examined */ +@= +static scrap scrap_info[max_scraps]; /* memory array for scraps */ +static scrap_pointer scrap_info_end=scrap_info+max_scraps-1; /* end of |scrap_info| */ +static scrap_pointer scrap_base; /* beginning of the current scrap sequence */ +static scrap_pointer scrap_ptr; /* ending of the current scrap sequence */ +static scrap_pointer max_scr_ptr; /* largest value assumed by |scrap_ptr| */ +static scrap_pointer pp; /* current position for reducing productions */ +static scrap_pointer lo_ptr; /* last scrap that has been examined */ +static scrap_pointer hi_ptr; /* first scrap that has not been examined */ @ @= scrap_base=scrap_info+1; @@ -2141,10 +2135,7 @@ 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' */ -@= -static void print_text(text_pointer p);@/ - -@ @c +@c static void print_text(@t\1\1@> /* prints a token list for debugging; not used in |main| */ text_pointer p@t\2\2@>) @@ -2169,6 +2160,8 @@ text_pointer p@t\2\2@>) update_terminal; } +@ @=@+static void print_text(text_pointer p); + @ @= switch (r) { case math_rel: printf("\\mathrel{"@q}@>); break; @@ -2265,13 +2258,13 @@ productions as they were listed earlier. @d app(a) *(tok_ptr++)=(token)(a) @d app1(a) *(tok_ptr++)=(token)(tok_flag+(int)((a)->trans-tok_start)) -@= -int cur_mathness, init_mathness; +@= +static int cur_mathness, init_mathness; @ @= static void app_str(const char *);@/ static void big_app(token);@/ -static void big_app1(scrap_pointer);@/ +static void big_app1(scrap_pointer); @ @c static void @@ -2428,7 +2421,7 @@ more properly alpha\-betized, static token_pointer find_first_ident(text_pointer);@/ static void make_reserved(scrap_pointer);@/ static void make_underlined(scrap_pointer);@/ -static void underline_xref(name_pointer);@/ +static void underline_xref(name_pointer); @ @c static token_pointer @@ -3022,7 +3015,7 @@ too large, since it is assumed that this test was done beforehand. @= static void reduce(scrap_pointer,short,eight_bits,short,short);@/ -static void squash(scrap_pointer,short,eight_bits,short,short);@/ +static void squash(scrap_pointer,short,eight_bits,short,short); @ @c static void @@ -3114,8 +3107,8 @@ current stack categories will be printed out when |tracing| is set to 2; a sequence of two or more irreducible scraps will be printed out when |tracing| is set to 1. -@= -int tracing; /* can be used to show parsing details */ +@= +static int tracing; /* can be used to show parsing details */ @ @= { scrap_pointer k_l; /* pointer into |scrap_info| */ @@ -3146,10 +3139,7 @@ lists with up to six tokens without checking for overflow. Before calling since |translate| might add a new text and a new scrap before it checks for overflow. -@= -static text_pointer translate(void);@/ - -@ @c +@c static text_pointer translate(void) /* converts a sequence of scraps */ { @@ -3161,6 +3151,8 @@ translate(void) /* converts a sequence of scraps */ @@; } +@ @=@+static text_pointer translate(void); + @ If the initial sequence of scraps does not reduce to a single scrap, we concatenate the translations of all remaining scraps, separated by blank spaces, with dollar signs surrounding the translations of scraps @@ -3214,10 +3206,7 @@ repeatedly to read \CEE/ text until encountering the next `\.{\v}' or what it reads are appended into the |cat| and |trans| arrays, and |scrap_ptr| is advanced. -@= -static void C_parse(eight_bits);@/ - -@ @c +@c static void C_parse(@t\1\1@> /* creates scraps from \CEE/ tokens */ eight_bits spec_ctrl@t\2\2@>) @@ -3231,6 +3220,8 @@ C_parse(@t\1\1@> /* creates scraps from \CEE/ tokens */ } } +@ @=@+static void C_parse(eight_bits); + @ The following macro is used to append a scrap whose tokens have just been appended: @@ -3452,7 +3443,7 @@ token list; it also builds a new scrap if |scrapping==true|. @= static void app_cur_id(boolean);@/ static text_pointer C_translate(void);@/ -static void outer_parse(void);@/ +static void outer_parse(void); @ @c static void @@ -3604,12 +3595,12 @@ typedef output_state *stack_pointer; @d cur_mode cur_state.mode_field /* current mode of interpretation */ @d init_stack stack_ptr=stack;cur_mode=outer /* initialize the stack */ -@= -output_state cur_state; /* |cur_end|, |cur_tok|, |cur_mode| */ -output_state stack[stack_size]; /* info for non-current levels */ -stack_pointer stack_end=stack+stack_size-1; /* end of |stack| */ -stack_pointer stack_ptr; /* first unused location in the output state stack */ -stack_pointer max_stack_ptr; /* largest value assumed by |stack_ptr| */ +@= +static output_state cur_state; /* |cur_end|, |cur_tok|, |cur_mode| */ +static output_state stack[stack_size]; /* 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| */ @ @= max_stack_ptr=stack; @@ -3620,7 +3611,7 @@ The value of |cur_mode| is not changed. @= static void push_level(text_pointer);@/ -static void pop_level(void);@/ +static void pop_level(void); @ @c static void @@ -3658,8 +3649,8 @@ by a complex routine that might generate additional levels of output). In these cases |cur_name| points to the identifier or section name in question. -@= -name_pointer cur_name; +@= +static name_pointer cur_name; @ @d res_word 0201 /* returned by |get_output| for reserved words */ @d section_code 0200 /* returned by |get_output| for section names */ @@ -3667,7 +3658,7 @@ name_pointer cur_name; @= static eight_bits get_output(void);@/ static void output_C(void);@/ -static void make_output(void);@/ +static void make_output(void); @ @c static eight_bits @@ -3990,10 +3981,7 @@ is analogous to phase one, except that more work is involved because we must actually output the \TEX/ material instead of merely looking at the \.{CWEB} specifications. -@= -static void phase_two(void);@/ - -@ @c +@c static void phase_two(void) { reset_input(); if (show_progress) fputs("\nWriting the output file...",stdout); @@ -4003,6 +3991,8 @@ finish_line(); flush_buffer(out_buf,false,false); /* insert a blank line, it loo while (!input_has_ended) @@; } +@ @=@+static void phase_two(void); + @ The output file will contain the control sequence \.{\\Y} between non-null sections of a section, e.g., between the \TEX/ and definition parts if both are nonempty. This puts a little white space between the parts when they are @@ -4017,14 +4007,14 @@ and `|emit_space_if_needed|' are able to handle the situation: space_checked=true; @.\\Y@> -@= -int save_line; /* former value of |out_line| */ -char *save_place; /* former value of |out_ptr| */ -int sec_depth; /* the integer, if any, following \.{@@*} */ -boolean space_checked; /* have we done |emit_space_if_needed|? */ -boolean format_visible; /* should the next format declaration be output? */ -boolean doing_format=false; /* are we outputting a format declaration? */ -boolean group_found=false; /* has a starred section occurred? */ +@= +static int save_line; /* former value of |out_line| */ +static char *save_place; /* former value of |out_ptr| */ +static int sec_depth; /* the integer, if any, following \.{@@*} */ +static boolean space_checked; /* have we done |emit_space_if_needed|? */ +static boolean format_visible; /* should the next format declaration be output? */ +static boolean doing_format=false; /* are we outputting a format declaration? */ +static boolean group_found=false; /* has a starred section occurred? */ @ @= { section_count++; @@ -4113,10 +4103,7 @@ takes place, so that the translation will normally end with \.{\\6} or \.{\\7} (the \TEX/ macros for |force| and |big_force|). This \.{\\6} or \.{\\7} is replaced by the concluding \.{\\par} or by \.{\\Y\\par}. -@= -static void finish_C(boolean);@/ - -@ @c +@c static void finish_C(@t\1\1@> /* finishes a definition or a \CEE/ part */ boolean visible@t\2\2@>) /* nonzero if we should produce \TeX\ output */ @@ -4145,6 +4132,8 @@ finish_C(@t\1\1@> /* finishes a definition or a \CEE/ part */ /* forget the tokens and the scraps */ } +@ @=@+static void finish_C(boolean); + @ Keeping in line with the conventions of the \CEE/ preprocessor (and otherwise contrary to the rules of \.{CWEB}) we distinguish here between the case that `\.(' immediately follows an identifier and the @@ -4202,8 +4191,8 @@ it starts after we scan the matching `\.)'. |next_control>=begin_C|. We will make the global variable |this_section| point to the current section name, if it has a name. -@= -name_pointer this_section; /* the current section name, or zero */ +@= +static name_pointer this_section; /* the current section name, or zero */ @ @= this_section=name_dir; @@ -4286,10 +4275,7 @@ leaves |cur_xref| pointing to the first element not printed. Typical outputs: Note that the output of \.{CWEAVE} is not English-specific; users may supply new definitions for the macros \.{\\A}, \.{\\As}, etc. -@= -static void footnote(sixteen_bits);@/ - -@ @c +@c static void footnote(@t\1\1@> /* outputs section cross-references */ sixteen_bits flag@t\2\2@>) @@ -4305,6 +4291,8 @@ sixteen_bits flag@t\2\2@>) out('.'); } +@ @=@+static void footnote(sixteen_bits); + @ The following code distinguishes three cases, according as the number of cross-references is one, two, or more than two. Variable |q| points to the first cross-reference, and the last link is a zero. @@ -4335,10 +4323,7 @@ If the user has set the |no_xref| flag (the \.{-x} option on the command line), just finish off the page, omitting the index, section name list, and table of contents. -@= -static void phase_three(void);@/ - -@ @c +@c static void phase_three(void) { if (no_xref) { @@ -4386,11 +4371,13 @@ if (show_happiness) { check_complete(); /* was all of the change file used? */ } +@ @=@+static void phase_three(void); + @ Just before the index comes a list of all the changed sections, including the index section itself. -@= -sixteen_bits k_section; /* runs through the sections */ +@= +static sixteen_bits k_section; /* runs through the sections */ @ @= { /* remember that the index is already marked as changed */ @@ -4415,10 +4402,10 @@ letters, since we want to have `$t<\\{TeX}<\&{to}$'.) The list for character |c| begins at location |bucket[c]| and continues through the |blink| array. -@= -name_pointer bucket[256]; -name_pointer next_name; /* successor of |cur_name| when sorting */ -name_pointer blink[max_names]; /* links in the buckets */ +@= +static name_pointer bucket[256]; +static name_pointer next_name; /* successor of |cur_name| when sorting */ +static name_pointer blink[max_names]; /* links in the buckets */ @ To begin the sorting, we go through all the hash lists and put each entry having a nonempty cross-reference list into the proper bucket. @@ -4458,11 +4445,11 @@ name_pointer Head; @d sort_ptr scrap_ptr /* ditto */ @d max_sorts max_scraps /* ditto */ -@= -eight_bits cur_depth; /* depth of current buckets */ -char *cur_byte; /* index into |byte_mem| */ -sixteen_bits cur_val; /* current cross-reference number */ -sort_pointer max_sort_ptr; /* largest value of |sort_ptr| */ +@= +static eight_bits cur_depth; /* depth of current buckets */ +static char *cur_byte; /* index into |byte_mem| */ +static sixteen_bits cur_val; /* current cross-reference number */ +static sort_pointer max_sort_ptr; /* largest value of |sort_ptr| */ @ @= max_sort_ptr=scrap_info; @@ -4470,8 +4457,8 @@ max_sort_ptr=scrap_info; @ The desired alphabetic order is specified by the |collate| array; namely, $|collate|[0]<|collate|[1]<\cdots<|collate|[100]$. -@= -eight_bits collate[101+128]; /* collation order */ +@= +static eight_bits collate[101+128]; /* collation order */ @^high-bit character handling@> @ We use the order $\hbox{null}<\.\ <\hbox{other characters}<{}$\.\_${}< @@ -4530,10 +4517,7 @@ regarded as identical. @d infinity 255 /* $\infty$ (approximately) */ -@= -static void unbucket(eight_bits);@/ - -@ @c +@c static void unbucket(@t\1\1@> /* empties buckets having depth |d| */ eight_bits d@t\2\2@>) @@ -4551,6 +4535,8 @@ eight_bits d@t\2\2@>) } } +@ @=@+static void unbucket(eight_bits); + @ @= sort_ptr=scrap_info; unbucket(1); while (sort_ptr>scrap_info) { @@ -4635,8 +4621,8 @@ out('.'); finish_line(); @ List inversion is best thought of as popping elements off one stack and pushing them onto another. In this case |cur_xref| will be the head of the stack that we push things onto. -@= -xref_pointer next_xref, this_xref; +@= +static xref_pointer next_xref, this_xref; /* pointer variables for rearranging a list */ @ @= @@ -4650,10 +4636,7 @@ do { prints them. @^recursion@> -@= -static void section_print(name_pointer);@/ - -@ @c +@c static void section_print(@t\1\1@> /* print all section names in subtree |p| */ name_pointer p@t\2\2@>) @@ -4670,6 +4653,8 @@ name_pointer p@t\2\2@>) } } +@ @=@+static void section_print(name_pointer); + @ @=section_print(root); @ Because on some systems the difference between two pointers is a |ptrdiff_t| diff --git a/cwebmac.tex b/cwebmac.tex index 8b49cab..385dc47 100644 --- a/cwebmac.tex +++ b/cwebmac.tex @@ -1,7 +1,7 @@ % standard macros for CWEB listings (in addition to plain.tex) -% Version 4.1 --- February 2021 +% Version 4.2 --- February 2021 \ifx\renewenvironment\undefined\else\endinput\fi % LaTeX will use other macros -\xdef\fmtversion{\fmtversion+CWEB4.1} +\xdef\fmtversion{\fmtversion+CWEB4.2} \chardef\cwebversion=4 \chardef\cwebrevision=1 \newif\ifpdf \ifx\pdf+\pdftrue\fi diff --git a/cwebman.tex b/cwebman.tex index fd7f164..df65223 100644 --- a/cwebman.tex +++ b/cwebman.tex @@ -36,7 +36,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.1)} +\def\runninghead{{\tentt CWEB} USER MANUAL (VERSION 4.2)} % This verbatim mode assumes that ! marks are !! in the text being copied. \def\verbatim{\begingroup @@ -50,7 +50,7 @@ \null\vfill \centerline{\titlefont The {\ttitlefont CWEB} System of Structured Documentation} -\vskip 18pt\centerline{(Version 4.1 --- February 2021)} +\vskip 18pt\centerline{(Version 4.2 --- February 2021)} \vskip 24pt \centerline{\authorfont Donald E. Knuth and Silvio Levy} \vfill @@ -398,15 +398,15 @@ the assignment $\\{pa}\K{\AND}\|a[\T{0}]$ makes \\{pa} point to the zeroth element of \|a.}$$ The \TEX/ text would look like this in your \.{CWEB} file: -$$\lpile{\.{If |pa| is declared as `|int *pa|', the}\cr -\.{assignment |pa=\&a[0]| makes |pa| point -to the zeroth element of |a|.}\cr}$$ -And \.{CWEAVE} translates this into something you are glad you didn't have -to type: -$$\lpile{\.{If \\\\\{pa\} is declared as - `\\\&\{int\} \$\{\}\{*\}\\\\\{pa\}\$',}\cr -\.{the assignment \$\\\\\{pa\}\\K\{\\AND\}\\|a[\\T\{0\}]\$}\cr -\.{makes \\\\\{pa\} point to the zeroth element of \\|a.}\cr}$$ +$$\lpile{\.{If |pa| is declared as `|int *pa|', the assignment}\cr +\.{|pa=\&a[0]| makes |pa| point to the zeroth element of |a|.}\cr}$$ +And \.{CWEAVE} translates this into something +you are glad you didn't have to type: +$$\lpile{\.{If \\PB\{\\\\\{pa\}\} is declared as `\\PB\{\\\&\{int\} + \$\{\}\{*\}\\\\\{pa\}\$\}', the}\cr +\.{assignment \\PB\{\$\\\\\{pa\}\\K\{\\AND\}\\|a[\\T\{0\}]\$\} + makes \\PB\{\\\\\{pa\}\} point}\cr +\.{to the zeroth element of \\PB\{\\|a\}.}\cr}$$ Incidentally, the cross-reference index that \.{CWEAVE} would make, in the presence of a comment like this, would include the current section number as one of the index entries for \\{pa}, @@ -1011,7 +1011,7 @@ \section Running the programs. The \UNIX/ command line for \.{CTANGLE} is -$$\.{ctangle [options] web\_file[.w] [\{change\_file[.ch]|-\} [out\_file]]}$$ +$$\.{ctangle [options] webfile[.w] [\{changefile[.ch]|-\} [outfile[.c]]]}$$ and the same conventions apply to \.{CWEAVE}. If `\.-' or no change file is specified, the change file is null. The extensions \.{.w} and \.{.ch} are appended only if the given file names contain no dot. If the @@ -1042,7 +1042,7 @@ \option e Enclose \CEE/ material formatted by \.{CWEAVE} in brackets \.{\\PB\{...\}}, so that special hooks can be used. -(Off by default; has no effect on \.{CTANGLE}.) +(On by default; has no effect on \.{CTANGLE}.) \option f Force line breaks after each \CEE/ statement formatted by \.{CWEAVE}. (On by default; \.{-f} saves paper but looks less \CEE/-like @@ -1336,7 +1336,7 @@ \def\runninghead{APPENDIX A --- TRANSLATION BY {\tentt CWEAVE}} Here is the corresponding excerpt from \.{common.tex}. -(Code for section 31 omitted for space reasons.) +(Code for section 31 is omitted for space reasons.) \vskip6pt \begingroup \def\tt{\eighttt} \baselineskip9pt @@ -1591,7 +1591,7 @@ \.{ { }\\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.1)\}{ }\\vfill\}}\cr}$$ + \.{ { }\\vskip 15pt \\centerline\{(Version 4.2)\}{ }\\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.