From 4763ec8ceefaf2b038d591b8c15d88d081aec6c9 Mon Sep 17 00:00:00 2001 From: Norbert Preining Date: Tue, 2 Mar 2021 03:04:42 +0000 Subject: CTAN sync 202103020304 --- web/c_cpp/cweb/Makefile | 11 +- web/c_cpp/cweb/README | 21 +- web/c_cpp/cweb/comm-amiga.ch | 8 +- web/c_cpp/cweb/comm-bs.ch | 210 +++--- web/c_cpp/cweb/comm-mac.ch | 73 ++- web/c_cpp/cweb/comm-os2.ch | 16 +- web/c_cpp/cweb/comm-pc.ch | 22 +- web/c_cpp/cweb/comm-ql.ch | 257 +++----- web/c_cpp/cweb/comm-vms.ch | 43 +- web/c_cpp/cweb/comm-w32.ch | 50 +- web/c_cpp/cweb/common.c | 1059 ++++++++++++++++-------------- web/c_cpp/cweb/common.h | 202 +++--- web/c_cpp/cweb/common.w | 677 ++++++++------------ web/c_cpp/cweb/ctang-bs.ch | 124 ++-- web/c_cpp/cweb/ctang-pc.ch | 12 +- web/c_cpp/cweb/ctang-ql.ch | 8 +- web/c_cpp/cweb/ctang-vms.ch | 34 +- web/c_cpp/cweb/ctang-w32.ch | 62 +- web/c_cpp/cweb/ctangle.c | 1123 ++++++++++++++++---------------- web/c_cpp/cweb/ctangle.w | 536 ++++++++-------- web/c_cpp/cweb/cweav-bs.ch | 178 ++---- web/c_cpp/cweb/cweav-pc.ch | 19 +- web/c_cpp/cweb/cweav-ql.ch | 8 +- web/c_cpp/cweb/cweav-vms.ch | 35 +- web/c_cpp/cweb/cweav-w32.ch | 54 +- web/c_cpp/cweb/cweave.w | 1456 ++++++++++++++++++++++-------------------- web/c_cpp/cweb/cweb.1 | 22 +- web/c_cpp/cweb/cwebmac.tex | 19 +- web/c_cpp/cweb/cwebman.tex | 243 +++---- web/pwebmac/README.md | 6 +- web/pwebmac/index.md | 2 + web/pwebmac/makeall | 14 + web/pwebmac/trapman.ch | 23 + web/pwebmac/webman.ch | 198 ++++++ 34 files changed, 3480 insertions(+), 3345 deletions(-) create mode 100644 web/pwebmac/trapman.ch create mode 100644 web/pwebmac/webman.ch (limited to 'web') diff --git a/web/c_cpp/cweb/Makefile b/web/c_cpp/cweb/Makefile index 1367d00892..0c20d83c10 100644 --- a/web/c_cpp/cweb/Makefile +++ b/web/c_cpp/cweb/Makefile @@ -1,6 +1,6 @@ # This file is part of CWEB. # It is distributed WITHOUT ANY WARRANTY, express or implied. -# Version 3.64 --- February 2002 +# 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 @@ -125,7 +128,7 @@ SAVEctangle.c: SAVEcommon.c: $(CP) common.c SAVEcommon.c -common.c: common.w $(CCHANGES) +common.c: common.w $(CCHANGES) common.h $(CTANGLE) common $(CCHANGES) common.o: common.c @@ -134,13 +137,13 @@ common.o: common.c ctangle: ctangle.o common.o $(CC) $(LINKFLAGS) -o ctangle ctangle.o common.o -ctangle.c: ctangle.w $(TCHANGES) +ctangle.c: ctangle.w $(TCHANGES) common.h $(CTANGLE) ctangle $(TCHANGES) cweave: cweave.o common.o $(CC) $(LINKFLAGS) -o cweave cweave.o common.o -cweave.c: cweave.w $(WCHANGES) +cweave.c: cweave.w $(WCHANGES) common.h prod.w $(CTANGLE) cweave $(WCHANGES) doc: $(SOURCES:.w=.dvi) diff --git a/web/c_cpp/cweb/README b/web/c_cpp/cweb/README index 6429dabfa8..081dc5aa0b 100644 --- a/web/c_cpp/cweb/README +++ b/web/c_cpp/cweb/README @@ -1,7 +1,7 @@ % This file is part of CWEB. % The CWEB programs by Silvio Levy are based on programs by D. E. Knuth. % They are distributed WITHOUT ANY WARRANTY, express or implied. -% This README file last updated January 2016 by Don Knuth +% This README file last updated February 2021 by Andreas Scherer % Copyright (C) 1987,1990,1993,2000,2016 Silvio Levy and Donald E. Knuth @@ -18,9 +18,13 @@ % there will verify and forward bug reports. % % DEK takes no responsibility for the changefiles; they should be -% maintained independently. His job is to correct errors in -% ctangle.w, cweave.w, prod.w, common.w, cwebmac.tex, cwebman.tex, -% and in the files of examples/*.w, nothing more. +% maintained independently. He even transferred the job to correct errors +% in ctangle.w, cweave.w, prod.w, common.w, cwebmac.tex, cwebman.tex, +% and in the files of examples/*.w to Andreas Scherer in 2021. +% Further significant developments, including versions that neither +% Don Knuth nor Silvio Levy themselves do maintain, are ongoing. +% All of the really current news about CWEB is, in fact, now to be found +% on the CWEB development page https://github.com/ascherer/cweb. This directory contains the following files: @@ -30,6 +34,7 @@ comm-amiga.ch comm-bs.ch comm-mac.ch comm-man.ch +comm-os2.ch comm-pc.ch comm-ql.ch comm-vms.ch @@ -68,7 +73,7 @@ The files common.c and ctangle.c are used for bootstrapping. The file cweb.1 is a manual page. The file cweb.el is suggested for GNU-Emacs users. The file c++lib.w is for C++ users (say `@i c++lib.w' at beginning of program). -The files *-man.ch are used if you want to make the full 239-page CWEB manual. +The files *-man.ch are used if you want to make the full 240-page CWEB manual. The files *-bs.ch are used instead of *-pc.ch if you are doing BIG programs. You can use makefile.bs to make CWEB with *-bs.ch. The files *-ql.ch are for QDOS/SMSQ systems; see readme.ql for further info. @@ -102,9 +107,3 @@ Note that change files for VMS, AMIGA, MAC, and PCs are provided. When you are first bootstrapping to a new system, you may need to edit common.c and ctangle.c by hand, but the vast majority of the change-file changes are minor refinements that are not necessary for a rudimentary ctangle. - ------------------------------------------ -These archival sources are maintained only to the extent of fixing -significant bugs that were unintended at the time of writing. -A multi-decade ongoing project to improve and extend CWEB can be found at - https://github.com/ascherer/cwebbin diff --git a/web/c_cpp/cweb/comm-amiga.ch b/web/c_cpp/cweb/comm-amiga.ch index 57e65d1ccd..f17c2d333b 100644 --- a/web/c_cpp/cweb/comm-amiga.ch +++ b/web/c_cpp/cweb/comm-amiga.ch @@ -4,14 +4,14 @@ This is the change file for CWEB's COMMON on the Amiga With Lattice C 5.1, use compilation switches -b0 -r0, and ignore the compiler warnings. With SAS 6.0, use compilation switches Code=far Data=far. -@x section 69 +@x section 75 An omitted change file argument means that |"/dev/null"| should be used, @y An omitted change file argument means that |"nil:"| should be used, @z -@x section 70 - if (found_change<=0) strcpy(change_file_name,"/dev/null"); +@x section 76 + strcpy(change_file_name,"/dev/null"); @y - if (found_change<=0) strcpy(change_file_name,"nil:"); + strcpy(change_file_name,"nil:"); @z diff --git a/web/c_cpp/cweb/comm-bs.ch b/web/c_cpp/cweb/comm-bs.ch index 26f79b160d..b01b86799d 100644 --- a/web/c_cpp/cweb/comm-bs.ch +++ b/web/c_cpp/cweb/comm-bs.ch @@ -12,55 +12,68 @@ by using "huge" pointers. (This file contributed by Barry Schwartz, trashman@crud.mn.org, 28 Jun 94; revised 24 Jul 94.) +(Update attempt by Andreas Scherer, 31 Jan 2021. Good luck!) -@x Section 23. - cur_file_name[l]='/'; /* \UNIX/ pathname separator */ -@y - cur_file_name[l]='/'; /* A valid {\mc MSDOS} pathname separator */ -@z +@x Section 6. + for section names */ -@x Section 27. -@d max_names 4000 /* number of identifiers, strings, section names; - must be less than 10240 */ - -@= +@= typedef struct name_info { char *byte_start; /* beginning of the name in |byte_mem| */ - @@; + struct name_info *link; + union { + struct name_info *Rlink; /* right link in binary search tree for section + names */ + char Ilk; /* used by identifiers in \.{CWEAVE} only */ + } dummy; + void *equiv_or_xref; /* info corresponding to names */ } name_info; /* contains information about an identifier or section name */ -typedef name_info *name_pointer; /* pointer into array of |name_info|s */ -char byte_mem[max_bytes]; /* characters of names */ -char *byte_mem_end = byte_mem+max_bytes-1; /* end of |byte_mem| */ -name_info name_dir[max_names]; /* information about names */ -name_pointer name_dir_end = name_dir+max_names-1; /* end of |name_dir| */ +typedef name_info *name_pointer; /* pointer into array of \&{name\_info}s */ +typedef name_pointer *hash_pointer; +extern char byte_mem[]; /* characters of names */ +extern char *byte_mem_end; /* end of |byte_mem| */ @y -@d max_names 4000 /* number of identifiers, strings, section names; - must be less than 10240 */ + for section names */ @f huge extern -@= +@= typedef struct name_info { char huge* byte_start; /* beginning of the name in |byte_mem| */ - @@; + struct name_info *link; + union { + struct name_info *Rlink; /* right link in binary search tree for section + names */ + char Ilk; /* used by identifiers in \.{CWEAVE} only */ + } dummy; + union { + void huge* equiv_member; + void huge* xref_member; + } ptr_union; /* info corresponding to names */ } name_info; /* contains information about an identifier or section name */ -typedef name_info *name_pointer; /* pointer into array of |name_info|s */ -char huge byte_mem[max_bytes]; /* characters of names */ -char huge* byte_mem_end; /* end of |byte_mem| */ -name_info name_dir[max_names]; /* information about names */ -name_pointer name_dir_end = name_dir+max_names-1; +typedef name_info *name_pointer; /* pointer into array of \&{name\_info}s */ +typedef name_pointer *hash_pointer; +extern char huge byte_mem[]; /* characters of names */ +extern char huge* byte_mem_end; /* end of |byte_mem| */ +@z + + +@x Section 39. + cur_file_name[l]='/'; /* \UNIX/ pathname separator */ +@y + cur_file_name[l]='/'; /* A valid {\mc MSDOS} pathname separator */ @z -@x Section 29. +@x Section 44. char *byte_ptr; /* first unused position in |byte_mem| */ @y char huge* byte_ptr; /* first unused position in |byte_mem| */ @z -@x Section 30. +@x Section 45. @ @= name_dir->byte_start=byte_ptr=byte_mem; /* position zero in both arrays */ name_ptr=name_dir+1; /* |name_dir[0]| will be used only for error recovery */ @@ -74,156 +87,137 @@ byte_mem_end = byte_mem+max_bytes-1; @z -@x Section 42. +@x Section 52. void -print_section_name(p) -name_pointer p; +print_section_name( +name_pointer p) { char *ss, *s = first_chunk(p); @y void -print_section_name(p) -name_pointer p; +print_section_name( +name_pointer p) { char huge* ss, huge* s = first_chunk(p); @z -@x Section 43. +@x Section 53. void -sprint_section_name(dest,p) - char*dest; - name_pointer p; +sprint_section_name( + char *dest, + name_pointer p) { char *ss, *s = first_chunk(p); @y void -sprint_section_name(dest,p) - char*dest; - name_pointer p; +sprint_section_name( + char huge* dest, + name_pointer p) { char huge* ss, huge* s = first_chunk(p); @z -@x Section 44. +@x Section 54. void -print_prefix_name(p) -name_pointer p; +print_prefix_name( +name_pointer p) { char *s = first_chunk(p); @y void -print_prefix_name(p) -name_pointer p; +print_prefix_name( +name_pointer p) { char huge* s = first_chunk(p); @z -@x Section 47. -name_pointer -add_section_name(par,c,first,last,ispref) /* install a new node in the tree */ -name_pointer par; /* parent of new node */ -int c; /* right or left? */ -char *first; /* first character of section name */ -char *last; /* last character of section name, plus one */ -int ispref; /* are we adding a prefix or a full name? */ +@x Section 57. +static name_pointer +add_section_name(@t\1\1@> /* install a new node in the tree */ +name_pointer par, /* parent of new node */ +int c, /* right or left? */ +char *first, /* first character of section name */ +char *last, /* last character of section name, plus one */ +int ispref@t\2\2@>) /* are we adding a prefix or a full name? */ { name_pointer p=name_ptr; /* new node */ char *s=first_chunk(p); @y -name_pointer -add_section_name(par,c,first,last,ispref) /* install a new node in the tree */ -name_pointer par; /* parent of new node */ -int c; /* right or left? */ -char *first; /* first character of section name */ -char *last; /* last character of section name, plus one */ -int ispref; /* are we adding a prefix or a full name? */ +static name_pointer +add_section_name(@t\1\1@> /* install a new node in the tree */ +name_pointer par, /* parent of new node */ +int c, /* right or left? */ +char huge* first, /* first character of section name */ +char huge* last, /* last character of section name, plus one */ +int ispref@t\2\2@>) /* are we adding a prefix or a full name? */ { name_pointer p=name_ptr; /* new node */ char huge* s=first_chunk(p); @z -@x Section 48. -void -extend_section_name(p,first,last,ispref) -name_pointer p; /* name to be extended */ -char *first; /* beginning of extension text */ -char *last; /* one beyond end of extension text */ -int ispref; /* are we adding a prefix or a full name? */ +@x Section 58. +static void +extend_section_name(@t\1\1@> +name_pointer p, /* name to be extended */ +char *first, /* beginning of extension text */ +char *last, /* one beyond end of extension text */ +int ispref@t\2\2@>) /* are we adding a prefix or a full name? */ { char *s; @y -void -extend_section_name(p,first,last,ispref) -name_pointer p; /* name to be extended */ -char *first; /* beginning of extension text */ -char *last; /* one beyond end of extension text */ -int ispref; /* are we adding a prefix or a full name? */ +static void +extend_section_name(@t\1\1@> +name_pointer p, /* name to be extended */ +char huge* first, /* beginning of extension text */ +char huge* last, /* one beyond end of extension text */ +int ispref@t\2\2@>) /* are we adding a prefix or a full name? */ { char huge* s; @z -@x Section 54. -int section_name_cmp(pfirst,len,r) -char **pfirst; /* pointer to beginning of comparison string */ -int len; /* length of string */ -name_pointer r; /* section name being compared */ +@x Section 64. +static int section_name_cmp(@t\1\1@> +char **pfirst, /* pointer to beginning of comparison string */ +int len, /* length of string */ +name_pointer r@t\2\2@>) /* section name being compared */ { char *first=*pfirst; /* beginning of comparison string */ name_pointer q=r+1; /* access to subsequent chunks */ char *ss, *s=first_chunk(r); @y -int section_name_cmp(pfirst,len,r) -char **pfirst; /* pointer to beginning of comparison string */ -int len; /* length of string */ -name_pointer r; /* section name being compared */ +static int section_name_cmp(@t\1\1@> +char huge** pfirst, /* pointer to beginning of comparison string */ +int len, /* length of string */ +name_pointer r@t\2\2@>) /* section name being compared */ { - char *first=*pfirst; /* beginning of comparison string */ + char huge* first=*pfirst; /* beginning of comparison string */ name_pointer q=r+1; /* access to subsequent chunks */ char huge* ss, huge* s=first_chunk(r); @z -@x Section 55. -source files, respectively; here we just declare a common field -|equiv_or_xref| as a pointer to a |char|. - -@= -char *equiv_or_xref; /* info corresponding to names */ +@x Section 75. +An omitted change file argument means that |"/dev/null"| should be used, @y -source files, respectively. Here we just declare a common field -|ptr_union| as a union of pointers to |char|, which happen to have -different addressing attributes. - -@= -union { - char *equiv_member; - char huge* xref_member; -} ptr_union; /* info corresponding to names */ +An omitted change file argument means that |"NUL"| should be used, @z -@x Section 69. -An omitted change file argument means that |"/dev/null"| should be used, +@x Section 76. + strcpy(change_file_name,"/dev/null"); @y -An omitted change file argument means that |"NUL"| should be used, + strcpy(change_file_name,"NUL"); @z -@x Section 70. +@x Section 76. else if (*s=='/') dot_pos=NULL,name_pos=++s; @y else if (*s == ':' || *s == '\\' || *s == '/') dot_pos=NULL,name_pos=++s; @z - - -@x Section 70. - if (found_change<=0) strcpy(change_file_name,"/dev/null"); -@y - if (found_change<=0) strcpy(change_file_name,"NUL"); -@z diff --git a/web/c_cpp/cweb/comm-mac.ch b/web/c_cpp/cweb/comm-mac.ch index b9bd408655..aa3a77fed4 100644 --- a/web/c_cpp/cweb/comm-mac.ch +++ b/web/c_cpp/cweb/comm-mac.ch @@ -4,23 +4,26 @@ 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 3.64)} + \centerline{(Version 4.2)} @y - \centerline{(Version 3.64 for MacOS)} + \centerline{(Version 4.2 for MacOS)} @z -@x section 9: Make input_ln accept \n, \r, \n\r, or \r\n as line endings +@x sections 23/24: Make input_ln accept \n, \r, \n\r, or \r\n as line endings @ In the unlikely event that your standard I/O library does not support |feof|, |getc|, and |ungetc| you may have to change things here. @^system dependencies@> -@c -int input_ln(fp) /* copies a line into |buffer| or returns 0 */ -FILE *fp; /* what file to read from */ +@= +static boolean input_ln(FILE *);@/ + +@ @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 */ { register int c=EOF; /* character read; initialized so some compilers won't complain */ register char *k; /* where next character goes */ - if (feof(fp)) return(0); /* we have hit end-of-file */ + if (feof(fp)) return false; /* we have hit end-of-file */ limit = k = buffer; /* beginning of buffer */ while (k<=buffer_end && (c=getc(fp)) != EOF && c!='\n') if ((*(k++) = c) != ' ') limit = k; @@ -28,10 +31,10 @@ FILE *fp; /* what file to read from */ if ((c=getc(fp))!=EOF && c!='\n') { ungetc(c,fp); loc=buffer; err_print("! Input line too long"); @.Input line too long@> - } - if (c==EOF && limit==buffer) return(0); /* there was nothing after + } + if (c==EOF && limit==buffer) return false; /* there was nothing after the last newline */ - return(1); + return true; } @y @ In the unlikely event that your standard I/O library does not @@ -42,27 +45,30 @@ line endings, so that \.{CWEB} will works with ASCII files stored in \UNIX/, {\mc DOS} or {\mc MAC} format. @^system dependencies@> -@c -int input_ln(fp) /* copies a line into |buffer| or returns 0 */ -FILE *fp; /* what file to read from */ +@= +static boolean input_ln(FILE *);@/ + +@ @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 */ { register int c=EOF; /* character read; initialized so some compilers won't complain */ register char *k; /* where next character goes */ - if (feof(fp)) return(0); /* we have hit end-of-file */ + if (feof(fp)) return false; /* we have hit end-of-file */ limit = k = buffer; /* beginning of buffer */ - while (1) { + while (true) { c = getc(fp); - if (c==EOF) return (limit!=buffer); /* 0, if there was nothing after + if (c==EOF) return limit!=buffer; /* |false|, if there was nothing after the last newline */ else if (c=='\n' || c=='\r') { /* we have hit end-of-line */ int d = getc(fp); if (c+d!='\n'+'\r') /* no combination |"\n\r"| or |"\r\n"| */ ungetc(d,fp); - return (1); + return true; } else if (k>buffer_end) { ungetc(c,fp); loc=buffer; err_print("! Input line too long"); - return (1); + return true; @.Input line too long@> } else @@ -71,17 +77,17 @@ FILE *fp; /* what file to read from */ } @z -@x section 12, simply return if no change file was specified +@x section 28, simply return if no change file was specified change_limit=change_buffer; /* this value is used if the change file ends */ - @; + @@; @y change_limit=change_buffer; /* this value is used if the change file ends */ if (change_file_name[0] == '\0') /* no change file specified */ return; /* so we have reached the end of that file */ - @; + @@; @z -@x section 19, don't try to open a change file if none was specified +@x section 36, don't try to open a change file if none was specified if ((change_file=fopen(change_file_name,"r"))==NULL) fatal("! Cannot open change file ", change_file_name); @y @@ -91,7 +97,7 @@ else if ((change_file=fopen(change_file_name,"r"))==NULL) fatal("! Cannot open change file ", change_file_name); @z -@x section 22, declare colon as Mac's path separator +@x section 39, declare colon as Mac's path separator (Colon-separated paths are not supported.) The remainder of the \.{@@i} line after the file name is ignored. @@ -104,38 +110,37 @@ The remainder of the \.{@@i} line after the file name is ignored. @d PATH_SEP ':' /* MacOS pathname separator */ @^system dependencies@> @z - -@x section 23, use the path separator constant +@x section 39, use the path separator constant cur_file_name[l]='/'; /* \UNIX/ pathname separator */ @y cur_file_name[l]=PATH_SEP; /* pathname separator */ @z -@x section 69, explain the convention for omitted change files +@x section 75, explain the convention for omitted change files An omitted change file argument means that |"/dev/null"| should be used, @y An omitted change file argument means that no change file should be used, @z -@x section 70, use the Metrowerks |ccommand| to access command lines +@x section 76, make change file name empty when it is unspecified + strcpy(change_file_name,"/dev/null"); +@y + change_file_name[0]='\0'; /* empty string */ +@z +@x section 76, use the Metrowerks |ccommand| to access command lines while (--argc > 0) { @y argc = ccommand (&argv); /* use Mac interface to command line */ @^system dependencies@> while (--argc > 0) { @z -@x section 70, use the path separator constant +@x section 76, use the path separator constant else if (*s=='/') dot_pos=NULL,name_pos=++s; @y else if (*s==PATH_SEP) dot_pos=NULL,name_pos=++s; @z -@x section 70, make change file name empty when it is unspecified - if (found_change<=0) strcpy(change_file_name,"/dev/null"); -@y - if (found_change<=0) change_file_name[0]='\0'; /* empty string */ -@z -@x section 82, insert an extra module before the index +@x section 85, insert an extra module before the index @** Index. @y by putting the new module here, we preserve all the previous section numbers @ We assume an interface to \CEE/ command-line emulation as supplied by diff --git a/web/c_cpp/cweb/comm-os2.ch b/web/c_cpp/cweb/comm-os2.ch index 5e20a6706c..2b85f8b1f6 100644 --- a/web/c_cpp/cweb/comm-os2.ch +++ b/web/c_cpp/cweb/comm-os2.ch @@ -4,21 +4,21 @@ This is the change file for CWEB's COMMON under OS/2 These changes tested with WATCOM C v10.0a. No changes to CTANGLE or CWEAVE are needed with OS/2. -@x section 69 +@x section 75 An omitted change file argument means that |"/dev/null"| should be used, @y An omitted change file argument means that |"NUL"| should be used, @z -@x section 70 (this change copied from comm-pc.ch) - else if (*s=='/') dot_pos=NULL,name_pos=++s; +@x section 76 + strcpy(change_file_name,"/dev/null"); @y - else if (*s == ':' || *s == '\\' || *s == '/') - dot_pos=NULL,name_pos=++s; + strcpy(change_file_name,"NUL"); @z -@x section 70 - if (found_change<=0) strcpy(change_file_name,"/dev/null"); +@x section 76 (this change copied from comm-pc.ch) + else if (*s=='/') dot_pos=NULL,name_pos=++s; @y - if (found_change<=0) strcpy(change_file_name,"NUL"); + else if (*s == ':' || *s == '\\' || *s == '/') + dot_pos=NULL,name_pos=++s; @z diff --git a/web/c_cpp/cweb/comm-pc.ch b/web/c_cpp/cweb/comm-pc.ch index e69bafb524..5f7d9c42ff 100644 --- a/web/c_cpp/cweb/comm-pc.ch +++ b/web/c_cpp/cweb/comm-pc.ch @@ -4,30 +4,30 @@ This is the change file for CWEB's COMMON under DOS Changes necessary for compiling with Borland C/C++ Use compilation switches -mc -w-pro -Ff=5000 -Note: The change to section 27 is not necessary if using a compiler +Note: The change to section 16 is not necessary if using a compiler that allows >64K arrays. -@x section 27 -@d max_bytes 90000 /* the number of bytes in identifiers, +@x section 16 +@d max_bytes 1000000 /* the number of bytes in identifiers, @y @d max_bytes (unsigned)60000 /* the number of bytes in identifiers, @z -@x section 69 +@x section 75 An omitted change file argument means that |"/dev/null"| should be used, @y An omitted change file argument means that |"NUL"| should be used, @z -@x section 70 (this change copied from comm-bs.ch, July 94) - else if (*s=='/') dot_pos=NULL,name_pos=++s; +@x section 76 + strcpy(change_file_name,"/dev/null"); @y - else if (*s == ':' || *s == '\\' || *s == '/') - dot_pos=NULL,name_pos=++s; + strcpy(change_file_name,"NUL"); @z -@x section 70 - if (found_change<=0) strcpy(change_file_name,"/dev/null"); +@x section 76 (this change copied from comm-bs.ch, July 94) + else if (*s=='/') dot_pos=NULL,name_pos=++s; @y - if (found_change<=0) strcpy(change_file_name,"NUL"); + else if (*s == ':' || *s == '\\' || *s == '/') + dot_pos=NULL,name_pos=++s; @z diff --git a/web/c_cpp/cweb/comm-ql.ch b/web/c_cpp/cweb/comm-ql.ch index 8859e215b2..c03b9185cb 100644 --- a/web/c_cpp/cweb/comm-ql.ch +++ b/web/c_cpp/cweb/comm-ql.ch @@ -10,61 +10,39 @@ 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 3.64)} +\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 3.64)} + \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 3.64)} +\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 3.64)} + \centerline{(Version 4.2)} \vfill} \def\botofcontents{\vfill \noindent @z -@x -The line number of each open file is also kept for error reporting and -for the benefit of \.{CTANGLE}. - -@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 60 -@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 */ -@y -The line number of each open file is also kept for error reporting and -for the benefit of \.{CTANGLE}. For use on QDOS/SMSQ systems the variable |max_file_name_length| is shortened to 42 characters, i.e. 5 characters for the device name, 36 characters for the file name plus one character as string terminator. (Note that (current) QDOS/SMSQ file systems have a limitation of 36 characters as maximum length for a file name. - -@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 */ +@x +@d max_file_name_length 1024 +@y @d max_file_name_length 42 -@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 */ @z @@ -90,99 +68,6 @@ when no changes are desired. @^system dependencies@> If there's a third file name, it will be the output file. - -@= -void scan_args(); - -@ @c -void -scan_args() -{ - char *dot_pos; /* position of |'.'| in the argument */ - char *name_pos; /* file name beginning, sans directory */ - register char *s; /* register for scanning strings */ - boolean found_web=0,found_change=0,found_out=0; - /* have these names have been seen? */ - boolean flag_change; - - while (--argc > 0) { - if ((**(++argv)=='-'||**argv=='+')&&*(*argv+1)) @@; - else { - s=name_pos=*argv;@+dot_pos=NULL; - while (*s) { - if (*s=='.') dot_pos=s++; - else if (*s=='/') dot_pos=NULL,name_pos=++s; - else s++; - } - if (!found_web) @@; - else if (!found_change) @@; - else if (!found_out) @@; - else @; - } - } - if (!found_web) @; - if (found_change<=0) strcpy(change_file_name,"/dev/null"); -} - -@ 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. -The other file names come from adding other things -after the dot. We must check that there is enough room in -|web_file_name| and the other arrays for the argument. - -@= -{ - if (s-*argv > max_file_name_length-5) - @; - if (dot_pos==NULL) - sprintf(web_file_name,"%s.w",*argv); - else { - strcpy(web_file_name,*argv); - *dot_pos=0; /* string now ends where the dot was */ - } - sprintf(alt_web_file_name,"%s.web",*argv); - sprintf(tex_file_name,"%s.tex",name_pos); /* strip off directory name */ - sprintf(idx_file_name,"%s.idx",name_pos); - sprintf(scn_file_name,"%s.scn",name_pos); - sprintf(C_file_name,"%s.c",name_pos); - found_web=1; -} - -@ @= -{ - if (strcmp(*argv,"-")==0) found_change=-1; - else { - if (s-*argv > max_file_name_length-4) - @; - if (dot_pos==NULL) - sprintf(change_file_name,"%s.ch",*argv); - else strcpy(change_file_name,*argv); - found_change=1; - } -} - -@ @= -{ - if (s-*argv > max_file_name_length-5) - @; - if (dot_pos==NULL) { - sprintf(tex_file_name,"%s.tex",*argv); - sprintf(idx_file_name,"%s.idx",*argv); - sprintf(scn_file_name,"%s.scn",*argv); - sprintf(C_file_name,"%s.c",*argv); - } else { - strcpy(tex_file_name,*argv); - strcpy(C_file_name,*argv); - if (flags['x']) { /* indexes will be generated */ - *dot_pos=0; - sprintf(idx_file_name,"%s.idx",*argv); - sprintf(scn_file_name,"%s.scn",*argv); - } - } - found_out=1; -} @y @ 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} @@ -204,41 +89,42 @@ always use the {\em full} name (i.e. with full path). Fortunately the routine has been written to search for the last ``dot'', so the altered version will search for the last |"_"| (including directory separators), so we have what we want. +@z -@= -void scan_args(); -@ @c -void -scan_args() -{ +@x + char *dot_pos; /* position of |'.'| in the argument */ +@y char *dot_pos; /* position of |'_'| in the argument */ - char *name_pos; /* file name beginning, sans directory */ - register char *s; /* register for scanning strings */ - boolean found_web=0,found_change=0,found_out=0; - /* have these names have been seen? */ - boolean flag_change; - - while (--argc > 0) { - if ((**(++argv)=='-'||**argv=='+')&&*(*argv+1)) @@; - else { - s=name_pos=*argv;@+dot_pos=NULL; - while (*s) { +@z + + +@x + strcpy(change_file_name,"/dev/null"); +@y + strcpy(change_file_name,"NUL"); +@z + + +@x + if (*s=='.') dot_pos=s++; + else if (*s=='/') dot_pos=NULL,name_pos=++s; + else s++; +@y if (*s=='_') dot_pos=s++; else if (*s=='_') dot_pos=NULL,name_pos=++s; else s++; - } - if (!found_web) @@; - else if (!found_change) @@; - else if (!found_out) @@; - else @; - } - } - if (!found_web) @; - if (found_change<=0) strcpy(change_file_name,"NUL"); -} +@z + +@x +@ 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. +The other file names come from adding other things +after the dot. We must check that there is enough room in +|web_file_name| and the other arrays for the argument. +@y @ 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. @@ -250,7 +136,28 @@ If you've read the section before carefully you'll have noticed, that QDOS/SMSQ file names contain almost a |"_"|, so this routine will not work, i.e. you'll {\em have} to add the |"_w"| always. Nevertheless I adapted the routine as if it would work. +@z + +@x +@= +{ + if (s-*argv > max_file_name_length-5) + @@; + if (dot_pos==NULL) + sprintf(web_file_name,"%s.w",*argv); + else { + strcpy(web_file_name,*argv); + *dot_pos=0; /* string now ends where the dot was */ + } + sprintf(alt_web_file_name,"%s.web",*argv); + sprintf(tex_file_name,"%s.tex",name_pos); /* strip off directory name */ + sprintf(idx_file_name,"%s.idx",name_pos); + sprintf(scn_file_name,"%s.scn",name_pos); + sprintf(C_file_name,"%s.c",name_pos); + found_web=true; +} +@y @= { if (s-*argv > max_file_name_length-5) @@ -266,22 +173,60 @@ the routine as if it would work. sprintf(idx_file_name,"%s_idx",name_pos); sprintf(scn_file_name,"%s_scn",name_pos); sprintf(C_file_name,"%s_c",name_pos); - found_web=1; + found_web=true; } +@z + +@x @ @= { - if (strcmp(*argv,"-")==0) found_change=-1; - else { + if (strcmp(*argv,"-")!=0) { + if (s-*argv > max_file_name_length-4) + @@; + if (dot_pos==NULL) + sprintf(change_file_name,"%s.ch",*argv); + else strcpy(change_file_name,*argv); + } + found_change=true; +} +@y +@ @= +{ + if (strcmp(*argv,"-")!=0) { if (s-*argv > max_file_name_length-4) @; if (dot_pos==NULL) sprintf(change_file_name,"%s_ch",*argv); else strcpy(change_file_name,*argv); - found_change=1; + found_change=true; } } +@z + +@x +@ @= +{ + if (s-*argv > max_file_name_length-5) + @@; + if (dot_pos==NULL) { + sprintf(tex_file_name,"%s.tex",*argv); + sprintf(idx_file_name,"%s.idx",*argv); + sprintf(scn_file_name,"%s.scn",*argv); + sprintf(C_file_name,"%s.c",*argv); + } else { + strcpy(tex_file_name,*argv); + strcpy(C_file_name,*argv); + if (make_xrefs) { /* indexes will be generated */ + *dot_pos=0; + sprintf(idx_file_name,"%s.idx",*argv); + sprintf(scn_file_name,"%s.scn",*argv); + } + } + found_out=true; +} +@y @ @= { if (s-*argv > max_file_name_length-5) @@ -294,13 +239,13 @@ the routine as if it would work. } else { strcpy(tex_file_name,*argv); strcpy(C_file_name,*argv); - if (flags['x']) { /* indexes will be generated */ + if (make_xrefs) { /* indexes will be generated */ *dot_pos=0; sprintf(idx_file_name,"%s_idx",*argv); sprintf(scn_file_name,"%s_scn",*argv); } } - found_out=1; + found_out=true; } @z diff --git a/web/c_cpp/cweb/comm-vms.ch b/web/c_cpp/cweb/comm-vms.ch index cd5fe52439..caf8ecef79 100644 --- a/web/c_cpp/cweb/comm-vms.ch +++ b/web/c_cpp/cweb/comm-vms.ch @@ -13,19 +13,26 @@ modified: (only the two changes by BL are necessary for initial bootstrapping via hand-editing of common.c) -@x section 5 (01-FEB-1992 ST) -#include +@x section 3 (01-FEB-1992 ST) +#include /* definition of |@!isalpha|, |@!isdigit| and so on */ +#include /* definition of |@!bool|, |@!true| and |@!false| */ +#include /* definition of |@!ptrdiff_t| */ +#include /* definition of |@!uint8_t| and |@!uint16_t| */ +#include /* definition of |@!getenv| and |@!exit| */ +#include /* definition of |@!printf| and friends */ +#include /* definition of |@!strlen|, |@!strcmp| and so on */ @y -#include ctype /* VMS searches Textlibraries faster */ +#include ctype /* definition of |@!isalpha|, |@!isdigit| and so on */ + /* VMS searches text libraries faster */ +#include stdbool /* definition of |@!bool|, |@!true| and |@!false| */ +#include stddef /* definition of |@!ptrdiff_t| */ +#include stdint /* definition of |@!uint8_t| and |@!uint16_t| */ +#include stdlib /* definition of |@!getenv| and |@!exit| */ +#include stdio /* definition of |@!printf| and friends */ +#include string /* definition of |@!strlen|, |@!strcmp| and so on */ @z -@x section 8 (01-FEB-1992 ST) -#include -@y -#include stdio /* VMS searches Textlibraries faster */ -@z - -@x section 61 (01-FEB-1992 ST) +@x section 68 (01-FEB-1992 ST) programs are started. Here, for instance, we pass the operating system a status of 0 if and only if only harmless messages were printed. @y @@ -37,9 +44,9 @@ A suitable status to signal an error condition to VAX/VMS could be print |"%SYSTEM-F-ABORT, abort"|, if |history > harmless_message|. @z -@x section 61 (1987 BL) (01-FEB-1992 ST) (11-JAN-1993 DEK) - if (history > harmless_message) return(1); - else return(0); +@x section 68 (1987 BL) (01-FEB-1992 ST) (11-JAN-1993 DEK) + if (history > harmless_message) return EXIT_FAILURE; + else return EXIT_SUCCESS; @y /* VAX/VMS and UNIX have different error status conventions. @@ -52,7 +59,7 @@ print |"%SYSTEM-F-ABORT, abort"|, if |history > harmless_message|. else exit(SS$_NORMAL); @z -@x section 69 (01-FEB-1992 ST) +@x section 75 (01-FEB-1992 ST) An omitted change file argument means that |"/dev/null"| should be used, when no changes are desired. @y @@ -60,14 +67,14 @@ An omitted change file argument means that the null device |"NL:"| should be used, when no changes are desired. @z -@x section 70 (1987 BL) (01-FEB-1992 ST) (05-APR-1992 DEK) - if (found_change<=0) strcpy(change_file_name,"/dev/null"); +@x section 76 (1987 BL) (01-FEB-1992 ST) (05-APR-1992 DEK) + strcpy(change_file_name,"/dev/null"); @y - if (found_change<=) strcpy(change_file_name,"NL:"); + strcpy(change_file_name,"NL:"); /* {\tt NL:} is the VAX/VMS notation for {\tt /dev/null} */ @z -@x section 82 (01-FEB-1992 ST) +@x section 85 (01-FEB-1992 ST) @** Index. @y @* VAX/VMS specific code. diff --git a/web/c_cpp/cweb/comm-w32.ch b/web/c_cpp/cweb/comm-w32.ch index b300f496d2..d256cedf12 100644 --- a/web/c_cpp/cweb/comm-w32.ch +++ b/web/c_cpp/cweb/comm-w32.ch @@ -35,60 +35,32 @@ Admittedly, this is not vital for cweb, except that I build the whole texlive set of programs using the __fastcall convention. @x -@= -#include +extern boolean names_match(name_pointer,const char *,size_t,eight_bits);@/ @y -@= -#include -#include +extern boolean __cdecl names_match(name_pointer,const char *,size_t,eight_bits);@/ @z @x -@ @= -extern int names_match(); +extern void init_p(name_pointer,eight_bits);@/ @y -@ @= -extern int __cdecl names_match(); +extern void __cdecl init_p(name_pointer,eight_bits);@/ @z -@x -@= -void init_p(); +@x section 75 +An omitted change file argument means that |"/dev/null"| should be used, @y -@= -void __cdecl init_p(); +An omitted change file argument means that |"NUL"| should be used, @z -@x section 69 -An omitted change file argument means that |"/dev/null"| should be used, +@x section 76 + strcpy(change_file_name,"/dev/null"); @y -An omitted change file argument means that |"NUL"| should be used, + strcpy(change_file_name,"NUL"); @z -@x section 70 (this change copied from comm-bs.ch, July 94) +@x section 76 (this change copied from comm-bs.ch, July 94) else if (*s=='/') dot_pos=NULL,name_pos=++s; @y else if (*s == ':' || *s == '\\' || *s == '/') dot_pos=NULL,name_pos=++s; @z - -@x section 70 - if (found_change<=0) strcpy(change_file_name,"/dev/null"); -@y - if (found_change<=0) strcpy(change_file_name,"NUL"); -@z - -@x -@ We predeclare several standard system functions here instead of including -their system header files, because the names of the header files are not as -standard as the names of the functions. (For example, some \CEE/ environments -have \.{} where others have \.{}.) - -@= -extern int strlen(); /* length of string */ -extern int strcmp(); /* compare strings lexicographically */ -extern char* strcpy(); /* copy one string to another */ -extern int strncmp(); /* compare up to $n$ string characters */ -extern char* strncpy(); /* copy up to $n$ string characters */ -@y -@z diff --git a/web/c_cpp/cweb/common.c b/web/c_cpp/cweb/common.c index 2bf7a9d4a8..7dd0f0c083 100644 --- a/web/c_cpp/cweb/common.c +++ b/web/c_cpp/cweb/common.c @@ -1,26 +1,22 @@ /*1:*/ -#line 58 "common.w" +#line 66 "common.w" -/*5:*/ -#line 102 "common.w" - -#include - -/*:5*//*8:*/ -#line 165 "common.w" - -#include - -/*:8*//*22:*/ -#line 471 "common.w" +/*3:*/ +#line 46 "common.h" +#include +#include +#include +#include #include +#include +#include -/*:22*/ -#line 59 "common.w" +/*:3*/ +#line 67 "common.w" -#define ctangle 0 -#define cweave 1 \ +#define ctangle false +#define cweave true \ #define and_and 04 #define lt_lt 020 @@ -28,7 +24,7 @@ #define plus_plus 013 #define minus_minus 01 #define minus_gt 031 -#define not_eq 032 +#define non_eq 032 #define lt_eq 034 #define gt_eq 035 #define eq_eq 036 @@ -38,23 +34,65 @@ #define period_ast 026 #define minus_gt_ast 027 \ -#define buf_size 100 -#define longest_name 10000 -#define long_buf_size (buf_size+longest_name) -#define xisspace(c) (isspace(c) &&((unsigned char) c<0200) ) -#define xisupper(c) (isupper(c) &&((unsigned char) c<0200) ) \ +#define xisalpha(c) (isalpha((eight_bits) c) &&((eight_bits) c<0200) ) +#define xisdigit(c) (isdigit((eight_bits) c) &&((eight_bits) c<0200) ) +#define xisspace(c) (isspace((eight_bits) c) &&((eight_bits) c<0200) ) +#define xislower(c) (islower((eight_bits) c) &&((eight_bits) c<0200) ) +#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 60 +#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 +#define rlink dummy.Rlink +#define root name_dir->rlink \ + \ + +#define spotless 0 +#define harmless_message 1 +#define error_message 2 +#define fatal_message 3 +#define mark_harmless {if(history==spotless) history= harmless_message;} +#define mark_error history= error_message +#define confusion(s) fatal("! This can't happen: ",s) \ + \ + +#define show_banner flags['b'] +#define show_progress flags['p'] +#define show_stats flags['s'] +#define show_happiness flags['h'] +#define make_xrefs flags['x'] \ + +#define update_terminal fflush(stdout) +#define new_line putchar('\n') +#define putxchar putchar +#define term_write(a,b) fflush(stdout) ,fwrite(a,sizeof(char) ,b,stdout) +#define C_printf(c,a) fprintf(C_file,c,a) +#define C_putc(c) putc(c,C_file) \ + +#define max_bytes 1000000 \ + +#define max_toks 1000000 +#define max_names 10239 \ + +#define max_sections 4000 +#define max_texts 10239 +#define longest_name 10000 +#define stack_size 500 +#define buf_size 1000 +#define long_buf_size (buf_size+longest_name) \ + #define lines_dont_match (change_limit-change_buffer!=limit-buffer|| \ -strncmp(buffer,change_buffer,limit-buffer) ) \ +strncmp(buffer,change_buffer,(size_t) (limit-buffer) ) ) \ #define if_section_start_make_pending(b) {*limit= '!'; \ for(loc= buffer;xisspace(*loc) ;loc++) ; \ @@ -62,30 +100,14 @@ for(loc= buffer;xisspace(*loc) ;loc++) ; \ if(*loc=='@'&&(xisspace(*(loc+1) ) ||*(loc+1) =='*') ) change_pending= b; \ } \ -#define max_sections 2000 \ - \ - #define too_long() {include_depth--; \ err_print("! Include file name too long") ;goto restart;} \ -#define max_bytes 90000 \ - -#define max_names 4000 \ - \ - -#define length(c) (c+1) ->byte_start-(c) ->byte_start -#define print_id(c) term_write((c) ->byte_start,length((c) ) ) \ - -#define hash_size 353 \ - -#define llink link -#define rlink dummy.Rlink -#define root name_dir->rlink \ - \ +#define hash_size 8501 \ #define first_chunk(p) ((p) ->byte_start+2) -#define prefix_length(p) (int) ((unsigned char) *((p) ->byte_start) *256+ \ -(unsigned char) *((p) ->byte_start+1) ) +#define prefix_length(p) (int) ((eight_bits) *((p) ->byte_start) *256+ \ +(eight_bits) *((p) ->byte_start+1) ) #define set_prefix_length(p,m) (*((p) ->byte_start) = (m) /256, \ *((p) ->byte_start+1) = (m) %256) \ @@ -97,48 +119,140 @@ err_print("! Include file name too long") ;goto restart;} \ #define bad_extension 5 \ -#define spotless 0 -#define harmless_message 1 -#define error_message 2 -#define fatal_message 3 -#define mark_harmless {if(history==spotless) history= harmless_message;} -#define mark_error history= error_message \ +#define flag_change (**argv!='-') -#define confusion(s) fatal("! This can't happen: ",s) \ - \ +#line 68 "common.w" -#define show_banner flags['b'] -#define show_progress flags['p'] -#define show_stats flags['s'] -#define show_happiness flags['h'] \ +/*2:*/ +#line 37 "common.h" -#define update_terminal fflush(stdout) \ +typedef bool boolean; +typedef uint8_t eight_bits; +typedef uint16_t sixteen_bits; +extern boolean program; +extern int phase; -#define new_line putchar('\n') -#define putxchar putchar -#define term_write(a,b) fflush(stdout) ,fwrite(a,sizeof(char) ,b,stdout) -#define C_printf(c,a) fprintf(C_file,c,a) -#define C_putc(c) putc(c,C_file) \ +/*:2*//*4:*/ +#line 74 "common.h" +extern char section_text[]; +extern char*section_text_end; +extern char*id_first; +extern char*id_loc; -#line 60 "common.w" +/*:4*//*5:*/ +#line 88 "common.h" -/*2:*/ -#line 73 "common.w" +extern char buffer[]; +extern char*buffer_end; +extern char*loc; +extern char*limit; + +/*:5*//*6:*/ +#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; +struct name_info*link; +union{ +struct name_info*Rlink; + +char Ilk; +}dummy; +void*equiv_or_xref; +}name_info; +typedef name_info*name_pointer; +typedef name_pointer*hash_pointer; +extern char byte_mem[]; +extern char*byte_mem_end; +extern char*byte_ptr; +extern name_info name_dir[]; +extern name_pointer name_dir_end; +extern name_pointer name_ptr; +extern name_pointer hash[]; +extern hash_pointer hash_end; +extern hash_pointer h; + +/*:9*//*11:*/ +#line 183 "common.h" + +extern int history; + +/*:11*//*13:*/ +#line 199 "common.h" + +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 boolean flags[]; + +/*:13*//*14:*/ +#line 215 "common.h" + +extern FILE*C_file; +extern FILE*tex_file; +extern FILE*idx_file; +extern FILE*scn_file; +extern FILE*active_file; + +/*:14*/ +#line 69 "common.w" + +/*18:*/ +#line 83 "common.w" -typedef short boolean; boolean program; -/*:2*//*7:*/ -#line 159 "common.w" +/*:18*//*19:*/ +#line 92 "common.w" + +int phase; + +/*:19*//*21:*/ +#line 130 "common.w" + +char section_text[longest_name+1]; +char*section_text_end= section_text+longest_name; +char*id_first; +char*id_loc; + +/*:21*//*22:*/ +#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; -/*:7*//*10:*/ -#line 214 "common.w" +/*:22*//*25:*/ +#line 194 "common.w" int include_depth; FILE*file[max_include_depth]; @@ -146,79 +260,57 @@ 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; boolean input_has_ended; boolean changing; -boolean web_file_open= 0; +boolean web_file_open= false; -/*:10*//*20:*/ -#line 418 "common.w" +/*:25*//*26:*/ +#line 220 "common.w" + +static char change_buffer[buf_size]; +static char*change_limit; + +/*:26*//*37:*/ +#line 399 "common.w" -typedef unsigned short sixteen_bits; sixteen_bits section_count; boolean changed_section[max_sections]; boolean change_pending; -boolean print_where= 0; +boolean print_where= false; -/*:20*//*27:*/ -#line 594 "common.w" +/*:37*//*43:*/ +#line 596 "common.w" -typedef struct name_info{ -char*byte_start; -/*31:*/ -#line 631 "common.w" - -struct name_info*link; - -/*:31*//*40:*/ -#line 730 "common.w" - -union{ -struct name_info*Rlink; - -char Ilk; -}dummy; - -/*:40*//*55:*/ -#line 1062 "common.w" - -char*equiv_or_xref; - -/*:55*/ -#line 597 "common.w" - -}name_info; -typedef name_info*name_pointer; char byte_mem[max_bytes]; char*byte_mem_end= byte_mem+max_bytes-1; name_info name_dir[max_names]; name_pointer name_dir_end= name_dir+max_names-1; -/*:27*//*29:*/ -#line 617 "common.w" +/*:43*//*44:*/ +#line 607 "common.w" -name_pointer name_ptr; char*byte_ptr; +name_pointer name_ptr; -/*:29*//*32:*/ -#line 644 "common.w" +/*:44*//*46:*/ +#line 627 "common.w" -typedef name_pointer*hash_pointer; name_pointer hash[hash_size]; hash_pointer hash_end= hash+hash_size-1; hash_pointer h; -/*:32*//*56:*/ -#line 1082 "common.w" +/*:46*//*65:*/ +#line 1014 "common.w" int history= spotless; -/*:56*//*67:*/ -#line 1220 "common.w" +/*:65*//*73:*/ +#line 1135 "common.w" int argc; char**argv; @@ -228,8 +320,8 @@ char idx_file_name[max_file_name_length]; char scn_file_name[max_file_name_length]; boolean flags[128]; -/*:67*//*77:*/ -#line 1370 "common.w" +/*:73*//*83:*/ +#line 1282 "common.w" FILE*C_file; FILE*tex_file; @@ -237,138 +329,133 @@ FILE*idx_file; FILE*scn_file; FILE*active_file; -/*:77*/ -#line 61 "common.w" - -/*3:*/ -#line 83 "common.w" -int phase; - -/*:3*//*11:*/ -#line 240 "common.w" - -char change_buffer[buf_size]; -char*change_limit; - -/*:11*/ -#line 62 "common.w" - -/*33:*/ -#line 650 "common.w" - -extern int names_match(); +/*:83*/ +#line 70 "common.w" -/*:33*//*38:*/ -#line 703 "common.w" +/*7:*/ +#line 119 "common.h" -void init_p(); +extern boolean get_line(void); +extern void check_complete(void); +extern void reset_input(void); -/*:38*//*46:*/ -#line 852 "common.w" +/*:7*//*10:*/ +#line 162 "common.h" -extern void init_node(); +extern boolean names_match(name_pointer,const char*,size_t,eight_bits); +extern name_pointer id_lookup(const char*,const char*,char); -/*:46*//*53:*/ -#line 1017 "common.w" +extern name_pointer section_lookup(char*,char*,int); +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); -int section_name_cmp(); +/*:10*//*12:*/ +#line 186 "common.h" -/*:53*//*57:*/ -#line 1092 "common.w" +extern int wrap_up(void); +extern void err_print(const char*); +extern void fatal(const char*,const char*); +extern void overflow(const char*); -void err_print(); +/*:12*//*15:*/ +#line 223 "common.h" -/*:57*//*60:*/ -#line 1140 "common.w" +extern void common_init(void); +extern void print_stats(void); -int wrap_up(); -extern void print_stats(); +/*:15*//*24:*/ +#line 180 "common.w" +static boolean input_ln(FILE*); -/*:60*//*63:*/ -#line 1173 "common.w" +/*:24*//*28:*/ +#line 241 "common.w" +static void prime_the_change_buffer(void); -void fatal(),overflow(); +/*:28*//*33:*/ +#line 340 "common.w" +static void check_change(void); -/*:63*//*69:*/ -#line 1251 "common.w" +/*:33*//*55:*/ +#line 774 "common.w" -void scan_args(); +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); -/*:69*//*81:*/ -#line 1411 "common.w" +/*:55*//*64:*/ +#line 1002 "common.w" +static int section_name_cmp(char**,int,name_pointer); -extern int strlen(); -extern int strcmp(); -extern char*strcpy(); -extern int strncmp(); -extern char*strncpy(); +/*:64*//*76:*/ +#line 1197 "common.w" +static void scan_args(void); -/*:81*/ -#line 63 "common.w" +/*:76*/ +#line 71 "common.w" -/*:1*//*4:*/ -#line 89 "common.w" +/*:1*//*20:*/ +#line 99 "common.w" void -common_init() +common_init(void) { -/*30:*/ -#line 621 "common.w" +/*45:*/ +#line 611 "common.w" name_dir->byte_start= byte_ptr= byte_mem; name_ptr= name_dir+1; name_ptr->byte_start= byte_mem; +root= NULL; -/*:30*//*34:*/ -#line 655 "common.w" +/*:45*//*47:*/ +#line 634 "common.w" for(h= hash;h<=hash_end;*h++= NULL); -/*:34*//*41:*/ -#line 737 "common.w" +/*:47*/ +#line 103 "common.w" -root= NULL; +/*74:*/ +#line 1148 "common.w" -/*:41*/ -#line 93 "common.w" -; -/*68:*/ -#line 1233 "common.w" +show_banner= show_happiness= show_progress= make_xrefs= true; +show_stats= false; -show_banner= show_happiness= show_progress= 1; +/*:74*/ +#line 104 "common.w" -/*:68*/ -#line 94 "common.w" -; -/*78:*/ -#line 1377 "common.w" +/*84:*/ +#line 1289 "common.w" scan_args(); if(program==ctangle){ -if((C_file= fopen(C_file_name,"w"))==NULL) +if((C_file= fopen(C_file_name,"wb"))==NULL) fatal("! Cannot open output file ",C_file_name); } else{ -if((tex_file= fopen(tex_file_name,"w"))==NULL) +if((tex_file= fopen(tex_file_name,"wb"))==NULL) fatal("! Cannot open output file ",tex_file_name); } -/*:78*/ -#line 95 "common.w" -; +/*:84*/ +#line 105 "common.w" + } -/*:4*//*9:*/ -#line 172 "common.w" +/*:20*//*23:*/ +#line 160 "common.w" -int input_ln(fp) -FILE*fp; +static boolean input_ln( +FILE*fp) { register int c= EOF; register char*k; -if(feof(fp))return(0); +if(feof(fp))return false; limit= k= buffer; while(k<=buffer_end&&(c= getc(fp))!=EOF&&c!='\n') if((*(k++)= c)!=' ')limit= k; @@ -377,27 +464,27 @@ if((c= getc(fp))!=EOF&&c!='\n'){ ungetc(c,fp);loc= buffer;err_print("! Input line too long"); } -if(c==EOF&&limit==buffer)return(0); +if(c==EOF&&limit==buffer)return false; -return(1); +return true; } -/*:9*//*12:*/ -#line 251 "common.w" +/*:23*//*27:*/ +#line 231 "common.w" -void -prime_the_change_buffer() +static void +prime_the_change_buffer(void) { change_limit= change_buffer; -/*13:*/ -#line 265 "common.w" +/*29:*/ +#line 247 "common.w" -while(1){ +while(true){ change_line++; if(!input_ln(change_file))return; if(limit buffer+1&&buffer[0]=='@'){ -char xyz_code= xisupper(buffer[1])?tolower(buffer[1]):buffer[1]; -/*17:*/ -#line 358 "common.w" +char xyz_code= xisupper(buffer[1])?tolower((eight_bits)buffer[1]):buffer[1]; +/*34:*/ +#line 342 "common.w" if(xyz_code=='x'||xyz_code=='z'){ loc= buffer+2;err_print("! Where is the matching @y?"); @@ -478,27 +565,27 @@ change_depth= include_depth; return; } -/*:17*/ -#line 342 "common.w" -; +/*:34*/ +#line 324 "common.w" + } -/*15:*/ -#line 292 "common.w" +/*31:*/ +#line 274 "common.w" { -change_limit= change_buffer+(limit-buffer); -strncpy(change_buffer,buffer,limit-buffer+1); +change_limit= change_buffer+(ptrdiff_t)(limit-buffer); +strncpy(change_buffer,buffer,(size_t)(limit-buffer+1)); } -/*:15*/ -#line 344 "common.w" -; -changing= 0;cur_line++; +/*:31*/ +#line 326 "common.w" + +changing= false;cur_line++; while(!input_ln(cur_file)){ if(include_depth==0){ err_print("! CWEB file ended during a change"); -input_has_ended= 1;return; +input_has_ended= true;return; } include_depth--;cur_line++; } @@ -506,15 +593,15 @@ if(lines_dont_match)n++; } } -/*:16*//*18:*/ -#line 378 "common.w" +/*:32*//*35:*/ +#line 362 "common.w" void -reset_input() +reset_input(void) { limit= buffer;loc= buffer+1;buffer[0]= ' '; -/*19:*/ -#line 393 "common.w" +/*36:*/ +#line 377 "common.w" if((web_file= fopen(web_file_name,"r"))==NULL){ strcpy(web_file_name,alt_web_file_name); @@ -523,28 +610,28 @@ fatal("! Cannot open input file ",web_file_name); } -web_file_open= 1; +web_file_open= true; if((change_file= fopen(change_file_name,"r"))==NULL) fatal("! Cannot open change file ",change_file_name); -/*:19*/ -#line 383 "common.w" -; +/*:36*/ +#line 367 "common.w" + include_depth= 0;cur_line= 0;change_line= 0; change_depth= include_depth; changing= 1;prime_the_change_buffer();changing= !changing; -limit= buffer;loc= buffer+1;buffer[0]= ' ';input_has_ended= 0; +limit= buffer;loc= buffer+1;buffer[0]= ' ';input_has_ended= false; } -/*:18*//*21:*/ -#line 426 "common.w" +/*:35*//*38:*/ +#line 406 "common.w" -int get_line() +boolean get_line(void) { restart: if(changing&&include_depth==change_depth) -/*25:*/ -#line 537 "common.w" +/*41:*/ +#line 514 "common.w" { change_line++; if(!input_ln(change_file)){ @@ -554,37 +641,37 @@ buffer[0]= '@';buffer[1]= 'z';limit= buffer+2; } if(limit> buffer){ if(change_pending){ -if_section_start_make_pending(0); +if_section_start_make_pending(false); if(change_pending){ -changed_section[section_count]= 1;change_pending= 0; +changed_section[section_count]= true;change_pending= false; } } *limit= ' '; if(buffer[0]=='@'){ -if(xisupper(buffer[1]))buffer[1]= tolower(buffer[1]); +if(xisupper(buffer[1]))buffer[1]= tolower((eight_bits)buffer[1]); if(buffer[1]=='x'||buffer[1]=='y'){ loc= buffer+2; err_print("! Where is the matching @z?"); } else if(buffer[1]=='z'){ -prime_the_change_buffer();changing= !changing;print_where= 1; +prime_the_change_buffer();changing= !changing;print_where= true; } } } } -/*:25*/ -#line 431 "common.w" -; +/*:41*/ +#line 411 "common.w" + if(!changing||include_depth> change_depth){ -/*24:*/ -#line 520 "common.w" +/*40:*/ +#line 497 "common.w" { cur_line++; while(!input_ln(cur_file)){ -print_where= 1; -if(include_depth==0){input_has_ended= 1;break;} +print_where= true; +if(include_depth==0){input_has_ended= true;break;} else{ fclose(cur_file);include_depth--; if(changing&&include_depth==change_depth)break; @@ -597,12 +684,12 @@ if(buffer[0]==change_buffer[0]) if(change_limit> change_buffer)check_change(); } -/*:24*/ -#line 433 "common.w" -; +/*:40*/ +#line 413 "common.w" + if(changing&&include_depth==change_depth)goto restart; } -if(input_has_ended)return 0; +if(input_has_ended)return false; loc= buffer;*limit= ' '; if(buffer[0]=='@'&&(buffer[1]=='i'||buffer[1]=='I')){ loc= buffer+2;*limit= '"'; @@ -618,8 +705,8 @@ err_print("! Too many nested includes"); goto restart; } include_depth++; -/*23:*/ -#line 474 "common.w" +/*39:*/ +#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; @@ -636,7 +723,7 @@ if(k> cur_file_name_end)too_long(); *k= '\0'; if((cur_file= fopen(cur_file_name,"r"))!=NULL){ -cur_line= 0;print_where= 1; +cur_line= 0;print_where= true; goto restart; } kk= getenv("CWEBINPUTS"); @@ -659,61 +746,61 @@ for(;k>=cur_file_name;k--)*(k+l+1)= *k; strcpy(cur_file_name,temp_file_name); cur_file_name[l]= '/'; if((cur_file= fopen(cur_file_name,"r"))!=NULL){ -cur_line= 0;print_where= 1; +cur_line= 0;print_where= true; goto restart; } } include_depth--;err_print("! Cannot open include file");goto restart; } -/*:23*/ -#line 452 "common.w" -; +/*:39*/ +#line 432 "common.w" + } -return 1; +return true; } -/*:21*//*26:*/ -#line 569 "common.w" +/*:38*//*42:*/ +#line 546 "common.w" void -check_complete(){ +check_complete(void){ if(change_limit!=change_buffer){ -strncpy(buffer,change_buffer,change_limit-change_buffer+1); -limit= buffer+(int)(change_limit-change_buffer); -changing= 1;change_depth= include_depth;loc= buffer; +strncpy(buffer,change_buffer,(size_t)(change_limit-change_buffer+1)); +limit= buffer+(ptrdiff_t)(change_limit-change_buffer); +changing= true;change_depth= include_depth;loc= buffer; err_print("! Change file entry did not match"); } } -/*:26*//*35:*/ -#line 660 "common.w" +/*:42*//*48:*/ +#line 639 "common.w" name_pointer -id_lookup(first,last,t) -char*first; -char*last; -char t; +id_lookup( +const char*first, +const char*last, +char t) { -char*i= first; +const char*i= first; int h; int l; name_pointer p; if(last==NULL)for(last= first;*last!='\0';last++); -l= last-first; -/*36:*/ -#line 683 "common.w" +l= (int)(last-first); +/*49:*/ +#line 662 "common.w" -h= (unsigned char)*i; -while(++ilink; @@ -722,53 +809,53 @@ p= name_ptr; p->link= hash[h];hash[h]= p; } -/*:37*/ -#line 674 "common.w" -; -if(p==name_ptr)/*39:*/ -#line 706 "common.w" +/*:50*/ +#line 653 "common.w" + +if(p==name_ptr)/*51:*/ +#line 681 "common.w" { if(byte_ptr+l> byte_mem_end)overflow("byte memory"); if(name_ptr>=name_dir_end)overflow("name"); strncpy(byte_ptr,first,l); (++name_ptr)->byte_start= byte_ptr+= l; -if(program==cweave)init_p(p,t); +init_p(p,t); } -/*:39*/ -#line 675 "common.w" -; -return(p); +/*:51*/ +#line 654 "common.w" + +return p; } -/*:35*//*42:*/ -#line 764 "common.w" +/*:48*//*52:*/ +#line 713 "common.w" void -print_section_name(p) -name_pointer p; +print_section_name( +name_pointer p) { char*ss,*s= first_chunk(p); name_pointer q= p+1; while(p!=name_dir){ ss= (p+1)->byte_start-1; if(*ss==' '&&ss>=s){ -term_write(s,ss-s);p= q->link;q= p; +term_write(s,(size_t)(ss-s));p= q->link;q= p; }else{ -term_write(s,ss+1-s);p= name_dir;q= NULL; +term_write(s,(size_t)(ss+1-s));p= name_dir;q= NULL; } s= p->byte_start; } if(q)term_write("...",3); } -/*:42*//*43:*/ -#line 783 "common.w" +/*:52*//*53:*/ +#line 732 "common.w" void -sprint_section_name(dest,p) -char*dest; -name_pointer p; +sprint_section_name( +char*dest, +name_pointer p) { char*ss,*s= first_chunk(p); name_pointer q= p+1; @@ -779,18 +866,18 @@ p= q->link;q= p; }else{ ss++;p= name_dir; } -strncpy(dest,s,ss-s),dest+= ss-s; +strncpy(dest,s,(size_t)(ss-s)),dest+= ss-s; s= p->byte_start; } *dest= '\0'; } -/*:43*//*44:*/ -#line 804 "common.w" +/*:53*//*54:*/ +#line 753 "common.w" void -print_prefix_name(p) -name_pointer p; +print_prefix_name( +name_pointer p) { char*s= first_chunk(p); int l= prefix_length(p); @@ -798,12 +885,14 @@ term_write(s,l); if(s+l<(p+1)->byte_start)term_write("...",3); } -/*:44*//*45:*/ -#line 825 "common.w" +/*:54*//*56:*/ +#line 779 "common.w" -int web_strcmp(j,j_len,k,k_len) -char*j,*k; -int j_len,k_len; +static int web_strcmp( +char*j, +int j_len, +char*k, +int k_len) { char*j1= j+j_len,*k1= k+k_len; while(k byte_mem_end)overflow("byte memory"); if(name_ptr+1>=name_dir_end)overflow("name"); (++name_ptr)->byte_start= byte_ptr= s+name_len; @@ -845,19 +934,19 @@ init_node(p); return par==NULL?(root= p):c==less?(par->llink= p):(par->rlink= p); } -/*:47*//*48:*/ -#line 884 "common.w" +/*:57*//*58:*/ +#line 837 "common.w" -void -extend_section_name(p,first,last,ispref) -name_pointer p; -char*first; -char*last; -int ispref; +static void +extend_section_name( +name_pointer p, +char*first, +char*last, +int ispref) { char*s; name_pointer q= p+1; -int name_len= last-first+ispref; +int name_len= (int)(last-first)+ispref; if(name_ptr>=name_dir_end)overflow("name"); while(q->link!=name_dir)q= q->link; q->link= name_ptr; @@ -869,13 +958,13 @@ strncpy(s,first,name_len); if(ispref)*(byte_ptr-1)= ' '; } -/*:48*//*49:*/ -#line 912 "common.w" +/*:58*//*59:*/ +#line 865 "common.w" name_pointer -section_lookup(first,last,ispref) -char*first,*last; -int ispref; +section_lookup( +char*first,char*last, +int ispref) { int c= 0; name_pointer p= root; @@ -883,9 +972,9 @@ name_pointer q= NULL; name_pointer r= NULL; name_pointer par= NULL; -int name_len= last-first+1; -/*50:*/ -#line 936 "common.w" +int name_len= (int)(last-first)+1; +/*60:*/ +#line 889 "common.w" while(p){ c= web_strcmp(first,name_len,first_chunk(p),prefix_length(p)); @@ -895,10 +984,10 @@ par= p; p= (c==less?p->llink:p->rlink); }else{ if(r!=NULL){ -printf("\n! Ambiguous prefix: matches <"); +fputs("\n! Ambiguous prefix: matches <",stdout); print_prefix_name(p); -printf(">\n and <"); +fputs(">\n and <",stdout); print_prefix_name(r); err_print(">"); return name_dir; @@ -911,26 +1000,26 @@ if(p==NULL) p= q,q= NULL; } -/*:50*/ -#line 926 "common.w" -; -/*51:*/ -#line 961 "common.w" +/*:60*/ +#line 879 "common.w" + +/*61:*/ +#line 914 "common.w" if(r==NULL) return add_section_name(par,c,first,last+1,ispref); -/*:51*/ -#line 927 "common.w" -; -/*52:*/ -#line 969 "common.w" +/*:61*/ +#line 880 "common.w" + +/*62:*/ +#line 922 "common.w" switch(section_name_cmp(&first,name_len,r)){ case prefix: if(!ispref){ -printf("\n! New name is a prefix of <"); +fputs("\n! New name is a prefix of <",stdout); print_section_name(r); err_print(">"); @@ -942,71 +1031,71 @@ case extension:if(!ispref||first<=last) extend_section_name(r,first,last+1,ispref); return r; case bad_extension: -printf("\n! New name extends <"); +fputs("\n! New name extends <",stdout); print_section_name(r); err_print(">"); return r; default: -printf("\n! Section name incompatible with <"); +fputs("\n! Section name incompatible with <",stdout); print_prefix_name(r); -printf(">,\n which abbreviates <"); +fputs(">,\n which abbreviates <",stdout); print_section_name(r); err_print(">"); return r; } -/*:52*/ -#line 928 "common.w" -; +/*:62*/ +#line 881 "common.w" + } -/*:49*//*54:*/ -#line 1020 "common.w" +/*:59*//*63:*/ +#line 970 "common.w" -int section_name_cmp(pfirst,len,r) -char**pfirst; -int len; -name_pointer r; +static int section_name_cmp( +char**pfirst, +int len, +name_pointer r) { char*first= *pfirst; name_pointer q= r+1; char*ss,*s= first_chunk(r); int c; int ispref; -while(1){ +while(true){ ss= (r+1)->byte_start-1; if(*ss==' '&&ss>=r->byte_start)ispref= 1,q= q->link; else ispref= 0,ss++,q= name_dir; switch(c= web_strcmp(first,len,s,ss-s)){ case equal:if(q==name_dir) if(ispref){ -*pfirst= first+(ss-s); +*pfirst= first+(ptrdiff_t)(ss-s); return extension; }else return equal; else return(q->byte_start==(q+1)->byte_start)?equal:prefix; case extension: if(!ispref)return bad_extension; first+= ss-s; -if(q!=name_dir){len-= ss-s;s= q->byte_start;r= q;continue;} +if(q!=name_dir){len-= (int)(ss-s);s= q->byte_start;r= q;continue;} *pfirst= first;return extension; default:return c; } } } -/*:54*//*58:*/ -#line 1095 "common.w" +/*:63*//*66:*/ +#line 1024 "common.w" void -err_print(s) -char*s; +err_print( +const char*s) { char*k,*l; printf(*s=='!'?"\n%s":"%s",s); -if(web_file_open)/*59:*/ -#line 1115 "common.w" +if(web_file_open)/*67:*/ +#line 1044 "common.w" {if(changing&&include_depth==change_depth) printf(". (l. %d of change file)\n",change_line); @@ -1025,85 +1114,83 @@ if(*limit=='|')putchar('|'); putchar(' '); } -/*:59*/ -#line 1102 "common.w" -; +/*:67*/ +#line 1031 "common.w" + update_terminal;mark_error; } -/*:58*//*61:*/ -#line 1150 "common.w" +/*:66*//*68:*/ +#line 1076 "common.w" -int wrap_up(){ -putchar('\n'); +int wrap_up(void){ +if(show_progress)new_line; if(show_stats) print_stats(); -/*62:*/ -#line 1160 "common.w" +/*69:*/ +#line 1086 "common.w" switch(history){ -case spotless:if(show_happiness)printf("(No errors were found.)\n");break; +case spotless:if(show_happiness)puts("(No errors were found.)");break; case harmless_message: -printf("(Did you see the warning message above?)\n");break; +puts("(Did you see the warning message above?)");break; case error_message: -printf("(Pardon me, but I think I spotted something wrong.)\n");break; -case fatal_message:printf("(That was a fatal error, my friend.)\n"); +puts("(Pardon me, but I think I spotted something wrong.)");break; +case fatal_message:puts("(That was a fatal error, my friend.)"); } -/*:62*/ -#line 1155 "common.w" -; -if(history> harmless_message)return(1); -else return(0); +/*:69*/ +#line 1081 "common.w" + +if(history> harmless_message)return EXIT_FAILURE; +else return EXIT_SUCCESS; } -/*:61*//*64:*/ -#line 1179 "common.w" +/*:68*//*70:*/ +#line 1102 "common.w" void -fatal(s,t) -char*s,*t; +fatal( +const char*s,const char*t) { -if(*s)printf(s); +if(*s)err_print(s); err_print(t); history= fatal_message;exit(wrap_up()); } -/*:64*//*65:*/ -#line 1190 "common.w" +/*:70*//*71:*/ +#line 1113 "common.w" void -overflow(t) -char*t; +overflow( +const char*t) { printf("\n! Sorry, %s capacity exceeded",t);fatal("",""); } -/*:65*//*70:*/ -#line 1254 "common.w" +/*:71*//*75:*/ +#line 1167 "common.w" -void -scan_args() +static void +scan_args(void) { char*dot_pos; char*name_pos; register char*s; -boolean found_web= 0,found_change= 0,found_out= 0; +boolean found_web= false,found_change= false,found_out= false; -boolean flag_change; +strcpy(change_file_name,"/dev/null"); while(--argc> 0){ -if((**(++argv)=='-'||**argv=='+')&&*(*argv+1))/*74:*/ -#line 1344 "common.w" +if((**(++argv)=='-'||**argv=='+')&&*(*argv+1))/*80:*/ +#line 1258 "common.w" { -if(**argv=='-')flag_change= 0; -else flag_change= 1; for(dot_pos= *argv+1;*dot_pos> '\0';dot_pos++) -flags[*dot_pos]= flag_change; +flags[(eight_bits)*dot_pos]= flag_change; } -/*:74*/ -#line 1266 "common.w" +/*:80*/ +#line 1179 "common.w" else{ s= name_pos= *argv;dot_pos= NULL; @@ -1112,19 +1199,19 @@ if(*s=='.')dot_pos= s++; else if(*s=='/')dot_pos= NULL,name_pos= ++s; else s++; } -if(!found_web)/*71:*/ -#line 1292 "common.w" +if(!found_web)/*77:*/ +#line 1206 "common.w" { if(s-*argv> max_file_name_length-5) -/*76:*/ -#line 1364 "common.w" +/*82:*/ +#line 1276 "common.w" fatal("! Filename too long\n",*argv); -/*:76*/ -#line 1295 "common.w" -; +/*:82*/ +#line 1209 "common.w" + if(dot_pos==NULL) sprintf(web_file_name,"%s.w",*argv); else{ @@ -1136,50 +1223,49 @@ sprintf(tex_file_name,"%s.tex",name_pos); sprintf(idx_file_name,"%s.idx",name_pos); sprintf(scn_file_name,"%s.scn",name_pos); sprintf(C_file_name,"%s.c",name_pos); -found_web= 1; +found_web= true; } -/*:71*/ -#line 1275 "common.w" +/*:77*/ +#line 1188 "common.w" -else if(!found_change)/*72:*/ -#line 1310 "common.w" +else if(!found_change)/*78:*/ +#line 1224 "common.w" { -if(strcmp(*argv,"-")==0)found_change= -1; -else{ +if(strcmp(*argv,"-")!=0){ if(s-*argv> max_file_name_length-4) -/*76:*/ -#line 1364 "common.w" +/*82:*/ +#line 1276 "common.w" fatal("! Filename too long\n",*argv); -/*:76*/ -#line 1315 "common.w" -; +/*:82*/ +#line 1228 "common.w" + if(dot_pos==NULL) sprintf(change_file_name,"%s.ch",*argv); else strcpy(change_file_name,*argv); -found_change= 1; } +found_change= true; } -/*:72*/ -#line 1276 "common.w" +/*:78*/ +#line 1189 "common.w" -else if(!found_out)/*73:*/ -#line 1323 "common.w" +else if(!found_out)/*79:*/ +#line 1236 "common.w" { if(s-*argv> max_file_name_length-5) -/*76:*/ -#line 1364 "common.w" +/*82:*/ +#line 1276 "common.w" fatal("! Filename too long\n",*argv); -/*:76*/ -#line 1326 "common.w" -; +/*:82*/ +#line 1239 "common.w" + if(dot_pos==NULL){ sprintf(tex_file_name,"%s.tex",*argv); sprintf(idx_file_name,"%s.idx",*argv); @@ -1188,20 +1274,20 @@ sprintf(C_file_name,"%s.c",*argv); }else{ strcpy(tex_file_name,*argv); strcpy(C_file_name,*argv); -if(flags['x']){ +if(make_xrefs){ *dot_pos= 0; sprintf(idx_file_name,"%s.idx",*argv); sprintf(scn_file_name,"%s.scn",*argv); } } -found_out= 1; +found_out= true; } -/*:73*/ -#line 1277 "common.w" +/*:79*/ +#line 1190 "common.w" -else/*75:*/ -#line 1352 "common.w" +else/*81:*/ +#line 1264 "common.w" { if(program==ctangle) @@ -1214,13 +1300,13 @@ else fatal( ,""); } -/*:75*/ -#line 1278 "common.w" -; +/*:81*/ +#line 1191 "common.w" + } } -if(!found_web)/*75:*/ -#line 1352 "common.w" +if(!found_web)/*81:*/ +#line 1264 "common.w" { if(program==ctangle) @@ -1233,10 +1319,9 @@ else fatal( ,""); } -/*:75*/ -#line 1281 "common.w" -; -if(found_change<=0)strcpy(change_file_name,"/dev/null"); +/*:81*/ +#line 1194 "common.w" + } -/*:70*/ +/*:75*/ diff --git a/web/c_cpp/cweb/common.h b/web/c_cpp/cweb/common.h index d6c0bfb601..425239f1c7 100644 --- a/web/c_cpp/cweb/common.h +++ b/web/c_cpp/cweb/common.h @@ -2,7 +2,7 @@ % This program by Silvio Levy and Donald E. Knuth % is based on a program by Knuth. % It is distributed WITHOUT ANY WARRANTY, express or implied. -% Version 3.64 --- February 2017 (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 @@ -15,25 +15,42 @@ % entire resulting derived work is distributed under the terms of a % permission notice identical to this one. -% Please send comments, suggestions, etc. to levy@@math.berkeley.edu. +% Amendments to 'common.h' resulting in this updated version were created +% by numerous collaborators over the course of many years. + +% Please send comments, suggestions, etc. to tex-k@@tug.org. % The next few sections contain stuff from the file |"common.w"| that has % to be included in both |"ctangle.w"| and |"cweave.w"|. It appears in this -% file |"common.h"|, which needs to be updated when |"common.w"| changes. +% file |"common.h"|, which is also included in |"common.w"| to propagate +% possible changes from this single source consistently. First comes general stuff: -@d ctangle 0 -@d cweave 1 +@s boolean int +@s uint8_t int +@s uint16_t int + +@d ctangle false +@d cweave true -@= -typedef short boolean; -typedef char unsigned eight_bits; +@= +typedef bool boolean; +typedef uint8_t eight_bits; +typedef uint16_t sixteen_bits; extern boolean program; /* \.{CWEAVE} or \.{CTANGLE}? */ extern int phase; /* which phase are we in? */ -@ @= -#include +@ Interface to the standard \CEE/ library: + +@= +#include /* definition of |@!isalpha|, |@!isdigit| and so on */ +#include /* definition of |@!bool|, |@!true| and |@!false| */ +#include /* definition of |@!ptrdiff_t| */ +#include /* definition of |@!uint8_t| and |@!uint16_t| */ +#include /* definition of |@!getenv| and |@!exit| */ +#include /* definition of |@!printf| and friends */ +#include /* definition of |@!strlen|, |@!strcmp| and so on */ @ Code related to the character set: @^ASCII code dependencies@> @@ -44,7 +61,7 @@ extern int phase; /* which phase are we in? */ @d plus_plus 013 /* `\.{++}'\,; corresponds to MIT's {\tentex\char'13} */ @d minus_minus 01 /* `\.{--}'\,; corresponds to MIT's {\tentex\char'1} */ @d minus_gt 031 /* `\.{->}'\,; corresponds to MIT's {\tentex\char'31} */ -@d not_eq 032 /* `\.{!=}'\,; corresponds to MIT's {\tentex\char'32} */ +@d non_eq 032 /* `\.{!=}'\,; corresponds to MIT's {\tentex\char'32} */ @d lt_eq 034 /* `\.{<=}'\,; corresponds to MIT's {\tentex\char'34} */ @d gt_eq 035 /* `\.{>=}'\,; corresponds to MIT's {\tentex\char'35} */ @d eq_eq 036 /* `\.{==}'\,; corresponds to MIT's {\tentex\char'36} */ @@ -55,34 +72,69 @@ extern int phase; /* which phase are we in? */ @d minus_gt_ast 027 /* `\.{->*}'\,; corresponds to MIT's {\tentex\char'27} */ @= -char section_text[longest_name+1]; /* name being sought for */ -char *section_text_end = section_text+longest_name; /* end of |section_text| */ -char *id_first; /* where the current identifier begins in the buffer */ -char *id_loc; /* just after the current identifier in the buffer */ +extern char section_text[]; /* text being sought for */ +extern char *section_text_end; /* end of |section_text| */ +extern char *id_first; /* where the current identifier begins in the buffer */ +extern char *id_loc; /* just after the current identifier in the buffer */ @ Code related to input routines: - -@d xisalpha(c) (isalpha(c)&&((eight_bits)c<0200)) -@d xisdigit(c) (isdigit(c)&&((eight_bits)c<0200)) -@d xisspace(c) (isspace(c)&&((eight_bits)c<0200)) -@d xislower(c) (islower(c)&&((eight_bits)c<0200)) -@d xisupper(c) (isupper(c)&&((eight_bits)c<0200)) -@d xisxdigit(c) (isxdigit(c)&&((eight_bits)c<0200)) +@d xisalpha(c) (isalpha((eight_bits)c)&&((eight_bits)c<0200)) +@d xisdigit(c) (isdigit((eight_bits)c)&&((eight_bits)c<0200)) +@d xisspace(c) (isspace((eight_bits)c)&&((eight_bits)c<0200)) +@d xislower(c) (islower((eight_bits)c)&&((eight_bits)c<0200)) +@d xisupper(c) (isupper((eight_bits)c)&&((eight_bits)c<0200)) +@d xisxdigit(c) (isxdigit((eight_bits)c)&&((eight_bits)c<0200)) @= extern char buffer[]; /* where each line of input goes */ extern char *buffer_end; /* end of |buffer| */ -extern char *loc; /* points to the next character to be read from the 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) (c+1)->byte_start-(c)->byte_start /* the length of a name */ +@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 */ @d llink link /* left link in binary search tree for section names */ @d rlink dummy.Rlink /* right link in binary search tree for section names */ @d root name_dir->rlink /* the root of the binary search tree for section names */ -@d chunk_marker 0 @= typedef struct name_info { @@ -93,22 +145,30 @@ typedef struct name_info { names */ char Ilk; /* used by identifiers in \.{CWEAVE} only */ } dummy; - char *equiv_or_xref; /* info corresponding to names */ + void *equiv_or_xref; /* info corresponding to names */ } name_info; /* contains information about an identifier or section name */ typedef name_info *name_pointer; /* pointer into array of \&{name\_info}s */ typedef name_pointer *hash_pointer; extern char byte_mem[]; /* characters of names */ extern char *byte_mem_end; /* end of |byte_mem| */ +extern char *byte_ptr; /* first unused position in |byte_mem| */ extern name_info name_dir[]; /* information about names */ extern name_pointer name_dir_end; /* end of |name_dir| */ extern name_pointer name_ptr; /* first unused position in |name_dir| */ -extern char *byte_ptr; /* first unused position in |byte_mem| */ extern name_pointer hash[]; /* heads of hash lists */ extern hash_pointer hash_end; /* end of |hash| */ extern hash_pointer h; /* index into hash-head array */ -extern name_pointer id_lookup(); /* looks up a string in the identifier table */ -extern name_pointer section_lookup(); /* finds section name */ -extern void print_section_name(), sprint_section_name(); + +@ @= +extern boolean names_match(name_pointer,const char *,size_t,eight_bits);@/ +extern name_pointer id_lookup(const char *,const char *,char); + /* looks up a string in the identifier table */ +extern name_pointer section_lookup(char *,char *,int); /* finds section name */ +extern void init_node(name_pointer);@/ +extern void init_p(name_pointer,eight_bits);@/ +extern void print_prefix_name(name_pointer);@/ +extern void print_section_name(name_pointer);@/ +extern void sprint_section_name(char *,name_pointer); @ Code related to error handling: @d spotless 0 /* |history| value for normal jobs */ @@ -118,67 +178,39 @@ extern void print_section_name(), sprint_section_name(); @d mark_harmless {if (history==spotless) history=harmless_message;} @d mark_error history=error_message @d confusion(s) fatal("! This can't happen: ",s) - -@= -extern history; /* indicates how bad this run was */ -extern err_print(); /* print error message and context */ -extern wrap_up(); /* indicate |history| and exit */ -extern void fatal(); /* issue error message and die */ -extern void overflow(); /* succumb because a table has overflowed */ - -@ Code related to file handling: -@f line x /* make |line| an unreserved word */ -@d max_file_name_length 60 -@d cur_file file[include_depth] /* current file */ -@d cur_file_name file_name[include_depth] /* current file name */ -@d web_file_name file_name[0] /* main source file name */ -@d cur_line line[include_depth] /* number of current line in current file */ +@.This can't happen@> @= -extern 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 line[]; /* number of current line in the stacked files */ -extern change_line; /* number of current line in change file */ -extern 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 reset_input(); /* initialize to read the web file and change file */ -extern get_line(); /* inputs the next line */ -extern check_complete(); /* checks that all changes were picked up */ +extern int history; /* indicates how bad this run was */ -@ Code related to section numbers: -@= -typedef unsigned short sixteen_bits; -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 */ +@ @= +extern int wrap_up(void); /* indicate |history| and exit */ +extern void err_print(const char *); /* print error message and context */ +extern void fatal(const char *,const char *); /* issue error message and die */ +extern void overflow(const char *); /* succumb because a table has overflowed */ @ 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? */ +@d show_stats flags['s'] /* should statistics be printed at end of run? */ @d show_happiness flags['h'] /* should lack of errors be announced? */ +@d make_xrefs flags['x'] /* should cross references be output? */ @= 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) @d C_printf(c,a) fprintf(C_file,c,a) -@d C_putc(c) putc(c,C_file) +@d C_putc(c) putc(c,C_file) /* isn't \CEE/ wonderfully consistent? */ @= extern FILE *C_file; /* where output of \.{CTANGLE} goes */ @@ -188,6 +220,24 @@ extern FILE *scn_file; /* where list of sections from \.{CWEAVE} goes */ extern FILE *active_file; /* currently active file for \.{CWEAVE} output */ @ The procedure that gets everything rolling: - -@= -extern void common_init(); +@= +extern void common_init(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 +\.{CWEB}. + +@d max_bytes 1000000 /* the number of bytes in identifiers, + index entries, and section names */ +@d max_toks 1000000 /* number of bytes in compressed \CEE/ code */ +@d max_names 10239 /* number of identifiers, strings, section names; + must be less than 10240 */ +@d max_sections 4000 /* greater than the total number of sections */ +@d max_texts 10239 /* number of replacement texts, must be less than 10240 */ +@d longest_name 10000 /* file and section names and section texts shouldn't be longer than this */ +@d stack_size 500 /* number of simultaneous levels of macro expansion */ +@d buf_size 1000 /* maximum length of input line, plus one */ +@d long_buf_size (buf_size+longest_name) /* for \.{CWEAVE} */ + +@ End of \.{COMMON} interface. diff --git a/web/c_cpp/cweb/common.w b/web/c_cpp/cweb/common.w index d8aacfb7b9..15e93c2c5e 100644 --- a/web/c_cpp/cweb/common.w +++ b/web/c_cpp/cweb/common.w @@ -2,7 +2,7 @@ % This program by Silvio Levy and Donald E. Knuth % is based on a program by Knuth. % It is distributed WITHOUT ANY WARRANTY, express or implied. -% Version 3.64 --- January 2002 +% Version 4.2 --- February 2021 % Copyright (C) 1987,1990,1993,2000 Silvio Levy and Donald E. Knuth @@ -15,14 +15,19 @@ % entire resulting derived work is given a different name and distributed % under the terms of a permission notice identical to this one. +% Amendments to 'common.w' resulting in this updated version were created +% by numerous collaborators over the course of many years. + +% Please send comments, suggestions, etc. to tex-k@@tug.org. + \def\v{\char'174} % vertical (|) in typewriter font -\def\title{Common code for CTANGLE and CWEAVE (Version 3.64)} +\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 3.64)} + \centerline{(Version 4.2)} \vfill} \def\botofcontents{\vfill \noindent @@ -41,7 +46,10 @@ under the terms of a permission notice identical to this one. \pageno=\contentspagenumber \advance\pageno by 1 \let\maybe=\iftrue -@s not_eq normal @q unreserve a C++ keyword @> + +@s boolean int +@s uint8_t int +@s uint16_t int @** Introduction. This file contains code common to both \.{CTANGLE} and \.{CWEAVE}, which roughly concerns the following @@ -58,20 +66,21 @@ The file begins with a few basic definitions. @c @@/ @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. + +@i common.h @ In certain cases \.{CTANGLE} and \.{CWEAVE} should do almost, but not quite, the same thing. In these cases we've written common code for both, differentiating between the two by means of the global variable |program|. -@d ctangle 0 -@d cweave 1 - -@= -typedef short boolean; +@= boolean program; /* \.{CWEAVE} or \.{CTANGLE}? */ @ \.{CWEAVE} operates in three phases: First it inputs the source @@ -80,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 @@ -88,29 +98,26 @@ procedure later. @c void -common_init() +common_init(void) { - @; - @; - @; + @@; + @@; + @@; } @* The character set. \.{CWEB} uses the conventions of \CEE/ programs found in the standard \.{ctype.h} header file. -@= -#include +A few character pairs are encoded internally as single characters, +using the definitions in the interface sections above. These definitions +are consistent with an extension of ASCII code originally developed at +MIT and explained in Appendix~C of {\sl The \TEX/book\/}; thus, users +who have such a character set can type things like \.{\char'32} and +\.{\char'4} instead of \.{!=} and \.{\&\&}. (However, their files will +not be too portable until more people adopt the extended code.) -@ A few character pairs are encoded internally as single characters, -using the definitions below. These definitions are consistent with -an extension of ASCII code originally developed at MIT and explained in -Appendix~C of {\sl The \TEX/book\/}; thus, users who have such a -character set can type things like \.{\char'32} and \.{\char'4} instead -of \.{!=} and \.{\&\&}. (However, their files will not be too portable -until more people adopt the extended code.) - -If the character set is not ASCII, the definitions given here may conflict +If the character set is not ASCII, the definitions given may conflict with existing characters; in such cases, other arbitrary codes should be substituted. The indexes to \.{CTANGLE} and \.{CWEAVE} mention every case where similar codes may have to be changed in order to @@ -120,26 +127,16 @@ in those indexes. @^ASCII code dependencies@> @^system dependencies@> -@d and_and 04 /* `\.{\&\&}'\,; corresponds to MIT's {\tentex\char'4} */ -@d lt_lt 020 /* `\.{<<}'\,; corresponds to MIT's {\tentex\char'20} */ -@d gt_gt 021 /* `\.{>>}'\,; corresponds to MIT's {\tentex\char'21} */ -@d plus_plus 013 /* `\.{++}'\,; corresponds to MIT's {\tentex\char'13} */ -@d minus_minus 01 /* `\.{--}'\,; corresponds to MIT's {\tentex\char'1} */ -@d minus_gt 031 /* `\.{->}'\,; corresponds to MIT's {\tentex\char'31} */ -@d not_eq 032 /* `\.{!=}'\,; corresponds to MIT's {\tentex\char'32} */ -@d lt_eq 034 /* `\.{<=}'\,; corresponds to MIT's {\tentex\char'34} */ -@d gt_eq 035 /* `\.{>=}'\,; corresponds to MIT's {\tentex\char'35} */ -@d eq_eq 036 /* `\.{==}'\,; corresponds to MIT's {\tentex\char'36} */ -@d or_or 037 /* `\.{\v\v}'\,; corresponds to MIT's {\tentex\char'37} */ -@d dot_dot_dot 016 /* `\.{...}'\,; corresponds to MIT's {\tentex\char'16} */ -@d colon_colon 06 /* `\.{::}'\,; corresponds to MIT's {\tentex\char'6} */ -@d period_ast 026 /* `\.{.*}'\,; corresponds to MIT's {\tentex\char'26} */ -@d minus_gt_ast 027 /* `\.{->*}'\,; corresponds to MIT's {\tentex\char'27} */ +@= +char section_text[longest_name+1]; /* text being sought for */ +char *section_text_end = section_text+longest_name; /* end of |section_text| */ +char *id_first; /* where the current identifier begins in the buffer */ +char *id_loc; /* just after the current identifier in the buffer */ @** Input routines. The lowest level of input to the \.{CWEB} programs is performed by |input_ln|, which must be told which file to read from. -The return value of |input_ln| is 1 if the read is successful and 0 if -not (generally this means the file has ended). The conventions +The return value of |input_ln| is |true| if the read is successful and +|false| if not (generally this means the file has ended). The conventions of \TEX/ are followed; i.e., the characters of the next line of the file are copied into the |buffer| array, and the global variable |limit| is set to the first unoccupied position. @@ -150,32 +147,23 @@ Since |buf_size| is strictly less than |long_buf_size|, some of \.{CWEB}'s routines use the fact that it is safe to refer to |*(limit+2)| without overstepping the bounds of the array. -@d buf_size 100 /* for \.{CWEAVE} and \.{CTANGLE} */ -@d longest_name 10000 -@d long_buf_size (buf_size+longest_name) /* for \.{CWEAVE} */ -@d xisspace(c) (isspace(c)&&((unsigned char)c<0200)) -@d xisupper(c) (isupper(c)&&((unsigned char)c<0200)) - -@= +@= 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 */ - -@ @= -#include +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@> @c -int input_ln(fp) /* copies a line into |buffer| or returns 0 */ -FILE *fp; /* what file to read from */ +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 */ { register int c=EOF; /* character read; initialized so some compilers won't complain */ register char *k; /* where next character goes */ - if (feof(fp)) return(0); /* we have hit end-of-file */ + if (feof(fp)) return false; /* we have hit end-of-file */ limit = k = buffer; /* beginning of buffer */ while (k<=buffer_end && (c=getc(fp)) != EOF && c!='\n') if ((*(k++) = c) != ' ') limit = k; @@ -183,12 +171,14 @@ FILE *fp; /* what file to read from */ if ((c=getc(fp))!=EOF && c!='\n') { ungetc(c,fp); loc=buffer; err_print("! Input line too long"); @.Input line too long@> - } - if (c==EOF && limit==buffer) return(0); /* there was nothing after + } + if (c==EOF && limit==buffer) return false; /* there was nothing after the last newline */ - return(1); + 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 @@ -201,32 +191,22 @@ from the |change_file|. The line number of each open file is also kept for error reporting and for the benefit of \.{CTANGLE}. -@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 60 -@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 */ - -@= +@= int include_depth; /* current level of nesting */ FILE *file[max_include_depth]; /* stack of non-change files */ 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 */ boolean input_has_ended; /* if there is no more input */ boolean changing; /* if the current line is from |change_file| */ -boolean web_file_open=0; /* if the web file is being read */ +boolean web_file_open=false; /* if the web file is being read */ -@ When |changing==0|, the next line of |change_file| is kept in +@ When |changing==false|, the next line of |change_file| is kept in |change_buffer|, for purposes of comparison with the next line of |cur_file|. After the change file has been completely input, we set |change_limit=change_buffer|, @@ -234,41 +214,43 @@ so that no further matches will be made. Here's a shorthand expression for inequality between the two lines: -@d lines_dont_match (change_limit-change_buffer != limit-buffer || - strncmp(buffer, change_buffer, limit-buffer)) +@d lines_dont_match (change_limit-change_buffer != limit-buffer || @| + 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. Since blank lines in the change file are not used for matching, we have |(change_limit==change_buffer && !changing)| if and only if the change file is exhausted. This procedure is called only when -|changing| is 1; hence error messages will be reported correctly. +|changing| is |true|; hence error messages will be reported correctly. @c -void -prime_the_change_buffer() +static void +prime_the_change_buffer(void) { change_limit=change_buffer; /* this value is used if the change file ends */ - @; - @; - @; + @@; + @@; + @@; } +@ @=@+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). @= -while(1) { +while(true) { change_line++; if (!input_ln(change_file)) return; if (limit= { - change_limit=change_buffer+(limit-buffer); - strncpy(change_buffer,buffer,limit-buffer+1); + change_limit=change_buffer+(ptrdiff_t)(limit-buffer); + strncpy(change_buffer,buffer,(size_t)(limit-buffer+1)); } @ The following procedure is used to see if the next change entry should -go into effect; it is called only when |changing| is 0. +go into effect; it is called only when |changing| is |false|. The idea is to test whether or not the current contents of |buffer| matches the current contents of |change_buffer|. If not, there's nothing more to do; but if so, a change is called for: @@ -306,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 - change_limit=change_buffer; changing=0; + change_limit=change_buffer; changing=false; return; } if (limit>buffer+1 && buffer[0]=='@@') { - char xyz_code=xisupper(buffer[1])? tolower(buffer[1]): buffer[1]; + char xyz_code=xisupper(buffer[1])? tolower((eight_bits)buffer[1]): buffer[1]; @; + report any discrepancies and |return|@>@; } - @; - changing=0; cur_line++; + @@; + changing=false; cur_line++; while (!input_ln(cur_file)) { /* pop the stack or quit */ if (include_depth==0) { err_print("! CWEB file ended during a change"); @.CWEB file ended...@> - input_has_ended=1; return; + input_has_ended=true; return; } include_depth--; cur_line++; } @@ -355,6 +337,8 @@ check_change() /* 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?"); @@ -377,14 +361,14 @@ phases one and two of \.{CWEAVE}. @c void -reset_input() +reset_input(void) { limit=buffer; loc=buffer+1; buffer[0]=' '; - @; + @@; include_depth=0; cur_line=0; change_line=0; change_depth=include_depth; changing=1; prime_the_change_buffer(); changing=!changing; - limit=buffer; loc=buffer+1; buffer[0]=' '; input_has_ended=0; + limit=buffer; loc=buffer+1; buffer[0]=' '; input_has_ended=false; } @ The following code opens the input files. @@ -398,7 +382,7 @@ if ((web_file=fopen(web_file_name,"r"))==NULL) { } @.Cannot open input file@> @.Cannot open change file@> -web_file_open=1; +web_file_open=true; if ((change_file=fopen(change_file_name,"r"))==NULL) fatal("! Cannot open change file ", change_file_name); @@ -412,28 +396,24 @@ If we've just changed from the |cur_file| to the |change_file|, or if the |cur_file| has changed, we tell \.{CTANGLE} to print this information in the \CEE/ file by means of the |print_where| flag. -@d max_sections 2000 /* number of identifiers, strings, section names; - must be less than 10240 */ - -@= -typedef unsigned short sixteen_bits; +@= sixteen_bits section_count; /* the current section number */ boolean changed_section[max_sections]; /* is the section changed? */ boolean change_pending; /* if the current change is not yet recorded in |changed_section[section_count]| */ -boolean print_where=0; /* should \.{CTANGLE} print line and file info? */ +boolean print_where=false; /* should \.{CTANGLE} print line and file info? */ @ @c -int get_line() /* inputs the next line */ +boolean get_line(void) /* inputs the next line */ { restart: if (changing && include_depth==change_depth) - @; + @@; if (! changing || include_depth>change_depth) { - @; + @@; if (changing && include_depth==change_depth) goto restart; } - if (input_has_ended) return 0; + if (input_has_ended) return false; loc=buffer; *limit=' '; if (buffer[0]=='@@' && (buffer[1]=='i' || buffer[1]=='I')) { loc=buffer+2; *limit='"'; @@ -449,9 +429,9 @@ int get_line() /* inputs the next line */ goto restart; } include_depth++; /* push input stack */ - @; + @@; } - return 1; + return true; } @ When an \.{@@i} line is found in the |cur_file|, we must temporarily @@ -468,10 +448,7 @@ The remainder of the \.{@@i} line after the file name is ignored. @d too_long() {include_depth--; err_print("! Include file name too long"); goto restart;} -@= -#include /* declaration of |getenv| and |exit| */ - -@ @= { +@.CWEBINPUTS@>@= { char temp_file_name[max_file_name_length]; char *cur_file_name_end=cur_file_name+max_file_name_length-1; char *k=cur_file_name, *kk; @@ -487,7 +464,7 @@ The remainder of the \.{@@i} line after the file name is ignored. @.Include file name ...@> *k='\0'; if ((cur_file=fopen(cur_file_name,"r"))!=NULL) { - cur_line=0; print_where=1; + cur_line=0; print_where=true; goto restart; /* success */ } kk=getenv("CWEBINPUTS"); @@ -510,7 +487,7 @@ The remainder of the \.{@@i} line after the file name is ignored. strcpy(cur_file_name,temp_file_name); cur_file_name[l]='/'; /* \UNIX/ pathname separator */ if ((cur_file=fopen(cur_file_name,"r"))!=NULL) { - cur_line=0; print_where=1; + cur_line=0; print_where=true; goto restart; /* success */ } } @@ -520,8 +497,8 @@ The remainder of the \.{@@i} line after the file name is ignored. @ @= { cur_line++; while (!input_ln(cur_file)) { /* pop the stack or quit */ - print_where=1; - if (include_depth==0) {input_has_ended=1; break;} + print_where=true; + if (include_depth==0) {input_has_ended=true; break;} else { fclose(cur_file); include_depth--; if (changing && include_depth==change_depth) break; @@ -543,21 +520,21 @@ The remainder of the \.{@@i} line after the file name is ignored. } if (limit>buffer) { /* check if the change has ended */ if (change_pending) { - if_section_start_make_pending(0); + if_section_start_make_pending(false); if (change_pending) { - changed_section[section_count]=1; change_pending=0; + changed_section[section_count]=true; change_pending=false; } } *limit=' '; if (buffer[0]=='@@') { - if (xisupper(buffer[1])) buffer[1]=tolower(buffer[1]); + if (xisupper(buffer[1])) buffer[1]=tolower((eight_bits)buffer[1]); if (buffer[1]=='x' || buffer[1]=='y') { loc=buffer+2; err_print("! Where is the matching @@z?"); @.Where is the match...@> } else if (buffer[1]=='z') { - prime_the_change_buffer(); changing=!changing; print_where=1; + prime_the_change_buffer(); changing=!changing; print_where=true; } } } @@ -568,11 +545,11 @@ had a line that didn't match any relevant line in |web_file|. @c void -check_complete(){ - if (change_limit!=change_buffer) { /* |changing| is 0 */ - strncpy(buffer,change_buffer,change_limit-change_buffer+1); - limit=buffer+(int)(change_limit-change_buffer); - changing=1; change_depth=include_depth; loc=buffer; +check_complete(void) { + if (change_limit!=change_buffer) { /* |changing| is |false| */ + strncpy(buffer,change_buffer,(size_t)(change_limit-change_buffer+1)); + limit=buffer+(ptrdiff_t)(change_limit-change_buffer); + changing=true; change_depth=include_depth; loc=buffer; err_print("! Change file entry did not match"); @.Change file entry did not match@> } @@ -584,52 +561,58 @@ other strings in a large array of |char|s, called |byte_mem|. Information about the names is kept in the array |name_dir|, whose elements are structures of type |name_info|, containing a pointer into the |byte_mem| array (the address where the name begins) and other data. -A |name_pointer| variable is a pointer into |name_dir|. - -@d max_bytes 90000 /* the number of bytes in identifiers, - index entries, and section names; must be less than $2^{24}$ */ -@d max_names 4000 /* number of identifiers, strings, section names; - must be less than 10240 */ - -@= -typedef struct name_info { - char *byte_start; /* beginning of the name in |byte_mem| */ - @@; -} name_info; /* contains information about an identifier or section name */ -typedef name_info *name_pointer; /* pointer into array of |name_info|s */ +A |name_pointer| variable is a pointer into |name_dir|. You find the +complete layout of |name_info| in the interface sections above. + +The actual sequence of characters in the name pointed to by a |name_pointer +p| appears in positions |p->byte_start| to |(p+1)->byte_start-1|, inclusive. + +The names of identifiers are found by computing a hash address |h| and +then looking at strings of bytes signified by the |name_pointer|s +|hash[h]|, |hash[h]->link|, |hash[h]->link->link|, \dots, +until either finding the desired name or encountering the null pointer. + +The names of sections are stored in |byte_mem| together +with the identifier names, but a hash table is not used for them because +\.{CTANGLE} needs to be able to recognize a section name when given a prefix of +that name. A conventional binary search tree is used to retrieve section names, +with fields called |llink| and |rlink| (where |llink| takes the place +of |link|). The root of this tree is stored in |name_dir->rlink|; +this will be the only information in |name_dir[0]|. + +Since the space used by |rlink| has a different function for +identifiers than for section names, we declare it as a |union|. + +The last component of |name_info| is different for \.{CTANGLE} and +\.{CWEAVE}. In \.{CTANGLE}, if |p| is a pointer to a section name, +|p->equiv| is a pointer to its replacement text, an element of the +array |text_info|. In \.{CWEAVE}, on the other hand, if +|p| points to an identifier, |p->xref| is a pointer to its +list of cross-references, an element of the array |xmem|. The make-up +of |text_info| and |xmem| is discussed in the \.{CTANGLE} and \.{CWEAVE} +source files, respectively; here we just declare a common field +|equiv_or_xref| as a pointer to |void|. + +@= char byte_mem[max_bytes]; /* characters of names */ char *byte_mem_end = byte_mem+max_bytes-1; /* end of |byte_mem| */ name_info name_dir[max_names]; /* information about names */ name_pointer name_dir_end = name_dir+max_names-1; /* end of |name_dir| */ -@ The actual sequence of characters in the name pointed to by a |name_pointer -p| appears in positions |p->byte_start| to |(p+1)->byte_start-1|, inclusive. -The |print_id| macro prints this text on the user's terminal. - -@d length(c) (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 */ - @ The first unused position in |byte_mem| and |name_dir| is kept in |byte_ptr| and |name_ptr|, respectively. Thus we 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 */ name_ptr=name_dir+1; /* |name_dir[0]| will be used only for error recovery */ name_ptr->byte_start=byte_mem; /* this makes name 0 of length zero */ - -@ The names of identifiers are found by computing a hash address |h| and -then looking at strings of bytes signified by the |name_pointer|s -|hash[h]|, |hash[h]->link|, |hash[h]->link->link|, \dots, -until either finding the desired name or encountering the null pointer. - -@= -struct name_info *link; +root=NULL; /* the binary search tree starts out with nothing in it */ @ The hash table itself consists of |hash_size| entries of type |name_pointer|, and is @@ -639,17 +622,13 @@ function |names_match|, which is slightly different in \.{CWEAVE} and \.{CTANGLE}. If there is no match for the identifier, it is inserted into the table. -@d hash_size 353 /* should be prime */ +@d hash_size 8501 /* should be prime */ -@= -typedef name_pointer *hash_pointer; +@= name_pointer hash[hash_size]; /* heads of hash lists */ hash_pointer hash_end = hash+hash_size-1; /* end of |hash| */ hash_pointer h; /* index into hash-head array */ -@ @= -extern int names_match(); - @ Initially all the hash lists are empty. @= @@ -659,21 +638,21 @@ for (h=hash; h<=hash_end; *h++=NULL) ; @c name_pointer -id_lookup(first,last,t) /* looks up a string in the identifier table */ -char *first; /* first character of string */ -char *last; /* last character of string plus one */ -char t; /* the |ilk|; used by \.{CWEAVE} only */ +id_lookup(@t\1\1@> /* looks up a string in the identifier table */ +const char *first, /* first character of string */ +const char *last, /* last character of string plus one */ +char t@t\2\2@>) /* the |ilk|; used by \.{CWEAVE} only */ { - char *i=first; /* position in |buffer| */ + const char *i=first; /* position in |buffer| */ int h; /* hash code */ int l; /* length of the given identifier */ name_pointer p; /* where the identifier is being sought */ if (last==NULL) for (last=first; *last!='\0'; last++); - l=last-first; /* compute the length */ - @; - @; - if (p==name_ptr) @; - return(p); + l=(int)(last-first); /* compute the length */ + @@; + @@; + if (p==name_ptr) @@; + return p; } @ A simple hash code is used: If the sequence of @@ -681,8 +660,8 @@ character codes is $c_1c_2\ldots c_n$, its hash value will be $$(2^{n-1}c_1+2^{n-2}c_2+\cdots+c_n)\,\bmod\,|hash_size|.$$ @= -h=(unsigned char)*i; -while (++i @ If the identifier is new, it will be placed in position |p=name_ptr|, @@ -699,44 +678,14 @@ if (p==NULL) { @ The information associated with a new identifier must be initialized in a slightly different way in \.{CWEAVE} than in \.{CTANGLE}; hence the |init_p| procedure. - -@= -void init_p(); - -@ @= { +@= { if (byte_ptr+l>byte_mem_end) overflow("byte memory"); if (name_ptr>=name_dir_end) overflow("name"); strncpy(byte_ptr,first,l); (++name_ptr)->byte_start=byte_ptr+=l; - if (program==cweave) init_p(p,t); + init_p(p,t); } -@ The names of sections are stored in |byte_mem| together -with the identifier names, but a hash table is not used for them because -\.{CTANGLE} needs to be able to recognize a section name when given a prefix of -that name. A conventional binary search tree is used to retrieve section names, -with fields called |llink| and |rlink| (where |llink| takes the place -of |link|). The root of this tree is stored in |name_dir->rlink|; -this will be the only information in |name_dir[0]|. - -Since the space used by |rlink| has a different function for -identifiers than for section names, we declare it as a |union|. - -@d llink link /* left link in binary search tree for section names */ -@d rlink dummy.Rlink /* right link in binary search tree for section names */ -@d root name_dir->rlink /* the root of the binary search tree - for section names */ - -@= -union { - struct name_info *Rlink; /* right link in binary search tree for section - names */ - char Ilk; /* used by identifiers in \.{CWEAVE} only */ -} dummy; - -@ @= -root=NULL; /* the binary search tree starts out with nothing in it */ - @ If |p| is a |name_pointer| variable, as we have seen, |p->byte_start| is the beginning of the area where the name corresponding to |p| is stored. However, if |p| refers to a section @@ -756,24 +705,24 @@ to additional chunks in the same way. Null links are represented by |name_dir|. @d first_chunk(p) ((p)->byte_start+2) -@d prefix_length(p) (int)((unsigned char)*((p)->byte_start)*256 + - (unsigned char)*((p)->byte_start+1)) +@d prefix_length(p) (int)((eight_bits)*((p)->byte_start)*256 + + (eight_bits)*((p)->byte_start+1)) @d set_prefix_length(p,m) (*((p)->byte_start)=(m)/256, *((p)->byte_start+1)=(m)%256) @c void -print_section_name(p) -name_pointer p; +print_section_name( +name_pointer p) { char *ss, *s = first_chunk(p); name_pointer q = p+1; while (p!=name_dir) { ss = (p+1)->byte_start-1; if (*ss==' ' && ss>=s) { - term_write(s,ss-s); p=q->link; q=p; + term_write(s,(size_t)(ss-s)); p=q->link; q=p; } else { - term_write(s,ss+1-s); p=name_dir; q=NULL; + term_write(s,(size_t)(ss+1-s)); p=name_dir; q=NULL; } s = p->byte_start; } @@ -782,9 +731,9 @@ name_pointer p; @ @c void -sprint_section_name(dest,p) - char*dest; - name_pointer p; +sprint_section_name( + char *dest, + name_pointer p) { char *ss, *s = first_chunk(p); name_pointer q = p+1; @@ -795,7 +744,7 @@ sprint_section_name(dest,p) } else { ss++; p=name_dir; } - strncpy(dest,s,ss-s), dest+=ss-s; + strncpy(dest,s,(size_t)(ss-s)), dest+=ss-s; s = p->byte_start; } *dest='\0'; @@ -803,8 +752,8 @@ sprint_section_name(dest,p) @ @c void -print_prefix_name(p) -name_pointer p; +print_prefix_name( +name_pointer p) { char *s = first_chunk(p); int l = prefix_length(p); @@ -822,10 +771,17 @@ are null-terminated, and we keep an eye open for prefixes and extensions. @d prefix 3 /* the first name is a proper prefix of the second */ @d extension 4 /* the first name is a proper extension of the second */ -@c -int web_strcmp(j,j_len,k,k_len) /* fuller comparison than |strcmp| */ - char *j, *k; /* beginning of first and second strings */ - int j_len, k_len; /* length of strings */ +@= +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); + +@ @c +static int web_strcmp(@t\1\1@> /* fuller comparison than |strcmp| */ + char *j, /* beginning of first string */ + int j_len, /* length of first string */ + char *k, /* beginning of second string */ + int k_len@t\2\2@>) /* length of second string */ { char *j1=j+j_len, *k1=k+k_len; while (k= -extern void init_node(); - -@ @c -name_pointer -add_section_name(par,c,first,last,ispref) /* install a new node in the tree */ -name_pointer par; /* parent of new node */ -int c; /* right or left? */ -char *first; /* first character of section name */ -char *last; /* last character of section name, plus one */ -int ispref; /* are we adding a prefix or a full name? */ +@c +static name_pointer +add_section_name(@t\1\1@> /* install a new node in the tree */ +name_pointer par, /* parent of new node */ +int c, /* right or left? */ +char *first, /* first character of section name */ +char *last, /* last character of section name, plus one */ +int ispref@t\2\2@>) /* are we adding a prefix or a full name? */ { name_pointer p=name_ptr; /* new node */ char *s=first_chunk(p); - int name_len=last-first+ispref; /* length of section name */ + int name_len=(int)(last-first)+ispref; /* length of section name */ if (s+name_len>byte_mem_end) overflow("byte memory"); if (name_ptr+1>=name_dir_end) overflow("name"); (++name_ptr)->byte_start=byte_ptr=s+name_len; @@ -882,16 +835,16 @@ int ispref; /* are we adding a prefix or a full name? */ } @ @c -void -extend_section_name(p,first,last,ispref) -name_pointer p; /* name to be extended */ -char *first; /* beginning of extension text */ -char *last; /* one beyond end of extension text */ -int ispref; /* are we adding a prefix or a full name? */ +static void +extend_section_name(@t\1\1@> +name_pointer p, /* name to be extended */ +char *first, /* beginning of extension text */ +char *last, /* one beyond end of extension text */ +int ispref@t\2\2@>) /* are we adding a prefix or a full name? */ { char *s; name_pointer q=p+1; - int name_len=last-first+ispref; + int name_len=(int)(last-first)+ispref; if (name_ptr>=name_dir_end) overflow("name"); while (q->link!=name_dir) q=q->link; q->link=name_ptr; @@ -911,9 +864,9 @@ exactly equals or is a prefix or extension of a name in the tree. @c name_pointer -section_lookup(first,last,ispref) /* find or install section name in tree */ -char *first, *last; /* first and last characters of new name */ -int ispref; /* is the new name a prefix or a full name? */ +section_lookup(@t\1\1@> /* find or install section name in tree */ +char *first,char *last, /* first and last characters of new name */ +int ispref@t\2\2@>) /* is the new name a prefix or a full name? */ { int c=0; /* comparison between two names; initialized so some compilers won't complain */ name_pointer p=root; /* current node of the search tree */ @@ -921,11 +874,11 @@ int ispref; /* is the new name a prefix or a full name? */ name_pointer r=NULL; /* where a match has been found */ name_pointer par=NULL; /* parent of |p|, if |r| is |NULL|; otherwise parent of |r| */ - int name_len=last-first+1; + int name_len=(int)(last-first)+1; @; - @; - @; + if more than one is found@>@; + @@; + @@; } @ A legal new name matches an existing section name if and only if it @@ -942,10 +895,10 @@ while (p) { /* compare shortest prefix of |p| with new name */ p=(c==less?p->llink:p->rlink); } else { /* new name matches |p| */ if (r!=NULL) { /* and also |r|: illegal */ - printf("\n! Ambiguous prefix: matches <"); + fputs("\n! Ambiguous prefix: matches <",stdout); @.Ambiguous prefix ... @> print_prefix_name(p); - printf(">\n and <"); + fputs(">\n and <",stdout); print_prefix_name(r); err_print(">"); return name_dir; /* the unsection */ @@ -971,7 +924,7 @@ switch(section_name_cmp(&first,name_len,r)) { /* compare all of |r| with new name */ case prefix: if (!ispref) { - printf("\n! New name is a prefix of <"); + fputs("\n! New name is a prefix of <",stdout); @.New name is a prefix...@> print_section_name(r); err_print(">"); @@ -983,16 +936,16 @@ switch(section_name_cmp(&first,name_len,r)) { extend_section_name(r,first,last+1,ispref); return r; case bad_extension: - printf("\n! New name extends <"); + fputs("\n! New name extends <",stdout); @.New name extends...@> print_section_name(r); err_print(">"); return r; default: /* no match: illegal */ - printf("\n! Section name incompatible with <"); + fputs("\n! Section name incompatible with <",stdout); @.Section name incompatible...@> print_prefix_name(r); - printf(">,\n which abbreviates <"); + fputs(">,\n which abbreviates <",stdout); print_section_name(r); err_print(">"); return r; @@ -1014,53 +967,39 @@ us to regard \.{@@} as an ``extension'' of itself. @d bad_extension 5 -@= -int section_name_cmp(); - -@ @c -int section_name_cmp(pfirst,len,r) -char **pfirst; /* pointer to beginning of comparison string */ -int len; /* length of string */ -name_pointer r; /* section name being compared */ +@c +static int section_name_cmp(@t\1\1@> +char **pfirst, /* pointer to beginning of comparison string */ +int len, /* length of string */ +name_pointer r@t\2\2@>) /* section name being compared */ { char *first=*pfirst; /* beginning of comparison string */ name_pointer q=r+1; /* access to subsequent chunks */ char *ss, *s=first_chunk(r); int c; /* comparison */ int ispref; /* is chunk |r| a prefix? */ - while (1) { + while (true) { ss=(r+1)->byte_start-1; if (*ss==' ' && ss>=r->byte_start) ispref=1,q=q->link; else ispref=0,ss++,q=name_dir; switch(c=web_strcmp(first,len,s,ss-s)) { case equal: if (q==name_dir) if (ispref) { - *pfirst=first+(ss-s); + *pfirst=first+(ptrdiff_t)(ss-s); return extension; /* null extension */ } else return equal; else return (q->byte_start==(q+1)->byte_start)? equal: prefix; case extension: if (!ispref) return bad_extension; first += ss-s; - if (q!=name_dir) {len -= ss-s; s=q->byte_start; r=q; continue;} + if (q!=name_dir) {len -= (int)(ss-s); s=q->byte_start; r=q; continue;} *pfirst=first; return extension; default: return c; } } } -@ The last component of |name_info| is different for \.{CTANGLE} and -\.{CWEAVE}. In \.{CTANGLE}, if |p| is a pointer to a section name, -|p->equiv| is a pointer to its replacement text, an element of the -array |text_info|. In \.{CWEAVE}, on the other hand, if -|p| points to an identifier, |p->xref| is a pointer to its -list of cross-references, an element of the array |xmem|. The make-up -of |text_info| and |xmem| is discussed in the \.{CTANGLE} and \.{CWEAVE} -source files, respectively; here we just declare a common field -|equiv_or_xref| as a pointer to a |char|. - -@= -char *equiv_or_xref; /* info corresponding to names */ +@ @=@+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 @@ -1072,14 +1011,7 @@ terminated abnormally. The value of |history| does not influence the behavior of the program; it is simply computed for the convenience of systems that might want to use such information. -@d spotless 0 /* |history| value for normal jobs */ -@d harmless_message 1 /* |history| value when non-serious info was printed */ -@d error_message 2 /* |history| value when an error was noted */ -@d fatal_message 3 /* |history| value when we had to stop prematurely */ -@d mark_harmless {if (history==spotless) history=harmless_message;} -@d mark_error history=error_message - -@= +@= int history=spotless; /* indicates how bad this run was */ @ The command `|err_print("! Error message")|' will report a syntax error to @@ -1089,17 +1021,14 @@ Note that no period follows the error message, since the error routine will automatically supply a period. A newline is automatically supplied if the string begins with |"!"|. -@= -void err_print(); - -@ @c +@c void -err_print(s) /* prints `\..' and location of error message */ -char *s; +err_print(@t\1\1@> /* prints `\..' and location of error message */ +const char *s@t\2\2@>) { char *k,*l; /* pointers into |buffer| */ printf(*s=='!'? "\n%s" : "%s",s); - if(web_file_open) @; + if(web_file_open) @@; update_terminal; mark_error; } @@ -1135,52 +1064,46 @@ up and quit as graciously as possible. This is done by calling the function |wrap_up| at the end of the code. \.{CTANGLE} and \.{CWEAVE} have their own notions about how to -print the job statistics. +print the job statistics. See the function(s) |print_stats| in the +interface above and in the index. -@= -int wrap_up(); -extern void print_stats(); - -@ Some implementations may wish to pass the |history| value to the +Some implementations may wish to pass the |history| value to the operating system so that it can be used to govern whether or not other programs are started. Here, for instance, we pass the operating system a status of 0 if and only if only harmless messages were printed. @^system dependencies@> @c -int wrap_up() { - putchar('\n'); +int wrap_up(void) { + if (show_progress) new_line; if (show_stats) print_stats(); /* print statistics about memory usage */ - @; - if (history > harmless_message) return(1); - else return(0); + @@; + if (history > harmless_message) return EXIT_FAILURE; + else return EXIT_SUCCESS; } @ @= switch (history) { -case spotless: if (show_happiness) printf("(No errors were found.)\n"); break; +case spotless: if (show_happiness) puts("(No errors were found.)"); break; case harmless_message: - printf("(Did you see the warning message above?)\n"); break; + puts("(Did you see the warning message above?)"); break; case error_message: - printf("(Pardon me, but I think I spotted something wrong.)\n"); break; -case fatal_message: printf("(That was a fatal error, my friend.)\n"); + puts("(Pardon me, but I think I spotted something wrong.)"); break; +case fatal_message: puts("(That was a fatal error, my friend.)"); } /* there are no other cases */ @ When there is no way to recover from an error, the |fatal| subroutine is invoked. This happens most often when |overflow| occurs. -@= -void fatal(), overflow(); - -@ The two parameters to |fatal| are strings that are essentially +The two parameters to |fatal| are strings that are essentially concatenated to print the final error message. @c void -fatal(s,t) - char *s,*t; +fatal( + const char *s,const char *t) { - if (*s) printf(s); + if (*s) err_print(s); err_print(t); history=fatal_message; exit(wrap_up()); } @@ -1188,8 +1111,8 @@ fatal(s,t) @ An overflow stop occurs if \.{CWEB}'s tables aren't large enough. @c void -overflow(t) - char *t; +overflow( + const char *t) { printf("\n! Sorry, %s capacity exceeded",t); fatal("",""); } @@ -1200,9 +1123,6 @@ and \.{CWEB} prints an error message that is really for the \.{CWEB} maintenance person, not the user. In such cases the program says |confusion("indication of where we are")|. -@d confusion(s) fatal("! This can't happen: ",s) -@.This can't happen@> - @** Command line arguments. The user calls \.{CWEAVE} and \.{CTANGLE} with arguments on the command line. These are either file names or flags to be turned off (beginning with |"-"|) @@ -1212,12 +1132,7 @@ of the program. The various file name variables contain strings with the names of those files. Most of the 128 flags are undefined but available for future extensions. -@d show_banner flags['b'] /* should the banner line be printed? */ -@d show_progress flags['p'] /* should progress reports be printed? */ -@d show_stats flags['s'] /* should statistics be printed at end of run? */ -@d show_happiness flags['h'] /* should lack of errors be announced? */ - -@= +@= int argc; /* copy of |ac| parameter to |main| */ char **argv; /* copy of |av| parameter to |main| */ char C_file_name[max_file_name_length]; /* name of |C_file| */ @@ -1226,12 +1141,13 @@ char idx_file_name[max_file_name_length]; /* name of |idx_file| */ char scn_file_name[max_file_name_length]; /* name of |scn_file| */ boolean flags[128]; /* an option for each 7-bit code */ -@ The |flags| will be initially zero. Some of them are set to~1 before -scanning the arguments; if additional flags are 1 by default they +@ The |flags| will be initially |false|. Some of them are set to~|true| before +scanning the arguments; if additional flags are |true| by default they should be set before calling |common_init|. @= -show_banner=show_happiness=show_progress=1; +show_banner=show_happiness=show_progress=make_xrefs=true;@/ +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} @@ -1248,20 +1164,17 @@ when no changes are desired. If there's a third file name, it will be the output file. -@= -void scan_args(); - -@ @c -void -scan_args() +@c +static void +scan_args(void) { char *dot_pos; /* position of |'.'| in the argument */ char *name_pos; /* file name beginning, sans directory */ register char *s; /* register for scanning strings */ - boolean found_web=0,found_change=0,found_out=0; + boolean found_web=false,found_change=false,found_out=false; /* have these names been seen? */ - boolean flag_change; + strcpy(change_file_name,"/dev/null"); while (--argc > 0) { if ((**(++argv)=='-'||**argv=='+')&&*(*argv+1)) @@; else { @@ -1275,13 +1188,14 @@ scan_args() |web_file_name|, |tex_file_name|, and |C_file_name|@>@; else if (!found_change) @@; else if (!found_out) @@; - else @; + else @@; } } - if (!found_web) @; - if (found_change<=0) strcpy(change_file_name,"/dev/null"); + 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. @@ -1292,7 +1206,7 @@ after the dot. We must check that there is enough room in @= { if (s-*argv > max_file_name_length-5) - @; + @@; if (dot_pos==NULL) sprintf(web_file_name,"%s.w",*argv); else { @@ -1304,26 +1218,25 @@ after the dot. We must check that there is enough room in sprintf(idx_file_name,"%s.idx",name_pos); sprintf(scn_file_name,"%s.scn",name_pos); sprintf(C_file_name,"%s.c",name_pos); - found_web=1; + found_web=true; } @ @= { - if (strcmp(*argv,"-")==0) found_change=-1; - else { + if (strcmp(*argv,"-")!=0) { if (s-*argv > max_file_name_length-4) - @; + @@; if (dot_pos==NULL) sprintf(change_file_name,"%s.ch",*argv); else strcpy(change_file_name,*argv); - found_change=1; } + found_change=true; } @ @= { if (s-*argv > max_file_name_length-5) - @; + @@; if (dot_pos==NULL) { sprintf(tex_file_name,"%s.tex",*argv); sprintf(idx_file_name,"%s.idx",*argv); @@ -1332,21 +1245,20 @@ after the dot. We must check that there is enough room in } else { strcpy(tex_file_name,*argv); strcpy(C_file_name,*argv); - if (flags['x']) { /* indexes will be generated */ + if (make_xrefs) { /* indexes will be generated */ *dot_pos=0; sprintf(idx_file_name,"%s.idx",*argv); sprintf(scn_file_name,"%s.scn",*argv); } } - found_out=1; + found_out=true; } -@ @= +@ @d flag_change (**argv!='-') +@= { - if (**argv=='-') flag_change=0; - else flag_change=1; for(dot_pos=*argv+1;*dot_pos>'\0';dot_pos++) - flags[*dot_pos]=flag_change; + flags[(eight_bits)*dot_pos]=flag_change; } @ @= @@ -1367,7 +1279,7 @@ else fatal( @** Output. Here is the code that opens the output file: @^system dependencies@> -@= +@= FILE *C_file; /* where output of \.{CTANGLE} goes */ FILE *tex_file; /* where output of \.{CWEAVE} goes */ FILE *idx_file; /* where index from \.{CWEAVE} goes */ @@ -1377,42 +1289,13 @@ FILE *active_file; /* currently active file for \.{CWEAVE} output */ @ @= scan_args(); if (program==ctangle) { - if ((C_file=fopen(C_file_name,"w"))==NULL) + if ((C_file=fopen(C_file_name,"wb"))==NULL) fatal("! Cannot open output file ", C_file_name); @.Cannot open output file@> } else { - if ((tex_file=fopen(tex_file_name,"w"))==NULL) + if ((tex_file=fopen(tex_file_name,"wb"))==NULL) fatal("! Cannot open output file ", tex_file_name); } -@ The |update_terminal| procedure is called when we want -to make sure that everything we have output to the terminal so far has -actually left the computer's internal buffers and been sent. -@^system dependencies@> - -@d update_terminal fflush(stdout) /* empty the terminal output buffer */ - -@ Terminal output uses |putchar| and |putc| when we have to -translate from \.{CWEB}'s code into the external character code, -and |printf| when we just want to print strings. -Several macros make other kinds of output convenient. -@^system dependencies@> -@d new_line putchar('\n') @d putxchar putchar -@d term_write(a,b) fflush(stdout),fwrite(a,sizeof(char),b,stdout) -@d C_printf(c,a) fprintf(C_file,c,a) -@d C_putc(c) putc(c,C_file) /* isn't \CEE/ wonderfully consistent? */ - -@ We predeclare several standard system functions here instead of including -their system header files, because the names of the header files are not as -standard as the names of the functions. (For example, some \CEE/ environments -have \.{} where others have \.{}.) - -@= -extern int strlen(); /* length of string */ -extern int strcmp(); /* compare strings lexicographically */ -extern char* strcpy(); /* copy one string to another */ -extern int strncmp(); /* compare up to $n$ string characters */ -extern char* strncpy(); /* copy up to $n$ string characters */ - @** Index. diff --git a/web/c_cpp/cweb/ctang-bs.ch b/web/c_cpp/cweb/ctang-bs.ch index c4062c4064..55cc27cd00 100644 --- a/web/c_cpp/cweb/ctang-bs.ch +++ b/web/c_cpp/cweb/ctang-bs.ch @@ -17,64 +17,17 @@ by using "huge" pointers. The ``banner line'' defined here should be changed whenever \.{CTANGLE} is modified. -@d banner "This is CTANGLE (Version 3.64)\n" +@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 3.64pc/big)\n" -@z - - -@x Section 4. -@ The following parameters were sufficient in the original \.{TANGLE} to -handle \TEX/, -so they should be sufficient for most applications of \.{CTANGLE}. -If you change |max_bytes|, |max_names| or |hash_size| you should also -change them in the file |"common.w"|. - -@d max_bytes 90000 /* the number of bytes in identifiers, - index entries, and section names; used in |"common.w"| */ -@d max_toks 270000 /* number of bytes in compressed \CEE/ code */ -@d max_names 4000 /* number of identifiers, strings, section names; - must be less than 10240; used in |"common.w"| */ -@d max_texts 2500 /* number of replacement texts, must be less than 10240 */ -@d hash_size 353 /* should be prime; used in |"common.w"| */ -@d longest_name 10000 /* section names shouldn't be longer than this */ -@d stack_size 50 /* number of simultaneous levels of macro expansion */ -@d buf_size 100 /* for \.{CWEAVE} and \.{CTANGLE} */ -@y -@ The following parameters were sufficient in the original \.{TANGLE} to -handle \TEX/, -so they should be sufficient for most applications of \.{CTANGLE}. -If you change |max_bytes|, |max_names| or |hash_size| you should also -change them in the file |"common.w"|. - -(This is a modified version of \.{CTANGLE}, and in fact one of the parameters -has been reduced in value. The parameter |max_toks| -has been reduced from 270000 [which -was sufficient to handle \TEX/] to -170000, so that \.{CTANGLE} -may be run on {\mc MSDOS} -systems that are tight on memory. Consider, for -instance, an 80286-based machine with several TSRs and drivers, trying -to run \.{CTANGLE} from a makefile.) - -@d max_bytes 90000 /* the number of bytes in identifiers, - index entries, and section names; used in |"common.w"| */ -@d max_toks 170000 /* number of bytes in compressed \CEE/ code */ -@d max_names 4000 /* number of identifiers, strings, section names; - must be less than 10240; used in |"common.w"| */ -@d max_texts 2500 /* number of replacement texts, must be less than 10240 */ -@d hash_size 353 /* should be prime; used in |"common.w"| */ -@d longest_name 10000 /* section names shouldn't be longer than this */ -@d stack_size 50 /* number of simultaneous levels of macro expansion */ -@d buf_size 100 /* for \.{CWEAVE} and \.{CTANGLE} */ +@d banner "This is CTANGLE (Version 4.2pc/big)" @z @x Section 9. -@d chunk_marker 0 + for section names */ @= typedef struct name_info { @@ -85,24 +38,21 @@ typedef struct name_info { names */ char Ilk; /* used by identifiers in \.{CWEAVE} only */ } dummy; - char *equiv_or_xref; /* info corresponding to names */ + void *equiv_or_xref; /* info corresponding to names */ } name_info; /* contains information about an identifier or section name */ typedef name_info *name_pointer; /* pointer into array of \&{name\_info}s */ typedef name_pointer *hash_pointer; extern char byte_mem[]; /* characters of names */ extern char *byte_mem_end; /* end of |byte_mem| */ +extern char *byte_ptr; /* first unused position in |byte_mem| */ extern name_info name_dir[]; /* information about names */ extern name_pointer name_dir_end; /* end of |name_dir| */ extern name_pointer name_ptr; /* first unused position in |name_dir| */ -extern char *byte_ptr; /* first unused position in |byte_mem| */ extern name_pointer hash[]; /* heads of hash lists */ extern hash_pointer hash_end; /* end of |hash| */ extern hash_pointer h; /* index into hash-head array */ -extern name_pointer id_lookup(); /* looks up a string in the identifier table */ -extern name_pointer section_lookup(); /* finds section name */ -extern void print_section_name(), sprint_section_name(); @y -@d chunk_marker 0 + for section names */ @f huge extern @@ -131,9 +81,49 @@ extern char huge* byte_ptr; /* first unused position in |byte_mem| */ extern name_pointer hash[]; /* heads of hash lists */ extern hash_pointer hash_end; /* end of |hash| */ extern hash_pointer h; /* index into hash-head array */ -extern name_pointer id_lookup(); /* looks up a string in the identifier table */ -extern name_pointer section_lookup(); /* finds section name */ -extern void print_section_name(), sprint_section_name(); +@z + + +@x Section 17. +@ The following parameters were sufficient in the original \.{WEB} to +handle \TEX/, so they should be sufficient for most applications of +\.{CWEB}. + +@d max_bytes 1000000 /* the number of bytes in identifiers, + index entries, and section names */ +@d max_toks 1000000 /* number of bytes in compressed \CEE/ code */ +@d max_names 10239 /* number of identifiers, strings, section names; + must be less than 10240 */ +@d max_sections 4000 /* greater than the total number of sections */ +@d max_texts 10239 /* number of replacement texts, must be less than 10240 */ +@d longest_name 10000 /* file and section names and section texts shouldn't be longer than this */ +@d stack_size 500 /* number of simultaneous levels of macro expansion */ +@d buf_size 1000 /* maximum length of input line, plus one */ +@y +@ The following parameters were sufficient in the original \.{WEB} to +handle \TEX/, so they should be sufficient for most applications of +\.{CWEB}. + +(This is a modified version of \.{CTANGLE}, and in fact one of the parameters +has been reduced in value. The parameter |max_toks| +has been reduced from 270000 [which +was sufficient to handle \TEX/] to +170000, so that \.{CTANGLE} +may be run on {\mc MSDOS} +systems that are tight on memory. Consider, for +instance, an 80286-based machine with several TSRs and drivers, trying +to run \.{CTANGLE} from a makefile.) + +@d max_bytes 90000 /* the number of bytes in identifiers, + index entries, and section names */ +@d max_toks 170000 /* number of bytes in compressed \CEE/ code */ +@d max_names 4000 /* number of identifiers, strings, section names; + must be less than 10240 */ +@d max_sections 4000 /* greater than the total number of sections */ +@d max_texts 2500 /* number of replacement texts, must be less than 10240 */ +@d longest_name 10000 /* file and section names and section texts shouldn't be longer than this */ +@d stack_size 50 /* number of simultaneous levels of macro expansion */ +@d buf_size 100 /* for \.{CWEAVE} */ @z @@ -151,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 @@ -190,8 +180,8 @@ text_ptr=text_info+1; text_ptr->tok_start=tok_mem; @x Section 49. -out_char(cur_char) -eight_bits cur_char; +out_char( +eight_bits cur_char) { char *j, *k; /* pointer into |byte_mem| */ @y diff --git a/web/c_cpp/cweb/ctang-pc.ch b/web/c_cpp/cweb/ctang-pc.ch index 67f32fae0c..ddf281b3fc 100644 --- a/web/c_cpp/cweb/ctang-pc.ch +++ b/web/c_cpp/cweb/ctang-pc.ch @@ -9,16 +9,16 @@ 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 3.64)\n" +@d banner "This is CTANGLE (Version 4.2)" @y -@d banner "This is CTANGLE (Version 3.64pc)\n" +@d banner "This is CTANGLE (Version 4.2pc)" @z @x section 4 -@d max_bytes 90000 /* the number of bytes in identifiers, - index entries, and section names; used in |"common.w"| */ -@d max_toks 270000 /* number of bytes in compressed \CEE/ code */ +@d max_bytes 1000000 /* the number of bytes in identifiers, + index entries, and section names */ +@d max_toks 1000000 /* number of bytes in compressed \CEE/ code */ @y (note that CWEAVE itself needs only about 42K toks) @d max_bytes (unsigned)60000 /* the number of bytes in identifiers, - index entries, and section names; used in |"common.w"| */ + index entries, and section names */ @d max_toks (unsigned)60000 /* number of bytes in compressed \CEE/ code */ @z diff --git a/web/c_cpp/cweb/ctang-ql.ch b/web/c_cpp/cweb/ctang-ql.ch index a0920243a9..64f0e81a72 100644 --- a/web/c_cpp/cweb/ctang-ql.ch +++ b/web/c_cpp/cweb/ctang-ql.ch @@ -7,15 +7,15 @@ ex cc;"-v -h -c -=500000 ctangle_c" @x -\def\title{CTANGLE (Version 3.64)} +\def\title{CTANGLE (Version 4.2)} @y -\def\title{CTANGLE (QL Version 3.64)} +\def\title{CTANGLE (QL Version 4.2)} @z @x section 1 -@d banner "This is CTANGLE (Version 3.64)\n" +@d banner "This is CTANGLE (Version 4.2)" @y -@d banner "This is CTANGLE (QL Version 3.64)\n" +@d banner "This is CTANGLE (QL Version 4.2)" @z @x diff --git a/web/c_cpp/cweb/ctang-vms.ch b/web/c_cpp/cweb/ctang-vms.ch index 7e538abc27..5686c66b9a 100644 --- a/web/c_cpp/cweb/ctang-vms.ch +++ b/web/c_cpp/cweb/ctang-vms.ch @@ -10,26 +10,26 @@ created: (these changes not necessary for initial bootstrapping) @x section 1 (01-FEB-1992 ST) -@d banner "This is CTANGLE (Version 3.64)\n" +@d banner "This is CTANGLE (Version 4.2)" @y -@d banner "This is CTANGLE (VAX/VMS Version 3.64)\n" +@d banner "This is CTANGLE (VAX/VMS Version 4.2)" @z -@x section 6 (from common.h) (01-FEB-1992 ST) -#include +@x section 3 (01-FEB-1992 ST) +#include /* definition of |@!isalpha|, |@!isdigit| and so on */ +#include /* definition of |@!bool|, |@!true| and |@!false| */ +#include /* definition of |@!ptrdiff_t| */ +#include /* definition of |@!uint8_t| and |@!uint16_t| */ +#include /* definition of |@!getenv| and |@!exit| */ +#include /* definition of |@!printf| and friends */ +#include /* definition of |@!strlen|, |@!strcmp| and so on */ @y -#include stdio /* VMS searches Textlibraries faster */ -@z - -@x section 62 (01-FEB-1992 ST) -#include /* definition of |isalpha|, |isdigit| and so on */ -@y -#include ctype /* definition of |isalpha|, |isdigit| and so on */ +#include ctype /* definition of |@!isalpha|, |@!isdigit| and so on */ /* VMS searches text libraries faster */ -@z - -@x section 63 (01-FEB-1992 ST) -@d isxalpha(c) ((c)=='_') /* non-alpha character allowed in identifier */ -@y -@d isxalpha(c) ((c)=='_' || (c)=='$') /* non-alpha characters allowed in id */ +#include stdbool /* definition of |@!bool|, |@!true| and |@!false| */ +#include stddef /* definition of |@!ptrdiff_t| */ +#include stdint /* definition of |@!uint8_t| and |@!uint16_t| */ +#include stdlib /* definition of |@!getenv| and |@!exit| */ +#include stdio /* definition of |@!printf| and friends */ +#include string /* definition of |@!strlen|, |@!strcmp| and so on */ @z diff --git a/web/c_cpp/cweb/ctang-w32.ch b/web/c_cpp/cweb/ctang-w32.ch index 523985ce3d..1c687e5eb6 100644 --- a/web/c_cpp/cweb/ctang-w32.ch +++ b/web/c_cpp/cweb/ctang-w32.ch @@ -4,63 +4,41 @@ 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 3.64)\n" +@d banner "This is CTANGLE (Version 4.2)" @y -@d banner "This is CTANGLE (Version 3.64win32)\n" +@d banner "This is CTANGLE (Version 4.2win32)" @z @x -@ We predeclare several standard system functions here instead of including -their system header files, because the names of the header files are not as -standard as the names of the functions. (For example, some \CEE/ environments -have \.{} where others have \.{}.) - -@= -extern int strlen(); /* length of string */ -extern int strcmp(); /* compare strings lexicographically */ -extern char* strcpy(); /* copy one string to another */ -extern int strncmp(); /* compare up to $n$ string characters */ -extern char* strncpy(); /* copy up to $n$ string characters */ -@y -@z - -@x -int names_match(p,first,l) -name_pointer p; /* points to the proposed match */ -char *first; /* position of first character of string */ +boolean names_match(@t\1\1@> +name_pointer p, /* points to the proposed match */ +const char *first, /* position of first character of string */ +size_t l, /* length of identifier */ +eight_bits t@t\2\2@>) /* not used by \.{TANGLE} */ @y -int __cdecl names_match(p,first,l) -name_pointer p; /* points to the proposed match */ -char *first; /* position of first character of string */ +boolean __cdecl names_match(@t\1\1@> +name_pointer p, /* points to the proposed match */ +const char *first, /* position of first character of string */ +size_t l, /* length of identifier */ +eight_bits t@t\2\2@>) /* not used by \.{TANGLE} */ @z @x void -init_node(node) -name_pointer node; +init_node( +name_pointer node) { - node->equiv=(char *)text_info; + node->equiv=(void *)text_info; } void -init_p() {} +init_p(name_pointer p,eight_bits t) {@+(void)p;@+(void)t;@+} @y void -init_node(node) -name_pointer node; +init_node( +name_pointer node) { - node->equiv=(char *)text_info; + node->equiv=(void *)text_info; } void __cdecl -init_p() {} -@z - -@x -@ @= -#include /* definition of |isalpha|, |isdigit| and so on */ -#include /* definition of |exit| */ -@y -@ @= -#include /* definition of |isalpha|, |isdigit| and so on */ -#include /* definition of |exit| */ -#include +init_p(name_pointer p,eight_bits t) {@+(void)p;@+(void)t;@+} @z diff --git a/web/c_cpp/cweb/ctangle.c b/web/c_cpp/cweb/ctangle.c index b7a1b553ce..d955da9d57 100644 --- a/web/c_cpp/cweb/ctangle.c +++ b/web/c_cpp/cweb/ctangle.c @@ -1,35 +1,24 @@ /*1:*/ -#line 64 "ctangle.w" - -/*6:*/ -#line 35 "common.h" - -#include +#line 66 "ctangle.w" -/*:6*//*62:*/ -#line 888 "ctangle.w" +/*4:*/ +#line 46 "common.h" #include +#include +#include +#include #include +#include +#include -/*:62*/ -#line 65 "ctangle.w" - -#define banner "This is CTANGLE (Version 3.64)\n" \ - -#define max_bytes 90000 \ - -#define max_toks 270000 -#define max_names 4000 \ +/*:4*/ +#line 67 "ctangle.w" -#define max_texts 2500 -#define hash_size 353 -#define longest_name 10000 -#define stack_size 50 -#define buf_size 100 \ +#define banner "This is CTANGLE (Version 4.2)" \ -#define ctangle 0 -#define cweave 1 \ +#define ctangle false +#define cweave true \ #define and_and 04 #define lt_lt 020 @@ -37,7 +26,7 @@ #define plus_plus 013 #define minus_minus 01 #define minus_gt 031 -#define not_eq 032 +#define non_eq 032 #define lt_eq 034 #define gt_eq 035 #define eq_eq 036 @@ -47,20 +36,28 @@ #define period_ast 026 #define minus_gt_ast 027 \ -#define xisalpha(c) (isalpha(c) &&((eight_bits) c<0200) ) -#define xisdigit(c) (isdigit(c) &&((eight_bits) c<0200) ) -#define xisspace(c) (isspace(c) &&((eight_bits) c<0200) ) -#define xislower(c) (islower(c) &&((eight_bits) c<0200) ) -#define xisupper(c) (isupper(c) &&((eight_bits) c<0200) ) -#define xisxdigit(c) (isxdigit(c) &&((eight_bits) c<0200) ) \ +#define xisalpha(c) (isalpha((eight_bits) c) &&((eight_bits) c<0200) ) +#define xisdigit(c) (isdigit((eight_bits) c) &&((eight_bits) c<0200) ) +#define xisspace(c) (isspace((eight_bits) c) &&((eight_bits) c<0200) ) +#define xislower(c) (islower((eight_bits) c) &&((eight_bits) c<0200) ) +#define xisupper(c) (isupper((eight_bits) c) &&((eight_bits) c<0200) ) +#define xisxdigit(c) (isxdigit((eight_bits) c) &&((eight_bits) c<0200) ) \ -#define length(c) (c+1) ->byte_start-(c) ->byte_start +#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 #define rlink dummy.Rlink #define root name_dir->rlink \ - -#define chunk_marker 0 \ + \ #define spotless 0 #define harmless_message 1 @@ -69,16 +66,13 @@ #define mark_harmless {if(history==spotless) history= harmless_message;} #define mark_error history= error_message #define confusion(s) fatal("! This can't happen: ",s) \ - -#define max_file_name_length 60 -#define cur_file file[include_depth] -#define cur_file_name file_name[include_depth] -#define web_file_name file_name[0] -#define cur_line line[include_depth] \ + \ #define show_banner flags['b'] #define show_progress flags['p'] -#define show_happiness flags['h'] \ +#define show_stats flags['s'] +#define show_happiness flags['h'] +#define make_xrefs flags['x'] \ #define update_terminal fflush(stdout) #define new_line putchar('\n') @@ -87,6 +81,18 @@ #define C_printf(c,a) fprintf(C_file,c,a) #define C_putc(c) putc(c,C_file) \ +#define max_bytes 1000000 \ + +#define max_toks 1000000 +#define max_names 10239 \ + +#define max_sections 4000 +#define max_texts 10239 +#define longest_name 10000 +#define stack_size 500 +#define buf_size 1000 +#define long_buf_size (buf_size+longest_name) \ + #define equiv equiv_or_xref \ #define section_flag max_texts \ @@ -128,43 +134,68 @@ #define isxalpha(c) ((c) =='_'||(c) =='$') \ -#define ishigh(c) ((unsigned char) (c) > 0177) \ +#define ishigh(c) ((eight_bits) (c) > 0177) \ \ -#define compress(c) if(loc++<=limit) return(c) \ +#define compress(c) if(loc++<=limit) return c \ #define macro 0 #define app_repl(c) {if(tok_ptr==tok_mem_end) overflow("token") ;*tok_ptr++= c;} \ -#line 66 "ctangle.w" +#line 68 "ctangle.w" -/*5:*/ -#line 29 "common.h" +/*3:*/ +#line 37 "common.h" -typedef short boolean; -typedef char unsigned eight_bits; +typedef bool boolean; +typedef uint8_t eight_bits; +typedef uint16_t sixteen_bits; extern boolean program; extern int phase; -/*:5*//*7:*/ -#line 57 "common.h" +/*:3*//*5:*/ +#line 74 "common.h" -char section_text[longest_name+1]; -char*section_text_end= section_text+longest_name; -char*id_first; -char*id_loc; +extern char section_text[]; +extern char*section_text_end; +extern char*id_first; +extern char*id_loc; -/*:7*//*8:*/ -#line 72 "common.h" +/*:5*//*6:*/ +#line 88 "common.h" extern char buffer[]; extern char*buffer_end; extern char*loc; extern char*limit; -/*:8*//*9:*/ -#line 87 "common.h" +/*:6*//*7:*/ +#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; @@ -174,73 +205,38 @@ struct name_info*Rlink; char Ilk; }dummy; -char*equiv_or_xref; +void*equiv_or_xref; }name_info; typedef name_info*name_pointer; typedef name_pointer*hash_pointer; extern char byte_mem[]; extern char*byte_mem_end; +extern char*byte_ptr; extern name_info name_dir[]; extern name_pointer name_dir_end; extern name_pointer name_ptr; -extern char*byte_ptr; extern name_pointer hash[]; extern hash_pointer hash_end; extern hash_pointer h; -extern name_pointer id_lookup(); -extern name_pointer section_lookup(); -extern void print_section_name(),sprint_section_name(); -/*:9*//*10:*/ -#line 122 "common.h" +/*:10*//*12:*/ +#line 183 "common.h" -extern history; -extern err_print(); -extern wrap_up(); -extern void fatal(); -extern void overflow(); +extern int history; -/*:10*//*11:*/ -#line 137 "common.h" +/*:12*//*14:*/ +#line 199 "common.h" -extern 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 line[]; -extern change_line; -extern change_depth; -extern boolean input_has_ended; -extern boolean changing; -extern boolean web_file_open; -extern reset_input(); -extern get_line(); -extern check_complete(); - -/*:11*//*12:*/ -#line 159 "common.h" - -typedef unsigned short sixteen_bits; -extern sixteen_bits section_count; -extern boolean changed_section[]; -extern boolean change_pending; -extern boolean print_where; - -/*:12*//*13:*/ -#line 171 "common.h" - -extern int argc; -extern char**argv; extern boolean flags[]; -/*:13*//*14:*/ -#line 183 "common.h" +/*:14*//*15:*/ +#line 215 "common.h" extern FILE*C_file; extern FILE*tex_file; @@ -248,17 +244,11 @@ extern FILE*idx_file; extern FILE*scn_file; extern FILE*active_file; -/*:14*//*15:*/ -#line 192 "common.h" - -extern void common_init(); -#line 128 "ctangle.w" - /*:15*/ -#line 67 "ctangle.w" +#line 69 "ctangle.w" -/*16:*/ -#line 152 "ctangle.w" +/*19:*/ +#line 122 "ctangle.w" typedef struct{ eight_bits*tok_start; @@ -266,8 +256,8 @@ sixteen_bits text_link; }text; typedef text*text_pointer; -/*:16*//*27:*/ -#line 296 "ctangle.w" +/*:19*//*31:*/ +#line 269 "ctangle.w" typedef struct{ eight_bits*end_field; @@ -278,170 +268,219 @@ sixteen_bits section_field; }output_state; typedef output_state*stack_pointer; -/*:27*/ -#line 68 "ctangle.w" +/*:31*/ +#line 70 "ctangle.w" -/*17:*/ -#line 159 "ctangle.w" +/*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; -/*:17*//*23:*/ -#line 227 "ctangle.w" +/*:20*//*26:*/ +#line 198 "ctangle.w" -text_pointer last_unnamed; +static text_pointer last_unnamed; -/*:23*//*28:*/ -#line 312 "ctangle.w" +/*:26*//*32:*/ +#line 285 "ctangle.w" -output_state cur_state; +static output_state cur_state; -output_state stack[stack_size+1]; -stack_pointer stack_ptr; -stack_pointer stack_end= stack+stack_size; +static output_state stack[stack_size+1]; +static stack_pointer stack_end= stack+stack_size; +static stack_pointer stack_ptr; -/*:28*//*32:*/ -#line 384 "ctangle.w" +/*:32*//*37:*/ +#line 361 "ctangle.w" -int cur_val; +static int cur_val; -/*:32*//*36:*/ -#line 473 "ctangle.w" +/*:37*//*42:*/ +#line 452 "ctangle.w" -eight_bits out_state; -boolean protect; +static eight_bits out_state; +static boolean protect; -/*:36*//*38:*/ -#line 502 "ctangle.w" +/*:42*//*45:*/ +#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]; +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]; -/*:38*//*45:*/ -#line 599 "ctangle.w" +/*:45*//*52:*/ +#line 582 "ctangle.w" -boolean output_defs_seen= 0; +static boolean output_defs_seen= false; -/*:45*//*51:*/ -#line 710 "ctangle.w" +/*:52*//*57:*/ +#line 691 "ctangle.w" -char translit[128][translit_length]; +static char translit[128][translit_length]; -/*:51*//*56:*/ -#line 789 "ctangle.w" +/*:57*//*62:*/ +#line 770 "ctangle.w" -eight_bits ccode[256]; +static eight_bits ccode[256]; -/*:56*//*59:*/ -#line 845 "ctangle.w" +/*:62*//*66:*/ +#line 830 "ctangle.w" -boolean comment_continues= 0; +static boolean comment_continues= false; -/*:59*//*61:*/ -#line 884 "ctangle.w" +/*:66*//*68:*/ +#line 869 "ctangle.w" -name_pointer cur_section_name; -int no_where; +static name_pointer cur_section_name; +static boolean no_where; -/*:61*//*75:*/ -#line 1195 "ctangle.w" +/*:68*//*82:*/ +#line 1182 "ctangle.w" -text_pointer cur_text; -eight_bits next_control; +static text_pointer cur_text; +static eight_bits next_control; -/*:75*//*82:*/ -#line 1353 "ctangle.w" +/*:82*/ +#line 71 "ctangle.w" -extern sixteen_bits section_count; +/*8:*/ +#line 119 "common.h" -/*:82*/ -#line 69 "ctangle.w" +extern boolean get_line(void); +extern void check_complete(void); +extern void reset_input(void); -/*2:*/ -#line 77 "ctangle.w" +/*:8*//*11:*/ +#line 162 "common.h" -extern int strlen(); -extern int strcmp(); -extern char*strcpy(); -extern int strncmp(); -extern char*strncpy(); +extern boolean names_match(name_pointer,const char*,size_t,eight_bits); +extern name_pointer id_lookup(const char*,const char*,char); -/*:2*//*41:*/ -#line 533 "ctangle.w" +extern name_pointer section_lookup(char*,char*,int); +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); -void phase_two(); +/*:11*//*13:*/ +#line 186 "common.h" -/*:41*//*46:*/ -#line 602 "ctangle.w" +extern int wrap_up(void); +extern void err_print(const char*); +extern void fatal(const char*,const char*); +extern void overflow(const char*); -void output_defs(); +/*:13*//*16:*/ +#line 223 "common.h" -/*:46*//*48:*/ -#line 648 "ctangle.w" +extern void common_init(void); +extern void print_stats(void); -static void out_char(); +/*:16*//*30:*/ +#line 241 "ctangle.w" +static void store_two_bytes(sixteen_bits); -/*:48*//*90:*/ -#line 1460 "ctangle.w" +/*:30*//*35:*/ +#line 324 "ctangle.w" -void phase_one(); +static void push_level(name_pointer); +static void pop_level(boolean); -/*:90*//*92:*/ -#line 1478 "ctangle.w" +/*:35*//*39:*/ +#line 397 "ctangle.w" +static void get_output(void); -void skip_limbo(); +/*:39*//*44:*/ +#line 473 "ctangle.w" +static void flush_buffer(void); -/*:92*/ -#line 70 "ctangle.w" +/*:44*//*49:*/ +#line 549 "ctangle.w" +static void phase_two(void); + +/*:49*//*53:*/ +#line 585 "ctangle.w" + +static void output_defs(void); +static void out_char(eight_bits); + +/*:53*//*65:*/ +#line 810 "ctangle.w" +static eight_bits skip_ahead(void); +static boolean skip_comment(boolean); -/*:1*//*3:*/ -#line 91 "ctangle.w" +/*:65*//*70:*/ +#line 924 "ctangle.w" +static eight_bits get_next(void); + +/*:70*//*84:*/ +#line 1208 "ctangle.w" +static void scan_repl(eight_bits); + +/*:84*//*91:*/ +#line 1379 "ctangle.w" +static void scan_section(void); + +/*:91*//*99:*/ +#line 1460 "ctangle.w" +static void phase_one(void); + +/*:99*//*101:*/ +#line 1494 "ctangle.w" +static void skip_limbo(void); + +/*:101*/ +#line 72 "ctangle.w" -int main(ac,av) -int ac; -char**av; + +/*:1*//*2:*/ +#line 81 "ctangle.w" + +int main( +int ac, +char**av) { argc= ac;argv= av; program= ctangle; -/*18:*/ -#line 167 "ctangle.w" +/*21:*/ +#line 137 "ctangle.w" text_info->tok_start= tok_ptr= tok_mem; text_ptr= text_info+1;text_ptr->tok_start= tok_mem; -/*:18*//*20:*/ -#line 177 "ctangle.w" +/*:21*//*23:*/ +#line 147 "ctangle.w" -name_dir->equiv= (char*)text_info; +init_node(name_dir); -/*:20*//*24:*/ -#line 230 "ctangle.w" +/*:23*//*27:*/ +#line 201 "ctangle.w" last_unnamed= text_info;text_info->text_link= 0; -/*:24*//*39:*/ -#line 512 "ctangle.w" +/*:27*//*46:*/ +#line 493 "ctangle.w" cur_out_file= end_output_files= output_files+max_files; -/*:39*//*52:*/ -#line 713 "ctangle.w" +/*:46*//*58:*/ +#line 694 "ctangle.w" { int i; -for(i= 0;i<128;i++)sprintf(translit[i],"X%02X",(unsigned)(128+i)); +for(i= 0;i<128;i++)sprintf(translit[i],"X%02X",(unsigned int)(128+i)); } -/*:52*//*57:*/ -#line 792 "ctangle.w" +/*:58*//*63:*/ +#line 773 "ctangle.w" { int c; for(c= 0;c<256;c++)ccode[c]= ignore; @@ -460,62 +499,63 @@ ccode['<']= ccode['(']= section_name; ccode['\'']= ord; } -/*:57*//*71:*/ -#line 1116 "ctangle.w" +/*:63*//*78:*/ +#line 1103 "ctangle.w" section_text[0]= ' '; -/*:71*/ -#line 98 "ctangle.w" -; +/*:78*/ +#line 88 "ctangle.w" + common_init(); -if(show_banner)printf(banner); +if(show_banner)puts(banner); phase_one(); phase_two(); return wrap_up(); } -/*:3*//*21:*/ -#line 183 "ctangle.w" +/*:2*//*24:*/ +#line 153 "ctangle.w" -int names_match(p,first,l) -name_pointer p; -char*first; -int l; -{ -if(length(p)!=l)return 0; +boolean names_match( +name_pointer p, +const char*first, +size_t l, +eight_bits t) +{(void)t; +if(length(p)!=l)return false; return!strncmp(first,p->byte_start,l); } -/*:21*//*22:*/ -#line 198 "ctangle.w" +/*:24*//*25:*/ +#line 169 "ctangle.w" void -init_node(node) -name_pointer node; +init_node( +name_pointer node) { -node->equiv= (char*)text_info; +node->equiv= (void*)text_info; } void -init_p(){} +init_p(name_pointer p,eight_bits t){(void)p;(void)t;} -/*:22*//*26:*/ -#line 260 "ctangle.w" +/*:25*//*29:*/ +#line 231 "ctangle.w" -void -store_two_bytes(x) -sixteen_bits x; +static void +store_two_bytes( +sixteen_bits x) { if(tok_ptr+2> tok_mem_end)overflow("token"); *tok_ptr++= x>>8; *tok_ptr++= x&0377; } -/*:26*//*30:*/ -#line 336 "ctangle.w" +/*:29*//*34:*/ +#line 309 "ctangle.w" -void -push_level(p) -name_pointer p; +static void +push_level( +name_pointer p) { if(stack_ptr==stack_end)overflow("stack"); *stack_ptr= cur_state; @@ -527,12 +567,12 @@ cur_section= 0; } } -/*:30*//*31:*/ -#line 355 "ctangle.w" +/*:34*//*36:*/ +#line 332 "ctangle.w" -void -pop_level(flag) -int flag; +static void +pop_level( +boolean flag) { if(flag&&cur_repl->text_linktext_link+text_info; @@ -543,17 +583,17 @@ stack_ptr--; if(stack_ptr> stack)cur_state= *stack_ptr; } -/*:31*//*33:*/ -#line 391 "ctangle.w" +/*:36*//*38:*/ +#line 368 "ctangle.w" -void -get_output() +static void +get_output(void) { sixteen_bits a; restart:if(stack_ptr==stack)return; if(cur_byte==cur_end){ cur_val= -((int)cur_section); -pop_level(1); +pop_level(true); if(cur_val==0)goto restart; out_char(section_number);return; } @@ -566,23 +606,23 @@ a= (a-0200)*0400+*cur_byte++; switch(a/024000){ case 0:cur_val= a;out_char(identifier);break; case 1:if(a==output_defs_flag)output_defs(); -else/*34:*/ -#line 423 "ctangle.w" +else/*40:*/ +#line 402 "ctangle.w" { a-= 024000; -if((a+name_dir)->equiv!=(char*)text_info)push_level(a+name_dir); +if((a+name_dir)->equiv!=(void*)text_info)push_level(a+name_dir); else if(a!=0){ -printf("\n! Not present: <"); +fputs("\n! Not present: <",stdout); print_section_name(a+name_dir);err_print(">"); } goto restart; } -/*:34*/ -#line 412 "ctangle.w" -; +/*:40*/ +#line 389 "ctangle.w" + break; default:cur_val= a-050000;if(cur_val> 0)cur_section= cur_val; out_char(section_number); @@ -590,11 +630,11 @@ out_char(section_number); } } -/*:33*//*37:*/ -#line 481 "ctangle.w" +/*:38*//*43:*/ +#line 460 "ctangle.w" -void -flush_buffer() +static void +flush_buffer(void) { C_putc('\n'); if(cur_line%100==0&&show_progress){ @@ -605,33 +645,33 @@ update_terminal; cur_line++; } -/*:37*//*42:*/ -#line 536 "ctangle.w" +/*:43*//*48:*/ +#line 514 "ctangle.w" -void -phase_two(){ -web_file_open= 0; +static void +phase_two(void){ +web_file_open= false; cur_line= 1; -/*29:*/ -#line 325 "ctangle.w" +/*33:*/ +#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; -/*:29*/ -#line 541 "ctangle.w" -; -/*44:*/ -#line 595 "ctangle.w" +/*:33*/ +#line 519 "ctangle.w" + +/*51:*/ +#line 578 "ctangle.w" if(!output_defs_seen) output_defs(); -/*:44*/ -#line 542 "ctangle.w" -; +/*:51*/ +#line 520 "ctangle.w" + if(text_info->text_link==0&&cur_out_file==end_output_files){ -printf("\n! No program text was specified.");mark_harmless; +fputs("\n! No program text was specified.",stdout);mark_harmless; } else{ @@ -641,7 +681,7 @@ printf("\nWriting the output file (%s):",C_file_name); } else{ if(show_progress){ -printf("\nWriting the output files:"); +fputs("\nWriting the output files:",stdout); printf(" (%s)",C_file_name); update_terminal; @@ -650,17 +690,17 @@ if(text_info->text_link==0)goto writeloop; } while(stack_ptr> stack)get_output(); flush_buffer(); -writeloop:/*43:*/ -#line 572 "ctangle.w" +writeloop:/*50:*/ +#line 555 "ctangle.w" for(an_output_file= end_output_files;an_output_file> cur_out_file;){ an_output_file--; sprint_section_name(output_file_name,*an_output_file); fclose(C_file); -C_file= fopen(output_file_name,"w"); -if(C_file==0)fatal("! Cannot open output file:",output_file_name); +C_file= fopen(output_file_name,"wb"); +if(C_file==0)fatal("! Cannot open output file ",output_file_name); -printf("\n(%s)",output_file_name);update_terminal; +if(show_progress){printf("\n(%s)",output_file_name);update_terminal;} cur_line= 1; stack_ptr= stack+1; cur_name= (*an_output_file); @@ -671,18 +711,21 @@ while(stack_ptr> stack)get_output(); flush_buffer(); } -/*:43*/ -#line 563 "ctangle.w" -; -if(show_happiness)printf("\nDone."); +/*:50*/ +#line 541 "ctangle.w" + +if(show_happiness){ +if(show_progress)new_line; +fputs("Done.",stdout); +} } } -/*:42*//*47:*/ -#line 605 "ctangle.w" +/*:48*//*54:*/ +#line 589 "ctangle.w" -void -output_defs() +static void +output_defs(void) { sixteen_bits a; push_level(NULL); @@ -692,7 +735,7 @@ cur_byte= cur_text->tok_start; cur_end= (cur_text+1)->tok_start; C_printf("%s","#define "); out_state= normal; -protect= 1; +protect= true; while(cur_bytebyte_start; k= (cur_val+name_dir+1)->byte_start; while(j 0)C_printf("/*%d:*/",cur_val); @@ -776,11 +819,11 @@ C_printf("%s","\"\n"); } break; -/*:54*/ -#line 663 "ctangle.w" -; -/*50:*/ -#line 681 "ctangle.w" +/*:60*/ +#line 644 "ctangle.w" + +/*56:*/ +#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; @@ -790,7 +833,7 @@ case eq_eq:C_putc('=');C_putc('=');out_state= normal;break; case lt_lt:C_putc('<');C_putc('<');out_state= normal;break; case gt_eq:C_putc('>');C_putc('=');out_state= normal;break; case lt_eq:C_putc('<');C_putc('=');out_state= normal;break; -case not_eq:C_putc('!');C_putc('=');out_state= normal;break; +case non_eq:C_putc('!');C_putc('=');out_state= normal;break; case and_and:C_putc('&');C_putc('&');out_state= normal;break; case or_or:C_putc('|');C_putc('|');out_state= normal;break; case dot_dot_dot:C_putc('.');C_putc('.');C_putc('.');out_state= normal; @@ -800,9 +843,9 @@ case period_ast:C_putc('.');C_putc('*');out_state= normal;break; case minus_gt_ast:C_putc('-');C_putc('>');C_putc('*');out_state= normal; break; -/*:50*/ -#line 664 "ctangle.w" -; +/*:56*/ +#line 645 "ctangle.w" + case'=':case'>':C_putc(cur_char);C_putc(' '); out_state= normal;break; case join:out_state= unbreakable;break; @@ -819,74 +862,74 @@ default:C_putc(cur_char);out_state= normal;break; } } -/*:49*//*58:*/ -#line 813 "ctangle.w" +/*:55*//*64:*/ +#line 794 "ctangle.w" -eight_bits -skip_ahead() +static eight_bits +skip_ahead(void) { eight_bits c; -while(1){ -if(loc> limit&&(get_line()==0))return(new_section); +while(true){ +if(loc> limit&&(get_line()==false))return new_section; *(limit+1)= '@'; while(*loc!='@')loc++; if(loc<=limit){ loc++;c= ccode[(eight_bits)*loc];loc++; -if(c!=ignore||*(loc-1)=='>')return(c); +if(c!=ignore||*(loc-1)=='>')return c; } } } -/*:58*//*60:*/ -#line 848 "ctangle.w" +/*:64*//*67:*/ +#line 833 "ctangle.w" -int skip_comment(is_long_comment) -boolean is_long_comment; +static boolean skip_comment( +boolean is_long_comment) { char c; -while(1){ +while(true){ if(loc> limit){ if(is_long_comment){ -if(get_line())return(comment_continues= 1); +if(get_line())return comment_continues= true; else{ err_print("! Input ended in mid-comment"); -return(comment_continues= 0); +return comment_continues= false; } } -else return(comment_continues= 0); +else return comment_continues= false; } c= *(loc++); if(is_long_comment&&c=='*'&&*loc=='/'){ -loc++;return(comment_continues= 0); +loc++;return comment_continues= false; } if(c=='@'){ if(ccode[(eight_bits)*loc]==new_section){ err_print("! Section name ended in mid-comment");loc--; -return(comment_continues= 0); +return comment_continues= false; } else loc++; } } } -/*:60*//*63:*/ -#line 900 "ctangle.w" +/*:67*//*69:*/ +#line 881 "ctangle.w" -eight_bits -get_next() +static eight_bits +get_next(void) { static int preprocessing= 0; eight_bits c; -while(1){ +while(true){ if(loc> limit){ if(preprocessing&&*(limit-1)!='\\')preprocessing= 0; -if(get_line()==0)return(new_section); +if(get_line()==false)return new_section; else if(print_where&&!no_where){ -print_where= 0; -/*77:*/ -#line 1225 "ctangle.w" +print_where= false; +/*85:*/ +#line 1214 "ctangle.w" store_two_bytes(0150000); if(changing&&include_depth==change_depth){ @@ -897,25 +940,25 @@ id_first= cur_file_name; store_two_bytes((sixteen_bits)cur_line); } id_loc= id_first+strlen(id_first); -{int a= id_lookup(id_first,id_loc,0)-name_dir;app_repl((a/0400)+0200); -app_repl(a%0400);} +{int a_l= id_lookup(id_first,id_loc,0)-name_dir;app_repl((a_l/0400)+0200); +app_repl(a_l%0400);} + +/*:85*/ +#line 893 "ctangle.w" -/*:77*/ -#line 912 "ctangle.w" -; } -else return('\n'); +else return'\n'; } c= *loc; if(comment_continues||(c=='/'&&(*(loc+1)=='*'||*(loc+1)=='/'))){ skip_comment(comment_continues||*(loc+1)=='*'); -if(comment_continues)return('\n'); +if(comment_continues)return'\n'; else continue; } loc++; -if(xisdigit(c)||c=='.')/*66:*/ -#line 978 "ctangle.w" +if(xisdigit(c)||c=='.')/*73:*/ +#line 964 "ctangle.w" { id_first= loc-1; if(*id_first=='.'&&!xisdigit(*loc))goto mistake; @@ -936,29 +979,32 @@ while(xisdigit(*loc))loc++; found:while(*loc=='u'||*loc=='U'||*loc=='l'||*loc=='L' ||*loc=='f'||*loc=='F')loc++; id_loc= loc; -return(constant); +return constant; } -/*:66*/ -#line 924 "ctangle.w" +/*:73*/ +#line 905 "ctangle.w" -else if(c=='\''||c=='"'||(c=='L'&&(*loc=='\''||*loc=='"'))) -/*67:*/ -#line 1006 "ctangle.w" +else if(c=='\''||c=='"' +||((c=='L'||c=='u'||c=='U')&&(*loc=='\''||*loc=='"')) +||((c=='u'&&*loc=='8')&&(*(loc+1)=='\''||*(loc+1)=='"'))) +/*74:*/ +#line 992 "ctangle.w" { char delim= c; id_first= section_text+1; id_loc= section_text;*++id_loc= delim; -if(delim=='L'){ +if(delim=='L'||delim=='u'||delim=='U'){ +if(delim=='u'&&*loc=='8'){*++id_loc= *loc++;} delim= *loc++;*++id_loc= delim; } -while(1){ +while(true){ if(loc>=limit){ if(*(limit-1)!='\\'){ err_print("! String didn't end");loc= limit;break; } -if(get_line()==0){ +if(get_line()==false){ err_print("! Input ended in middle of string");loc= buffer;break; } @@ -977,32 +1023,33 @@ c= *loc++; if(++id_loc<=section_text_end)*id_loc= c; } if(id_loc>=section_text_end){ -printf("\n! String too long: "); +fputs("\n! String too long: ",stdout); term_write(section_text+1,25); err_print("..."); } id_loc++; -return(string); +return string; } -/*:67*/ -#line 926 "ctangle.w" +/*:74*/ +#line 909 "ctangle.w" else if(isalpha(c)||isxalpha(c)||ishigh(c)) -/*65:*/ -#line 972 "ctangle.w" +/*72:*/ +#line 957 "ctangle.w" { id_first= --loc; -while(isalpha(*++loc)||isdigit(*loc)||isxalpha(*loc)||ishigh(*loc)); -id_loc= loc;return(identifier); +while(isalpha((eight_bits)*++loc)||isdigit((eight_bits)*loc) +||isxalpha((eight_bits)*loc)||ishigh((eight_bits)*loc)); +id_loc= loc;return identifier; } -/*:65*/ -#line 928 "ctangle.w" +/*:72*/ +#line 911 "ctangle.w" -else if(c=='@')/*68:*/ -#line 1050 "ctangle.w" +else if(c=='@')/*75:*/ +#line 1037 "ctangle.w" { c= ccode[(eight_bits)*loc++]; switch(c){ @@ -1017,23 +1064,23 @@ err_print("! Double @ should be used in control text"); continue; case section_name: cur_section_name_char= *(loc-1); -/*70:*/ -#line 1098 "ctangle.w" +/*77:*/ +#line 1085 "ctangle.w" { char*k; -/*72:*/ -#line 1118 "ctangle.w" +/*79:*/ +#line 1105 "ctangle.w" k= section_text; -while(1){ -if(loc> limit&&get_line()==0){ +while(true){ +if(loc> limit&&get_line()==false){ err_print("! Input ended in section name"); loc= buffer+1;break; } c= *loc; -/*73:*/ -#line 1142 "ctangle.w" +/*80:*/ +#line 1129 "ctangle.w" if(c=='@'){ c= *(loc+1); @@ -1051,9 +1098,9 @@ err_print("! Nesting of section names not allowed");break; *(++k)= '@';loc++; } -/*:73*/ -#line 1127 "ctangle.w" -; +/*:80*/ +#line 1114 "ctangle.w" + loc++;if(k=section_text_end){ -printf("\n! Section name too long: "); +fputs("\n! Section name too long: ",stdout); term_write(section_text+1,25); printf("...");mark_harmless; } if(*k==' '&&k> section_text)k--; -/*:72*/ -#line 1100 "ctangle.w" -; +/*:79*/ +#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=='(') -/*40:*/ -#line 516 "ctangle.w" +/*47:*/ +#line 497 "ctangle.w" { for(an_output_file= cur_out_file; @@ -1091,31 +1138,31 @@ overflow("output files"); } } -/*:40*/ -#line 1106 "ctangle.w" -; -return(section_name); +/*:47*/ +#line 1093 "ctangle.w" + +return section_name; } -/*:70*/ -#line 1064 "ctangle.w" -; -case string:/*74:*/ -#line 1164 "ctangle.w" +/*:77*/ +#line 1051 "ctangle.w" + +case string:/*81:*/ +#line 1151 "ctangle.w" { id_first= loc++;*(limit+1)= '@';*(limit+2)= '>'; while(*loc!='@'||*(loc+1)!='>')loc++; if(loc>=limit)err_print("! Verbatim string didn't end"); id_loc= loc;loc+= 2; -return(string); +return string; } -/*:74*/ -#line 1065 "ctangle.w" -; -case ord:/*69:*/ -#line 1077 "ctangle.w" +/*:81*/ +#line 1052 "ctangle.w" + +case ord:/*76:*/ +#line 1064 "ctangle.w" id_first= loc; if(*loc=='\\'){ @@ -1135,32 +1182,32 @@ err_print("! String didn't end");loc= limit-1;break; } } loc++; -return(ord); +return ord; + +/*:76*/ +#line 1053 "ctangle.w" -/*:69*/ -#line 1066 "ctangle.w" -; -default:return(c); +default:return c; } } -/*:68*/ -#line 929 "ctangle.w" +/*:75*/ +#line 912 "ctangle.w" else if(xisspace(c)){ if(!preprocessing||loc> limit)continue; -else return(' '); +else return' '; } else if(c=='#'&&loc==buffer+1)preprocessing= 1; -mistake:/*64:*/ -#line 950 "ctangle.w" +mistake:/*71:*/ +#line 935 "ctangle.w" switch(c){ case'+':if(*loc=='+')compress(plus_plus);break; case'-':if(*loc=='-'){compress(minus_minus);} -else if(*loc=='>')if(*(loc+1)=='*'){loc++;compress(minus_gt_ast);} -else compress(minus_gt);break; +else{if(*loc=='>'){if(*(loc+1)=='*'){loc++;compress(minus_gt_ast);} +else compress(minus_gt);}}break; case'.':if(*loc=='*'){compress(period_ast);} else if(*loc=='.'&&*(loc+1)=='.'){ loc++;compress(dot_dot_dot); @@ -1174,26 +1221,26 @@ case'<':if(*loc=='='){compress(lt_eq);} else if(*loc=='<')compress(lt_lt);break; case'&':if(*loc=='&')compress(and_and);break; case'|':if(*loc=='|')compress(or_or);break; -case'!':if(*loc=='=')compress(not_eq);break; +case'!':if(*loc=='=')compress(non_eq);break; } -/*:64*/ -#line 936 "ctangle.w" +/*:71*/ +#line 919 "ctangle.w" -return(c); +return c; } } -/*:63*//*76:*/ -#line 1199 "ctangle.w" +/*:69*//*83:*/ +#line 1186 "ctangle.w" -void -scan_repl(t) -eight_bits t; +static void +scan_repl( +eight_bits t) { sixteen_bits a; -if(t==section_name){/*77:*/ -#line 1225 "ctangle.w" +if(t==section_name){/*85:*/ +#line 1214 "ctangle.w" store_two_bytes(0150000); if(changing&&include_depth==change_depth){ @@ -1204,23 +1251,23 @@ id_first= cur_file_name; store_two_bytes((sixteen_bits)cur_line); } id_loc= id_first+strlen(id_first); -{int a= id_lookup(id_first,id_loc,0)-name_dir;app_repl((a/0400)+0200); -app_repl(a%0400);} +{int a_l= id_lookup(id_first,id_loc,0)-name_dir;app_repl((a_l/0400)+0200); +app_repl(a_l%0400);} -/*:77*/ -#line 1205 "ctangle.w" -;} -while(1)switch(a= get_next()){ -/*78:*/ -#line 1238 "ctangle.w" +/*:85*/ +#line 1192 "ctangle.w" +} +while(true)switch(a= get_next()){ +/*86:*/ +#line 1227 "ctangle.w" case identifier:a= id_lookup(id_first,id_loc,0)-name_dir; app_repl((a/0400)+0200); app_repl(a%0400);break; case section_name:if(t!=section_name)goto done; else{ -/*79:*/ -#line 1271 "ctangle.w" +/*87:*/ +#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; } -/*:76*//*83:*/ -#line 1360 "ctangle.w" +/*:83*//*90:*/ +#line 1346 "ctangle.w" -void -scan_section() +static void +scan_section(void) { name_pointer p; text_pointer q; sixteen_bits a; -section_count++;no_where= 1; +section_count++;no_where= true; if(*(loc-1)=='*'&&show_progress){ printf("*%d",section_count);update_terminal; } next_control= 0; -while(1){ -/*84:*/ -#line 1399 "ctangle.w" +while(true){ +/*92:*/ +#line 1387 "ctangle.w" while(next_controltext_link= 0; +cur_text->text_link= macro; } -/*:85*/ -#line 1376 "ctangle.w" +/*:93*/ +#line 1362 "ctangle.w" continue; } @@ -1434,41 +1481,41 @@ p= name_dir;break; } if(next_control==section_name){ p= cur_section_name; -/*86:*/ -#line 1431 "ctangle.w" +/*94:*/ +#line 1419 "ctangle.w" while((next_control= get_next())=='+'); if(next_control!='='&&next_control!=eq_eq) continue; -/*:86*/ -#line 1384 "ctangle.w" -; +/*:94*/ +#line 1370 "ctangle.w" + break; } return; } -no_where= print_where= 0; -/*87:*/ -#line 1436 "ctangle.w" +no_where= print_where= false; +/*95:*/ +#line 1424 "ctangle.w" -/*88:*/ -#line 1441 "ctangle.w" +/*96:*/ +#line 1429 "ctangle.w" store_two_bytes((sixteen_bits)(0150000+section_count)); -/*:88*/ -#line 1437 "ctangle.w" -; +/*:96*/ +#line 1425 "ctangle.w" + scan_repl(section_name); -/*89:*/ -#line 1445 "ctangle.w" +/*97:*/ +#line 1433 "ctangle.w" if(p==name_dir||p==0){ (last_unnamed)->text_link= cur_text-text_info;last_unnamed= cur_text; } -else if(p->equiv==(char*)text_info)p->equiv= (char*)cur_text; +else if(p->equiv==(void*)text_info)p->equiv= (void*)cur_text; else{ q= (text_pointer)p->equiv; @@ -1479,20 +1526,20 @@ q->text_link= cur_text-text_info; cur_text->text_link= section_flag; -/*:89*/ -#line 1439 "ctangle.w" -; +/*:97*/ +#line 1427 "ctangle.w" + + +/*:95*/ +#line 1376 "ctangle.w" -/*:87*/ -#line 1390 "ctangle.w" -; } -/*:83*//*91:*/ -#line 1463 "ctangle.w" +/*:90*//*98:*/ +#line 1448 "ctangle.w" -void -phase_one(){ +static void +phase_one(void){ phase= 1; section_count= 0; reset_input(); @@ -1502,23 +1549,23 @@ check_complete(); phase= 2; } -/*:91*//*93:*/ -#line 1481 "ctangle.w" +/*:98*//*100:*/ +#line 1465 "ctangle.w" -void -skip_limbo() +static void +skip_limbo(void) { char c; -while(1){ -if(loc> limit&&get_line()==0)return; +while(true){ +if(loc> limit&&get_line()==false)return; *(limit+1)= '@'; while(*loc!='@')loc++; if(loc++<=limit){ c= *loc++; if(ccode[(eight_bits)c]==new_section)break; switch(ccode[(eight_bits)c]){ -case translit_code:/*94:*/ -#line 1510 "ctangle.w" +case translit_code:/*102:*/ +#line 1496 "ctangle.w" while(xisspace(*loc)&&loc limit||!xisxdigit(*(loc-3))||!xisxdigit(*(loc-2)) err_print("! Improper hex number following @l"); else{ -unsigned i; +unsigned int i; char*beg; sscanf(loc-3,"%x",&i); while(xisspace(*loc)&&loc=translit_length) err_print("! Replacement string in @l too long"); else{ -strncpy(translit[i-0200],beg,loc-beg); +strncpy(translit[i-0200],beg,(size_t)(loc-beg)); translit[i-0200][loc-beg]= '\0'; } } -/*:94*/ -#line 1494 "ctangle.w" -;break; +/*:102*/ +#line 1478 "ctangle.w" +break; case format_code:case'@':break; case control_text:if(c=='q'||c=='Q'){ while((c= skip_ahead())=='@'); @@ -1560,20 +1607,20 @@ default:err_print("! Double @ should be used in limbo"); } } -/*:93*//*95:*/ -#line 1536 "ctangle.w" +/*:100*//*103:*/ +#line 1522 "ctangle.w" void -print_stats(){ -printf("\nMemory usage statistics:\n"); +print_stats(void){ +puts("\nMemory usage statistics:"); printf("%ld names (out of %ld)\n", -(long)(name_ptr-name_dir),(long)max_names); +(ptrdiff_t)(name_ptr-name_dir),(long)max_names); printf("%ld replacement texts (out of %ld)\n", -(long)(text_ptr-text_info),(long)max_texts); +(ptrdiff_t)(text_ptr-text_info),(long)max_texts); printf("%ld bytes (out of %ld)\n", -(long)(byte_ptr-byte_mem),(long)max_bytes); +(ptrdiff_t)(byte_ptr-byte_mem),(long)max_bytes); printf("%ld tokens (out of %ld)\n", -(long)(tok_ptr-tok_mem),(long)max_toks); +(ptrdiff_t)(tok_ptr-tok_mem),(long)max_toks); } -/*:95*/ +/*:103*/ diff --git a/web/c_cpp/cweb/ctangle.w b/web/c_cpp/cweb/ctangle.w index 130800210e..e7e2d311fe 100644 --- a/web/c_cpp/cweb/ctangle.w +++ b/web/c_cpp/cweb/ctangle.w @@ -2,9 +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 3.64 --- February 2002 -% (same as Version 3.5 except for minor corrections) -% (also quotes backslashes in file names of #line directives) +% Version 4.2 --- February 2021 % Copyright (C) 1987,1990,1993,2000 Silvio Levy and Donald E. Knuth @@ -17,6 +15,11 @@ % entire resulting derived work is given a different name and distributed % under the terms of a permission notice identical to this one. +% Amendments to 'ctangle.w' resulting in this updated version were created +% by numerous collaborators over the course of many years. + +% Please send comments, suggestions, etc. to tex-k@@tug.org. + % Here is TeX material that gets inserted after \input cwebmac \def\hang{\hangindent 3em\indent\ignorespaces} \def\pb{$\.|\ldots\.|$} % C brackets (|...|) @@ -24,11 +27,11 @@ \mathchardef\RA="3221 % right arrow \mathchardef\BA="3224 % double arrow -\def\title{CTANGLE (Version 3.64)} +\def\title{CTANGLE (Version 4.2)} \def\topofcontents{\null\vfill \centerline{\titlefont The {\ttitlefont CTANGLE} processor} \vskip 15pt - \centerline{(Version 3.64)} + \centerline{(Version 4.2)} \vfill} \def\botofcontents{\vfill \noindent @@ -46,7 +49,6 @@ under the terms of a permission notice identical to this one. } \pageno=\contentspagenumber \advance\pageno by 1 \let\maybe=\iftrue -@s not_eq normal @q unreserve a C++ keyword @> @** Introduction. This is the \.{CTANGLE} program by Silvio Levy and Donald E. Knuth, @@ -59,27 +61,15 @@ Joachim Schrod, Lee Wittenberg, and others who have contributed improvements. The ``banner line'' defined here should be changed whenever \.{CTANGLE} is modified. -@d banner "This is CTANGLE (Version 3.64)\n" +@d banner "This is CTANGLE (Version 4.2)" @c @@/ @h @@/ @@/ -@@/ -@@/ - -@ We predeclare several standard system functions here instead of including -their system header files, because the names of the header files are not as -standard as the names of the functions. (For example, some \CEE/ environments -have \.{} where others have \.{}.) - -@= -extern int strlen(); /* length of string */ -extern int strcmp(); /* compare strings lexicographically */ -extern char* strcpy(); /* copy one string to another */ -extern int strncmp(); /* compare up to $n$ string characters */ -extern char* strncpy(); /* copy up to $n$ string characters */ +@@/ +@ @ \.{CTANGLE} has a fairly straightforward outline. It operates in two phases: First it reads the source file, saving the \CEE/ code in @@ -89,40 +79,24 @@ Please read the documentation for \.{common}, the set of routines common to \.{CTANGLE} and \.{CWEAVE}, before proceeding further. @c -int main (ac, av) -int ac; -char **av; +int main ( +int ac, +char **av) { argc=ac; argv=av; program=ctangle; - @; + @@; common_init(); - if (show_banner) printf(banner); /* print a ``banner line'' */ + if (show_banner) puts(banner); /* print a ``banner line'' */ phase_one(); /* read all the user's text and compress it into |tok_mem| */ phase_two(); /* output the contents of the compressed tables */ return wrap_up(); /* and exit gracefully */ } -@ The following parameters were sufficient in the original \.{TANGLE} to -handle \TEX/, -so they should be sufficient for most applications of \.{CTANGLE}. -If you change |max_bytes|, |max_names|, or |hash_size| you should also -change them in the file |"common.w"|. - -@d max_bytes 90000 /* the number of bytes in identifiers, - index entries, and section names; used in |"common.w"| */ -@d max_toks 270000 /* number of bytes in compressed \CEE/ code */ -@d max_names 4000 /* number of identifiers, strings, section names; - must be less than 10240; used in |"common.w"| */ -@d max_texts 2500 /* number of replacement texts, must be less than 10240 */ -@d hash_size 353 /* should be prime; used in |"common.w"| */ -@d longest_name 10000 /* section names and strings shouldn't be longer than this */ -@d stack_size 50 /* number of simultaneous levels of macro expansion */ -@d buf_size 100 /* for \.{CWEAVE} and \.{CTANGLE} */ - @ The next few sections contain stuff from the file |"common.w"| that must be included in both |"ctangle.w"| and |"cweave.w"|. It appears in -file |"common.h"|, which needs to be updated when |"common.w"| changes. +file |"common.h"|, which is also included in |"common.w"| to propagate +possible changes from this \.{COMMON} interface consistently. @i common.h @@ -137,7 +111,7 @@ A \&{text} variable is a structure containing a pointer into |tok_mem|, which tells where the corresponding text starts, and an integer |text_link|, which, as we shall see later, is used to connect pieces of text that have the same name. All the \&{text}s are stored in -the array |text_info|, and we use a |text_pointer| variable to refer +the array |text_info|, and we use a \&{text\_pointer} variable to refer to them. The first position of |tok_mem| that is unoccupied by @@ -145,10 +119,6 @@ replacement text is called |tok_ptr|, and the first unused location of |text_info| is called |text_ptr|. Thus we usually have the identity |text_ptr->tok_start==tok_ptr|. -If your machine does not support |unsigned char| you should change -the definition of \&{eight\_bits} to |unsigned short|. -@^system dependencies@> - @= typedef struct { eight_bits *tok_start; /* pointer into |tok_mem| */ @@ -156,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; @@ -175,18 +145,19 @@ replacement text, an element of the array |text_info|. @d equiv equiv_or_xref /* info corresponding to names */ @ @= -name_dir->equiv=(char *)text_info; /* the undefined section has no replacement text */ +init_node(name_dir); /* the undefined section has no replacement text */ @ Here's the procedure that decides whether a name of length |l| starting at position |first| equals the identifier pointed to by |p|: @c -int names_match(p,first,l) -name_pointer p; /* points to the proposed match */ -char *first; /* position of first character of string */ -int l; /* length of identifier */ -{ - if (length(p)!=l) return 0; +boolean names_match(@t\1\1@> +name_pointer p, /* points to the proposed match */ +const char *first, /* position of first character of string */ +size_t l, /* length of identifier */ +eight_bits t@t\2\2@>) /* not used by \.{TANGLE} */ +{@+(void)t; + if (length(p)!=l) return false; return !strncmp(first,p->byte_start,l); } @@ -197,13 +168,13 @@ the loader won't complain of its absence. @c void -init_node(node) -name_pointer node; +init_node( +name_pointer node) { - node->equiv=(char *)text_info; + node->equiv=(void *)text_info; } void -init_p() {} +init_p(name_pointer p,eight_bits t) {@+(void)p;@+(void)t;@+} @* Tokens. Replacement texts, which represent \CEE/ code in a compressed format, @@ -224,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; @@ -258,15 +229,17 @@ construction or numerical constant. |tok_mem| when a replacement text is being generated. @c -void -store_two_bytes(x) -sixteen_bits x; +static void +store_two_bytes( +sixteen_bits x) { if (tok_ptr+2>tok_mem_end) overflow("token"); *tok_ptr++=x>>8; /* store high byte */ *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: @@ -309,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_ptr; /* first unused location in the output state stack */ -stack_pointer stack_end=stack+stack_size; /* end of |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, @@ -334,9 +307,9 @@ We assume that the \CEE/ compiler can copy structures. @^system dependencies@> @c -void -push_level(p) /* suspends the current level */ -name_pointer p; +static void +push_level(@t\1\1@> /* suspends the current level */ +name_pointer p@t\2\2@>) { if (stack_ptr==stack_end) overflow("stack"); *stack_ptr=cur_state; @@ -348,14 +321,18 @@ name_pointer p; } } +@ @= +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. @c -void -pop_level(flag) /* do this when |cur_byte| reaches |cur_end| */ -int flag; /* |flag==0| means we are in |output_defs| */ +static void +pop_level(@t\1\1@> /* do this when |cur_byte| reaches |cur_end| */ +boolean flag@t\2\2@>) /* |flag==false| means we are in |output_defs| */ { if (flag && cur_repl->text_linktext_link+text_info; /* stay on the same level */ @@ -381,22 +358,22 @@ 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@> @c -void -get_output() /* sends next token to |out_char| */ +static void +get_output(void) /* sends next token to |out_char| */ { sixteen_bits a; /* value of current byte */ restart: if (stack_ptr==stack) return; if (cur_byte==cur_end) { cur_val=-((int)cur_section); /* cast needed because of sign extension */ - pop_level(1); + pop_level(true); if (cur_val==0) goto restart; out_char(section_number); return; } @@ -409,7 +386,7 @@ get_output() /* sends next token to |out_char| */ switch (a/024000) { /* |024000==(0250-0200)*0400| */ case 0: cur_val=a; out_char(identifier); break; case 1: if (a==output_defs_flag) output_defs(); - else @; + else @@; break; default: cur_val=a-050000; if (cur_val>0) cur_section=cur_val; out_char(section_number); @@ -417,15 +394,17 @@ get_output() /* 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. @= { a-=024000; - if ((a+name_dir)->equiv!=(char *)text_info) push_level(a+name_dir); + if ((a+name_dir)->equiv!=(void *)text_info) push_level(a+name_dir); else if (a!=0) { - printf("\n! Not present: <"); + fputs("\n! Not present: <",stdout); print_section_name(a+name_dir); err_print(">"); @.Not present:
@> } @@ -461,7 +440,7 @@ strings, verbatim constructions and numerical constants. \yskip\hang |normal| means none of the above. -\yskip\noindent Furthermore, if the variable |protect| is positive, newlines +\yskip\noindent Furthermore, if the variable |protect| is |true|, newlines are preceded by a `\.\\'. @d normal 0 /* non-unusual state */ @@ -470,17 +449,17 @@ 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. @c -void -flush_buffer() /* writes one line to output file */ +static void +flush_buffer(void) /* writes one line to output file */ { C_putc('\n'); if (cur_line % 100 == 0 && show_progress) { @@ -491,6 +470,8 @@ flush_buffer() /* 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 \.{@@(} @@ -499,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]; /* 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 @@ -530,18 +511,15 @@ complain we're out of room@>= @* The big output switch. Here then is the routine that does the output. -@= -void phase_two(); - -@ @c -void -phase_two () { - web_file_open=0; +@c +static void +phase_two (void) { + web_file_open=false; cur_line=1; - @; - @; + @@; + @@; if (text_info->text_link==0 && cur_out_file==end_output_files) { - printf("\n! No program text was specified."); mark_harmless; + fputs("\n! No program text was specified.",stdout); mark_harmless; @.No program text...@> } else { @@ -551,7 +529,7 @@ phase_two () { } else { if (show_progress) { - printf("\nWriting the output files:"); + fputs("\nWriting the output files:",stdout); @.Writing the output...@> printf(" (%s)",C_file_name); update_terminal; @@ -560,11 +538,16 @@ phase_two () { } while (stack_ptr>stack) get_output(); flush_buffer(); -writeloop: @; - if(show_happiness) printf("\nDone."); +writeloop: @@; + if (show_happiness) { + if (show_progress) new_line; + fputs("Done.",stdout); + } } } +@ @=@+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. @@ -574,10 +557,10 @@ for (an_output_file=end_output_files; an_output_file>cur_out_file;) { an_output_file--; sprint_section_name(output_file_name,*an_output_file); fclose(C_file); - C_file=fopen(output_file_name,"w"); - if (C_file ==0) fatal("! Cannot open output file:",output_file_name); + C_file=fopen(output_file_name,"wb"); + if (C_file ==0) fatal("! Cannot open output file ",output_file_name); @.Cannot open output file@> - printf("\n(%s)",output_file_name); update_terminal; + if (show_progress) { printf("\n(%s)",output_file_name); update_terminal; } cur_line=1; stack_ptr=stack+1; cur_name= (*an_output_file); @@ -596,15 +579,16 @@ that refer to macros, preceded by the \.{\#define} preprocessor command. if (!output_defs_seen) output_defs(); -@ @= -boolean output_defs_seen=0; +@ @= +static boolean output_defs_seen=false; @ @= -void output_defs(); +static void output_defs(void);@/ +static void out_char(eight_bits); @ @c -void -output_defs() +static void +output_defs(void) { sixteen_bits a; push_level(NULL); @@ -614,7 +598,7 @@ output_defs() cur_end=(cur_text+1)->tok_start; C_printf("%s","#define "); out_state=normal; - protect=1; /* newlines should be preceded by |'\\'| */ + protect=true; /* newlines should be preceded by |'\\'| */ while (cur_byte= -static void out_char(); - -@ @c +@c static void -out_char(cur_char) -eight_bits cur_char; +out_char( +eight_bits cur_char) { char *j, *k; /* pointer into |byte_mem| */ restart: @@ -659,9 +640,9 @@ restart: 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; - @/@t\4@>@; - @/@t\4@>@; - @/@t\4@>@; + @/@t\4@>@@; + @/@t\4@>@@; + @/@t\4@>@@; case '=': case '>': C_putc(cur_char); C_putc(' '); out_state=normal; break; case join: out_state=unbreakable; break; @@ -679,22 +660,22 @@ restart: } @ @= -case plus_plus: C_putc('+'); C_putc('+'); out_state=normal; break; -case minus_minus: C_putc('-'); C_putc('-'); out_state=normal; break; -case minus_gt: C_putc('-'); C_putc('>'); out_state=normal; break; -case gt_gt: C_putc('>'); C_putc('>'); out_state=normal; break; -case eq_eq: C_putc('='); C_putc('='); out_state=normal; break; -case lt_lt: C_putc('<'); C_putc('<'); out_state=normal; break; -case gt_eq: C_putc('>'); C_putc('='); out_state=normal; break; -case lt_eq: C_putc('<'); C_putc('='); out_state=normal; break; -case not_eq: C_putc('!'); C_putc('='); out_state=normal; break; -case and_and: C_putc('&'); C_putc('&'); out_state=normal; break; -case or_or: C_putc('|'); C_putc('|'); out_state=normal; break; -case dot_dot_dot: C_putc('.'); C_putc('.'); C_putc('.'); out_state=normal; +case plus_plus: C_putc('+');@+C_putc('+'); out_state=normal; break; +case minus_minus: C_putc('-');@+C_putc('-'); out_state=normal; break; +case minus_gt: C_putc('-');@+C_putc('>'); out_state=normal; break; +case gt_gt: C_putc('>');@+C_putc('>'); out_state=normal; break; +case eq_eq: C_putc('=');@+C_putc('='); out_state=normal; break; +case lt_lt: C_putc('<');@+C_putc('<'); out_state=normal; break; +case gt_eq: C_putc('>');@+C_putc('='); out_state=normal; break; +case lt_eq: C_putc('<');@+C_putc('='); out_state=normal; break; +case non_eq: C_putc('!');@+C_putc('='); out_state=normal; break; +case and_and: C_putc('&');@+C_putc('&'); out_state=normal; break; +case or_or: C_putc('|');@+C_putc('|'); out_state=normal; break; +case dot_dot_dot: C_putc('.');@+C_putc('.');@+C_putc('.'); out_state=normal; break; -case colon_colon: C_putc(':'); C_putc(':'); out_state=normal; break; -case period_ast: C_putc('.'); C_putc('*'); out_state=normal; break; -case minus_gt_ast: C_putc('-'); C_putc('>'); C_putc('*'); out_state=normal; +case colon_colon: C_putc(':');@+C_putc(':'); out_state=normal; break; +case period_ast: C_putc('.');@+C_putc('*'); out_state=normal; break; +case minus_gt_ast: C_putc('-');@+C_putc('>');@+C_putc('*'); out_state=normal; break; @ When an identifier is output to the \CEE/ file, characters in the @@ -707,13 +688,13 @@ This makes debugging a lot less confusing. @d translit_length 10 -@= -char translit[128][translit_length]; +@= +static char translit[128][translit_length]; @ @= { int i; - for (i=0;i<128;i++) sprintf(translit[i],"X%02X",(unsigned)(128+i)); + for (i=0;i<128;i++) sprintf(translit[i],"X%02X",(unsigned int)(128+i)); } @ @= @@ -722,9 +703,9 @@ case identifier: j=(cur_val+name_dir)->byte_start; k=(cur_val+name_dir+1)->byte_start; while (j - else C_printf("%s",translit[(unsigned char)(*j)-0200]); + else C_printf("%s",translit[(eight_bits)(*j)-0200]); j++; } out_state=num_or_id; break; @@ -786,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 */ @@ -811,21 +792,25 @@ eight_bits ccode[256]; /* meaning of a char following \.{@@} */ until finding the next non-ignorable control code, which it returns. @c -eight_bits -skip_ahead() /* skip to next control code */ +static eight_bits +skip_ahead(void) /* skip to next control code */ { eight_bits c; /* control code found */ - while (1) { - if (loc>limit && (get_line()==0)) return(new_section); + while (true) { + if (loc>limit && (get_line()==false)) return new_section; *(limit+1)='@@'; while (*loc!='@@') loc++; if (loc<=limit) { loc++; c=ccode[(eight_bits)*loc]; loc++; - if (c!=ignore || *(loc-1)=='>') return(c); + if (c!=ignore || *(loc-1)=='>') return c; } } } +@ @= +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| @@ -842,35 +827,35 @@ 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=0; /* are we scanning a comment? */ +@= +static boolean comment_continues=false; /* are we scanning a comment? */ @ @c -int skip_comment(is_long_comment) /* skips over comments */ -boolean is_long_comment; +static boolean skip_comment(@t\1\1@> /* skips over comments */ +boolean is_long_comment@t\2\2@>) { char c; /* current character */ - while (1) { + while (true) { if (loc>limit) { if (is_long_comment) { - if(get_line()) return(comment_continues=1); + if(get_line()) return comment_continues=true; else{ err_print("! Input ended in mid-comment"); @.Input ended in mid-comment@> - return(comment_continues=0); + return comment_continues=false; } } - else return(comment_continues=0); + else return comment_continues=false; } c=*(loc++); if (is_long_comment && c=='*' && *loc=='/') { - loc++; return(comment_continues=0); + loc++; return comment_continues=false; } if (c=='@@') { if (ccode[(eight_bits)*loc]==new_section) { err_print("! Section name ended in mid-comment"); loc--; @.Section name ended in mid-comment@> - return(comment_continues=0); + return comment_continues=false; } else loc++; } @@ -881,48 +866,46 @@ boolean is_long_comment; @d constant 03 -@= -name_pointer cur_section_name; /* name of section just scanned */ -int no_where; /* suppress |print_where|? */ - -@ @= -#include /* definition of |isalpha|, |isdigit| and so on */ -#include /* definition of |exit| */ +@= +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. @d isxalpha(c) ((c)=='_' || (c)=='$') /* non-alpha characters allowed in identifier */ -@d ishigh(c) ((unsigned char)(c)>0177) +@d ishigh(c) ((eight_bits)(c)>0177) @^high-bit character handling@> @c -eight_bits -get_next() /* produces the next input token */ +static eight_bits +get_next(void) /* produces the next input token */ { static int preprocessing=0; eight_bits c; /* the current character */ - while (1) { + while (true) { if (loc>limit) { if (preprocessing && *(limit-1)!='\\') preprocessing=0; - if (get_line()==0) return(new_section); + if (get_line()==false) return new_section; else if (print_where && !no_where) { - print_where=0; - @; + print_where=false; + @@; } - else return ('\n'); + else return '\n'; } c=*loc; if (comment_continues || (c=='/' && (*(loc+1)=='*' || *(loc+1)=='/'))) { skip_comment(comment_continues||*(loc+1)=='*'); /* scan to end of comment or newline */ - if (comment_continues) return('\n'); + if (comment_continues) return '\n'; else continue; } loc++; if (xisdigit(c) || c=='.') @@; - else if (c=='\'' || c=='"' || (c=='L'&&(*loc=='\'' || *loc=='"'))) + else if (c=='\'' || c=='"'@| + || ((c=='L' || c=='u' || c=='U')&&(*loc=='\'' || *loc=='"'))@| + || ((c=='u' && *loc=='8')&&(*(loc+1)=='\'' || *(loc+1)=='"'))) @@; else if (isalpha(c) || isxalpha(c) || ishigh(c)) @@; @@ -930,14 +913,16 @@ get_next() /* produces the next input token */ else if (xisspace(c)) { if (!preprocessing || loc>limit) continue; /* we don't want a blank after a final backslash */ - else return(' '); /* ignore spaces and tabs, unless preprocessing */ + else return ' '; /* ignore spaces and tabs, unless preprocessing */ } else if (c=='#' && loc==buffer+1) preprocessing=1; mistake: @@; - return(c); + return c; } } +@ @=@+static eight_bits get_next(void); + @ The following code assigns values to the combinations \.{++}, \.{--}, \.{->}, \.{>=}, \.{<=}, \.{==}, \.{<<}, \.{>>}, \.{!=}, \.{||} and \.{\&\&}, and to the \CPLUSPLUS/ @@ -945,14 +930,14 @@ combinations \.{...}, \.{::}, \.{.*} and \.{->*}. The compound assignment operators (e.g., \.{+=}) are treated as separate tokens. -@d compress(c) if (loc++<=limit) return(c) +@d compress(c) if (loc++<=limit) return c @= switch(c) { case '+': if (*loc=='+') compress(plus_plus); break; case '-': if (*loc=='-') {compress(minus_minus);} - else if (*loc=='>') if (*(loc+1)=='*') {loc++; compress(minus_gt_ast);} - else compress(minus_gt); break; + else { if (*loc=='>') { if (*(loc+1)=='*') {loc++; compress(minus_gt_ast);} + else compress(minus_gt); } } break; case '.': if (*loc=='*') {compress(period_ast);} else if (*loc=='.' && *(loc+1)=='.') { loc++; compress(dot_dot_dot); @@ -966,13 +951,14 @@ switch(c) { else if (*loc=='<') compress(lt_lt); break; case '&': if (*loc=='&') compress(and_and); break; case '|': if (*loc=='|') compress(or_or); break; - case '!': if (*loc=='=') compress(not_eq); break; + case '!': if (*loc=='=') compress(non_eq); break; } @ @= { id_first=--loc; - while (isalpha(*++loc) || isdigit(*loc) || isxalpha(*loc) || ishigh(*loc)); - id_loc=loc; return(identifier); + while (isalpha((eight_bits)*++loc) || isdigit((eight_bits)*loc) @| + || isxalpha((eight_bits)*loc) || ishigh((eight_bits)*loc)); + id_loc=loc; return identifier; } @ @= { @@ -995,7 +981,7 @@ switch(c) { found: while (*loc=='u' || *loc=='U' || *loc=='l' || *loc=='L' || *loc=='f' || *loc=='F') loc++; id_loc=loc; - return(constant); + return constant; } @ \CEE/ strings and character constants, delimited by double and single @@ -1007,16 +993,17 @@ convention, but do not allow the string to be longer than |longest_name|. char delim = c; /* what started the string */ id_first = section_text+1; id_loc = section_text; *++id_loc=delim; - if (delim=='L') { /* wide character constant */ + if (delim=='L' || delim=='u' || delim=='U') { /* wide character constant */ + if (delim=='u' && *loc=='8') { *++id_loc=*loc++; } delim=*loc++; *++id_loc=delim; } - while (1) { + while (true) { if (loc>=limit) { if(*(limit-1)!='\\') { err_print("! String didn't end"); loc=limit; break; @.String didn't end@> } - if(get_line()==0) { + if(get_line()==false) { err_print("! Input ended in middle of string"); loc=buffer; break; @.Input ended in middle of string@> } @@ -1035,13 +1022,13 @@ convention, but do not allow the string to be longer than |longest_name|. if (++id_loc<=section_text_end) *id_loc=c; } if (id_loc>=section_text_end) { - printf("\n! String too long: "); + fputs("\n! String too long: ",stdout); @.String too long@> term_write(section_text+1,25); err_print("..."); } id_loc++; - return(string); + return string; } @ After an \.{@@} sign has been scanned, the next character tells us @@ -1061,10 +1048,10 @@ whether there is more work to do. continue; case section_name: cur_section_name_char=*(loc-1); - @; - case string: @; - case ord: @; - default: return(c); + @@; + case string: @@; + case ord: @@; + default: return c; } } @@ -1093,18 +1080,18 @@ thus, \.{@@'\\nopq'} gives the same result as \.{@@'\\n'}. } } loc++; - return(ord); + return ord; @ @= { char *k; /* pointer into |section_text| */ - @; + @@; if (k-section_text>3 && strncmp(k-2,"...",3)==0) cur_section_name=section_lookup(section_text+1,k-3,1); /* 1 means is a prefix */ else cur_section_name=section_lookup(section_text+1,k,0); if (cur_section_name_char=='(') @; - return(section_name); + complain we're out of room@>@; + return section_name; } @ Section names are placed into the |section_text| array with consecutive spaces, @@ -1117,14 +1104,14 @@ character of the name.) @ @= k=section_text; -while (1) { - if (loc>limit && get_line()==0) { +while (true) { + if (loc>limit && get_line()==false) { err_print("! Input ended in section name"); @.Input ended in section name@> loc=buffer+1; break; } c=*loc; - @; + @@; loc++; if (k=section_text_end) { - printf("\n! Section name too long: "); + fputs("\n! Section name too long: ",stdout); @.Section name too long@> term_write(section_text+1,25); printf("..."); mark_harmless; @@ -1167,7 +1154,7 @@ buffer. We also set |loc| to the position just after the ending delimiter. if (loc>=limit) err_print("! Verbatim string didn't end"); @.Verbatim string didn't end@> id_loc=loc; loc+=2; - return(string); + return string; } @* Scanning a macro definition. @@ -1192,18 +1179,18 @@ 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 text_pointer cur_text; /* replacement text formed by |scan_repl| */ +static eight_bits next_control; @ @c -void -scan_repl(t) /* creates a replacement text */ -eight_bits t; +static void +scan_repl(@t\1\1@> /* creates a replacement text */ +eight_bits t@t\2\2@>) { sixteen_bits a; /* the current token */ - if (t==section_name) {@;} - while (1) switch (a=get_next()) { + if (t==section_name) {@@;} + while (true) switch (a=get_next()) { @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. @@ -1232,8 +1221,8 @@ if (changing && include_depth==change_depth) { /* correction made Feb 2017 */ store_two_bytes((sixteen_bits)cur_line); } id_loc=id_first+strlen(id_first); -{int a=id_lookup(id_first,id_loc,0)-name_dir; app_repl((a / 0400)+0200); - app_repl(a % 0400);} +{int a_l=id_lookup(id_first,id_loc,0)-name_dir; app_repl((a_l / 0400)+0200); + app_repl(a_l % 0400);} @ @= case identifier: a=id_lookup(id_first,id_loc,0)-name_dir; @@ -1241,26 +1230,26 @@ 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); - @; break; + @@; break; } case output_defs_code: if (t!=section_name) err_print("! Misplaced @@h"); @.Misplaced @@h@> else { - output_defs_seen=1; + output_defs_seen=true; a=output_defs_flag; app_repl((a / 0400)+0200); app_repl(a % 0400); - @; + @@; } break; case constant: case string: - @; + @@; case ord: - @; + @@; case definition: case format_code: case begin_C: if (t!=section_name) goto done; else { err_print("! @@d, @@f and @@c are ignored in C text"); continue; @@ -1268,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= -extern sixteen_bits section_count; /* the current section number */ - -@ 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. @c -void -scan_section() +static void +scan_section(void) { name_pointer p; /* section name for the current section */ text_pointer q; /* text for the current section */ sixteen_bits a; /* token for left-hand side of definition */ - section_count++; @+ no_where=1; + section_count++; @+ no_where=true; if (*(loc-1)=='*' && show_progress) { /* starred section */ printf("*%d",section_count); update_terminal; } next_control=0; - while (1) { + while (true) { @; + \.{@@\ } or the like@>@; if (next_control == definition) { /* \.{@@d} */ @@; continue; @@ -1381,15 +1367,17 @@ scan_section() } if (next_control == section_name) { /* \.{@@<} or \.{@@(} */ p=cur_section_name; - @; + @@; break; } return; /* \.{@@\ } or \.{@@*} */ } - no_where=print_where=0; - @; + no_where=print_where=false; + @@; } +@ @=@+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 @@ -1404,7 +1392,7 @@ while (next_control= { - while ((next_control=get_next())=='\n'); /*allow newline before definition */ + while ((next_control=get_next())=='\n'); /* allow newline before definition */ if (next_control!=identifier) { err_print("! Definition flushed, must start with identifier"); @.Definition flushed...@> @@ -1417,7 +1405,7 @@ while (next_controltext_link=0; /* |text_link==0| characterizes a macro */ + cur_text->text_link=macro; } @ If the section name is not followed by \.{=} or \.{+=}, no \CEE/ @@ -1434,9 +1422,9 @@ if (next_control!='=' && next_control!=eq_eq) continue; @ @= -@; +@@; scan_repl(section_name); /* now |cur_text| points to the replacement text */ -@; +@@; @ @= store_two_bytes((sixteen_bits)(0150000+section_count)); @@ -1446,7 +1434,7 @@ store_two_bytes((sixteen_bits)(0150000+section_count)); if (p==name_dir||p==0) { /* unnamed section, or bad section name */ (last_unnamed)->text_link=cur_text-text_info; last_unnamed=cur_text; } -else if (p->equiv==(char *)text_info) p->equiv=(char *)cur_text; +else if (p->equiv==(void *)text_info) p->equiv=(void *)cur_text; /* first section of this name */ else { q=(text_pointer)p->equiv; @@ -1457,12 +1445,9 @@ else { cur_text->text_link=section_flag; /* mark this replacement text as a nonmacro */ -@ @= -void phase_one(); - @ @c -void -phase_one() { +static void +phase_one(void) { phase=1; section_count=0; reset_input(); @@ -1472,26 +1457,25 @@ phase_one() { phase=2; } +@ @=@+static void phase_one(void); + @ Only a small subset of the control codes is legal in limbo, so limbo processing is straightforward. -@= -void skip_limbo(); - -@ @c -void -skip_limbo() +@c +static void +skip_limbo(void) { char c; - while (1) { - if (loc>limit && get_line()==0) return; + while (true) { + if (loc>limit && get_line()==false) return; *(limit+1)='@@'; while (*loc!='@@') loc++; if (loc++<=limit) { c=*loc++; if (ccode[(eight_bits)c]==new_section) break; switch (ccode[(eight_bits)c]) { - case translit_code: @; break; + case translit_code: @@; break; case format_code: case '@@': break; case control_text: if (c=='q' || c=='Q') { while ((c=skip_ahead())=='@@'); @@ -1507,6 +1491,8 @@ skip_limbo() } } +@ @=@+static void skip_limbo(void); + @ @= while(xisspace(*loc)&&loc else { - unsigned i; + unsigned int i; char *beg; sscanf(loc-3,"%x",&i); while(xisspace(*loc)&&loc else{ - strncpy(translit[i-0200],beg,loc-beg); + strncpy(translit[i-0200],beg,(size_t)(loc-beg)); translit[i-0200][loc-beg]='\0'; } } -@ Because on some systems the difference between two pointers is a |long| +@ Because on some systems the difference between two pointers is a |ptrdiff_t| but not an |int|, we use \.{\%ld} to print these quantities. @c void -print_stats() { - printf("\nMemory usage statistics:\n"); +print_stats(void) { + puts("\nMemory usage statistics:"); printf("%ld names (out of %ld)\n", - (long)(name_ptr-name_dir),(long)max_names); + (ptrdiff_t)(name_ptr-name_dir),(long)max_names); printf("%ld replacement texts (out of %ld)\n", - (long)(text_ptr-text_info),(long)max_texts); + (ptrdiff_t)(text_ptr-text_info),(long)max_texts); printf("%ld bytes (out of %ld)\n", - (long)(byte_ptr-byte_mem),(long)max_bytes); + (ptrdiff_t)(byte_ptr-byte_mem),(long)max_bytes); printf("%ld tokens (out of %ld)\n", - (long)(tok_ptr-tok_mem),(long)max_toks); + (ptrdiff_t)(tok_ptr-tok_mem),(long)max_toks); } @** Index. diff --git a/web/c_cpp/cweb/cweav-bs.ch b/web/c_cpp/cweb/cweav-bs.ch index 8c4c1fe8ff..bf2752881e 100644 --- a/web/c_cpp/cweb/cweav-bs.ch +++ b/web/c_cpp/cweb/cweav-bs.ch @@ -20,17 +20,17 @@ This file contributed by Barry Schwartz, trashman@crud.mn.org, 28 Jun 94. The ``banner line'' defined here should be changed whenever \.{CWEAVE} is modified. -@d banner "This is CWEAVE (Version 3.64)\n" +@d banner "This is CWEAVE (Version 4.2)" @y The ``banner line'' defined here should be changed whenever \.{CWEAVE} is modified. -@d banner "This is CWEAVE (Version 3.64pc/big)\n" +@d banner "This is CWEAVE (Version 4.2pc/big)" @z -@x Section 9. -@d chunk_marker 0 +@x Section 7. + for section names */ @= typedef struct name_info { @@ -41,24 +41,21 @@ typedef struct name_info { names */ char Ilk; /* used by identifiers in \.{CWEAVE} only */ } dummy; - char *equiv_or_xref; /* info corresponding to names */ + void *equiv_or_xref; /* info corresponding to names */ } name_info; /* contains information about an identifier or section name */ typedef name_info *name_pointer; /* pointer into array of \&{name\_info}s */ typedef name_pointer *hash_pointer; extern char byte_mem[]; /* characters of names */ extern char *byte_mem_end; /* end of |byte_mem| */ +extern char *byte_ptr; /* first unused position in |byte_mem| */ extern name_info name_dir[]; /* information about names */ extern name_pointer name_dir_end; /* end of |name_dir| */ extern name_pointer name_ptr; /* first unused position in |name_dir| */ -extern char *byte_ptr; /* first unused position in |byte_mem| */ extern name_pointer hash[]; /* heads of hash lists */ extern hash_pointer hash_end; /* end of |hash| */ extern hash_pointer h; /* index into hash-head array */ -extern name_pointer id_lookup(); /* looks up a string in the identifier table */ -extern name_pointer section_lookup(); /* finds section name */ -extern void print_section_name(), sprint_section_name(); @y -@d chunk_marker 0 + for section names */ @f huge extern @@ -87,13 +84,10 @@ extern char huge* byte_ptr; /* first unused position in |byte_mem| */ extern name_pointer hash[]; /* heads of hash lists */ extern hash_pointer hash_end; /* end of |hash| */ extern hash_pointer h; /* index into hash-head array */ -extern name_pointer id_lookup(); /* looks up a string in the identifier table */ -extern name_pointer section_lookup(); /* finds section name */ -extern void print_section_name(), sprint_section_name(); @z -@x Section 18. +@x Section 22. typedef struct xref_info { sixteen_bits num; /* section number plus zero or |def_flag| */ struct xref_info *xlink; /* pointer to the previous cross-reference */ @@ -108,81 +102,54 @@ typedef xref_info huge* xref_pointer; @z -@x Section 19. -xref_info xmem[max_refs]; /* contains cross-reference information */ -xref_pointer xmem_end = xmem+max_refs-1; +@x Section 23. +static xref_info xmem[max_refs]; /* contains cross-reference information */ +static xref_pointer xmem_end = xmem+max_refs-1; @y -xref_info huge xmem[max_refs]; /* contains cross-reference information */ -xref_pointer xmem_end; +static xref_info huge xmem[max_refs]; /* contains cross-reference information */ +static xref_pointer xmem_end; @z -@x Section 20. +@x Section 24. @d xref equiv_or_xref @y @d xref ptr_union.xref_member @z -@x Section 20. -xref_ptr=xmem; name_dir->xref=(char*)xmem; xref_switch=0; section_xref_switch=0; +@x Section 24. +xref_ptr=xmem; init_node(name_dir); xref_switch=0; section_xref_switch=0; xmem->num=0; /* sentinel value */ @y xmem_end = xmem + max_refs - 1; -xref_ptr=xmem; name_dir->xref=(char*)xmem; xref_switch=0; section_xref_switch=0; +xref_ptr=xmem; init_node(name_dir); xref_switch=0; section_xref_switch=0; xmem->num=0; /* sentinel value */ @z -@x Section 21. - append_xref(m); xref_ptr->xlink=q; p->xref=(char*)xref_ptr; -@y - append_xref(m); xref_ptr->xlink=q; p->xref=(char huge*)xref_ptr; -@z - - -@x Section 22. - if (r==xmem) p->xref=(char*)xref_ptr; -@y - if (r==xmem) p->xref=(char huge*)xref_ptr; -@z - - -@x Section 23. - q=(xref_pointer)p->xref; - if (q->num==file_flag) return; - append_xref(file_flag); - xref_ptr->xlink = q; - p->xref = (char *)xref_ptr; +@x Section 30. (to please Borland's C++, version 4.02) +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 - q=(xref_pointer)p->xref; - if (q->num==file_flag) return; - append_xref(file_flag); - xref_ptr->xlink = q; - p->xref = (char huge*)xref_ptr; +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 25. (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_start[max_texts]; /* directory into |tok_mem| */ -token_pointer tok_ptr; /* first unused position in |tok_mem| */ -text_pointer text_ptr; /* first unused position in |tok_start| */ -text_pointer tok_start_end = tok_start+max_texts-1; /* end of |tok_start| */ -token_pointer max_tok_ptr; /* largest value of |tok_ptr| */ -@y -token tok_mem[max_toks]; /* tokens */ -token_pointer tok_mem_end; /* end of |tok_mem| */ -token_pointer tok_start[max_texts]; /* directory into |tok_mem| */ -token_pointer tok_ptr; /* first unused position in |tok_mem| */ -text_pointer text_ptr; /* first unused position in |tok_start| */ -text_pointer tok_start_end; /* end of |tok_start| */ -token_pointer max_tok_ptr; /* largest value of |tok_ptr| */ -@z - -@x Section 26. (goes with the previous change) -tok_start[1]=tok_mem+1; -max_tok_ptr=tok_mem+1; max_text_ptr=tok_start+1; +@x Section 31. (goes with the previous change) +tok_ptr=max_tok_ptr=tok_mem+1;@/ +tok_start[0]=tok_start[1]=tok_mem+1;@/ +text_ptr=max_text_ptr=tok_start+1; @y tok_start[1]=tok_mem+1; tok_mem_end=tok_mem+max_toks-1; @@ -191,27 +158,20 @@ max_tok_ptr=tok_mem+1; max_text_ptr=tok_start+1; @z -@x Section 27. - p->ilk=t; p->xref=(char*)xmem; -@y - p->ilk=t; p->xref=(char huge*)xmem; -@z - - -@x Section 27. - p->xref=(char*)xmem; +@x Section 32. + p->xref=(void *)xmem; @y - p->xref=(char huge*)xmem; + p->xref=(void huge*)xmem; @z -@x Section 70. +@x Section 74. if (unindexed(lhs)) { /* retain only underlined entries */ xref_pointer q,r=NULL; for (q=(xref_pointer)lhs->xref;q>xmem;q=q->xlink) if (q->numxlink=q->xlink; - else lhs->xref=(char*)q->xlink; + else lhs->xref=(void *)q->xlink; else r=q; } @y @@ -220,13 +180,13 @@ max_tok_ptr=tok_mem+1; max_text_ptr=tok_start+1; for (q=(xref_pointer)lhs->xref;q>xmem;q=q->xlink) if (q->numxlink=q->xlink; - else lhs->xref=(char huge*)q->xlink; + else lhs->xref=(void huge*)q->xlink; else r=q; } @z -@x Section 87. +@x Section 93. char *k, *k_end=(p+1)->byte_start; /* pointers into |byte_mem| */ out('{'); for (k=p->byte_start; kxlink=(xref_pointer)p->xref; r=xref_ptr; - p->xref=(char*)xref_ptr; - while (r->xlink!=q) {r->num=r->xlink->num; r=r->xlink;} - r->num=m; /* everything from |q| on is left undisturbed */ -@y - append_xref(0); /* this number doesn't matter */ - xref_ptr->xlink=(xref_pointer)p->xref; r=xref_ptr; - p->xref=(char huge*)xref_ptr; - while (r->xlink!=q) {r->num=r->xlink->num; r=r->xlink;} - r->num=m; /* everything from |q| on is left undisturbed */ -@z - - -@x Section 163. -@ @= -@y -@ @= -#ifdef __MSDOS__ -if (d<0 && pp+d>pp) pp=scrap_base; /* segmented architecture caused wrap */ -else -#endif -@z - - -@x Section 194. +@x Section 209. char *p; /* index into |byte_mem| */ @y char huge *p; /* index into |byte_mem| */ @z -@x Section 229. - if (cur_name->xref!=(char*)xmem) { +@x Section 244. + if (cur_name->xref!=(void *)xmem) { @y - if (cur_name->xref!=(char huge*)xmem) { + if (cur_name->xref!=(void huge*)xmem) { @z -@x Section 232. -char *cur_byte; /* index into |byte_mem| */ +@x Section 246. +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 -@x Section 241. +@x Section 255. switch (cur_name->ilk) { - case normal: if (is_tiny(cur_name)) out_str("\\|"); + case normal: case func_template: if (is_tiny(cur_name)) out_str("\\|"); else {char *j; @y switch (cur_name->ilk) { - case normal: if (is_tiny(cur_name)) out_str("\\|"); + case normal: case func_template: if (is_tiny(cur_name)) out_str("\\|"); else {char huge* j; @z -@x Section 241. - case custom: case quoted: {char *j; out_str("$\\"); +@x Section 255. + case custom: {char *j; out_str("$\\"); @y - case custom: case quoted: {char huge* j; out_str("$\\"); + case custom: {char huge* j; out_str("$\\"); @z diff --git a/web/c_cpp/cweb/cweav-pc.ch b/web/c_cpp/cweb/cweav-pc.ch index 28cd94f5a3..b37f9f2ec3 100644 --- a/web/c_cpp/cweb/cweav-pc.ch +++ b/web/c_cpp/cweb/cweav-pc.ch @@ -11,29 +11,18 @@ 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 3.64)\n" +@d banner "This is CWEAVE (Version 4.2)" @y -@d banner "This is CWEAVE (Version 3.64pc)\n" +@d banner "This is CWEAVE (Version 4.2pc)" @z @x section 4 -@d max_bytes 90000 /* the number of bytes in identifiers, +@d max_bytes 1000000 /* the number of bytes in identifiers, @y @d max_bytes (unsigned)60000 /* the number of bytes in identifiers, @z @x -@d max_refs 20000 /* number of cross-references; must be less than 65536 */ +@d max_refs 65535 /* number of cross-references; must be less than 65536 */ @y @d max_refs 10000 /* number of cross-references; must be less than 65536 */ @z - -@x section 163 -@ @= -@y -@ @= -#ifdef __MSDOS__ -if (d<0 && pp+d>pp) pp=scrap_base; /* segmented architecture caused wrap */ -else -#endif -@z - diff --git a/web/c_cpp/cweb/cweav-ql.ch b/web/c_cpp/cweb/cweav-ql.ch index 3e37ba2352..28053eb158 100644 --- a/web/c_cpp/cweb/cweav-ql.ch +++ b/web/c_cpp/cweb/cweav-ql.ch @@ -7,15 +7,15 @@ ex cc;"-v -h -c =500000 cweave_c" @x -\def\title{CWEAVE (Version 3.64)} +\def\title{CWEAVE (Version 4.2)} @y -\def\title{CWEAVE (QL Version 3.64)} +\def\title{CWEAVE (QL Version 4.2)} @z @x section 1 -@d banner "This is CWEAVE (Version 3.64)\n" +@d banner "This is CWEAVE (Version 4.2)" @y -@d banner "This is CWEAVE (QL Version 3.64)\n" +@d banner "This is CWEAVE (QL Version 4.2)" @z @x diff --git a/web/c_cpp/cweb/cweav-vms.ch b/web/c_cpp/cweb/cweav-vms.ch index b6f46559cc..7d80d57c1e 100644 --- a/web/c_cpp/cweb/cweav-vms.ch +++ b/web/c_cpp/cweb/cweav-vms.ch @@ -13,25 +13,26 @@ modified: (also modified by Don Knuth to keep version numbers uptodate) @x section 1 (01-FEB-1992 ST) -@d banner "This is CWEAVE (Version 3.64)\n" +@d banner "This is CWEAVE (Version 4.2)" @y -@d banner "This is CWEAVE (VAX/VMS Version 3.64)\n" +@d banner "This is CWEAVE (VAX/VMS Version 4.2)" @z -@x section 6 (from common.h) (01-FEB-1992 ST) -#include +@x section 3 (01-FEB-1992 ST) +#include /* definition of |@!isalpha|, |@!isdigit| and so on */ +#include /* definition of |@!bool|, |@!true| and |@!false| */ +#include /* definition of |@!ptrdiff_t| */ +#include /* definition of |@!uint8_t| and |@!uint16_t| */ +#include /* definition of |@!getenv| and |@!exit| */ +#include /* definition of |@!printf| and friends */ +#include /* definition of |@!strlen|, |@!strcmp| and so on */ @y -#include stdio /* VMS searches Textlibraries faster */ -@z - -@x section 38 (1991 JM) (01-FEB-1992 ST) -#include /* definition of |isalpha|, |isdigit| and so on */ -@y -#include ctype /* VMS searches Textlibraries faster */ -@z - -@x section 39 (01-FEB-1992 ST) -@d isxalpha(c) ((c)=='_') /* non-alpha character allowed in identifier */ -@y -@d isxalpha(c) ((c)=='_' || (c)=='$') /* non-alpha characters allowed in id */ +#include ctype /* definition of |@!isalpha|, |@!isdigit| and so on */ + /* VMS searches text libraries faster */ +#include stdbool /* definition of |@!bool|, |@!true| and |@!false| */ +#include stddef /* definition of |@!ptrdiff_t| */ +#include stdint /* definition of |@!uint8_t| and |@!uint16_t| */ +#include stdlib /* definition of |@!getenv| and |@!exit| */ +#include stdio /* definition of |@!printf| and friends */ +#include string /* definition of |@!strlen|, |@!strcmp| and so on */ @z diff --git a/web/c_cpp/cweb/cweav-w32.ch b/web/c_cpp/cweb/cweav-w32.ch index 26825b0bfd..346d00771a 100644 --- a/web/c_cpp/cweb/cweav-w32.ch +++ b/web/c_cpp/cweb/cweav-w32.ch @@ -2,51 +2,33 @@ 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 3.64)\n" +@d banner "This is CWEAVE (Version 4.2)" @y -@d banner "This is CWEAVE (Version 3.64win32)\n" +@d banner "This is CWEAVE (Version 4.2win32)" @z @x -@ We predeclare several standard system functions here instead of including -their system header files, because the names of the header files are not as -standard as the names of the functions. (For example, some \CEE/ environments -have \.{} where others have \.{}.) - -@= -extern int strlen(); /* length of string */ -extern int strcmp(); /* compare strings lexicographically */ -extern char* strcpy(); /* copy one string to another */ -extern int strncmp(); /* compare up to $n$ string characters */ -extern char* strncpy(); /* copy up to $n$ string characters */ -@y -@z - -@x -int names_match(p,first,l,t) -name_pointer p; /* points to the proposed match */ +boolean names_match(@t\1\1@> +name_pointer p, /* points to the proposed match */ +const char *first, /* position of first character of string */ +size_t l, /* length of identifier */ +eight_bits t@t\2\2@>) /* desired |ilk| */ @y -int __cdecl names_match(p,first,l,t) -name_pointer p; /* points to the proposed match */ +boolean __cdecl names_match(@t\1\1@> +name_pointer p, /* points to the proposed match */ +const char *first, /* position of first character of string */ +size_t l, /* length of identifier */ +eight_bits t@t\2\2@>) /* desired |ilk| */ @z @x void -init_p(p,t) -name_pointer p; +init_p( +name_pointer p, +eight_bits t) @y void __cdecl -init_p(p,t) -name_pointer p; -@z - -@x -@ @= -#include /* definition of |isalpha|, |isdigit| and so on */ -#include /* definition of |exit| */ -@y -@ @= -#include /* definition of |isalpha|, |isdigit| and so on */ -#include /* definition of |exit| */ -#include /* definition of |strncmp| and |strncpy| */ +init_p( +name_pointer p, +eight_bits t) @z diff --git a/web/c_cpp/cweb/cweave.w b/web/c_cpp/cweb/cweave.w index e06762b1fc..a8e31055b2 100644 --- a/web/c_cpp/cweb/cweave.w +++ b/web/c_cpp/cweb/cweave.w @@ -2,10 +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 3.64 --- February 2002 -% (essentially the same as version 3.6, which added -% recently introduced features of standard C++ to version 3.4) -% (In November 2016 I made minor adjustments but changed no code -- DEK) +% Version 4.2 --- February 2021 % Copyright (C) 1987,1990,1993,2000 Silvio Levy and Donald E. Knuth @@ -18,6 +15,11 @@ % entire resulting derived work is given a different name and distributed % under the terms of a permission notice identical to this one. +% Amendments to 'cweave.w' resulting in this updated version were created +% by numerous collaborators over the course of many years. + +% Please send comments, suggestions, etc. to tex-k@@tug.org. + % Here is TeX material that gets inserted after \input cwebmac \def\hang{\hangindent 3em\indent\ignorespaces} \def\pb{$\.|\ldots\.|$} % C brackets (|...|) @@ -30,11 +32,11 @@ \def\skipxTeX{\\{skip\_\TEX/}} \def\copyxTeX{\\{copy\_\TEX/}} -\def\title{CWEAVE (Version 3.64)} +\def\title{CWEAVE (Version 4.2)} \def\topofcontents{\null\vfill \centerline{\titlefont The {\ttitlefont CWEAVE} processor} \vskip 15pt - \centerline{(Version 3.64)} + \centerline{(Version 4.2)} \vfill} \def\botofcontents{\vfill \noindent @@ -52,7 +54,6 @@ under the terms of a permission notice identical to this one. } \pageno=\contentspagenumber \advance\pageno by 1 \let\maybe=\iftrue -@s not_eq normal @q unreserve a C++ keyword @> @** Introduction. This is the \.{CWEAVE} program by Silvio Levy and Donald E. Knuth, @@ -66,27 +67,15 @@ 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 3.64)\n" +@d banner "This is CWEAVE (Version 4.2)" @c @@/ @h @@/ @@/ -@@/ +@@/ @ -@ We predeclare several standard system functions here instead of including -their system header files, because the names of the header files are not as -standard as the names of the functions. (For example, some \CEE/ environments -have \.{} where others have \.{}.) - -@= -extern int strlen(); /* length of string */ -extern int strcmp(); /* compare strings lexicographically */ -extern char* strcpy(); /* copy one string to another */ -extern int strncmp(); /* compare up to $n$ string characters */ -extern char* strncpy(); /* copy up to $n$ string characters */ - @ \.{CWEAVE} has a fairly straightforward outline. It operates in three phases: First it inputs the source file and stores cross-reference data, then it inputs the source once again and produces the \TEX/ output @@ -96,52 +85,40 @@ Please read the documentation for \.{common}, the set of routines common to \.{CTANGLE} and \.{CWEAVE}, before proceeding further. @c -int main (ac, av) -int ac; /* argument count */ -char **av; /* argument values */ +int main (@t\1\1@> +int ac, /* argument count */ +char **av@t\2\2@>) /* argument values */ { argc=ac; argv=av; program=cweave; - make_xrefs=force_lines=make_pb=1; /* controlled by command-line options */ + @@; common_init(); - @; - if (show_banner) printf(banner); /* print a ``banner line'' */ - @; + @@; + if (show_banner) puts(banner); /* print a ``banner line'' */ + @@; 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 */ } +@ The next few sections contain stuff from the file |"common.w"| that must +be included in both |"ctangle.w"| and |"cweave.w"|. It appears in +file |"common.h"|, which is also included in |"common.w"| to propagate +possible changes from this \.{COMMON} interface consistently. + +@i common.h + @ The following parameters were sufficient in the original \.{WEAVE} to handle \TEX/, so they should be sufficient for most applications of \.{CWEAVE}. -If you change |max_bytes|, |max_names|, |hash_size|, or |buf_size| -you have to change them also in the file |"common.w"|. - -@d max_bytes 90000 /* the number of bytes in identifiers, - index entries, and section names */ -@d max_names 4000 /* number of identifiers, strings, section names; - must be less than 10240; used in |"common.w"| */ -@d max_sections 2000 /* greater than the total number of sections */ -@d hash_size 353 /* should be prime */ -@d buf_size 100 /* maximum length of input line, plus one */ -@d longest_name 10000 /* section names and strings shouldn't be longer than this */ -@d long_buf_size (buf_size+longest_name) + @d line_length 80 /* lines of \TEX/ output have at most this many characters; should be less than 256 */ -@d max_refs 20000 /* number of cross-references; must be less than 65536 */ -@d max_toks 20000 /* number of symbols in \CEE/ texts being parsed; - must be less than 65536 */ -@d max_texts 4000 /* number of phrases in \CEE/ texts being parsed; +@d max_refs 65535 /* number of cross-references; must be less than 65536 */ +@d max_texts 10239 /* number of phrases in \CEE/ texts being parsed; must be less than 10240 */ -@d max_scraps 2000 /* number of tokens in \CEE/ texts being parsed */ -@d stack_size 400 /* number of simultaneous output levels */ - -@ The next few sections contain stuff from the file |"common.w"| that must -be included in both |"ctangle.w"| and |"cweave.w"|. It appears in -file |"common.h"|, which needs to be updated when |"common.w"| changes. - -@i common.h +@d max_scraps 10000 /* number of tokens in \CEE/ texts being parsed */ @* Data structures exclusive to {\tt CWEAVE}. As explained in \.{common.w}, the field of a |name_info| structure @@ -205,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 @@ -237,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|. @@ -252,7 +229,7 @@ has a special first cross-reference whose |num| field is |file_flag|. @d xref equiv_or_xref @= -xref_ptr=xmem; name_dir->xref=(char*)xmem; xref_switch=0; section_xref_switch=0; +xref_ptr=xmem; init_node(name_dir); xref_switch=0; section_xref_switch=0; xmem->num=0; /* sentinel value */ @ A new cross-reference for an identifier is formed by calling |new_xref|, @@ -266,16 +243,20 @@ If one were careful, one could probably make more changes around section @d append_xref(c) if (xref_ptr==xmem_end) overflow("cross-reference"); else (++xref_ptr)->num=c; -@d no_xref (flags['x']==0) -@d make_xrefs flags['x'] /* should cross references be output? */ +@d no_xref (!make_xrefs) @d is_tiny(p) ((p+1)->byte_start==(p)->byte_start+1) @d unindexed(a) (ailk>=custom) /* tells if uses of a name are to be indexed */ -@c -void -new_xref(p) -name_pointer p; +@= +static void new_xref(name_pointer);@/ +static void new_section_xref(name_pointer);@/ +static void set_file_flag(name_pointer); + +@ @c +static void +new_xref( +name_pointer p) { xref_pointer q; /* pointer to previous cross-reference */ sixteen_bits m, n; /* new and previous cross-reference value */ @@ -289,7 +270,7 @@ name_pointer p; q->num=m; return; } } - append_xref(m); xref_ptr->xlink=q; p->xref=(char*)xref_ptr; + append_xref(m); xref_ptr->xlink=q; update_node(p); } @ The cross-reference lists for section names are slightly different. @@ -304,9 +285,9 @@ the length of the list, under foreseeable uses of \.{CWEAVE} this inefficiency is insignificant. @c -void -new_section_xref(p) -name_pointer p; +static void +new_section_xref( +name_pointer p) { xref_pointer q,r; /* pointers to previous cross-references */ q=(xref_pointer)p->xref; r=xmem; @@ -316,7 +297,7 @@ name_pointer p; return; /* don't duplicate entries */ append_xref(section_count+section_xref_switch); xref_ptr->xlink=q; section_xref_switch=0; - if (r==xmem) p->xref=(char*)xref_ptr; + if (r==xmem) update_node(p); else r->xlink=xref_ptr; } @@ -324,23 +305,23 @@ name_pointer p; |file_flag|. Here's how that flag gets put~in. @c -void -set_file_flag(p) -name_pointer p; +static void +set_file_flag( +name_pointer p) { xref_pointer q; q=(xref_pointer)p->xref; if (q->num==file_flag) return; append_xref(file_flag); xref_ptr->xlink = q; - p->xref = (char *)xref_ptr; + update_node(p); } @ A third large area of memory is used for sixteen-bit `tokens', which appear in short lists similar to the strings of characters in |byte_mem|. Token lists are used to contain the result of \CEE/ code translated into \TEX/ form; -further details about them will be explained later. A |text_pointer| variable -is an index into |tok_start|. +further details about them will be explained later. A \&{text\_pointer} +variable is an index into |tok_start|. @= typedef sixteen_bits token; @@ -352,49 +333,58 @@ 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_start[max_texts]; /* directory into |tok_mem| */ -token_pointer tok_ptr; /* first unused position in |tok_mem| */ -text_pointer text_ptr; /* first unused position in |tok_start| */ -text_pointer tok_start_end = tok_start+max_texts-1; /* end of |tok_start| */ -token_pointer max_tok_ptr; /* largest value of |tok_ptr| */ -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=tok_mem+1; text_ptr=tok_start+1; tok_start[0]=tok_mem+1; -tok_start[1]=tok_mem+1; -max_tok_ptr=tok_mem+1; max_text_ptr=tok_start+1; +tok_ptr=max_tok_ptr=tok_mem+1;@/ +tok_start[0]=tok_start[1]=tok_mem+1;@/ +text_ptr=max_text_ptr=tok_start+1; @ Here are the three procedures needed to complete |id_lookup|: @c -int names_match(p,first,l,t) -name_pointer p; /* points to the proposed match */ -char *first; /* position of first character of string */ -int l; /* length of identifier */ -eight_bits t; /* desired ilk */ +boolean names_match(@t\1\1@> +name_pointer p, /* points to the proposed match */ +const char *first, /* position of first character of string */ +size_t l, /* length of identifier */ +eight_bits t@t\2\2@>) /* desired |ilk| */ { - if (length(p)!=l) return 0; - if (p->ilk!=t && !(t==normal && abnormal(p))) return 0; + if (length(p)!=l) return false; + if (p->ilk!=t && !(t==normal && abnormal(p))) return false; return !strncmp(first,p->byte_start,l); } void -init_p(p,t) -name_pointer p; -eight_bits t; +init_p( +name_pointer p, +eight_bits t) { - p->ilk=t; p->xref=(char*)xmem; + p->ilk=t; init_node(p); } void -init_node(p) -name_pointer p; +init_node( +name_pointer p) { - p->xref=(char*)xmem; + p->xref=(void *)xmem; } +static void +update_node( +name_pointer p) +{ + p->xref=(void *)xref_ptr; +} + +@ @=@+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 to insert them every time \.{CWEAVE} is run. Fortunately there are relatively @@ -499,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); @@ -556,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;} @@ -598,19 +587,20 @@ operation appears in limbo, we want to use it to adjust the default interpretation of identifiers. @= -void skip_limbo(); +static void skip_limbo(void);@/ +static eight_bits skip_TeX(void); @ @c -void -skip_limbo() { - while(1) { - if (loc>limit && get_line()==0) return; +static void +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(); - else if (c==format_code) @; + else if (c==format_code) @@; } } } @@ -623,15 +613,15 @@ assumed to exist at the very end of the file. @f skip_TeX TeX @c -unsigned -skip_TeX() /* skip past pure \TEX/ code */ +static eight_bits +skip_TeX(void) /* skip past pure \TEX/ code */ { - while (1) { - if (loc>limit && get_line()==0) return(new_section); + while (true) { + if (loc>limit && get_line()==false) return new_section; *(limit+1)='@@'; while (*loc!='@@' && *loc!='|') loc++; - if (*loc++ =='|') return('|'); - if (loc<=limit) return(ccode[(eight_bits)*(loc++)]); + if (*loc++ =='|') return '|'; + if (loc<=limit) return ccode[(eight_bits)*(loc++)]; } } @@ -675,13 +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 */ - -@ @= -#include /* definition of |isalpha|, |isdigit| and so on */ -#include /* definition of |exit| */ +@= +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. @@ -693,31 +679,33 @@ compilers even allow the dollar sign. @d ishigh(c) ((eight_bits)(c)>0177) @^high-bit character handling@> -@= -eight_bits get_next(); - -@ @c -eight_bits -get_next() /* produces the next input token */ -{@+eight_bits c; /* the current character */ - while (1) { - @; - if (loc>limit && get_line()==0) return(new_section); +@c +static eight_bits +get_next(void) /* produces the next input token */ +{ + eight_bits c; /* the current character */ + while (true) { + @@; + if (loc>limit && get_line()==false) return new_section; c=*(loc++); if (xisdigit(c) || c=='.') @@; - else if (c=='\'' || c=='"' || (c=='L'&&(*loc=='\'' || *loc=='"'))@| - || (c=='<' && sharp_include_line==1)) + else if (c=='\'' || c=='"'@| + || ((c=='L' || c=='u' || c=='U')&&(*loc=='\'' || *loc=='"'))@| + || ((c=='u' && *loc=='8')&&(*(loc+1)=='\'' || *(loc+1)=='"'))@| + || (c=='<' && sharp_include_line==true)) @@; else if (xisalpha(c) || isxalpha(c) || ishigh(c)) @@; else if (c=='@@') @@; else if (xisspace(c)) continue; /* ignore spaces and tabs */ - if (c=='#' && loc==buffer+1) @; + if (c=='#' && loc==buffer+1) @@; mistake: @@; - return(c); + return c; } } +@ @=@+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 @@ -731,25 +719,25 @@ 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=0; /* are we scanning a preprocessor command? */ +@= +static boolean preprocessing=false; /* are we scanning a preprocessor command? */ @ @= { - preprocessing=1; - @; - return (left_preproc); + preprocessing=true; + @@; + return left_preproc; } @ An additional complication is the freakish use of \.< and \.> to delimit a file name in lines that start with \.{\#include}. We must treat this file name as a string. -@= -boolean sharp_include_line=0; /* 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++; -if (loc<=buffer_end-6 && strncmp(loc,"include",7)==0) sharp_include_line=1; +if (loc<=buffer_end-6 && strncmp(loc,"include",7)==0) sharp_include_line=true; @ When we get to the end of a preprocessor line, we lower the flag and send a code |right_preproc|, unless @@ -757,10 +745,10 @@ the last character was a \.\\. @= while (loc==limit-1 && preprocessing && *loc=='\\') - if (get_line()==0) return(new_section); /* still in preprocessor mode */ + if (get_line()==false) return new_section; /* still in preprocessor mode */ if (loc>=limit && preprocessing) { - preprocessing=sharp_include_line=0; - return(right_preproc); + preprocessing=sharp_include_line=false; + return right_preproc; } @ The following code assigns values to the combinations \.{++}, @@ -770,7 +758,7 @@ combinations \.{...}, \.{::}, \.{.*} and \.{->*}. The compound assignment operators (e.g., \.{+=}) are treated as separate tokens. -@d compress(c) if (loc++<=limit) return(c) +@d compress(c) if (loc++<=limit) return c @= switch(c) { @@ -778,8 +766,8 @@ switch(c) { else if (*loc=='/') compress(begin_short_comment); break; case '+': if (*loc=='+') compress(plus_plus); break; case '-': if (*loc=='-') {compress(minus_minus);} - else if (*loc=='>') if (*(loc+1)=='*') {loc++; compress(minus_gt_ast);} - else compress(minus_gt); break; + else { if (*loc=='>') { if (*(loc+1)=='*') {loc++; compress(minus_gt_ast);} + else compress(minus_gt); } } break; case '.': if (*loc=='*') {compress(period_ast);} else if (*loc=='.' && *(loc+1)=='.') { loc++; compress(dot_dot_dot); @@ -793,13 +781,14 @@ switch(c) { else if (*loc=='<') compress(lt_lt); break; case '&': if (*loc=='&') compress(and_and); break; case '|': if (*loc=='|') compress(or_or); break; - case '!': if (*loc=='=') compress(not_eq); break; + case '!': if (*loc=='=') compress(non_eq); break; } @ @= { id_first=--loc; - while (isalpha(*++loc) || isdigit(*loc) || isxalpha(*loc) || ishigh(*loc)); - id_loc=loc; return(identifier); + while (isalpha((eight_bits)*++loc) || isdigit((eight_bits)*loc) @| + || isxalpha((eight_bits)*loc) || ishigh((eight_bits)*loc)); + id_loc=loc; return identifier; } @ Different conventions are followed by \TEX/ and \CEE/ to express octal @@ -833,9 +822,9 @@ are pointers into the array |section_text|, not into |buffer|. } while (*loc=='u' || *loc=='U' || *loc=='l' || *loc=='L' || *loc=='f' || *loc=='F') { - *id_loc++='$'; *id_loc++=toupper(*loc); loc++; + *id_loc++='$'; *id_loc++=toupper((eight_bits)*loc); loc++; } - return(constant); + return constant; } @ \CEE/ strings and character constants, delimited by double and single @@ -849,17 +838,18 @@ convention, but do not allow the string to be longer than |longest_name|. id_loc = section_text; if (delim=='\'' && *(loc-2)=='@@') {*++id_loc='@@'; *++id_loc='@@';} *++id_loc=delim; - if (delim=='L') { /* wide character constant */ + if (delim=='L' || delim=='u' || delim=='U') { /* wide character constant */ + if (delim=='u' && *loc=='8') { *++id_loc=*loc++; } delim=*loc++; *++id_loc=delim; } - if (delim=='<') delim='>'; /* for file names in |#include| lines */ - while (1) { + if (delim=='<') delim='>'; /* for file names in \&{\#include} lines */ + while (true) { if (loc>=limit) { if(*(limit-1)!='\\') { err_print("! String didn't end"); loc=limit; break; @.String didn't end@> } - if(get_line()==0) { + if(get_line()==false) { err_print("! Input ended in middle of string"); loc=buffer; break; @.Input ended in middle of string@> } @@ -868,20 +858,20 @@ convention, but do not allow the string to be longer than |longest_name|. if (++id_loc<=section_text_end) *id_loc=c; break; } - if (c=='\\') if (loc>=limit) continue; - else if (++id_loc<=section_text_end) { + if (c=='\\') { if (loc>=limit) continue; + else { if (++id_loc<=section_text_end) { *id_loc = '\\'; c=*loc++; - } + } } } if (++id_loc<=section_text_end) *id_loc=c; } if (id_loc>=section_text_end) { - printf("\n! String too long: "); + fputs("\n! String too long: ",stdout); @.String too long@> term_write(section_text+1,25); printf("..."); mark_error; } id_loc++; - return(string); + return string; } @ After an \.{@@} sign has been scanned, the next character tells us @@ -894,13 +884,13 @@ whether there is more work to do. @.Use @@l in limbo...@> case underline: xref_switch=def_flag; continue; case trace: tracing=c-'0'; continue; - case xref_roman: case xref_wildcard: case xref_typewriter: - case noop: case TeX_string: c=ccode[c]; skip_restricted(); return(c); + case xref_roman: case xref_wildcard: case xref_typewriter: case noop: + case TeX_string: c=ccode[(eight_bits)c]; skip_restricted(); return c; case section_name: - @; - case verbatim: @; - case ord: @; - default: return(ccode[(eight_bits)c]); + @@; + case verbatim: @@; + case ord: @@; + default: return ccode[(eight_bits)c]; } } @@ -910,11 +900,11 @@ because the section name might (for example) follow \&{int}. @= { char *k; /* pointer into |section_text| */ cur_section_char=*(loc-1); - @; + @@; if (k-section_text>3 && strncmp(k-2,"...",3)==0) cur_section=section_lookup(section_text+1,k-3,1); /* 1 indicates a prefix */ else cur_section=section_lookup(section_text+1,k,0); - xref_switch=0; return(section_name); + xref_switch=0; return section_name; } @ Section names are placed into the |section_text| array with consecutive spaces, @@ -927,14 +917,14 @@ character of the name.) @ @= k=section_text; -while (1) { - if (loc>limit && get_line()==0) { +while (true) { + if (loc>limit && get_line()==false) { err_print("! Input ended in section name"); @.Input ended in section name@> loc=buffer+1; break; } c=*loc; - @; + @@; loc++; if (k=section_text_end) { - printf("\n! Section name too long: "); + fputs("\n! Section name too long: ",stdout); @.Section name too long@> term_write(section_text+1,25); printf("..."); mark_harmless; @@ -968,12 +958,9 @@ if (c=='@@') { @ This function skips over a restricted context at relatively high speed. -@= -void skip_restricted(); - -@ @c -void -skip_restricted() +@c +static void +skip_restricted(void) { id_first=loc; *(limit+1)='@@'; false_alarm: @@ -991,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 @@ -1002,7 +991,7 @@ buffer. We also set |loc| to the position just after the ending delimiter. if (loc>=limit) err_print("! Verbatim string didn't end"); @.Verbatim string didn't end@> id_loc=loc; loc+=2; - return (verbatim); + return verbatim; } @** Phase one processing. @@ -1015,41 +1004,40 @@ 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. -@= -void phase_one(); - -@ @c -void -phase_one() { +@c +static void +phase_one(void) { phase=1; reset_input(); section_count=0; - skip_limbo(); change_exists=0; + skip_limbo(); change_exists=false; while (!input_has_ended) - @; + @@; changed_section[section_count]=change_exists; /* the index changes if anything does */ phase=2; /* prepare for second phase */ - @; + @@; } +@ @=@+static void phase_one(void); + @ @= { if (++section_count==max_sections) overflow("section number"); changed_section[section_count]=changing; - /* it will become 1 if any line changes */ + /* it will become |true| if any line changes */ if (*(loc-1)=='*' && show_progress) { printf("*%d",section_count); update_terminal; /* print a progress report */ } - @; - @; - @; - if (changed_section[section_count]) change_exists=1; + @@; + @@; + @@; + if (changed_section[section_count]) change_exists=true; } @ The |C_xref| subroutine stores references to identifiers in @@ -1074,12 +1062,13 @@ the relations |xref_roman==identifier+roman| and |xref_wildcard==identifier as well as |normal==0|. @= -void C_xref(); +static void C_xref(eight_bits);@/ +static void outer_xref(void); @ @c -void -C_xref( spec_ctrl ) /* makes cross-references for \CEE/ identifiers */ - eight_bits spec_ctrl; +static void +C_xref(@t\1\1@> /* makes cross-references for \CEE/ identifiers */ + eight_bits spec_ctrl@t\2\2@>) { name_pointer p; /* a referenced name */ while (next_control=format_code|. Thus, it handles \CEE/ text with embedded comments. -@= -void outer_xref(); - -@ @c -void -outer_xref() /* extension of |C_xref| */ +@c +static void +outer_xref(void) /* extension of |C_xref| */ { int bal; /* brace level in comment */ while (next_control} or \.{@@.}$\,\ldots\,$\.{@@>} or \.{@@:}$\,\ldots\,$\.{@@>}. @= -while (1) { +while (true) { switch (next_control=skip_TeX()) { case translit_code: err_print("! Use @@l in limbo only"); continue; @.Use @@l in limbo...@> @@ -1171,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|. @@ -1182,7 +1168,7 @@ while (next_control<=definition) { /* |format_code| or |definition| */ if (next_control==definition) { xref_switch=def_flag; /* implied \.{@@!} */ next_control=get_next(); - } else @; + } else @@; outer_xref(); } @@ -1205,7 +1191,7 @@ discover should be unindexed. for (q=(xref_pointer)lhs->xref;q>xmem;q=q->xlink) if (q->numxlink=q->xlink; - else lhs->xref=(char*)q->xlink; + else lhs->xref=(void *)q->xlink; else r=q; } next_control=get_next(); @@ -1255,41 +1241,42 @@ 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@> -@= -void section_check(); - -@ @c -void -section_check(p) -name_pointer p; /* print anomalies in subtree |p| */ +@c +static void +section_check( +name_pointer p) /* print anomalies in subtree |p| */ { if (p) { section_check(p->llink); cur_xref=(xref_pointer)p->xref; - if (cur_xref->num==file_flag) {an_output=1; cur_xref=cur_xref->xlink;} - else an_output=0; + if (cur_xref->num==file_flag) {an_output=true; cur_xref=cur_xref->xlink;} + else an_output=false; if (cur_xref->num '); mark_harmless; + fputs("\n! Never defined: <",stdout); + print_section_name(p); putchar('>'); mark_harmless; @.Never defined:
@> } while (cur_xref->num >=cite_flag) cur_xref=cur_xref->xlink; if (cur_xref==xmem && !an_output) { - printf("\n! Never used: <"); print_section_name(p); putchar('>'); mark_harmless; + fputs("\n! Never used: <",stdout); + print_section_name(p); putchar('>'); mark_harmless; @.Never used:
@> } section_check(p->rlink); } } -@ @=section_check(root) +@ @=@+static void section_check(name_pointer); + +@ @=section_check(root); @* Low-level output routines. The \TEX/ output is supposed to appear in lines at most |line_length| @@ -1297,17 +1284,17 @@ 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_ptr; /* last character in |out_buf| */ -char *out_buf_end = out_buf+line_length; /* end of |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. -If the |per_cent| parameter is 1 a |'%'| is appended to the line +If the |per_cent| parameter is |true|, a |'%'| is appended to the line that is being output; in this case the breakpoint |b| should be strictly -less than |out_buf_end|. If the |per_cent| parameter is |0|, +less than |out_buf_end|. If the |per_cent| parameter is |false|, trailing blanks are suppressed. The characters emptied from the buffer form a new line of output; if the |carryover| parameter is true, a |"%"| in that line will be @@ -1317,13 +1304,18 @@ of commented-out text). @d c_line_write(c) fflush(active_file),fwrite(out_buf+1,sizeof(char),c,active_file) @d tex_putc(c) putc(c,active_file) @d tex_new_line putc('\n',active_file) -@d tex_printf(c) fprintf(active_file,c) +@d tex_printf(c) fprintf(active_file,"%s",c) +@d tex_puts(c) fputs(c,active_file) -@c -void -flush_buffer(b,per_cent,carryover) -char *b; /* outputs from |out_buf+1| to |b|,where |b<=out_ptr| */ -boolean per_cent,carryover; +@= +static void flush_buffer(char *,boolean,boolean);@/ +static void finish_line(void); + +@ @c +static void +flush_buffer(@t\1\1@> +char *b, /* outputs from |out_buf+1| to |b|, where |b<=out_ptr| */ +boolean per_cent,boolean carryover@t\2\2@>) { char *j; j=b; /* pointer into |out_buf| */ if (! per_cent) /* remove trailing blanks */ @@ -1336,7 +1328,7 @@ boolean per_cent,carryover; if (*j--=='%' && (j==out_buf || *j!='\\')) { *b--='%'; break; } - if (bout_buf) flush_buffer(out_ptr,0,0); + if (out_ptr>out_buf) flush_buffer(out_ptr,false,false); else { for (k=buffer; k<=limit; k++) if (!(xisspace(*k))) return; - flush_buffer(out_buf,0,0); + flush_buffer(out_buf,false,false); } } @@ -1366,7 +1358,7 @@ beginning of phase two. We initialize the output variables in a slightly tricky way so that the first line of the output file will be `\.{\\input cwebmac}'. -@= +@= out_ptr=out_buf+1; out_line=1; active_file=tex_file; *out_ptr='c'; tex_printf("\\input cwebma"); @@ -1380,10 +1372,14 @@ A line break will occur at a space or after a single-nonletter @d out(c) {if (out_ptr>=out_buf_end) break_out(); *(++out_ptr)=c;} -@c -void -out_str(s) /* output characters from |s| to end of string */ -char *s; +@= +static void out_str(const char *);@/ +static void break_out(void); + +@ @c +static void +out_str(@t\1\1@> /* output characters from |s| to end of string */ +const char*s@t\2\2@>) { while (*s) out(*s++); } @@ -1399,21 +1395,18 @@ out_buf[0]='\\'; preceded by another backslash. In the latter case, a |'%'| is output at the break. -@= -void break_out(); - -@ @c -void -break_out() /* finds a way to break the output line */ +@c +static void +break_out(void) /* finds a way to break the output line */ { char *k=out_ptr; /* pointer into |out_buf| */ - while (1) { - if (k==out_buf) @; + while (true) { + if (k==out_buf) @@; if (*k==' ') { - flush_buffer(k,0,1); return; + flush_buffer(k,false,true); return; } if (*(k--)=='\\' && *k!='\\') { /* we've decreased |k| */ - flush_buffer(k,1,1); return; + flush_buffer(k,true,true); return; } } } @@ -1429,7 +1422,7 @@ line by putting a |'%'| just before the last character. @.Line had to be broken@> term_write(out_buf+1, out_ptr-out_buf-1); new_line; mark_harmless; - flush_buffer(out_ptr-1,1,1); return; + flush_buffer(out_ptr-1,true,true); return; } @ Here is a macro that outputs a section number in decimal notation. @@ -1437,10 +1430,14 @@ The number to be converted by |out_section| is known to be less than |def_flag|, so it cannot have more than five decimal digits. If the section is changed, we output `\.{\\*}' just after the number. -@c -void -out_section(n) -sixteen_bits n; +@= +static void out_section(sixteen_bits);@/ +static void out_name(name_pointer,boolean); + +@ @c +static void +out_section( +sixteen_bits n) { char s[6]; sprintf(s,"%d",n); out_str(s); @@ -1452,10 +1449,10 @@ sixteen_bits n; entry, enclosing it in braces. @c -void -out_name(p,quote_xalpha) -name_pointer p; -boolean quote_xalpha; +static void +out_name( +name_pointer p, +boolean quote_xalpha) { char *k, *k_end=(p+1)->byte_start; /* pointers into |byte_mem| */ out('{'); @@ -1469,11 +1466,9 @@ boolean quote_xalpha; } @* Routines that copy \TEX/ material. -During phase two, we use subroutines |copy_limbo|, |copy_TeX|, and -|copy_comment| in place of the analogous |skip_limbo|, |skip_TeX|, and -|skip_comment| that were used in phase one. (Well, |copy_comment| -was actually written in such a way that it functions as |skip_comment| -in phase one.) +During phase two, we use the subroutines |copy_limbo| and |copy_TeX| (and +|copy_comment|) in place of the analogous |skip_limbo| and |skip_TeX| +that were used in phase one. The |copy_limbo| routine, for example, takes \TEX/ material that is not part of any section and transcribes it almost verbatim to the output file. @@ -1481,13 +1476,18 @@ The use of `\.{@@}' signs is severely restricted in such material: `\.{@@@@}' pairs are replaced by singletons; `\.{@@l}' and `\.{@@q}' and `\.{@@s}' are interpreted. -@c -void -copy_limbo() +@= +static void copy_limbo(void);@/ +static eight_bits copy_TeX(void);@/ +static int copy_comment(boolean,int); + +@ @c +static void +copy_limbo(void) { char c; - while (1) { - if (loc>limit && (finish_line(), get_line()==0)) return; + while (true) { + if (loc>limit && (finish_line(), get_line()==false)) return; *(limit+1)='@@'; while (*loc!='@@') out(*(loc++)); if (loc++<=limit) { @@ -1515,21 +1515,21 @@ way. It returns the next control code or `\.{\v}' found in the input. We don't copy spaces or tab marks into the beginning of a line. This makes the test for empty lines in |finish_line| work. -@ @f copy_TeX TeX +@f copy_TeX TeX @c -eight_bits -copy_TeX() +static eight_bits +copy_TeX(void) { char c; /* current character being copied */ - while (1) { - if (loc>limit && (finish_line(), get_line()==0)) return(new_section); + while (true) { + if (loc>limit && (finish_line(), get_line()==false)) return new_section; *(limit+1)='@@'; while ((c=*(loc++))!='|' && c!='@@') { out(c); if (out_ptr==out_buf+1 && (xisspace(c))) out_ptr--; } - if (c=='|') return('|'); - if (loc<=limit) return(ccode[(eight_bits)*(loc++)]); + if (c=='|') return '|'; + if (loc<=limit) return ccode[(eight_bits)*(loc++)]; } } @@ -1545,19 +1545,16 @@ one further token without overflow. @d app_tok(c) {if (tok_ptr+2>tok_mem_end) overflow("token"); *(tok_ptr++)=c;} -@= -int copy_comment(); - -@ @c -int copy_comment(is_long_comment,bal) /* copies \TEX/ code in comments */ -boolean is_long_comment; /* is this a traditional \CEE/ comment? */ -int bal; /* brace balance */ +@c +static int copy_comment(@t\1\1@> /* copies \TeX\ code in comments */ +boolean is_long_comment, /* is this a traditional \CEE/ comment? */ +int bal@t\2\2@>) /* brace balance */ { char c; /* current character being copied */ - while (1) { + while (true) { if (loc>limit) { if (is_long_comment) { - if (get_line()==0) { + if (get_line()==false) { err_print("! Input ended in mid-comment"); @.Input ended in mid-comment@> loc=buffer+1; goto done; @@ -1570,13 +1567,13 @@ int bal; /* brace balance */ } } c=*(loc++); - if (c=='|') return(bal); - if (is_long_comment) @; + if (c=='|') return bal; + if (is_long_comment) @@; if (phase==2) { if (ishigh(c)) app_tok(quoted_char); app_tok(c); } - @; + @@; if (c=='{') bal++; else if (c=='}') { if(bal>1) bal--; @@ -1586,7 +1583,7 @@ int bal; /* brace balance */ } } } -done:@; +done:@@; } @ @= @@ -1605,15 +1602,15 @@ if (c=='@@') { loc-=2; if (phase==2) *(tok_ptr-1)=' '; goto done; } } -else if (c=='\\' && *loc!='@@') - if (phase==2) app_tok(*(loc++))@; else loc++; +else { if (c=='\\' && *loc!='@@') { + if (phase==2) app_tok(*(loc++))@; else loc++; } } @ We output enough right braces to keep \TEX/ happy. @= if (phase==2) while (bal-- >0) app_tok('}'); -return(0); +return 0; @** Parsing. The most intricate part of \.{CWEAVE} is its mechanism for converting @@ -1660,9 +1657,12 @@ In the \TEX/ file, this will specify an optional line break after the comma, with penalty 90. At each opportunity the longest possible production is applied. For -example, if the current sequence of scraps is |int_like| |cast| -|lbrace|, rule 31 is applied; but if the sequence is |int_like| |cast| -followed by anything other than |lbrace|, rule 32 takes effect. +example, if the current sequence of scraps is |if_clause| |stmt| +|else_like| |if_like|, rule 63 is applied; but if the sequence is +|if_clause| |stmt| |else_like| followed by anything other than +|if_like|, rule 64 takes effect; and if the sequence is |if_clause| +|stmt| followed by anything other than |else_like|, rule 65 takes +effect. Translation rules such as `$E_1C\,\\{opt}9\,E_2$' above use subscripts to distinguish between translations of scraps whose categories have the @@ -1711,13 +1711,11 @@ same initial letter; these subscripts are assigned from left to right. @d begin_arg 61 /* \.{@@[} */ @d end_arg 62 /* \.{@@]} */ -@= -char cat_name[256][12]; -eight_bits cat_index; +@= +static char cat_name[256][12]; @ @= - for (cat_index=0;cat_index<255;cat_index++) - strcpy(cat_name[cat_index],"UNKNOWN"); +{int c; for (c=0;c<256;c++) strcpy(cat_name[c],"UNKNOWN");} @.UNKNOWN@> strcpy(cat_name[exp],"exp"); strcpy(cat_name[unop],"unop"); @@ -1781,13 +1779,15 @@ eight_bits cat_index; @ This code allows \.{CWEAVE} to display its parsing steps. @c -void -print_cat(c) /* symbolic printout of a category */ -eight_bits c; +static void +print_cat(@t\1\1@> /* symbolic printout of a category */ +eight_bits c@t\2\2@>) { - printf(cat_name[c]); + 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. @@ -2098,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 pp; /* current position for reducing productions */ -scrap_pointer scrap_base; /* beginning of the current scrap sequence */ -scrap_pointer scrap_ptr; /* ending of the current scrap sequence */ -scrap_pointer lo_ptr; /* last scrap that has been examined */ -scrap_pointer hi_ptr; /* first scrap that has not been examined */ -scrap_pointer max_scr_ptr; /* largest value assumed by |scrap_ptr| */ +@= +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; @@ -2136,9 +2136,9 @@ translated without line-break controls. @d inner_tok_flag 5*id_flag /* signifies a token list in `\pb' */ @c -void -print_text(p) /* prints a token list for debugging; not used in |main| */ -text_pointer p; +static void +print_text(@t\1\1@> /* prints a token list for debugging; not used in |main| */ +text_pointer p@t\2\2@>) { token_pointer j; /* index into |tok_mem| */ sixteen_bits r; /* remainder of token after the flag has been stripped off */ @@ -2154,12 +2154,14 @@ text_pointer p; break; /* |section_flag| */ case 4: printf("[[%d]]",r); break; /* |tok_flag| */ case 5: printf("|[[%d]]|",r); break; /* |inner_tok_flag| */ - default: @; + default: @@; } } - fflush(stdout); + update_terminal; } +@ @=@+static void print_text(text_pointer p); + @ @= switch (r) { case math_rel: printf("\\mathrel{"@q}@>); break; @@ -2173,7 +2175,7 @@ switch (r) { case force: printf("[force]"); break; case big_force: printf("[fforce]"); break; case preproc_line: printf("[preproc]"); break; - case quoted_char: j++; printf("[%o]",(unsigned)*j); break; + case quoted_char: j++; printf("[%o]",(unsigned int)*j); break; case end_translation: printf("[quit]"); break; case inserted: printf("[inserted]"); break; default: putxchar(r); @@ -2219,7 +2221,7 @@ example, `|squash(pp,3,exp,-2,3)|' is an abbreviation for `\\{app3}|(pp); reduce(pp,3,exp,-2,3)|'. A couple more words of explanation: -Both |big_app| and |app| append a token (while |big_app1| to |big_app4| +Both |big_app| and |app| append a token (while |big_app1| to |big_app3| append the specified number of scrap translations) to the current token list. The difference between |big_app| and |app| is simply that |big_app| checks whether there can be a conflict between math and non-math @@ -2253,24 +2255,28 @@ productions as they were listed earlier. @d maybe_math 0 /* works in either horizontal or math mode */ @d big_app2(a) big_app1(a);big_app1(a+1) @d big_app3(a) big_app2(a);big_app1(a+2) -@d big_app4(a) big_app3(a);big_app1(a+3) -@d app(a) *(tok_ptr++)=a -@d app1(a) *(tok_ptr++)=tok_flag+(int)((a)->trans-tok_start) +@d app(a) *(tok_ptr++)=(token)(a) +@d app1(a) *(tok_ptr++)=(token)(tok_flag+(int)((a)->trans-tok_start)) + +@= +static int cur_mathness, init_mathness; -@= -int cur_mathness, init_mathness; +@ @= +static void app_str(const char *);@/ +static void big_app(token);@/ +static void big_app1(scrap_pointer); @ @c -void -app_str(s) -char *s; +static void +app_str( +const char *s) { while (*s) app_tok(*(s++)); } -void -big_app(a) -token a; +static void +big_app( +token a) { if (a==' ' || (a>=big_cancel && a<=big_force)) /* non-math token */ { if (cur_mathness==maybe_math) init_mathness=no_math; @@ -2285,9 +2291,9 @@ token a; app(a); } -void -big_app1(a) -scrap_pointer a; +static void +big_app1( +scrap_pointer a) { switch (a->mathness % 4) { /* left boundary */ case (no_math): @@ -2316,11 +2322,11 @@ code needs to be provided with a proper environment. @d lhs_not_simple (pp->cat!=public_like && pp->cat!=semi && pp->cat!=prelangle - && pp->cat!=prerangle + && pp->cat!=prerangle @| && pp->cat!=template_like && pp->cat!=new_like && pp->cat!=new_exp - && pp->cat!=ftemplate + && pp->cat!=ftemplate @| && pp->cat!=raw_ubin && pp->cat!=const_like && pp->cat!=raw_int @@ -2336,53 +2342,53 @@ code needs to be provided with a proper environment. else if (cat3==insert) squash(pp+2,2,(pp+2)->cat,0,0); else switch (pp->cat) { - case exp: @; @+break; - case lpar: @; @+break; - case unop: @; @+break; - case ubinop: @; @+break; - case binop: @; @+break; - case cast: @; @+break; - case sizeof_like: @; @+break; - case int_like: @; @+break; - case public_like: @; @+break; - case colcol: @; @+break; - case decl_head: @; @+break; - case decl: @; @+break; - case base: @; @+break; - case struct_like: @; @+break; - case struct_head: @; @+break; - case fn_decl: @; @+break; - case function: @; @+break; - case lbrace: @; @+break; - case if_like: @; @+break; - case else_like: @; @+break; - case else_head: @; @+break; - case if_clause: @; @+break; - case if_head: @; @+break; - case do_like: @; @+break; - case case_like: @; @+break; - case catch_like: @; @+break; - case tag: @; @+break; - case stmt: @; @+break; - case semi: @; @+break; - case lproc: @; @+break; - case section_scrap: @; @+break; - case insert: @; @+break; - case prelangle: @; @+break; - case prerangle: @; @+break; - case langle: @; @+break; - case template_like: @; @+break; - case new_like: @; @+break; - case new_exp: @; @+break; - case ftemplate: @; @+break; - case for_like: @; @+break; - case raw_ubin: @; @+break; - case const_like: @; @+break; - case raw_int: @; @+break; - case operator_like: @; @+break; - case typedef_like: @; @+break; - case delete_like: @; @+break; - case question: @; @+break; + case exp: @@; @+break; + case lpar: @@; @+break; + case unop: @@; @+break; + case ubinop: @@; @+break; + case binop: @@; @+break; + case cast: @@; @+break; + case sizeof_like: @@; @+break; + case int_like: @@; @+break; + case public_like: @@; @+break; + case colcol: @@; @+break; + case decl_head: @@; @+break; + case decl: @@; @+break; + case base: @@; @+break; + case struct_like: @@; @+break; + case struct_head: @@; @+break; + case fn_decl: @@; @+break; + case function: @@; @+break; + case lbrace: @@; @+break; + case if_like: @@; @+break; + case else_like: @@; @+break; + case else_head: @@; @+break; + case if_clause: @@; @+break; + case if_head: @@; @+break; + case do_like: @@; @+break; + case case_like: @@; @+break; + case catch_like: @@; @+break; + case tag: @@; @+break; + case stmt: @@; @+break; + case semi: @@; @+break; + case lproc: @@; @+break; + case section_scrap: @@; @+break; + case insert: @@; @+break; + case prelangle: @@; @+break; + case prerangle: @@; @+break; + case langle: @@; @+break; + case template_like: @@; @+break; + case new_like: @@; @+break; + case new_exp: @@; @+break; + case ftemplate: @@; @+break; + case for_like: @@; @+break; + case raw_ubin: @@; @+break; + case const_like: @@; @+break; + case raw_int: @@; @+break; + case operator_like: @@; @+break; + case typedef_like: @@; @+break; + case delete_like: @@; @+break; + case question: @@; @+break; } pp++; /* if no match was found, we move to the right */ } @@ -2404,17 +2410,23 @@ of identifiers in case labels. If the first identifier is the keyword `\&{operator}', we give up; users who want to index definitions of overloaded \CPLUSPLUS/ operators should say, for example, `\.{@@!@@\^\\\&\{operator\} \$+\{=\}\$@@>}' (or, -more properly alphebetized, +more properly alpha\-betized, `\.{@@!@@:operator+=\}\{\\\&\{operator\} \$+\{=\}\$@@>}'). @d no_ident_found (token_pointer)0 /* distinct from any identifier token */ @d case_found (token_pointer)1 /* likewise */ @d operator_found (token_pointer)2 /* likewise */ -@c -token_pointer -find_first_ident(p) -text_pointer p; +@= +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); + +@ @c +static token_pointer +find_first_ident( +text_pointer p) { token_pointer q; /* token to be returned */ token_pointer j; /* token being looked at */ @@ -2444,11 +2456,11 @@ occurrence of the identifier that we're making reserved; hence the |for| loop below. @c -void -make_reserved(p) /* make the first identifier in |p->trans| like |int| */ -scrap_pointer p; +static void +make_reserved(@t\1\1@> /* make the first identifier in |p->trans| like |int| */ +scrap_pointer p@t\2\2@>) { - sixteen_bits tok_value; /* the name of this identifier, plus its flag*/ + sixteen_bits tok_value; /* the name of this identifier, plus its flag */ token_pointer tok_loc; /* pointer to |tok_value| */ if ((tok_loc=find_first_ident(p->trans))<=operator_found) return; /* this should not happen */ @@ -2475,10 +2487,10 @@ of a function, we find out that the identifier is being defined only after it has been swallowed up by an |exp|. @c -void -make_underlined(p) +static void +make_underlined(@t\1\1@> /* underline the entry for the first identifier in |p->trans| */ -scrap_pointer p; +scrap_pointer p@t\2\2@>) { token_pointer tok_loc; /* where the first identifier appears */ if ((tok_loc=find_first_ident(p->trans))<=operator_found) @@ -2492,13 +2504,10 @@ because this would just make a new cross-reference at the end of the list. We actually have to search through the list for the existing cross-reference. -@= -void underline_xref(); - -@ @c -void -underline_xref(p) -name_pointer p; +@c +static void +underline_xref( +name_pointer p) { xref_pointer q=(xref_pointer)p->xref; /* pointer to cross-reference being examined */ xref_pointer r; /* temporary pointer for permuting cross-references */ @@ -2515,7 +2524,7 @@ name_pointer p; else if (n>=def_flag && nxlink; } - @; + @@; } @ We get to this section only when the identifier is one letter long, @@ -2528,7 +2537,7 @@ to insert the new cross-reference not at the beginning of the list @= append_xref(0); /* this number doesn't matter */ xref_ptr->xlink=(xref_pointer)p->xref; r=xref_ptr; - p->xref=(char*)xref_ptr; + update_node(p); while (r->xlink!=q) {r->num=r->xlink->num; r=r->xlink;} r->num=m; /* everything from |q| on is left undisturbed */ @@ -2818,7 +2827,11 @@ else if (cat1==stmt||cat1==decl||cat1==function) { grouped together on the same line. @d force_lines flags['f'] /* should each statement be on its own line? */ -@= + +@= +force_lines=true; + +@ @= if (cat1==stmt||cat1==decl||cat1==function) { big_app1(pp); if (cat1==function) big_app(big_force); @@ -3000,12 +3013,16 @@ too large, since it is assumed that this test was done beforehand. @d freeze_text *(++text_ptr)=tok_ptr -@c -void -reduce(j,k,c,d,n) -scrap_pointer j; -eight_bits c; -short k, d, n; +@= +static void reduce(scrap_pointer,short,eight_bits,short,short);@/ +static void squash(scrap_pointer,short,eight_bits,short,short); + +@ @c +static void +reduce( +scrap_pointer j, short k, +eight_bits c, +short d, short n) { scrap_pointer i, i1; /* pointers into scrap memory */ j->cat=c; j->trans=text_ptr; @@ -3019,7 +3036,7 @@ short k, d, n; lo_ptr=lo_ptr-k+1; } pp=(pp+d; + @@; pp--; /* we next say |pp++| */ } @@ -3027,16 +3044,16 @@ short k, d, n; takes advantage of the simplification that occurs when |k==1|. @c -void -squash(j,k,c,d,n) -scrap_pointer j; -eight_bits c; -short k, d, n; +static void +squash( +scrap_pointer j, short k, +eight_bits c, +short d, short n) { scrap_pointer i; /* pointers into scrap memory */ if (k==1) { j->cat=c; pp=(pp+d; + @@; pp--; /* we next say |pp++| */ return; } @@ -3058,8 +3075,8 @@ than to squeeze the last bit of space from the memory arrays. @d safe_scrap_incr 10 @= -while (1) { - @; +while (true) { + @@; if (tok_ptr+safe_tok_incr>tok_mem_end) { if (tok_ptr>max_tok_ptr) max_tok_ptr=tok_ptr; overflow("token"); @@ -3070,7 +3087,7 @@ while (1) { } if (pp>lo_ptr) break; init_mathness=cur_mathness=maybe_math; - @; + @@; } @ If we get to the end of the scrap list, category codes equal to zero are @@ -3090,22 +3107,22 @@ 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; /* pointer into |scrap_info| */ +{ scrap_pointer k_l; /* pointer into |scrap_info| */ if (tracing==2) { printf("\n%d:",n); - for (k=scrap_base; k<=lo_ptr; k++) { - if (k==pp) putxchar('*'); else putxchar(' '); - if (k->mathness %4 == yes_math) putchar('+'); - else if (k->mathness %4 == no_math) putchar('-'); - print_cat(k->cat); - if (k->mathness /4 == yes_math) putchar('+'); - else if (k->mathness /4 == no_math) putchar('-'); + for (k_l=scrap_base; k_l<=lo_ptr; k_l++) { + if (k_l==pp) putxchar('*'); else putxchar(' '); + if (k_l->mathness %4 == yes_math) putchar('+'); + else if (k_l->mathness %4 == no_math) putchar('-'); + print_cat(k_l->cat); + if (k_l->mathness /4 == yes_math) putchar('+'); + else if (k_l->mathness /4 == no_math) putchar('-'); } - if (hi_ptr<=scrap_ptr) printf("..."); /* indicate that more is coming */ + if (hi_ptr<=scrap_ptr) fputs("...",stdout); /* indicate that more is coming */ } } @@ -3123,24 +3140,26 @@ since |translate| might add a new text and a new scrap before it checks for overflow. @c -text_pointer -translate() /* converts a sequence of scraps */ +static text_pointer +translate(void) /* converts a sequence of scraps */ { scrap_pointer i, /* index into |cat| */ j; /* runs through final scraps */ pp=scrap_base; lo_ptr=pp-1; hi_ptr=pp; - @; - @; - @; + @@; + @@; + @@; } +@ @=@+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 where appropriate. @= { - @; + @@; for (j=scrap_base; j<=lo_ptr; j++) { if (j!=scrap_base) app(' '); if (j->mathness % 4 == yes_math) app('$'); @@ -3148,7 +3167,7 @@ where appropriate. if (j->mathness / 4 == yes_math) app('$'); if (tok_ptr+6>tok_mem_end) overflow("token"); } - freeze_text; return(text_ptr-1); + freeze_text; return text_ptr-1; } @ @= @@ -3188,19 +3207,21 @@ what it reads are appended into the |cat| and |trans| arrays, and |scrap_ptr| is advanced. @c -void -C_parse(spec_ctrl) /* creates scraps from \CEE/ tokens */ - eight_bits spec_ctrl; +static void +C_parse(@t\1\1@> /* creates scraps from \CEE/ tokens */ + eight_bits spec_ctrl@t\2\2@>) { int count; /* characters remaining before string break */ while (next_control; + @@; next_control=get_next(); if (next_control=='|' || next_control==begin_comment || next_control==begin_short_comment) return; } } +@ @=@+static void C_parse(eight_bits); + @ The following macro is used to append a scrap whose tokens have just been appended: @@ -3211,76 +3232,77 @@ been appended: } @ @= -@; +@@; switch (next_control) { case section_name: app(section_flag+(int)(cur_section-name_dir)); app_scrap(section_scrap,maybe_math); app_scrap(exp,yes_math);@+break; - case string: case constant: case verbatim: @; - @+break; - case identifier: app_cur_id(1);@+break; - case TeX_string: @;@+break; + case string: case constant: case verbatim: + @@;@+break; + case identifier: app_cur_id(true);@+break; + case TeX_string: + @@;@+break; case '/': case '.': - app(next_control); app_scrap(binop,yes_math);@+break; + app(next_control);@+app_scrap(binop,yes_math);@+break; case '<': app_str("\\langle");@+app_scrap(prelangle,yes_math);@+break; @.\\langle@> case '>': app_str("\\rangle");@+app_scrap(prerangle,yes_math);@+break; @.\\rangle@> - case '=': app_str("\\K"); app_scrap(binop,yes_math);@+break; + case '=': app_str("\\K");@+app_scrap(binop,yes_math);@+break; @.\\K@> - case '|': app_str("\\OR"); app_scrap(binop,yes_math);@+break; + case '|': app_str("\\OR");@+app_scrap(binop,yes_math);@+break; @.\\OR@> - case '^': app_str("\\XOR"); app_scrap(binop,yes_math);@+break; + case '^': app_str("\\XOR");@+app_scrap(binop,yes_math);@+break; @.\\XOR@> - case '%': app_str("\\MOD"); app_scrap(binop,yes_math);@+break; + case '%': app_str("\\MOD");@+app_scrap(binop,yes_math);@+break; @.\\MOD@> - case '!': app_str("\\R"); app_scrap(unop,yes_math);@+break; + case '!': app_str("\\R");@+app_scrap(unop,yes_math);@+break; @.\\R@> - case '~': app_str("\\CM"); app_scrap(unop,yes_math);@+break; + case '~': app_str("\\CM");@+app_scrap(unop,yes_math);@+break; @.\\CM@> - case '+': case '-': app(next_control); app_scrap(ubinop,yes_math);@+break; - case '*': app(next_control); app_scrap(raw_ubin,yes_math);@+break; - case '&': app_str("\\AND"); app_scrap(raw_ubin,yes_math);@+break; + case '+': case '-': app(next_control);@+app_scrap(ubinop,yes_math);@+break; + case '*': app(next_control);@+app_scrap(raw_ubin,yes_math);@+break; + case '&': app_str("\\AND");@+app_scrap(raw_ubin,yes_math);@+break; @.\\AND@> - case '?': app_str("\\?"); app_scrap(question,yes_math);@+break; + case '?': app_str("\\?");@+app_scrap(question,yes_math);@+break; @.\\?@> - case '#': app_str("\\#"); app_scrap(ubinop,yes_math);@+break; + case '#': app_str("\\#");@+app_scrap(ubinop,yes_math);@+break; @.\\\#@> case ignore: case xref_roman: case xref_wildcard: case xref_typewriter: case noop:@+break; - case '(': case '[': app(next_control); app_scrap(lpar,maybe_math);@+break; - case ')': case ']': app(next_control); app_scrap(rpar,maybe_math);@+break; - case '{': app_str("\\{"@q}@>); app_scrap(lbrace,yes_math);@+break; + case '(': case '[': app(next_control);@+app_scrap(lpar,maybe_math);@+break; + case ')': case ']': app(next_control);@+app_scrap(rpar,maybe_math);@+break; + case '{': app_str("\\{"@q}@>);@+app_scrap(lbrace,yes_math);@+break; @.\\\{@>@q}@> - case '}': app_str(@q{@>"\\}"); app_scrap(rbrace,yes_math);@+break; + case '}': app_str(@q{@>"\\}");@+app_scrap(rbrace,yes_math);@+break; @q{@>@.\\\}@> - case ',': app(','); app_scrap(comma,yes_math);@+break; - case ';': app(';'); app_scrap(semi,maybe_math);@+break; - case ':': app(':'); app_scrap(colon,no_math);@+break;@/ + case ',': app(',');@+app_scrap(comma,yes_math);@+break; + case ';': app(';');@+app_scrap(semi,maybe_math);@+break; + case ':': app(':');@+app_scrap(colon,no_math);@+break;@/ @t\4@> @@; - case thin_space: app_str("\\,"); app_scrap(insert,maybe_math);@+break; + case thin_space: app_str("\\,");@+app_scrap(insert,maybe_math);@+break; @.\\,@> - case math_break: app(opt); app_str("0"); + case math_break: app(opt);@+app_str("0");@+ app_scrap(insert,maybe_math);@+break; - case line_break: app(force); app_scrap(insert,no_math);@+break; - case left_preproc: app(force); app(preproc_line); - app_str("\\#"); app_scrap(lproc,no_math);@+break; + case line_break: app(force);@+app_scrap(insert,no_math);@+break; + case left_preproc: app(force);@+app(preproc_line);@+app_str("\\#"); + app_scrap(lproc,no_math);@+break; @.\\\#@> - case right_preproc: app(force); app_scrap(rproc,no_math);@+break; - case big_line_break: app(big_force); app_scrap(insert,no_math);@+break; - case no_line_break: app(big_cancel); app(noop); app(break_space); - app(noop); app(big_cancel); + case right_preproc: app(force);@+app_scrap(rproc,no_math);@+break; + case big_line_break: app(big_force);@+app_scrap(insert,no_math);@+break; + case no_line_break: app(big_cancel);@+app(noop);@+app(break_space);@+ + app(noop);@+app(big_cancel); app_scrap(insert,no_math);@+break; case pseudo_semi: app_scrap(semi,maybe_math);@+break; case macro_arg_open: app_scrap(begin_arg,maybe_math);@+break; case macro_arg_close: app_scrap(end_arg,maybe_math);@+break; - case join: app_str("\\J"); app_scrap(insert,no_math);@+break; + case join: app_str("\\J");@+app_scrap(insert,no_math);@+break; @.\\J@> - case output_defs_code: app(force); app_str("\\ATH"); app(force); + case output_defs_code: app(force);@+app_str("\\ATH");@+app(force); app_scrap(insert,no_math);@+break; @.\\ATH@> - default: app(inserted); app(next_control); + default: app(inserted);@+app(next_control); app_scrap(insert,maybe_math);@+break; } @@ -3299,7 +3321,7 @@ standard ones. They are converted to \TEX/ control sequences so that it is possible to keep \.{CWEAVE} from outputting unusual |char| codes. @= -case not_eq: app_str("\\I");@+app_scrap(binop,yes_math);@+break; +case non_eq: app_str("\\I");@+app_scrap(binop,yes_math);@+break; @.\\I@> case lt_eq: app_str("\\Z");@+app_scrap(binop,yes_math);@+break; @.\\Z@> @@ -3416,15 +3438,17 @@ while (id_first'}'); @ The function |app_cur_id| appends the current identifier to the -token list; it also builds a new scrap if |scrapping==1|. +token list; it also builds a new scrap if |scrapping==true|. @= -void app_cur_id(); +static void app_cur_id(boolean);@/ +static text_pointer C_translate(void);@/ +static void outer_parse(void); @ @c -void -app_cur_id(scrapping) -boolean scrapping; /* are we making this into a scrap? */ +static void +app_cur_id(@t\1\1@> +boolean scrapping@t\2\2@>) /* are we making this into a scrap? */ { name_pointer p=id_lookup(id_first,id_loc,normal); if (p->ilk<=custom) { /* not a reserved word */ @@ -3447,8 +3471,8 @@ that text. If scraps exist in |scrap_info|, they are unaffected by this translation process. @c -text_pointer -C_translate() +static text_pointer +C_translate(void) { text_pointer p; /* points to the translation */ scrap_pointer save_base; /* holds original value of |scrap_base| */ @@ -3461,7 +3485,7 @@ C_translate() p=translate(); /* make the translation */ if (scrap_ptr>max_scr_ptr) max_scr_ptr=scrap_ptr; scrap_ptr=scrap_base-1; scrap_base=save_base; /* scrap the scraps */ - return(p); + return p; } @ The |outer_parse| routine is to |C_parse| as |outer_xref| @@ -3476,9 +3500,12 @@ program text. @d make_pb flags['e'] -@c -void -outer_parse() /* makes scraps from \CEE/ tokens and comments */ +@= +make_pb=true; + +@ @c +static void +outer_parse(void) /* makes scraps from \CEE/ tokens and comments */ { int bal; /* brace level in comment */ text_pointer p, q; /* partial comments */ @@ -3487,7 +3514,7 @@ outer_parse() /* makes scraps from \CEE/ tokens and comments */ C_parse(ignore); else { boolean is_long_comment=(next_control==begin_comment); - @; + @@; app(cancel); app(inserted); if (is_long_comment) app_str("\\C{"@q}@>); @.\\C@> @@ -3568,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_ptr; /* first unused location in the output state stack */ -stack_pointer stack_end=stack+stack_size-1; /* end of |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; @@ -3582,10 +3609,14 @@ max_stack_ptr=stack; is called; it saves the old level of output and gets a new one going. The value of |cur_mode| is not changed. -@c -void -push_level(p) /* suspends the current level */ -text_pointer p; +@= +static void push_level(text_pointer);@/ +static void pop_level(void); + +@ @c +static void +push_level(@t\1\1@> /* suspends the current level */ +text_pointer p@t\2\2@>) { if (stack_ptr==stack_end) overflow("stack"); if (stack_ptr>stack) { /* save current state */ @@ -3603,8 +3634,8 @@ force when the current level was begun. This subroutine will never be called when |stack_ptr==1|. @c -void -pop_level() +static void +pop_level(void) { cur_end=(--stack_ptr)->end_field; cur_tok=stack_ptr->tok_field; cur_mode=stack_ptr->mode_field; @@ -3618,15 +3649,20 @@ 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 */ -@c -eight_bits -get_output() /* returns the next token of output */ +@= +static eight_bits get_output(void);@/ +static void output_C(void);@/ +static void make_output(void); + +@ @c +static eight_bits +get_output(void) /* returns the next token of output */ { sixteen_bits a; /* current item read from |tok_mem| */ restart: while (cur_tok==cur_end) pop_level(); @@ -3634,16 +3670,16 @@ get_output() /* returns the next token of output */ if (a>=0400) { cur_name=a % id_flag + name_dir; switch (a / id_flag) { - case 2: return(res_word); /* |a==res_flag+cur_name| */ - case 3: return(section_code); /* |a==section_flag+cur_name| */ + case 2: return res_word ; /* |a==res_flag+cur_name| */ + case 3: return section_code ; /* |a==section_flag+cur_name| */ case 4: push_level(a % id_flag + tok_start); goto restart; /* |a==tok_flag+cur_name| */ case 5: push_level(a % id_flag + tok_start); cur_mode=inner; goto restart; /* |a==inner_tok_flag+cur_name| */ - default: return(identifier); /* |a==id_flag+cur_name| */ + default: return identifier; /* |a==id_flag+cur_name| */ } } - return(a); + return (eight_bits)a; } @ The real work associated with token output is done by |make_output|. @@ -3662,8 +3698,8 @@ while outputting the name of a section. @^recursion@> @c -void -output_C() /* outputs the current token list */ +static void +output_C(void) /* outputs the current token list */ { token_pointer save_tok_ptr; text_pointer save_text_ptr; @@ -3684,17 +3720,14 @@ output_C() /* outputs the current token list */ @ Here is \.{CWEAVE}'s major output handler. -@= -void make_output(); - -@ @c -void -make_output() /* outputs the equivalents of tokens */ +@c +static void +make_output(void) /* outputs the equivalents of tokens */ { - eight_bits a, /* current output byte */ + eight_bits a=0, /* current output byte */ b; /* next output byte */ int c; /* count of |indent| and |outdent| tokens */ - char scratch[longest_name]; /* scratch area for section names */ + char scratch[longest_name+1]; /* scratch area for section names */ char *k, *k_limit; /* indices into |scratch| */ char *j; /* index into |buffer| */ char *p; /* index into |byte_mem| */ @@ -3704,28 +3737,28 @@ make_output() /* outputs the equivalents of tokens */ boolean save_mode; /* value of |cur_mode| before a sequence of breaks */ app(end_translation); /* append a sentinel */ freeze_text; push_level(text_ptr-1); - while (1) { + while (true) { a=get_output(); reswitch: switch(a) { case end_translation: return; - case identifier: case res_word: @; break; - case section_code: @; break; + case identifier: case res_word: @@; break; + case section_code: @@; break; case math_rel: out_str("\\MRL{"@q}@>); @.\\MRL@> case noop: case inserted: break; case cancel: case big_cancel: c=0; b=a; - while (1) { + while (true) { a=get_output(); if (a==inserted) continue; if ((abig_force) break; if (a==indent) c++; else if (a==outdent) c--; else if (a==opt) a=get_output(); } - @; + @@; goto reswitch; case indent: case outdent: case opt: case backup: case break_space: case force: case big_force: case preproc_line: @; break; + look ahead in case of line breaks, possibly |goto reswitch|@>@; break; case quoted_char: out(*(cur_tok++)); case qualifier: break; default: out(a); /* otherwise |a| is an ordinary character */ @@ -3767,7 +3800,7 @@ if (is_tiny(cur_name)) { out('\\'); out((cur_name->byte_start)[0]); } -else out_name(cur_name,1); +else out_name(cur_name,true); @ The current mode does not affect the behavior of \.{CWEAVE}'s output routine except when we are outputting control tokens. @@ -3783,7 +3816,7 @@ if (a if (a==opt) { b=get_output(); /* |opt| is followed by a digit */ - if (b!='0' || force_lines==0) out(b)@; + if (b!='0' || force_lines==false) out(b)@; else out_str("{-1}"); /* |force_lines| encourages more \.{@@\v} breaks */ } } else if (a==opt) b=get_output(); /* ignore digit following |opt| */ @@ -3798,18 +3831,18 @@ is suppressed (i.e., a line break that follows `\.{\\Y\\B}'). @= { b=a; save_mode=cur_mode; c=0; - while (1) { + while (true) { a=get_output(); if (a==inserted) continue; if (a==cancel || a==big_cancel) { - @; + @@; goto reswitch; /* |cancel| overrides everything */ } if ((a!=' ' && abig_force) { if (save_mode==outer) { if (out_ptr>out_buf+3 && strncmp(out_ptr-3,"\\Y\\B",4)==0) goto reswitch; - @; + @@; out('\\'); out(b-cancel+'0'); @.\\5@> @.\\6@> @@ -3843,8 +3876,8 @@ input buffer and the translation process uses the end of the active out_str("\\X"); @.\\X@> cur_xref=(xref_pointer)cur_name->xref; - if (cur_xref->num==file_flag) {an_output=1; cur_xref=cur_xref->xlink;} - else an_output=0; + if (cur_xref->num==file_flag) {an_output=true; cur_xref=cur_xref->xlink;} + else an_output=false; if (cur_xref->num>=def_flag) { out_section(cur_xref->num-def_flag); if (phase==3) { @@ -3860,7 +3893,7 @@ input buffer and the translation process uses the end of the active out(':'); if (an_output) out_str("\\.{"@q}@>); @.\\.@> - @; + @@; if (an_output) out_str(@q{@>" }"); out_str("\\X"); } @@ -3872,7 +3905,7 @@ k_limit=scratch+strlen(scratch); cur_section_name=cur_name; while (k; + if (b=='@@') @@; if (an_output) switch (b) { case ' ':case '\\':case '#':case '%':case '$':case '^': @@ -3891,18 +3924,18 @@ while (k default: out(b); } - else if (b!='|') out(b)@; + else { if (b!='|') out(b)@; else { - @; + @@; save_loc=loc; save_limit=limit; loc=limit+2; limit=j+1; *limit='|'; output_C(); loc=save_loc; limit=save_limit; - } + } } } @ @= if (*k++!='@@') { - printf("\n! Illegal control code in section name: <"); + fputs("\n! Illegal control code in section name: <",stdout); @.Illegal control code...@> print_section_name(cur_section_name); printf("> "); mark_error; } @@ -3915,9 +3948,9 @@ equals the delimiter that began the string being copied. @= j=limit+1; *j='|'; delim=0; -while (1) { +while (true) { if (k>=k_limit) { - printf("\n! C text in section name didn't end: <"); + fputs("\n! C text in section name didn't end: <",stdout); @.C text...didn't end@> print_section_name(cur_section_name); printf("> "); mark_error; break; } @@ -3925,9 +3958,9 @@ while (1) { if (b=='@@' || (b=='\\' && delim!=0)) @@; else { - if (b=='\'' || b=='"') + if (b=='\'' || b=='"') { if (delim==0) delim=b; - else if (delim==b) delim=0; + else if (delim==b) delim=0; } if (b!='|' || delim!=0) { if (j>buffer+long_buf_size-3) overflow("buffer"); *(++j)=b; @@ -3948,19 +3981,18 @@ 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. -@= -void phase_two(); - -@ @c -void -phase_two() { -reset_input(); if (show_progress) printf("\nWriting the output file..."); +@c +static void +phase_two(void) { +reset_input(); if (show_progress) fputs("\nWriting the output file...",stdout); @.Writing the output file...@> -section_count=0; format_visible=1; copy_limbo(); -finish_line(); flush_buffer(out_buf,0,0); /* insert a blank line, it looks nice */ -while (!input_has_ended) @; +section_count=0; format_visible=true; copy_limbo(); +finish_line(); flush_buffer(out_buf,false,false); /* insert a blank line, it looks nice */ +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 @@ -3972,27 +4004,27 @@ and `|emit_space_if_needed|' are able to handle the situation: @d save_position save_line=out_line; save_place=out_ptr @d emit_space_if_needed if (save_line!=out_line || save_place!=out_ptr) out_str("\\Y"); - space_checked=1 + 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=0; /* are we outputting a format declaration? */ -boolean group_found=0; /* 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++; - @; + @@; save_position; - @; - @; - @; - @; - @; + @@; + @@; + @@; + @@; + @@; } @ Sections beginning with the \.{CWEB} control sequence `\.{@@\ }' start in the @@ -4016,7 +4048,7 @@ else { sec_depth = sec_depth*10 + (*loc) -'0'; } while (*loc == ' ') loc++; /* remove spaces before group title */ - group_found=1; + group_found=true; out_str("\\N"); @.\\N@> {@+ char s[32];@+sprintf(s,"{%d}",sec_depth+1);@+out_str(s);@+} @@ -4052,13 +4084,13 @@ index entries are not copied and \CEE/ text within \pb\ is translated. the token memory is in its initial empty state. @= -space_checked=0; +space_checked=false; while (next_control<=definition) { /* |format_code| or |definition| */ init_stack; if (next_control==definition) @@; - else @; - outer_parse(); finish_C(format_visible); format_visible=1; - doing_format=0; + else @@; + outer_parse(); finish_C(format_visible); format_visible=true; + doing_format=false; } @ The |finish_C| procedure outputs the translation of the current @@ -4071,13 +4103,10 @@ 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}. -@= -void finish_C(); - -@ @c -void -finish_C(visible) /* finishes a definition or a \CEE/ part */ - boolean visible; /* nonzero if we should produce \TEX/ output */ +@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 */ { text_pointer p; /* translation of the scraps */ if (visible) { @@ -4085,13 +4114,15 @@ finish_C(visible) /* finishes a definition or a \CEE/ part */ p=translate(); @.\\B@> app(tok_flag+(int)(p-tok_start)); make_output(); /* output the list */ - if (out_ptr>out_buf+1) - if (*(out_ptr-1)=='\\') + if (out_ptr>out_buf+1) { + if (*(out_ptr-1)=='\\') { @.\\6@> @.\\7@> @.\\Y@> if (*out_ptr=='6') out_ptr-=2; else if (*out_ptr=='7') *out_ptr='Y'; + } + } out_str("\\par"); finish_line(); } if (text_ptr>max_text_ptr) max_text_ptr=text_ptr; @@ -4101,6 +4132,8 @@ finish_C(visible) /* 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 @@ -4118,11 +4151,11 @@ it starts after we scan the matching `\.)'. err_print("! Improper macro definition"); @.Improper macro definition@> else { - app('$'); app_cur_id(0); + app('$'); app_cur_id(false); if (*loc=='(') reswitch: switch (next_control=get_next()) { case '(': case ',': app(next_control); goto reswitch; - case identifier: app_cur_id(0); goto reswitch; + case identifier: app_cur_id(false); goto reswitch; case ')': app(next_control); next_control=get_next(); break; default: err_print("! Improper macro definition"); break; } @@ -4133,8 +4166,8 @@ it starts after we scan the matching `\.)'. } @ @= { - doing_format=1; - if(*(loc-1)=='s' || *(loc-1)=='S') format_visible=0; + doing_format=true; + if(*(loc-1)=='s' || *(loc-1)=='S') format_visible=false; if(!space_checked){emit_space_if_needed;save_position;} app_str("\\F"); /* this will produce `\&{format }' */ @.\\F@> @@ -4158,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; @@ -4169,13 +4202,13 @@ if (next_control<=section_name) { else { this_section=cur_section; @ @@ -4223,8 +4256,8 @@ after the section ends. @= if (this_section>name_dir) { cur_xref=(xref_pointer)this_section->xref; - if (cur_xref->num==file_flag){an_output=1;cur_xref=cur_xref->xlink;} - else an_output=0; + if (cur_xref->num==file_flag){an_output=true;cur_xref=cur_xref->xlink;} + else an_output=false; if (cur_xref->num>def_flag) cur_xref=cur_xref->xlink; /* bypass current section number */ footnote(def_flag); footnote(cite_flag); footnote(0); @@ -4242,13 +4275,10 @@ 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. -@= -void footnote(); - -@ @c -void -footnote(flag) /* outputs section cross-references */ -sixteen_bits flag; +@c +static void +footnote(@t\1\1@> /* outputs section cross-references */ +sixteen_bits flag@t\2\2@>) { xref_pointer q; /* cross-reference pointer variable */ if (cur_xref->num<=flag) return; @@ -4257,17 +4287,19 @@ sixteen_bits flag; @.\\Q@> @.\\U@> out(flag==0? 'U': flag==cite_flag? 'Q': 'A'); - @; + @@; 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. @= q=cur_xref; if (q->xlink->num>flag) out('s'); /* plural */ -while (1) { +while (true) { out_section(cur_xref->num-flag); cur_xref=cur_xref->xlink; /* point to the next cross-reference to output */ if (cur_xref->num<=flag) break; @@ -4281,7 +4313,7 @@ while (1) { @ @= out_str("\\fi"); finish_line(); @.\\fi@> -flush_buffer(out_buf,0,0); /* insert a blank line, it looks nice */ +flush_buffer(out_buf,false,false); /* insert a blank line, it looks nice */ @** Phase three processing. We are nearly finished! \.{CWEAVE}'s only remaining task is to write out the @@ -4291,12 +4323,9 @@ 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. -@= -void phase_three(); - -@ @c -void -phase_three() { +@c +static void +phase_three(void) { if (no_xref) { finish_line(); out_str("\\end"); @@ -4304,29 +4333,29 @@ if (no_xref) { finish_line(); } else { - phase=3; if (show_progress) printf("\nWriting the index..."); + phase=3; if (show_progress) fputs("\nWriting the index...",stdout); @.Writing the index...@> finish_line(); - if ((idx_file=fopen(idx_file_name,"w"))==NULL) + if ((idx_file=fopen(idx_file_name,"wb"))==NULL) fatal("! Cannot open index file ",idx_file_name); @.Cannot open index file@> if (change_exists) { - @; finish_line(); finish_line(); + @@; finish_line(); finish_line(); } out_str("\\inx"); finish_line(); @.\\inx@> active_file=idx_file; /* change active file to the index file */ - @; - @; + @@; + @@; finish_line(); fclose(active_file); /* finished with |idx_file| */ active_file=tex_file; /* switch back to |tex_file| for a tic */ out_str("\\fin"); finish_line(); @.\\fin@> - if ((scn_file=fopen(scn_file_name,"w"))==NULL) + if ((scn_file=fopen(scn_file_name,"wb"))==NULL) fatal("! Cannot open section file ",scn_file_name); @.Cannot open section file@> active_file=scn_file; /* change active file to section listing file */ - @; + @@; finish_line(); fclose(active_file); /* finished with |scn_file| */ active_file=tex_file; if (group_found) out_str("\\con");@+else out_str("\\end"); @@ -4335,15 +4364,20 @@ else { finish_line(); fclose(active_file); } -if (show_happiness) printf("\nDone."); +if (show_happiness) { + if (show_progress) new_line; + fputs("Done.",stdout); +} 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 */ @@ -4362,28 +4396,28 @@ sixteen_bits k_section; /* runs through the sections */ @ A left-to-right radix sorting method is used, since this makes it easy to adjust the collating sequence and since the running time will be at worst proportional to the total length of all entries in the index. We put the -identifiers into 102 different lists based on their first characters. +identifiers into different lists based on their first characters. (Uppercase letters are put into the same list as the corresponding lowercase 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. @= { int c; -for (c=0; c<=255; c++) bucket[c]=NULL; +for (c=0; c<256; c++) bucket[c]=NULL; for (h=hash; h<=hash_end; h++) { next_name=*h; while (next_name) { cur_name=next_name; next_name=cur_name->link; - if (cur_name->xref!=(char*)xmem) { + if (cur_name->xref!=(void *)xmem) { c=(eight_bits)((cur_name->byte_start)[0]); if (xisupper(c)) c=tolower(c); blink[cur_name-name_dir]=bucket[c]; bucket[c]=cur_name; @@ -4401,7 +4435,7 @@ present; the lists are output in reverse order (first |sort_ptr|, then |k| characters of all entries on this list are known to be equal we have |depth[j]==k|. -@ @= +@= name_pointer Head; @ @d depth cat /* reclaims memory that is no longer needed for parsing */ @@ -4411,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; @@ -4423,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[102+128]; /* collation order */ +@= +static eight_bits collate[101+128]; /* collation order */ @^high-bit character handling@> @ We use the order $\hbox{null}<\.\ <\hbox{other characters}<{}$\.\_${}< @@ -4438,29 +4472,41 @@ some \CEE/ compilers choke on long strings. @= collate[0]=0; -strcpy(collate+1," \1\2\3\4\5\6\7\10\11\12\13\14\15\16\17"); +memcpy((char *)collate+1, + " \1\2\3\4\5\6\7\10\11\12\13\14\15\16\17",16); /* 16 characters + 1 = 17 */ -strcpy(collate+17,"\20\21\22\23\24\25\26\27\30\31\32\33\34\35\36\37"); +memcpy((char *)collate+17, + "\20\21\22\23\24\25\26\27\30\31\32\33\34\35\36\37",16); /* 16 characters + 17 = 33 */ -strcpy(collate+33,"!\42#$%&'()*+,-./:;<=>?@@[\\]^`{|}~_"); +memcpy((char *)collate+33, + "!\42#$%&'()*+,-./:;<=>?@@[\\]^`{|}~_",32); /* 32 characters + 33 = 65 */ -strcpy(collate+65,"abcdefghijklmnopqrstuvwxyz0123456789"); +memcpy((char *)collate+65, + "abcdefghijklmnopqrstuvwxyz0123456789",36); /* (26 + 10) characters + 65 = 101 */ -strcpy(collate+101,"\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217"); +memcpy((char *)collate+101, + "\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217",16); /* 16 characters + 101 = 117 */ -strcpy(collate+117,"\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237"); +memcpy((char *)collate+117, + "\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237",16); /* 16 characters + 117 = 133 */ -strcpy(collate+133,"\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257"); +memcpy((char *)collate+133, + "\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257",16); /* 16 characters + 133 = 149 */ -strcpy(collate+149,"\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277"); +memcpy((char *)collate+149, + "\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277",16); /* 16 characters + 149 = 165 */ -strcpy(collate+165,"\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317"); +memcpy((char *)collate+165, + "\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317",16); /* 16 characters + 165 = 181 */ -strcpy(collate+181,"\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337"); +memcpy((char *)collate+181, + "\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337",16); /* 16 characters + 181 = 197 */ -strcpy(collate+197,"\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357"); +memcpy((char *)collate+197, + "\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357",16); /* 16 characters + 197 = 213 */ -strcpy(collate+213,"\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377"); +memcpy((char *)collate+213, + "\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377",16); /* 16 characters + 213 = 229 */ @ Procedure |unbucket| goes through the buckets and adds nonempty lists @@ -4471,16 +4517,13 @@ regarded as identical. @d infinity 255 /* $\infty$ (approximately) */ -@= -void unbucket(); - -@ @c -void -unbucket(d) /* empties buckets having depth |d| */ -eight_bits d; +@c +static void +unbucket(@t\1\1@> /* empties buckets having depth |d| */ +eight_bits d@t\2\2@>) { int c; /* index into |bucket|; cannot be a simple |char| because of sign - comparison below*/ + comparison below */ for (c=100+128; c>= 0; c--) if (bucket[collate[c]]) { @^high-bit character handling@> if (sort_ptr>=scrap_info_end) overflow("sorting"); @@ -4492,13 +4535,15 @@ eight_bits d; } } +@ @=@+static void unbucket(eight_bits); + @ @= sort_ptr=scrap_info; unbucket(1); while (sort_ptr>scrap_info) { cur_depth=sort_ptr->depth; if (blink[sort_ptr->head-name_dir]==0 || cur_depth==infinity) @@; - else @; + else @@; } @ @= { @@ -4522,8 +4567,8 @@ while (sort_ptr>scrap_info) { do { out_str("\\I"); @.\\I@> - @; - @; + @@; + @@; cur_name=blink[cur_name-name_dir]; } while (cur_name); --sort_ptr; @@ -4546,7 +4591,7 @@ lowcase: out_str("\\\\"); @.\\9@> case typewriter: out_str("\\."); @.\\.@> - case roman: not_an_identifier: out_name(cur_name,0); goto name_done; + case roman: not_an_identifier: out_name(cur_name,false); goto name_done; case custom: {char *j; out_str("$\\"); for (j=cur_name->byte_start;j<(cur_name+1)->byte_start;j++) out(*j=='_'? 'x': *j=='$'? 'X': *j); @@ -4556,14 +4601,14 @@ lowcase: out_str("\\\\"); default: out_str("\\&"); @.\\\&@> } -out_name(cur_name,1); +out_name(cur_name,true); name_done:@; @ Section numbers that are to be underlined are enclosed in `\.{\\[}$\,\ldots\,$\.]'. @= -@; +@@; do { out_str(", "); cur_val=cur_xref->num; if (cur_val= -xref_pointer next_xref, this_xref; +@= +static xref_pointer next_xref, this_xref; /* pointer variables for rearranging a list */ @ @= @@ -4591,13 +4636,10 @@ do { prints them. @^recursion@> -@= -void section_print(); - -@ @c -void -section_print(p) /* print all section names in subtree |p| */ -name_pointer p; +@c +static void +section_print(@t\1\1@> /* print all section names in subtree |p| */ +name_pointer p@t\2\2@>) { if (p) { section_print(p->llink); out_str("\\I"); @@ -4611,34 +4653,36 @@ name_pointer p; } } -@ @=section_print(root) +@ @=@+static void section_print(name_pointer); + +@ @=section_print(root); -@ Because on some systems the difference between two pointers is a |long| +@ Because on some systems the difference between two pointers is a |ptrdiff_t| rather than an |int|, we use \.{\%ld} to print these quantities. @c void -print_stats() { - printf("\nMemory usage statistics:\n"); +print_stats(void) { + puts("\nMemory usage statistics:"); @.Memory usage statistics:@> printf("%ld names (out of %ld)\n", - (long)(name_ptr-name_dir),(long)max_names); + (ptrdiff_t)(name_ptr-name_dir),(long)max_names); printf("%ld cross-references (out of %ld)\n", - (long)(xref_ptr-xmem),(long)max_refs); + (ptrdiff_t)(xref_ptr-xmem),(long)max_refs); printf("%ld bytes (out of %ld)\n", - (long)(byte_ptr-byte_mem),(long)max_bytes); - printf("Parsing:\n"); + (ptrdiff_t)(byte_ptr-byte_mem),(long)max_bytes); + puts("Parsing:"); printf("%ld scraps (out of %ld)\n", - (long)(max_scr_ptr-scrap_info),(long)max_scraps); + (ptrdiff_t)(max_scr_ptr-scrap_info),(long)max_scraps); printf("%ld texts (out of %ld)\n", - (long)(max_text_ptr-tok_start),(long)max_texts); + (ptrdiff_t)(max_text_ptr-tok_start),(long)max_texts); printf("%ld tokens (out of %ld)\n", - (long)(max_tok_ptr-tok_mem),(long)max_toks); + (ptrdiff_t)(max_tok_ptr-tok_mem),(long)max_toks); printf("%ld levels (out of %ld)\n", - (long)(max_stack_ptr-stack),(long)stack_size); - printf("Sorting:\n"); + (ptrdiff_t)(max_stack_ptr-stack),(long)stack_size); + puts("Sorting:"); printf("%ld levels (out of %ld)\n", - (long)(max_sort_ptr-scrap_info),(long)max_scraps); + (ptrdiff_t)(max_sort_ptr-scrap_info),(long)max_scraps); } @** Index. diff --git a/web/c_cpp/cweb/cweb.1 b/web/c_cpp/cweb/cweb.1 index ad41c427ea..a9aa69bf43 100644 --- a/web/c_cpp/cweb/cweb.1 +++ b/web/c_cpp/cweb/cweb.1 @@ -1,4 +1,4 @@ -.TH CWEB 1L 2002-Apr-13 +.TH CWEB 1 2018-Dec-16 . .SH NAME ctangle, cweave \- translate CWEB to C and/or TeX @@ -10,14 +10,14 @@ ctangle, cweave \- translate CWEB to C and/or TeX .B \-bhp ] [ .B +s -] webfile[.w] [changefile[.ch]] [outputfile[.c]] +] webfile[.w] [{changefile[.ch]|-} [outputfile[.c]]] .br .B cweave [ .B \-befhpx ] [ .B +s -] webfile[.w] [changefile[.ch]] [outputfile[.tex]] +] webfile[.w] [{changefile[.ch]|-} [outputfile[.tex]]] .ad . .SH DESCRIPTION @@ -78,8 +78,7 @@ If you say -bhp, you get nothing but error messages. .PP The .B +s -option prints statistics about memory usage at the end of a run -(assuming that the programs have been compiled with the -DSTAT switch). +option prints statistics about memory usage at the end of a run. .PP There are three other options applicable to .I cweave @@ -99,20 +98,15 @@ and similar programs. means omit the index and table of contents. . .SH FILES +The location of the files mentioned below varies from system to system. .TP -/usr/local/lib/tex/inputs/cwebmac.tex +cwebmac.tex TeX macros used by cweave output. .TP -/usr/local/src/cweb/cwebman.tex +cwebman.tex The user manual. .TP -/usr/local/src/cweb/examples/wc.w -An introductory example. -.TP -/usr/local/src/cweb/examples/wmerge.w -Patch program based on CWEB-style change files. -.TP -/usr/local/lib/cweb +/usr/lib/cweb Directory for cweb "include" files. . .SH "SEE ALSO" diff --git a/web/c_cpp/cweb/cwebmac.tex b/web/c_cpp/cweb/cwebmac.tex index 60f86ce5a9..385dc474e7 100644 --- a/web/c_cpp/cweb/cwebmac.tex +++ b/web/c_cpp/cweb/cwebmac.tex @@ -1,19 +1,20 @@ % standard macros for CWEB listings (in addition to plain.tex) -% Version 3.70 --- July 2017 +% Version 4.2 --- February 2021 \ifx\renewenvironment\undefined\else\endinput\fi % LaTeX will use other macros -\xdef\fmtversion{\fmtversion+CWEB3.70} -\chardef\cwebversion=3 \chardef\cwebrevision=70 +\xdef\fmtversion{\fmtversion+CWEB4.2} +\chardef\cwebversion=4 \chardef\cwebrevision=1 \newif\ifpdf \ifx\pdf+\pdftrue\fi % Uncomment the following line if you want PDF goodies to be the default %\ifx\pdf-\else\pdftrue\fi \def\pdflinkcolor{0 0 1} % the RGB values for hyperlink color +\ifx\undefined\XeTeXrevision\else\pdftrue\fi % XeTeX produces PDF output \newif\ifpdftex \ifx\pdfoutput\undefined \pdftexfalse \else\ifnum\pdfoutput=0 \pdftexfalse %\else \pdftextrue \pdfoutput=1 \input pdfcolor \let\setcolor\pdfsetcolor \fi\fi \else \pdftextrue \pdfoutput=1 % changed in 3.69 \def\Black{\pdfliteral{0 g 0 G}} % use rgb colors for direct PDF output too - \def\Blue{\pdfliteral{0 0 1 rg 0 0 1 RG}} + \def\Blue{\pdfliteral{\pdflinkcolor\space rg \pdflinkcolor\space RG}} \fi\fi \newif\ifacro \ifpdf\acrotrue\fi \ifpdftex\acrotrue\fi @@ -281,12 +282,10 @@ \def\stsec{\rightskip=0pt % get out of C mode (cf. \B) \sfcode`;=1500 \pretolerance 200 \hyphenpenalty 50 \exhyphenpenalty 50 \noindent{\let\*=\lapstar\bf\secstar.\quad}% - \ifpdftex\smash{\raise\baselineskip\hbox to0pt{% -% \let\*=\empty\pdfdest num \secstar fith}} % bad space in versions < 3.68 - \let\*=\empty\pdfdest num \secstar fith}}% changed in version 3.68 - \else\ifpdf\smash{\raise\baselineskip\hbox to0pt{% - \let\*=\empty\special{% - pdf: dest (\romannumeral\secstar) [ @thispage /FitH @ypos ]}}}\fi\fi} + \ifacro \smash{\raise\baselineskip\hbox to0pt{\let\*=\empty + \ifpdftex \pdfdest num \secstar fith% + \else \special{pdf: dest (\romannumeral\secstar) + [ @thispage /FitH @ypos ]}\fi}}\fi} \let\startsection=\stsec \def\defin#1{\global\advance\ind by 2 \1\&{#1 } } % begin `define' or `format' \def\A{\note{See also section}} % xref for doubly defined section name diff --git a/web/c_cpp/cweb/cwebman.tex b/web/c_cpp/cweb/cwebman.tex index 2e4ec65ea5..df652232b7 100644 --- a/web/c_cpp/cweb/cwebman.tex +++ b/web/c_cpp/cweb/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 3.64)} +\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 3.64 --- February 2002)} +\vskip 18pt\centerline{(Version 4.2 --- February 2021)} \vskip 24pt \centerline{\authorfont Donald E. Knuth and Silvio Levy} \vfill @@ -87,6 +87,10 @@ for their own personal use. Internet page \.{http://www-cs-faculty.stanford.edu/\char`\~knuth/cweb.html} contains current info about \.{CWEB} and related topics. +\smallskip\noindent +From there you can also reach the \.{CWEB} development page +\.{https://github.com/ascherer/cweb} with the really current news. + \pageno=0 \titletrue\eject \titletrue @@ -103,7 +107,7 @@ adapted to \CEE/ by Silvio Levy. Since its creation in 1987, \.{CWEB} has been revised and enhanced in various ways, by both Knuth and Levy. We now believe that its evolution is near an end; however, bug reports, suggestions and comments are still welcome, and -should be sent to Levy (\.{levy@math.berkeley.edu}). +should be sent to the \TeX-related mailing list \.{tex-k@tug.org}. Readers who are familiar with Knuth's memo ``The \.{WEB} System of Structured Documentation'' will be able @@ -394,15 +398,15 @@ $$\hbox{ If \\{pa} is declared as `\&{int} ${}{*}\\{pa}$', 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}, @@ -521,7 +525,7 @@ specifically below. \@@ [LTMCrc] A double \.@ denotes the single character `\.@'. This is the only control code that is legal everywhere. Note that you must use this convention if you are giving an internet -email address in a \.{CWEB} file (e.g., \.{levy@@math.berkeley.edu}). +email address in a \.{CWEB} file (e.g., \.{tex-k@@tug.org}). \subsec Here are the codes that introduce the \TEX/ part of a section. @@ -1007,7 +1011,7 @@ part of a \.{struct}, even though \CEE/ does allow this. \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 @@ -1038,7 +1042,7 @@ by default.) \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 @@ -1151,6 +1155,8 @@ for the macros that make this work.) Alternatively, thanks to H\`an Th\^e\kern-.3em\raise.3ex\hbox{\'{}} Th\`anh and Andreas Scherer, you can generate \.{cob.pdf} in one step by simply saying `\.{pdftex}~\.{cob}'. +A third way to create PDF output from \.{CWEB} input is to say +`\.{xetex}~\.{cob}'. A more elaborate system called \.{CTWILL}, which extends the usual cross references of \.{CWEAVE} by preparing links from the uses of identifiers @@ -1184,17 +1190,16 @@ appendices D, E, and~F, which exhibit the complete source code for This appendix consists of four listings. The first shows the \.{CWEB} input that -generated sections 12--15 of the file \.{common.w}, which contains +generated sections 27--31 of the file \.{common.w}, which contains routines common to \.{CWEAVE} and \.{CTANGLE}. Note that some of the lines are indented to show the program structure; the indentation is ignored by \.{CWEAVE} and \.{CTANGLE}, but users find that \.{CWEB} files are quite readable if they have some such indentation. -The second and third listings -show corresponding parts -of the \CEE/ code output by \.{CTANGLE} and of -the corresponding \TEX/ code output by \.{CWEAVE}, when run on \.{common.w}. -The fourth listing shows how that output looks when printed out. +The second and third listings show corresponding parts of +the \CEE/ code output by \.{CTANGLE} and of +the \TEX/ code output by \.{CWEAVE}, when run on \.{common.w}. +The fourth listing shows how that output looks in print. \vskip 6pt \begingroup \def\tt{\eighttt} \baselineskip9pt @@ -1204,16 +1209,19 @@ sets |change_buffer| in preparation for the next matching operation. Since blank lines in the change file are not used for matching, we have |(change_limit==change_buffer && !!changing)| if and only if the change file is exhausted. This procedure is called only when -|changing| is 1; hence error messages will be reported correctly. +|changing| is |true|; hence error messages will be reported correctly. + +@= +static void prime_the_change_buffer(void);@/ -@c -void -prime_the_change_buffer() +@ @c +static void +prime_the_change_buffer(void) { change_limit=change_buffer; /* this value is used if the change file ends */ - @; - @; - @; + @@; + @@; + @@; } @ While looking for a line that begins with \.{@@x} in the change file, we @@ -1221,12 +1229,12 @@ 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). @= -while(1) { +while(true) { change_line++; if (!!input_ln(change_file)) return; if (limit= { - change_limit=change_buffer-buffer+limit; - strncpy(change_buffer,buffer,limit-buffer+1); + change_limit=change_buffer+(ptrdiff_t)(limit-buffer); + strncpy(change_buffer,buffer,(size_t)(limit-buffer+1)); } - !endgroup \endgroup \vfill\eject @@ -1260,28 +1267,28 @@ do { \def\runninghead{APPENDIX A --- TRANSLATION BY {\tentt CTANGLE}} Here's the portion of the \CEE/ code generated by \.{CTANGLE} that corresponds -to the source on the preceding page. Notice that sections~13, 14 and~15 -have been tangled into section~12. +to the source on the preceding page. Notice that sections~29, 30 and~31 +have been tangled into section~28. \vskip6pt \begingroup \def\tt{\eighttt} \baselineskip9pt \verbatim -/*:9*//*12:*/ -#line 247 "common.w" +/*:24*//*28:*/ +#line 234 "common.w" -void -prime_the_change_buffer() +static void +prime_the_change_buffer(void) { change_limit= change_buffer; -/*13:*/ -#line 261 "common.w" +/*29:*/ +#line 248 "common.w" -while(1){ +while(true){ change_line++; if(!!input_ln(change_file))return; if(limit> >>}\fi + \gdef\bkminfo{}% + \global\advance\destcount by 1\relax + \kern2.5ex\relax + }\fi{\bf #1.}\quad\ignorespaces} + +\def\appA{7} +\def\appB{8} +\def\appC{9} +\def\appD{0} +\def\appE{0} +\def\appF{10} +\def\appG{11} +\def\appH{12} + +\def\Appendix#1{\leavevmode + \ifnum\csname app#1\endcsname>0 % + \ifacro\ifpdftex + \pdfstartlink attr{/Border[0 0 0]} goto num\csname app#1\endcsname\relax + \PDFlinkcolor\hbox{Appendix}~#1\Black + \pdfendlink + \else + \setbox0=\hbox{\special{pdf: bc [ \pdflinkcolor ]}{\hbox{Appendix}~#1}% + \special{pdf: ec}}\special{pdf: ann width \thewidth height \theheight + depth \thedepth << /Type /Annot /Subtype /Link /Border [0 0 0] + /A << /S /GoTo /D (\csname app#1\endcsname) >> >>}\box0\relax + \fi\else Appendix~#1\fi + \else Appendix~#1\fi} +@z + +@x +program for \.{TANGLE}, in the appendix, gives precise details about this +@y +program for \.{TANGLE}, in \pdfURL{Appendix~E}{tangle.pdf}, +gives precise details about this +@z + +@x l.626 +outputs of \.{WEAVE} and \.{TANGLE} (see Appendix~C\null). Meta-comments +@y +outputs of \.{WEAVE} (see \Appendix B\null) and \.{TANGLE} +(see \Appendix C\null). Meta-comments +@z + +@x l.893 +examples of ``real'' programs. Appendix~A shows the \.{WEB} input that +generated modules 55--59 of the \.{WEAVE} program; Appendix~B shows the +corresponding \TeX\ code output by \.{WEAVE}; and Appendix~C shows excerpts +@y +examples of ``real'' programs. \Appendix A shows the \.{WEB} input that +generated modules 55--59 of the \.{WEAVE} program; \Appendix B shows the +corresponding \TeX\ code output by \.{WEAVE}; and \Appendix C shows excerpts +@z + +@x l.900 +report, in Appendices D and~E. The reader should first compare Appendix~A +to the corresponding portion of Appendix~D; then the same material should +be compared to Appendices B and~C. Finally, if time permits, the reader may +enjoy studying the complete programs in Appendices D and~E, since \.{WEAVE} +@y +report, in Appendices \pdfURL{D}{weave.pdf} and~\pdfURL{E}{tangle.pdf}. +The reader should first compare \Appendix A to the corresponding portion of +\pdfURL{Appendix~D}{weave.pdf}; then the same material should be compared to +\Appendix B and \Appendix C. Finally, if time permits, the reader may enjoy +studying the complete programs in Appendices \pdfURL{D}{weave.pdf} +and~\pdfURL{E}{tangle.pdf}, since \.{WEAVE} +@z + +@x l.908 +Finally, Appendix F is the `\.{webmac}' file that sets \TeX\ up to accept +the output of \.{WEAVE}; Appendix~G discusses how to use some of its macros +to vary the output formats; and Appendix~H discusses what needs to be done +@y +Finally, \Appendix F is the `\.{webmac}' file that sets \TeX\ up to accept +the output of \.{WEAVE}; \Appendix G discusses how to use some of its macros +to vary the output formats; and \Appendix H discusses what needs to be done +@z + +@x l.913 +The programs in Appendices D and E will optionally keep statistics on +@y +The programs in Appendices \pdfURL{D}{weave.pdf} and \pdfURL{E}{tangle.pdf} +will optionally keep statistics on +@z + +@x l.989 +\section Appendix A. +This excerpt from \.{WEAVE.WEB} produced modules 55--59 in Appendix~D. +@y +\def\bkminfo{WEB file format} +\section Appendix A. +This excerpt from \.{WEAVE.WEB} produced modules 55--59 in +\pdfURL{Appendix~D}{weave.pdf}. +@z + +@x l.1061 +\section Appendix B. +This excerpt from \.{WEAVE.TEX} corresponds to Appendix A. +@y +\def\bkminfo{Translations by WEAVE} +\section Appendix B. +This excerpt from \.{WEAVE.TEX} corresponds to \Appendix A. +@z + +@x l.1143 +\section Appendix C. +@y +\def\bkminfo{Translation by TANGLE} +\section Appendix C. +@z + +@x l.1425 +in small caps. For example, Appendix~D was produced after saying +@y +in small caps. For example, \pdfURL{Appendix~D}{weave.pdf} was produced +after saying +@z + +@x l.1468 +\.{\\pageno=\\contentspagenumber} \.{\\advance\\pageno by 1}'. (Appendix~D +@y +\.{\\pageno=\\contentspagenumber} \.{\\advance\\pageno by 1}'. +(\pdfURL{Appendix~D}{weave.pdf} +@z + +@x l.1479 +For example, Appendix~D was produced with the following definitions: +@y +For example, \pdfURL{Appendix~D}{weave.pdf} was produced with the following +definitions: +@z + +@x l.1491 +for every starred module. For example, when Appendix~D was being generated, +@y +for every starred module. For example, when \pdfURL{Appendix~D}{weave.pdf} +was being generated, +@z + +@x l.1583 +dependencies'' in the index of Appendix~E above, and figure out what changes +@y +dependencies'' in the index of \pdfURL{Appendix~E}{tangle.pdf} above, +and figure out what changes +@z + +@x l.1609 +the index to Appendix~D. +@y +the index to \pdfURL{Appendix~D}{weave.pdf}. +@z + +@x l.1616 +Appendix~E. This listing will incorporate your changes. +@y +\pdfURL{Appendix~E}{tangle.pdf}. This listing will incorporate your changes. +@z + +@x l.1620 +Appendix~D that incorporates your changes. +@y +\pdfURL{Appendix~D}{weave.pdf} that incorporates your changes. +@z + +@x l.1666 +computer by following Appendices D and E. Then you have to simulate the +@y +computer by following Appendices \pdfURL{D}{weave.pdf} +and~\pdfURL{E}{tangle.pdf}. Then you have to simulate the +@z -- cgit v1.2.3