summaryrefslogtreecommitdiff
path: root/web
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2021-03-02 03:04:42 +0000
committerNorbert Preining <norbert@preining.info>2021-03-02 03:04:42 +0000
commit4763ec8ceefaf2b038d591b8c15d88d081aec6c9 (patch)
tree113e7c21358dd01318b8e7a1e3f3228ec33bc563 /web
parent3a1a102e980610859d9f1b197733d6ce6a541c62 (diff)
CTAN sync 202103020304
Diffstat (limited to 'web')
-rw-r--r--web/c_cpp/cweb/Makefile11
-rw-r--r--web/c_cpp/cweb/README21
-rw-r--r--web/c_cpp/cweb/comm-amiga.ch8
-rw-r--r--web/c_cpp/cweb/comm-bs.ch210
-rw-r--r--web/c_cpp/cweb/comm-mac.ch73
-rw-r--r--web/c_cpp/cweb/comm-os2.ch16
-rw-r--r--web/c_cpp/cweb/comm-pc.ch22
-rw-r--r--web/c_cpp/cweb/comm-ql.ch257
-rw-r--r--web/c_cpp/cweb/comm-vms.ch43
-rw-r--r--web/c_cpp/cweb/comm-w32.ch50
-rw-r--r--web/c_cpp/cweb/common.c1059
-rw-r--r--web/c_cpp/cweb/common.h202
-rw-r--r--web/c_cpp/cweb/common.w677
-rw-r--r--web/c_cpp/cweb/ctang-bs.ch124
-rw-r--r--web/c_cpp/cweb/ctang-pc.ch12
-rw-r--r--web/c_cpp/cweb/ctang-ql.ch8
-rw-r--r--web/c_cpp/cweb/ctang-vms.ch34
-rw-r--r--web/c_cpp/cweb/ctang-w32.ch62
-rw-r--r--web/c_cpp/cweb/ctangle.c1123
-rw-r--r--web/c_cpp/cweb/ctangle.w536
-rw-r--r--web/c_cpp/cweb/cweav-bs.ch178
-rw-r--r--web/c_cpp/cweb/cweav-pc.ch19
-rw-r--r--web/c_cpp/cweb/cweav-ql.ch8
-rw-r--r--web/c_cpp/cweb/cweav-vms.ch35
-rw-r--r--web/c_cpp/cweb/cweav-w32.ch54
-rw-r--r--web/c_cpp/cweb/cweave.w1456
-rw-r--r--web/c_cpp/cweb/cweb.122
-rw-r--r--web/c_cpp/cweb/cwebmac.tex19
-rw-r--r--web/c_cpp/cweb/cwebman.tex243
-rw-r--r--web/pwebmac/README.md6
-rw-r--r--web/pwebmac/index.md2
-rwxr-xr-xweb/pwebmac/makeall14
-rw-r--r--web/pwebmac/trapman.ch23
-rw-r--r--web/pwebmac/webman.ch198
34 files changed, 3480 insertions, 3345 deletions
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 */
-
-@<Definitions that...@>=
+@<Common code...@>=
typedef struct name_info {
char *byte_start; /* beginning of the name in |byte_mem| */
- @<More elements of |name_info| structure@>@;
+ 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
-@<Definitions that...@>=
+@<Common code...@>=
typedef struct name_info {
char huge* byte_start; /* beginning of the name in |byte_mem| */
- @<More elements of |name_info| structure@>@;
+ 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.
@ @<Init...@>=
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|.
-
-@<More elements of |name...@>=
-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.
-
-@<More elements of |name...@>=
-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 */
+@<Predecl...@>=
+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 */
+@<Predecl...@>=
+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 */
- @<Skip over comment lines in the change file; |return| if end of file@>;
+ @<Skip over comment lines in the change file; |return| if end of file@>@;
@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 */
- @<Skip over comment lines in the change file; |return| if end of file@>;
+ @<Skip over comment lines in the change file; |return| if end of 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 <dev_>cc;'-v -h -c -=500000 -DCWEBINPUTS=flp2_ common_c'
@x
\def\v{\char'174} % vertical (|) in typewriter font
-\def\title{Common code for CTANGLE and CWEAVE (Version 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.
-
-@<Pred...@>=
-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)) @<Handle flag argument@>@;
- 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) @<Make
- |web_file_name|, |tex_file_name| and |C_file_name|@>@;
- else if (!found_change) @<Make |change_file_name| from |fname|@>@;
- else if (!found_out) @<Override |tex_file_name| and |C_file_name|@>@;
- else @<Print usage error message and quit@>;
- }
- }
- if (!found_web) @<Print usage error message and quit@>;
- 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.
-
-@<Make |web_file_name|...@>=
-{
- if (s-*argv > max_file_name_length-5)
- @<Complain about argument length@>;
- 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;
-}
-
-@ @<Make |change_file_name|...@>=
-{
- if (strcmp(*argv,"-")==0) found_change=-1;
- else {
- if (s-*argv > max_file_name_length-4)
- @<Complain about argument length@>;
- if (dot_pos==NULL)
- sprintf(change_file_name,"%s.ch",*argv);
- else strcpy(change_file_name,*argv);
- found_change=1;
- }
-}
-
-@ @<Override...@>=
-{
- if (s-*argv > max_file_name_length-5)
- @<Complain about argument length@>;
- if (dot_pos==NULL) {
- sprintf(tex_file_name,"%s.tex",*argv);
- sprintf(idx_file_name,"%s.idx",*argv);
- sprintf(scn_file_name,"%s.scn",*argv);
- sprintf(C_file_name,"%s.c",*argv);
- } else {
- strcpy(tex_file_name,*argv);
- strcpy(C_file_name,*argv);
- if (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
-@<Pred...@>=
-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)) @<Handle flag argument@>@;
- 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) @<Make
- |web_file_name|, |tex_file_name| and |C_file_name|@>@;
- else if (!found_change) @<Make |change_file_name| from |fname|@>@;
- else if (!found_out) @<Override |tex_file_name| and |C_file_name|@>@;
- else @<Print usage error message and quit@>;
- }
- }
- if (!found_web) @<Print usage error message and quit@>;
- 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
+@<Make |web_file_name|...@>=
+{
+ if (s-*argv > max_file_name_length-5)
+ @<Complain about argument length@>@;
+ 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
@<Make |web_file_name|...@>=
{
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
@ @<Make |change_file_name|...@>=
{
- if (strcmp(*argv,"-")==0) found_change=-1;
- else {
+ if (strcmp(*argv,"-")!=0) {
+ if (s-*argv > max_file_name_length-4)
+ @<Complain about argument length@>@;
+ if (dot_pos==NULL)
+ sprintf(change_file_name,"%s.ch",*argv);
+ else strcpy(change_file_name,*argv);
+ }
+ found_change=true;
+}
+@y
+@ @<Make |change_file_name|...@>=
+{
+ if (strcmp(*argv,"-")!=0) {
if (s-*argv > max_file_name_length-4)
@<Complain about argument length@>;
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
+@ @<Override...@>=
+{
+ if (s-*argv > max_file_name_length-5)
+ @<Complain about argument length@>@;
+ if (dot_pos==NULL) {
+ sprintf(tex_file_name,"%s.tex",*argv);
+ sprintf(idx_file_name,"%s.idx",*argv);
+ sprintf(scn_file_name,"%s.scn",*argv);
+ sprintf(C_file_name,"%s.c",*argv);
+ } else {
+ strcpy(tex_file_name,*argv);
+ strcpy(C_file_name,*argv);
+ if (make_xrefs) { /* indexes will be generated */
+ *dot_pos=0;
+ sprintf(idx_file_name,"%s.idx",*argv);
+ sprintf(scn_file_name,"%s.scn",*argv);
+ }
+ }
+ found_out=true;
+}
+@y
@ @<Override...@>=
{
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 <ctype.h>
+@x section 3 (01-FEB-1992 ST)
+#include <ctype.h> /* definition of |@!isalpha|, |@!isdigit| and so on */
+#include <stdbool.h> /* definition of |@!bool|, |@!true| and |@!false| */
+#include <stddef.h> /* definition of |@!ptrdiff_t| */
+#include <stdint.h> /* definition of |@!uint8_t| and |@!uint16_t| */
+#include <stdlib.h> /* definition of |@!getenv| and |@!exit| */
+#include <stdio.h> /* definition of |@!printf| and friends */
+#include <string.h> /* 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 <stdio.h>
-@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 files@>=
-#include <ctype.h>
+extern boolean names_match(name_pointer,const char *,size_t,eight_bits);@/
@y
-@<Include files@>=
-#include <ctype.h>
-#include <string.h>
+extern boolean __cdecl names_match(name_pointer,const char *,size_t,eight_bits);@/
@z
@x
-@ @<Predec...@>=
-extern int names_match();
+extern void init_p(name_pointer,eight_bits);@/
@y
-@ @<Predec...@>=
-extern int __cdecl names_match();
+extern void __cdecl init_p(name_pointer,eight_bits);@/
@z
-@x
-@<Pred...@>=
-void init_p();
+@x section 75
+An omitted change file argument means that |"/dev/null"| should be used,
@y
-@<Pred...@>=
-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 \.{<string.h>} where others have \.{<strings.h>}.)
-
-@<Predecl...@>=
-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 <ctype.h>
-
-/*:5*//*8:*/
-#line 165 "common.w"
-
-#include <stdio.h>
-
-/*:8*//*22:*/
-#line 471 "common.w"
+/*3:*/
+#line 46 "common.h"
+#include <ctype.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
-/*: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+2)continue;
if(buffer[0]!='@')continue;
-if(xisupper(buffer[1]))buffer[1]= tolower(buffer[1]);
+if(xisupper(buffer[1]))buffer[1]= tolower((eight_bits)buffer[1]);
if(buffer[1]=='x')break;
if(buffer[1]=='y'||buffer[1]=='z'||buffer[1]=='i'){
loc= buffer+2;
@@ -406,11 +493,11 @@ err_print("! Missing @x in change file");
}
}
-/*:13*/
-#line 256 "common.w"
-;
-/*14:*/
-#line 282 "common.w"
+/*:29*/
+#line 236 "common.w"
+
+/*30:*/
+#line 264 "common.w"
do{
change_line++;
@@ -421,47 +508,47 @@ return;
}
}while(limit==buffer);
-/*:14*/
-#line 257 "common.w"
-;
-/*15:*/
-#line 292 "common.w"
+/*:30*/
+#line 237 "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 258 "common.w"
-;
+/*:31*/
+#line 238 "common.w"
+
}
-/*:12*//*16:*/
-#line 320 "common.w"
+/*:27*//*32:*/
+#line 302 "common.w"
-void
-check_change()
+static void
+check_change(void)
{
int n= 0;
if(lines_dont_match)return;
-change_pending= 0;
+change_pending= false;
if(!changed_section[section_count]){
-if_section_start_make_pending(1);
-if(!change_pending)changed_section[section_count]= 1;
+if_section_start_make_pending(true);
+if(!change_pending)changed_section[section_count]= true;
}
-while(1){
-changing= 1;print_where= 1;change_line++;
+while(true){
+changing= true;print_where= true;change_line++;
if(!input_ln(change_file)){
err_print("! Change file ended before @y");
-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];
-/*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(++i<last)h= (h+h+(int)((unsigned char)*i))%hash_size;
+h= (eight_bits)*i;
+while(++i<last)h= (h+h+(int)((eight_bits)*i))%hash_size;
-/*:36*/
-#line 673 "common.w"
-;
-/*37:*/
-#line 691 "common.w"
+/*:49*/
+#line 652 "common.w"
+
+/*50:*/
+#line 670 "common.w"
p= hash[h];
while(p&&!names_match(p,first,l,t))p= p->link;
@@ -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<k1&&j<j1&&*j==*k)k++,j++;
@@ -814,20 +903,20 @@ else if(*j<*k)return less;
else return greater;
}
-/*:45*//*47:*/
-#line 855 "common.w"
+/*:56*//*57:*/
+#line 808 "common.w"
-name_pointer
-add_section_name(par,c,first,last,ispref)
-name_pointer par;
-int c;
-char*first;
-char*last;
-int ispref;
+static name_pointer
+add_section_name(
+name_pointer par,
+int c,
+char*first,
+char*last,
+int ispref)
{
name_pointer p= name_ptr;
char*s= first_chunk(p);
-int name_len= last-first+ispref;
+int name_len= (int)(last-first)+ispref;
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;
@@ -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
-@<Common code for \.{CWEAVE} and \.{CTANGLE}@>=
-typedef short boolean;
-typedef char unsigned eight_bits;
+@<Common code...@>=
+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 files@>=
-#include <stdio.h>
+@ Interface to the standard \CEE/ library:
+
+@<Include files@>=
+#include <ctype.h> /* definition of |@!isalpha|, |@!isdigit| and so on */
+#include <stdbool.h> /* definition of |@!bool|, |@!true| and |@!false| */
+#include <stddef.h> /* definition of |@!ptrdiff_t| */
+#include <stdint.h> /* definition of |@!uint8_t| and |@!uint16_t| */
+#include <stdlib.h> /* definition of |@!getenv| and |@!exit| */
+#include <stdio.h> /* definition of |@!printf| and friends */
+#include <string.h> /* 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} */
@<Common code...@>=
-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))
@<Common code...@>=
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 */
+
+@<Common code...@>=
+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 */
+
+@ @<Predecl...@>=
+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:
+@<Common code...@>=
+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
@<Common code...@>=
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();
+
+@ @<Predecl...@>=
+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)
-
-@<Common...@>=
-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@>
@<Common code...@>=
-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:
-@<Common code...@>=
-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 */
+@ @<Predecl...@>=
+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? */
@<Common code...@>=
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? */
@<Common code...@>=
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:
-
-@<Common code...@>=
-extern void common_init();
+@<Predecl...@>=
+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
@<Include files@>@/
@h
-@<Definitions that should agree with \.{CTANGLE} and \.{CWEAVE}@>@/
-@<Other definitions@>@/
-@<Predeclaration of procedures@>@/
+@<Common code for \.{CWEAVE} and \.{CTANGLE}@>@/
+@<Global variables@>@/
+@<Predeclaration of procedures@>
+
+@ 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
-
-@<Definitions...@>=
-typedef short boolean;
+@<Global var...@>=
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.
-@<Other...@>= int phase; /* which phase are we in? */
+@<Global var...@>=
+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)
{
- @<Initialize pointers@>;
- @<Set the default options common to \.{CTANGLE} and \.{CWEAVE}@>;
- @<Scan arguments and open output files@>;
+ @<Initialize pointers@>@;
+ @<Set the default options common to \.{CTANGLE} and \.{CWEAVE}@>@;
+ @<Scan arguments and open output files@>@;
}
@* The character set.
\.{CWEB} uses the conventions of \CEE/ programs found in the standard
\.{ctype.h} header file.
-@<Include files@>=
-#include <ctype.h>
+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} */
+@<Global var...@>=
+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))
-
-@<Definitions...@>=
+@<Global var...@>=
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 files@>=
-#include <stdio.h>
+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;
}
+@ @<Predecl...@>=@+static boolean input_ln(FILE *);
+
@ Now comes the problem of deciding which file to read from next.
Recall that the actual text that \.{CWEB} should process comes from two
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 */
-
-@<Definitions...@>=
+@<Global var...@>=
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)))
-@<Other...@>=
-char change_buffer[buf_size]; /* next line of |change_file| */
-char *change_limit; /* points to the last character in |change_buffer| */
+@<Global var...@>=
+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 */
- @<Skip over comment lines in the change file; |return| if end of file@>;
- @<Skip to the next nonblank line; |return| if end of file@>;
- @<Move |buffer| and |limit| to |change_buffer| and |change_limit|@>;
+ @<Skip over comment lines in the change file; |return| if end of file@>@;
+ @<Skip to the next nonblank line; |return| if end of file@>@;
+ @<Move |buffer| and |limit| to |change_buffer| and |change_limit|@>@;
}
+@ @<Predecl...@>=@+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).
@<Skip over comment lines in the change file...@>=
-while(1) {
+while(true) {
change_line++;
if (!input_ln(change_file)) return;
if (limit<buffer+2) continue;
if (buffer[0]!='@@') continue;
- if (xisupper(buffer[1])) buffer[1]=tolower(buffer[1]);
+ if (xisupper(buffer[1])) buffer[1]=tolower((eight_bits)buffer[1]);
if (buffer[1]=='x') break;
if (buffer[1]=='y' || buffer[1]=='z' || buffer[1]=='i') {
loc=buffer+2;
@@ -291,12 +273,12 @@ do {
@ @<Move |buffer| and |limit| to |change_buffer| and |change_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<limit|, i.e., when the
current line is nonempty.
@@ -318,36 +300,36 @@ current line is nonempty.
}
@c
-void
-check_change() /* switches to |change_file| if the buffers match */
+static void
+check_change(void) /* switches to |change_file| if the buffers match */
{
int n=0; /* the number of discrepancies found */
if (lines_dont_match) return;
- change_pending=0;
+ change_pending=false;
if (!changed_section[section_count]) {
- if_section_start_make_pending(1);
- if (!change_pending) changed_section[section_count]=1;
+ if_section_start_make_pending(true);
+ if (!change_pending) changed_section[section_count]=true;
}
- while (1) {
- changing=1; print_where=1; change_line++;
+ while (true) {
+ changing=true; print_where=true; change_line++;
if (!input_ln(change_file)) {
err_print("! Change file ended before @@y");
@.Change file ended...@>
- 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];
@<If the current line starts with \.{@@y},
- report any discrepancies and |return|@>;
+ report any discrepancies and |return|@>@;
}
- @<Move |buffer| and |limit|...@>;
- changing=0; cur_line++;
+ @<Move |buffer| and |limit|...@>@;
+ 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 */
}
}
+@ @<Predecl...@>=@+static void check_change(void);
+
@ @<If the current line starts with \.{@@y}...@>=
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]=' ';
- @<Open input files@>;
+ @<Open input files@>@;
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 */
-
-@<Defin...@>=
-typedef unsigned short sixteen_bits;
+@<Global var...@>=
sixteen_bits section_count; /* the current section number */
boolean changed_section[max_sections]; /* is the section changed? */
boolean change_pending; /* if the current change is not yet recorded in
|changed_section[section_count]| */
-boolean print_where=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)
- @<Read from |change_file| and maybe turn off |changing|@>;
+ @<Read from |change_file| and maybe turn off |changing|@>@;
if (! changing || include_depth>change_depth) {
- @<Read from |cur_file| and maybe turn on |changing|@>;
+ @<Read from |cur_file| and maybe turn on |changing|@>@;
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 */
- @<Try to open include file, abort push if unsuccessful, go to |restart|@>;
+ @<Try to open include file, abort push if unsuccessful, go to |restart|@>@;
}
- 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...@>=
-#include <stdlib.h> /* declaration of |getenv| and |exit| */
-
-@ @<Try to open...@>= {
+@.CWEBINPUTS@>@<Try to open...@>= {
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.
@ @<Read from |cur_file|...@>= {
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 */
-
-@<Definitions that...@>=
-typedef struct name_info {
- char *byte_start; /* beginning of the name in |byte_mem| */
- @<More elements of |name_info| structure@>@;
-} 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|.
+
+@<Global var...@>=
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|.
-@<Defini...@>=
-name_pointer name_ptr; /* first unused position in |name_dir| */
+@<Global var...@>=
char *byte_ptr; /* first unused position in |byte_mem| */
+name_pointer name_ptr; /* first unused position in |name_dir| */
@ @<Init...@>=
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.
-
-@<More elements of |name...@>=
-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 */
-@<Defini...@>=
-typedef name_pointer *hash_pointer;
+@<Global var...@>=
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 */
-@ @<Predec...@>=
-extern int names_match();
-
@ Initially all the hash lists are empty.
@<Init...@>=
@@ -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 */
- @<Compute the hash code |h|@>;
- @<Compute the name location |p|@>;
- if (p==name_ptr) @<Enter a new name into the table at position |p|@>;
- return(p);
+ l=(int)(last-first); /* compute the length */
+ @<Compute the hash code |h|@>@;
+ @<Compute the name location |p|@>@;
+ if (p==name_ptr) @<Enter a new name into the table at position |p|@>@;
+ 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|.$$
@<Compute the hash...@>=
-h=(unsigned char)*i;
-while (++i<last) h=(h+h+(int)((unsigned char)*i)) % hash_size;
+h=(eight_bits)*i;
+while (++i<last) h=(h+h+(int)((eight_bits)*i)) % hash_size;
@^high-bit character handling@>
@ 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.
-
-@<Pred...@>=
-void init_p();
-
-@ @<Enter a new name...@>= {
+@<Enter a new name...@>= {
if (byte_ptr+l>byte_mem_end) overflow("byte memory");
if (name_ptr>=name_dir_end) overflow("name");
strncpy(byte_ptr,first,l);
(++name_ptr)->byte_start=byte_ptr+=l;
- 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 */
-
-@<More elements of |name...@>=
-union {
- struct name_info *Rlink; /* right link in binary search tree for section
- names */
- char Ilk; /* used by identifiers in \.{CWEAVE} only */
-} dummy;
-
-@ @<Init...@>=
-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 */
+@<Predecl...@>=
+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<k1 && j<j1 && *j==*k) k++, j++;
@@ -849,21 +805,18 @@ differently in \.{CWEAVE} and \.{CTANGLE}; hence the
|init_node| procedure, which is defined differently in \.{cweave.w}
and \.{ctangle.w}.
-@<Prede...@>=
-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;
@<Look for matches for new name among shortest prefixes, complaining
- if more than one is found@>;
- @<If no match found, add new name to tree@>;
- @<If one match found, check for compatibility and return match@>;
+ if more than one is found@>@;
+ @<If no match found, add new name to tree@>@;
+ @<If one match found, check for compatibility and return match@>@;
}
@ 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 \.{@@<foo...@@>} as an ``extension'' of itself.
@d bad_extension 5
-@<Predec...@>=
-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|.
-
-@<More elements of |name...@>=
-char *equiv_or_xref; /* info corresponding to names */
+@ @<Predec...@>=@+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
-
-@<Definit...@>=
+@<Global var...@>=
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 |"!"|.
-@<Predecl...@>=
-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) @<Print error location based on input buffer@>;
+ if(web_file_open) @<Print error location based on input buffer@>@;
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.
-@<Prede...@>=
-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 */
- @<Print the job |history|@>;
- if (history > harmless_message) return(1);
- else return(0);
+ @<Print the job |history|@>@;
+ if (history > harmless_message) return EXIT_FAILURE;
+ else return EXIT_SUCCESS;
}
@ @<Print the job |history|@>=
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.
-@<Predec...@>=
-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? */
-
-@<Defin...@>=
+@<Global var...@>=
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|.
@<Set the default options common to \.{CTANGLE} and \.{CWEAVE}@>=
-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.
-@<Pred...@>=
-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)) @<Handle flag argument@>@;
else {
@@ -1275,13 +1188,14 @@ scan_args()
|web_file_name|, |tex_file_name|, and |C_file_name|@>@;
else if (!found_change) @<Make |change_file_name| from |fname|@>@;
else if (!found_out) @<Override |tex_file_name| and |C_file_name|@>@;
- else @<Print usage error message and quit@>;
+ else @<Print usage error message and quit@>@;
}
}
- if (!found_web) @<Print usage error message and quit@>;
- if (found_change<=0) strcpy(change_file_name,"/dev/null");
+ if (!found_web) @<Print usage error message and quit@>@;
}
+@ @<Pred...@>=@+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
@<Make |web_file_name|...@>=
{
if (s-*argv > max_file_name_length-5)
- @<Complain about argument length@>;
+ @<Complain about argument length@>@;
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;
}
@ @<Make |change_file_name|...@>=
{
- if (strcmp(*argv,"-")==0) found_change=-1;
- else {
+ if (strcmp(*argv,"-")!=0) {
if (s-*argv > max_file_name_length-4)
- @<Complain about argument length@>;
+ @<Complain about argument length@>@;
if (dot_pos==NULL)
sprintf(change_file_name,"%s.ch",*argv);
else strcpy(change_file_name,*argv);
- found_change=1;
}
+ found_change=true;
}
@ @<Override...@>=
{
if (s-*argv > max_file_name_length-5)
- @<Complain about argument length@>;
+ @<Complain about argument length@>@;
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;
}
-@ @<Handle flag...@>=
+@ @d flag_change (**argv!='-')
+@<Handle flag...@>=
{
- 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;
}
@ @<Print usage error message and quit@>=
@@ -1367,7 +1279,7 @@ else fatal(
@** Output. Here is the code that opens the output file:
@^system dependencies@>
-@<Defin...@>=
+@<Global var...@>=
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 arguments and open output files@>=
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 \.{<string.h>} where others have \.{<strings.h>}.)
-
-@<Predecl...@>=
-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 */
@<Common code...@>=
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 <dev_>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 <stdio.h>
+@x section 3 (01-FEB-1992 ST)
+#include <ctype.h> /* definition of |@!isalpha|, |@!isdigit| and so on */
+#include <stdbool.h> /* definition of |@!bool|, |@!true| and |@!false| */
+#include <stddef.h> /* definition of |@!ptrdiff_t| */
+#include <stdint.h> /* definition of |@!uint8_t| and |@!uint16_t| */
+#include <stdlib.h> /* definition of |@!getenv| and |@!exit| */
+#include <stdio.h> /* definition of |@!printf| and friends */
+#include <string.h> /* definition of |@!strlen|, |@!strcmp| and so on */
@y
-#include stdio /* VMS searches Textlibraries faster */
-@z
-
-@x section 62 (01-FEB-1992 ST)
-#include <ctype.h> /* 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 \.{<string.h>} where others have \.{<strings.h>}.)
-
-@<Predecl...@>=
-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...@>=
-#include <ctype.h> /* definition of |isalpha|, |isdigit| and so on */
-#include <stdlib.h> /* definition of |exit| */
-@y
-@ @<Include...@>=
-#include <ctype.h> /* definition of |isalpha|, |isdigit| and so on */
-#include <stdlib.h> /* definition of |exit| */
-#include <string.h>
+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 <stdio.h>
+#line 66 "ctangle.w"
-/*:6*//*62:*/
-#line 888 "ctangle.w"
+/*4:*/
+#line 46 "common.h"
#include <ctype.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
-/*: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_link<section_flag){
cur_repl= cur_repl->text_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_byte<cur_end){
a= *cur_byte++;
if(cur_byte==cur_end&&a=='\n')break;
@@ -712,18 +755,18 @@ cur_val= a-050000;cur_section= cur_val;out_char(section_number);
}
}
-protect= 0;
+protect= false;
flush_buffer();
}
-pop_level(0);
+pop_level(false);
}
-/*:47*//*49:*/
-#line 651 "ctangle.w"
+/*:54*//*55:*/
+#line 632 "ctangle.w"
static void
-out_char(cur_char)
-eight_bits cur_char;
+out_char(
+eight_bits cur_char)
{
char*j,*k;
restart:
@@ -731,26 +774,26 @@ switch(cur_char){
case'\n':if(protect&&out_state!=verbatim)C_putc(' ');
if(protect||out_state==verbatim)C_putc('\\');
flush_buffer();if(out_state!=verbatim)out_state= normal;break;
-/*53:*/
-#line 719 "ctangle.w"
+/*59:*/
+#line 700 "ctangle.w"
case identifier:
if(out_state==num_or_id)C_putc(' ');
j= (cur_val+name_dir)->byte_start;
k= (cur_val+name_dir+1)->byte_start;
while(j<k){
-if((unsigned char)(*j)<0200)C_putc(*j);
+if((eight_bits)(*j)<0200)C_putc(*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;
-/*:53*/
-#line 662 "ctangle.w"
-;
-/*54:*/
-#line 732 "ctangle.w"
+/*:59*/
+#line 643 "ctangle.w"
+
+/*60:*/
+#line 713 "ctangle.w"
case section_number:
if(cur_val> 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)k++;
if(xisspace(c)){
c= ' ';if(*(k-1)==' ')k--;
@@ -1061,22 +1108,22 @@ c= ' ';if(*(k-1)==' ')k--;
*k= c;
}
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<limit)try_loc++;
@@ -1232,14 +1279,14 @@ if(*try_loc=='=')err_print("! Missing `@ ' before a named section");
}
-/*:79*/
-#line 1244 "ctangle.w"
-;
+/*:87*/
+#line 1233 "ctangle.w"
+
a= cur_section_name-name_dir;
app_repl((a/0400)+0250);
app_repl(a%0400);
-/*77:*/
-#line 1225 "ctangle.w"
+/*85:*/
+#line 1214 "ctangle.w"
store_two_bytes(0150000);
if(changing&&include_depth==change_depth){
@@ -1250,22 +1297,22 @@ 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 1248 "ctangle.w"
-;break;
+/*:85*/
+#line 1237 "ctangle.w"
+break;
}
case output_defs_code:if(t!=section_name)err_print("! Misplaced @h");
else{
-output_defs_seen= 1;
+output_defs_seen= true;
a= output_defs_flag;
app_repl((a/0400)+0200);
app_repl(a%0400);
-/*77:*/
-#line 1225 "ctangle.w"
+/*85:*/
+#line 1214 "ctangle.w"
store_two_bytes(0150000);
if(changing&&include_depth==change_depth){
@@ -1276,17 +1323,17 @@ 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 1246 "ctangle.w"
-/*:77*/
-#line 1257 "ctangle.w"
-;
}
break;
case constant:case string:
-/*80:*/
-#line 1282 "ctangle.w"
+/*88:*/
+#line 1271 "ctangle.w"
app_repl(a);
while(id_first<id_loc){
@@ -1299,12 +1346,12 @@ app_repl(*id_first++);
}
app_repl(a);break;
-/*:80*/
-#line 1261 "ctangle.w"
-;
+/*:88*/
+#line 1250 "ctangle.w"
+
case ord:
-/*81:*/
-#line 1298 "ctangle.w"
+/*89:*/
+#line 1287 "ctangle.w"
{
int c= (eight_bits)*id_first;
if(c=='\\'){
@@ -1330,12 +1377,12 @@ case'x':
if(xisdigit(*(id_first+1)))c= *(++id_first)-'0';
else if(xisxdigit(*(id_first+1))){
++id_first;
-c= toupper(*id_first)-'A'+10;
+c= toupper((eight_bits)*id_first)-'A'+10;
}
if(xisdigit(*(id_first+1)))c= 16*c+*(++id_first)-'0';
else if(xisxdigit(*(id_first+1))){
++id_first;
-c= 16*c+toupper(*id_first)-'A'+10;
+c= 16*c+toupper((eight_bits)*id_first)-'A'+10;
}
break;
case'\\':c= '\\';break;
@@ -1354,9 +1401,9 @@ app_repl(constant);
}
break;
-/*:81*/
-#line 1263 "ctangle.w"
-;
+/*:89*/
+#line 1252 "ctangle.w"
+
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;
@@ -1364,8 +1411,8 @@ err_print("! @d, @f and @c are ignored in C text");continue;
}
case new_section:goto done;
-/*:78*/
-#line 1210 "ctangle.w"
+/*:86*/
+#line 1197 "ctangle.w"
case')':app_repl(a);
if(t==macro)app_repl(' ');
@@ -1377,23 +1424,23 @@ if(text_ptr> 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_control<definition)
@@ -1401,12 +1448,12 @@ if((next_control= skip_ahead())==section_name){
loc-= 2;next_control= get_next();
}
-/*:84*/
-#line 1374 "ctangle.w"
-;
+/*:92*/
+#line 1360 "ctangle.w"
+
if(next_control==definition){
-/*85:*/
-#line 1406 "ctangle.w"
+/*93:*/
+#line 1394 "ctangle.w"
{
while((next_control= get_next())=='\n');
if(next_control!=identifier){
@@ -1421,11 +1468,11 @@ if(*loc!='('){
app_repl(string);app_repl(' ');app_repl(string);
}
scan_repl(macro);
-cur_text->text_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)loc++;
loc+= 3;
@@ -1527,7 +1574,7 @@ if(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<limit)loc++;
@@ -1537,14 +1584,14 @@ if(loc-beg>=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
@<Include files@>@/
@h
@<Common code for \.{CWEAVE} and \.{CTANGLE}@>@/
@<Typedef declarations@>@/
-@<Global variables@>@/
-@<Predeclaration of procedures@>@/
-
-@ 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 \.{<string.h>} where others have \.{<strings.h>}.)
-
-@<Predecl...@>=
-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 */
+@<Private variables@>@/
+@<Predeclaration of procedures@>
@ \.{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;
- @<Set initial values@>;
+ @<Set initial values@>@;
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@>
-
@<Typed...@>=
typedef struct {
eight_bits *tok_start; /* pointer into |tok_mem| */
@@ -156,13 +126,13 @@ typedef struct {
} text;
typedef text *text_pointer;
-@ @<Glob...@>=
-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| */
+@ @<Private...@>=
+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| */
@ @<Set init...@>=
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 */
@ @<Set init...@>=
-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 */
-@<Glob...@>=
-text_pointer last_unnamed; /* most recent replacement text of unnamed section */
+@<Private...@>=
+static text_pointer last_unnamed; /* most recent replacement text of unnamed section */
@ @<Set init...@>= 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 */
}
+@ @<Predecl...@>=@+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 */
-@<Global...@>=
-output_state cur_state; /* |cur_end|, |cur_byte|, |cur_name|, |cur_repl|,
+@<Private...@>=
+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;
}
}
+@ @<Predecl...@>=
+static void push_level(name_pointer);@/
+static void pop_level(boolean);
+
@ When we come to the end of a replacement text, the |pop_level| subroutine
does the right thing: It either moves to the continuation of this replacement
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_link<section_flag) { /* link to a continuation */
cur_repl=cur_repl->text_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 */
-@<Global...@>=
-int cur_val; /* additional information corresponding to output token */
+@<Private...@>=
+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 @<Expand section |a-024000|, |goto restart|@>;
+ else @<Expand section |a-024000|, |goto restart|@>@;
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| */
}
}
+@ @<Predecl...@>=@+static void get_output(void);
+
@ The user may have forgotten to give any \CEE/ text for a section name,
or the \CEE/ text may have been associated with a different name by mistake.
@<Expand section |a-...@>=
{
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: <section name>@>
}
@@ -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 */
-@<Global...@>=
-eight_bits out_state; /* current status of partial output */
-boolean protect; /* should newline characters be quoted? */
+@<Private...@>=
+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++;
}
+@ @<Predecl...@>=@+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
-@<Glob...@>=
-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 */
+@<Private...@>=
+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.
-@<Predecl...@>=
-void phase_two();
-
-@ @c
-void
-phase_two () {
- web_file_open=0;
+@c
+static void
+phase_two (void) {
+ web_file_open=false;
cur_line=1;
- @<Initialize the output stacks@>;
- @<Output macro definitions if appropriate@>;
+ @<Initialize the output stacks@>@;
+ @<Output macro definitions if appropriate@>@;
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: @<Write all the named output files@>;
- if(show_happiness) printf("\nDone.");
+writeloop: @<Write all the named output files@>@;
+ if (show_happiness) {
+ if (show_progress) new_line;
+ fputs("Done.",stdout);
+ }
}
}
+@ @<Predecl...@>=@+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();
-@ @<Glob...@>=
-boolean output_defs_seen=0;
+@ @<Private...@>=
+static boolean output_defs_seen=false;
@ @<Predecl...@>=
-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<cur_end) {
a=*cur_byte++;
if (cur_byte==cur_end && a=='\n') break; /* disregard a final newline */
@@ -634,10 +618,10 @@ output_defs()
/* no other cases */
}
}
- protect=0;
+ protect=false;
flush_buffer();
}
- pop_level(0);
+ pop_level(false);
}
@ A many-way switch is used to send the output. Note that this function
@@ -645,13 +629,10 @@ is not called if |out_state==verbatim|, except perhaps with arguments
|'\n'| (protect the newline), |string| (end the string), or |constant|
(end the constant).
-@<Predecl...@>=
-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@>@<Case of an identifier@>;
- @/@t\4@>@<Case of a section number@>;
- @/@t\4@>@<Cases like \.{!=}@>;
+ @/@t\4@>@<Case of an identifier@>@;
+ @/@t\4@>@<Case of a section number@>@;
+ @/@t\4@>@<Cases like \.{!=}@>@;
case '=': case '>': C_putc(cur_char); C_putc(' ');
out_state=normal; break;
case join: out_state=unbreakable; break;
@@ -679,22 +660,22 @@ restart:
}
@ @<Cases like \.{!=}@>=
-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
-@<Glo...@>=
-char translit[128][translit_length];
+@<Private...@>=
+static char translit[128][translit_length];
@ @<Set init...@>=
{
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));
}
@ @<Case of an identifier@>=
@@ -722,9 +703,9 @@ case identifier:
j=(cur_val+name_dir)->byte_start;
k=(cur_val+name_dir+1)->byte_start;
while (j<k) {
- if ((unsigned char)(*j)<0200) C_putc(*j);
+ if ((eight_bits)(*j)<0200) C_putc(*j);
@^high-bit character handling@>
- 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 `\.{@@*}' */
-@<Global...@>=
-eight_bits ccode[256]; /* meaning of a char following \.{@@} */
+@<Private...@>=
+static eight_bits ccode[256]; /* meaning of a char following \.{@@} */
@ @<Set ini...@>= {
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;
}
}
}
+@ @<Predecl...@>=
+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 `\.{@@*}'.
-@<Global...@>=
-boolean comment_continues=0; /* are we scanning a comment? */
+@<Private...@>=
+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
-@<Global...@>=
-name_pointer cur_section_name; /* name of section just scanned */
-int no_where; /* suppress |print_where|? */
-
-@ @<Include...@>=
-#include <ctype.h> /* definition of |isalpha|, |isdigit| and so on */
-#include <stdlib.h> /* definition of |exit| */
+@<Private...@>=
+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;
- @<Insert the line number into |tok_mem|@>;
+ print_where=false;
+ @<Insert the line number into |tok_mem|@>@;
}
- 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=='.') @<Get a constant@>@;
- 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)=='"')))
@<Get a string@>@;
else if (isalpha(c) || isxalpha(c) || ishigh(c))
@<Get an identifier@>@;
@@ -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: @<Compress two-symbol operator@>@;
- return(c);
+ return c;
}
}
+@ @<Predecl...@>=@+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
@<Compress tw...@>=
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;
}
@ @<Get an identifier@>= {
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;
}
@ @<Get a constant@>= {
@@ -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);
- @<Scan the section name and make |cur_section_name| point to it@>;
- case string: @<Scan a verbatim string@>;
- case ord: @<Scan an ASCII constant@>;
- default: return(c);
+ @<Scan the section name and make |cur_section_name| point to it@>@;
+ case string: @<Scan a verbatim string@>@;
+ case ord: @<Scan an ASCII constant@>@;
+ default: return c;
}
}
@@ -1093,18 +1080,18 @@ thus, \.{@@'\\nopq'} gives the same result as \.{@@'\\n'}.
}
}
loc++;
- return(ord);
+ return ord;
@ @<Scan the section name...@>= {
char *k; /* pointer into |section_text| */
- @<Put section name into |section_text|@>;
+ @<Put section name 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=='(')
@<If it's not there, add |cur_section_name| to the output file stack, or
- complain we're out of room@>;
- 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.)
@ @<Put section 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;
- @<If end of name or erroneous nesting, |break|@>;
+ @<If end of name or erroneous nesting, |break|@>@;
loc++; if (k<section_text_end) k++;
if (xisspace(c)) {
c=' '; if (*(k-1)==' ') k--;
@@ -1132,7 +1119,7 @@ while (1) {
*k=c;
}
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;}
-@<Global...@>=
-text_pointer cur_text; /* replacement text formed by |scan_repl| */
-eight_bits next_control;
+@<Private...@>=
+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) {@<Insert the line number into |tok_mem|@>;}
- while (1) switch (a=get_next()) {
+ if (t==section_name) {@<Insert the line number into |tok_mem|@>@;}
+ while (true) switch (a=get_next()) {
@<In cases that |a| is a non-|char| token (|identifier|,
|section_name|, etc.), either process it and change |a| to a byte
that should be stored, or |continue| if |a| should be ignored,
@@ -1218,6 +1205,8 @@ eight_bits t;
cur_text=text_ptr; (++text_ptr)->tok_start=tok_ptr;
}
+@ @<Predecl...@>=@+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);}
@ @<In cases that |a| is...@>=
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 {
- @<Was an `@@' missed here?@>;
+ @<Was an `\.{@@}' missed here?@>@;
a=cur_section_name-name_dir;
app_repl((a / 0400)+0250);
app_repl(a % 0400);
- @<Insert the line number into |tok_mem|@>; break;
+ @<Insert the line number into |tok_mem|@>@; 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);
- @<Insert the line number into |tok_mem|@>;
+ @<Insert the line number into |tok_mem|@>@;
}
break;
case constant: case string:
- @<Copy a string or verbatim construction or numerical constant@>;
+ @<Copy a string or verbatim construction or numerical constant@>@;
case ord:
- @<Copy an ASCII constant@>;
+ @<Copy an ASCII constant@>@;
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;
-@ @<Was an `@@'...@>= {
+@ @<Was an `\.{@@}'...@>= {
char *try_loc=loc;
while (*try_loc==' ' && try_loc<limit) try_loc++;
if (*try_loc=='+' && try_loc<limit) try_loc++;
@@ -1320,12 +1309,12 @@ code internally.
if (xisdigit(*(id_first+1))) c=*(++id_first)-'0';
else if (xisxdigit(*(id_first+1))) {
++id_first;
- c=toupper(*id_first)-'A'+10;
+ c=toupper((eight_bits)*id_first)-'A'+10;
}
if (xisdigit(*(id_first+1))) c=16*c+*(++id_first)-'0';
else if (xisxdigit(*(id_first+1))) {
++id_first;
- c=16*c+toupper(*id_first)-'A'+10;
+ c=16*c+toupper((eight_bits)*id_first)-'A'+10;
}
break;
case '\\':c='\\';@+break;
@@ -1350,28 +1339,25 @@ sensed in the input, and it proceeds until the end of that section. It
uses |section_count| to keep track of the current section number; with luck,
\.{CWEAVE} and \.{CTANGLE} will both assign the same numbers to sections.
-@<Global...@>=
-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) {
@<Skip ahead until |next_control| corresponds to \.{@@d}, \.{@@<},
- \.{@@\ } or the like@>;
+ \.{@@\ } or the like@>@;
if (next_control == definition) { /* \.{@@d} */
@<Scan a definition@>@;
continue;
@@ -1381,15 +1367,17 @@ scan_section()
}
if (next_control == section_name) { /* \.{@@<} or \.{@@(} */
p=cur_section_name;
- @<If section is not being defined, |continue| @>;
+ @<If section is not being defined, |continue| @>@;
break;
}
return; /* \.{@@\ } or \.{@@*} */
}
- no_where=print_where=0;
- @<Scan the \CEE/ part of the current section@>;
+ no_where=print_where=false;
+ @<Scan the \CEE/ part of the current section@>@;
}
+@ @<Predecl...@>=@+static void scan_section(void);
+
@ At the top of this loop, if |next_control==section_name|, the
section name has already been scanned (see |@<Get control code
and...@>|). Thus, if we encounter |next_control==section_name| in the
@@ -1404,7 +1392,7 @@ while (next_control<definition)
}
@ @<Scan a definition@>= {
- 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_control<definition)
app_repl(string); app_repl(' '); app_repl(string);
}
scan_repl(macro);
- cur_text->text_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 the \CEE/...@>=
-@<Insert the section number into |tok_mem|@>;
+@<Insert the section number into |tok_mem|@>@;
scan_repl(section_name); /* now |cur_text| points to the replacement text */
-@<Update the data structure so that the replacement text is accessible@>;
+@<Update the data structure so that the replacement text is accessible@>@;
@ @<Insert the section number...@>=
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 */
-@ @<Predec...@>=
-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;
}
+@ @<Predec...@>=@+static void phase_one(void);
+
@ Only a small subset of the control codes is legal in limbo, so limbo
processing is straightforward.
-@<Predecl...@>=
-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: @<Read in transliteration of a character@>; break;
+ case translit_code: @<Read in transliteration of a character@>@; break;
case format_code: case '@@': break;
case control_text: if (c=='q' || c=='Q') {
while ((c=skip_ahead())=='@@');
@@ -1507,6 +1491,8 @@ skip_limbo()
}
}
+@ @<Predecl...@>=@+static void skip_limbo(void);
+
@ @<Read in transliteration of a character@>=
while(xisspace(*loc)&&loc<limit) loc++;
loc+=3;
@@ -1515,7 +1501,7 @@ skip_limbo()
err_print("! Improper hex number following @@l");
@.Improper hex number...@>
else {
- unsigned i;
+ unsigned int i;
char *beg;
sscanf(loc-3,"%x",&i);
while(xisspace(*loc)&&loc<limit) loc++;
@@ -1525,26 +1511,26 @@ skip_limbo()
err_print("! Replacement string in @@l too long");
@.Replacement string in @@l...@>
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 */
@<Common code...@>=
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->num<def_flag)
if (r) r->xlink=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->num<def_flag)
if (r) r->xlink=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; k<k_end; k++) {
@@ -237,66 +197,40 @@ max_tok_ptr=tok_mem+1; max_text_ptr=tok_start+1;
@z
-@x Section 116.
- append_xref(0); /* this number doesn't matter */
- xref_ptr->xlink=(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.
-@ @<Change |pp| to $\max...@>=
-@y
-@ @<Change |pp| to $\max...@>=
-#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
-@ @<Change |pp| to $\max...@>=
-@y
-@ @<Change |pp| to $\max...@>=
-#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 <dev_>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 <stdio.h>
+@x section 3 (01-FEB-1992 ST)
+#include <ctype.h> /* definition of |@!isalpha|, |@!isdigit| and so on */
+#include <stdbool.h> /* definition of |@!bool|, |@!true| and |@!false| */
+#include <stddef.h> /* definition of |@!ptrdiff_t| */
+#include <stdint.h> /* definition of |@!uint8_t| and |@!uint16_t| */
+#include <stdlib.h> /* definition of |@!getenv| and |@!exit| */
+#include <stdio.h> /* definition of |@!printf| and friends */
+#include <string.h> /* 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 <ctype.h> /* 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 \.{<string.h>} where others have \.{<strings.h>}.)
-
-@<Predecl...@>=
-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...@>=
-#include <ctype.h> /* definition of |isalpha|, |isdigit| and so on */
-#include <stdlib.h> /* definition of |exit| */
-@y
-@ @<Include...@>=
-#include <ctype.h> /* definition of |isalpha|, |isdigit| and so on */
-#include <stdlib.h> /* definition of |exit| */
-#include <string.h> /* 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 @<Include files@>@/
@h
@<Common code for \.{CWEAVE} and \.{CTANGLE}@>@/
@<Typedef declarations@>@/
-@<Global variables@>@/
+@<Private variables@>@/
@<Predeclaration of procedures@>
-@ 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 \.{<string.h>} where others have \.{<strings.h>}.)
-
-@<Predecl...@>=
-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 */
+ @<Set initial values@>@;
common_init();
- @<Set initial values@>;
- if (show_banner) printf(banner); /* print a ``banner line'' */
- @<Store all the reserved words@>;
+ @<Start \TEX/ output@>@;
+ if (show_banner) puts(banner); /* print a ``banner line'' */
+ @<Store all the reserved words@>@;
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.
-@<Global...@>=
-boolean change_exists; /* has any section changed? */
+@<Private...@>=
+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;
-@ @<Global...@>=
-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| */
+@ @<Private...@>=
+static xref_info xmem[max_refs]; /* contains cross-reference information */
+static xref_pointer xmem_end = xmem+max_refs-1;
+static xref_pointer xref_ptr; /* the largest occupied position in |xmem| */
+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
@<Set init...@>=
-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) (a<res_wd_end && a->ilk>=custom)
/* tells if uses of a name are to be indexed */
-@c
-void
-new_xref(p)
-name_pointer p;
+@<Predecl...@>=
+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|.
@<Typed...@>=
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|.
-@<Global...@>=
-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| */
+@<Private...@>=
+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| */
@ @<Set init...@>=
-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;
+}
+
+@ @<Predecl...@>=@+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|.
-@<Global...@>=
-eight_bits ccode[256]; /* meaning of a char following \.{@@} */
+@<Private...@>=
+static eight_bits ccode[256]; /* meaning of a char following \.{@@} */
@ @<Set ini...@>=
{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.
@<Predec...@>=
-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) @<Process simple format in limbo@>;
+ else if (c==format_code) @<Process simple format in limbo@>@;
}
}
}
@@ -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 */
-@<Global...@>=
-name_pointer cur_section; /* name of section just scanned */
-char cur_section_char; /* the character just before that name */
-
-@ @<Include...@>=
-#include <ctype.h> /* definition of |isalpha|, |isdigit| and so on */
-#include <stdlib.h> /* definition of |exit| */
+@<Private...@>=
+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@>
-@<Predecl...@>=
-eight_bits get_next();
-
-@ @c
-eight_bits
-get_next() /* produces the next input token */
-{@+eight_bits c; /* the current character */
- while (1) {
- @<Check if we're at the end of a preprocessor command@>;
- 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) {
+ @<Check if we're at the end of a preprocessor command@>@;
+ if (loc>limit && get_line()==false) return new_section;
c=*(loc++);
if (xisdigit(c) || c=='.') @<Get a constant@>@;
- 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))
@<Get a string@>@;
else if (xisalpha(c) || isxalpha(c) || ishigh(c))
@<Get an identifier@>@;
else if (c=='@@') @<Get control code and possible section name@>@;
else if (xisspace(c)) continue; /* ignore spaces and tabs */
- if (c=='#' && loc==buffer+1) @<Raise preprocessor flag@>;
+ if (c=='#' && loc==buffer+1) @<Raise preprocessor flag@>@;
mistake: @<Compress two-symbol operator@>@;
- return(c);
+ return c;
}
}
+@ @<Predecl...@>=@+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 */
-@<Glob...@>=
-boolean preprocessing=0; /* are we scanning a preprocessor command? */
+@<Private...@>=
+static boolean preprocessing=false; /* are we scanning a preprocessor command? */
@ @<Raise prep...@>= {
- preprocessing=1;
- @<Check if next token is |include|@>;
- return (left_preproc);
+ preprocessing=true;
+ @<Check if next token is |include|@>@;
+ 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.
-@<Glob...@>=
-boolean sharp_include_line=0; /* are we scanning a |#include| line? */
+@<Private...@>=
+static boolean sharp_include_line=false; /* are we scanning a \&{\#include} line? */
@ @<Check if next token is |include|@>=
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 \.\\.
@<Check if we're at...@>=
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
@<Compress tw...@>=
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;
}
@ @<Get an identifier@>= {
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:
- @<Scan the section name and make |cur_section| point to it@>;
- case verbatim: @<Scan a verbatim string@>;
- case ord: @<Get a string@>;
- default: return(ccode[(eight_bits)c]);
+ @<Scan the section name and make |cur_section| point to it@>@;
+ case verbatim: @<Scan a verbatim string@>@;
+ case ord: @<Get a string@>@;
+ default: return ccode[(eight_bits)c];
}
}
@@ -910,11 +900,11 @@ because the section name might (for example) follow \&{int}.
@<Scan the section name...@>= {
char *k; /* pointer into |section_text| */
cur_section_char=*(loc-1);
- @<Put section name into |section_text|@>;
+ @<Put section name into |section_text|@>@;
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.)
@ @<Put section 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;
- @<If end of name or erroneous control code, |break|@>;
+ @<If end of name or erroneous control code, |break|@>@;
loc++; if (k<section_text_end) k++;
if (xisspace(c)) {
c=' '; if (*(k-1)==' ') k--;
@@ -942,7 +932,7 @@ while (1) {
*k=c;
}
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.
-@<Predecl...@>=
-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:
}
}
+@ @<Predecl...@>=@+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.
-@<Global...@>=
-eight_bits next_control; /* control code waiting to be acting upon */
+@<Private...@>=
+static eight_bits next_control; /* control code waiting to be acting upon */
@ The overall processing strategy in phase one has the following
straightforward outline.
-@<Predecl...@>=
-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)
- @<Store cross-reference data for the current section@>;
+ @<Store cross-reference data for the current section@>@;
changed_section[section_count]=change_exists;
/* the index changes if anything does */
phase=2; /* prepare for second phase */
- @<Print error messages about unused or undefined section names@>;
+ @<Print error messages about unused or undefined section names@>@;
}
+@ @<Predecl...@>=@+static void phase_one(void);
+
@ @<Store cross-reference data...@>=
{
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 */
}
- @<Store cross-references in the \TEX/ part of a section@>;
- @<Store cross-references in the definition part of a section@>;
- @<Store cross-references in the \CEE/ part of a section@>;
- if (changed_section[section_count]) change_exists=1;
+ @<Store cross-references in the \TEX/ part of a section@>@;
+ @<Store cross-references in the definition part of a section@>@;
+ @<Store cross-references in the \CEE/ part of a section@>@;
+ 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|.
@<Predecl...@>=
-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 || next_control==spec_ctrl) {
@@ -1101,12 +1090,9 @@ C_xref( spec_ctrl ) /* makes cross-references for \CEE/ identifiers */
with |next_control!='|'| and ends with |next_control>=format_code|. Thus, it
handles \CEE/ text with embedded comments.
-@<Predecl...@>=
-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<format_code)
@@ -1129,7 +1115,7 @@ enclosed in \.{@@\^}$\,\ldots\,$\.{@@>} or \.{@@.}$\,\ldots\,$\.{@@>}
or \.{@@:}$\,\ldots\,$\.{@@>}.
@<Store cross-references in the \T...@>=
-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.
-@<Global...@>=
-name_pointer lhs, rhs; /* pointers to |byte_start| for format identifiers */
-name_pointer res_wd_end; /* pointer to the first nonreserved identifier */
+@<Private...@>=
+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 @<Process a format definition@>;
+ } else @<Process a format definition@>@;
outer_xref();
}
@@ -1205,7 +1191,7 @@ discover should be unindexed.
for (q=(xref_pointer)lhs->xref;q>xmem;q=q->xlink)
if (q->num<def_flag)
if (r) r->xlink=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.
-@<Global...@>=
-xref_pointer cur_xref; /* temporary cross-reference pointer */
-boolean an_output; /* did |file_flag| precede |cur_xref|? */
+@<Private...@>=
+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@>
-@<Predecl...@>=
-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 <def_flag) {
- printf("\n! Never defined: <"); print_section_name(p); putchar('>'); mark_harmless;
+ fputs("\n! Never defined: <",stdout);
+ print_section_name(p); putchar('>'); mark_harmless;
@.Never defined: <section name>@>
}
while (cur_xref->num >=cite_flag) cur_xref=cur_xref->xlink;
if (cur_xref==xmem && !an_output) {
- 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 name>@>
}
section_check(p->rlink);
}
}
-@ @<Print error messages about un...@>=section_check(root)
+@ @<Predecl...@>=@+static void section_check(name_pointer);
+
+@ @<Print error messages about un...@>=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.
-@<Global...@>=
-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 */
+@<Private...@>=
+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;
+@<Predecl...@>=
+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 (b<out_ptr) strncpy(out_buf+1,b+1,out_ptr-b);
+ if (b<out_ptr) memcpy(out_buf+1,b+1,(size_t)(out_ptr-b));
out_ptr-=b-out_buf;
}
@@ -1349,15 +1341,15 @@ will not be copied. The |finish_line| routine is called just before
been emitted during the output of translated \CEE/ text.
@c
-void
-finish_line() /* do this at the end of a line */
+static void
+finish_line(void) /* do this at the end of a line */
{
char *k; /* pointer into |buffer| */
- if (out_ptr>out_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}'.
-@<Set init...@>=
+@<Start \TEX/...@>=
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;
+@<Predecl...@>=
+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.
-@<Predecl...@>=
-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) @<Print warning message, break the line, |return|@>;
+ while (true) {
+ if (k==out_buf) @<Print warning message, break the line, |return|@>@;
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;
+@<Predecl...@>=
+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()
+@<Predecl...@>=
+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;}
-@<Predec...@>=
-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) @<Check for end of comment@>;
+ if (c=='|') return bal;
+ if (is_long_comment) @<Check for end of comment@>@;
if (phase==2) {
if (ishigh(c)) app_tok(quoted_char);
app_tok(c);
}
- @<Copy special things when |c=='@@', '\\'|@>;
+ @<Copy special things when |c=='@@', '\\'|@>@;
if (c=='{') bal++;
else if (c=='}') {
if(bal>1) bal--;
@@ -1586,7 +1583,7 @@ int bal; /* brace balance */
}
}
}
-done:@<Clear |bal| and |return|@>;
+done:@<Clear |bal| and |return|@>@;
}
@ @<Check for end of comment@>=
@@ -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.
@<Clear |bal|...@>=
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 /* \.{@@]} */
-@<Glo...@>=
-char cat_name[256][12];
-eight_bits cat_index;
+@<Private...@>=
+static char cat_name[256][12];
@ @<Set in...@>=
- 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);
}
+@ @<Predecl...@>=@+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 */
-@<Global...@>=
-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| */
+@<Private...@>=
+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 */
@ @<Set init...@>=
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: @<Print token |r| in symbolic form@>;
+ default: @<Print token |r| in symbolic form@>@;
}
}
- fflush(stdout);
+ update_terminal;
}
+@ @<Predecl...@>=@+static void print_text(text_pointer p);
+
@ @<Print token |r|...@>=
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))
+
+@<Private...@>=
+static int cur_mathness, init_mathness;
-@<Global...@>=
-int cur_mathness, init_mathness;
+@ @<Predecl...@>=
+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: @<Cases for |exp|@>; @+break;
- case lpar: @<Cases for |lpar|@>; @+break;
- case unop: @<Cases for |unop|@>; @+break;
- case ubinop: @<Cases for |ubinop|@>; @+break;
- case binop: @<Cases for |binop|@>; @+break;
- case cast: @<Cases for |cast|@>; @+break;
- case sizeof_like: @<Cases for |sizeof_like|@>; @+break;
- case int_like: @<Cases for |int_like|@>; @+break;
- case public_like: @<Cases for |public_like|@>; @+break;
- case colcol: @<Cases for |colcol|@>; @+break;
- case decl_head: @<Cases for |decl_head|@>; @+break;
- case decl: @<Cases for |decl|@>; @+break;
- case base: @<Cases for |base|@>; @+break;
- case struct_like: @<Cases for |struct_like|@>; @+break;
- case struct_head: @<Cases for |struct_head|@>; @+break;
- case fn_decl: @<Cases for |fn_decl|@>; @+break;
- case function: @<Cases for |function|@>; @+break;
- case lbrace: @<Cases for |lbrace|@>; @+break;
- case if_like: @<Cases for |if_like|@>; @+break;
- case else_like: @<Cases for |else_like|@>; @+break;
- case else_head: @<Cases for |else_head|@>; @+break;
- case if_clause: @<Cases for |if_clause|@>; @+break;
- case if_head: @<Cases for |if_head|@>; @+break;
- case do_like: @<Cases for |do_like|@>; @+break;
- case case_like: @<Cases for |case_like|@>; @+break;
- case catch_like: @<Cases for |catch_like|@>; @+break;
- case tag: @<Cases for |tag|@>; @+break;
- case stmt: @<Cases for |stmt|@>; @+break;
- case semi: @<Cases for |semi|@>; @+break;
- case lproc: @<Cases for |lproc|@>; @+break;
- case section_scrap: @<Cases for |section_scrap|@>; @+break;
- case insert: @<Cases for |insert|@>; @+break;
- case prelangle: @<Cases for |prelangle|@>; @+break;
- case prerangle: @<Cases for |prerangle|@>; @+break;
- case langle: @<Cases for |langle|@>; @+break;
- case template_like: @<Cases for |template_like|@>; @+break;
- case new_like: @<Cases for |new_like|@>; @+break;
- case new_exp: @<Cases for |new_exp|@>; @+break;
- case ftemplate: @<Cases for |ftemplate|@>; @+break;
- case for_like: @<Cases for |for_like|@>; @+break;
- case raw_ubin: @<Cases for |raw_ubin|@>; @+break;
- case const_like: @<Cases for |const_like|@>; @+break;
- case raw_int: @<Cases for |raw_int|@>; @+break;
- case operator_like: @<Cases for |operator_like|@>; @+break;
- case typedef_like: @<Cases for |typedef_like|@>; @+break;
- case delete_like: @<Cases for |delete_like|@>; @+break;
- case question: @<Cases for |question|@>; @+break;
+ case exp: @<Cases for |exp|@>@; @+break;
+ case lpar: @<Cases for |lpar|@>@; @+break;
+ case unop: @<Cases for |unop|@>@; @+break;
+ case ubinop: @<Cases for |ubinop|@>@; @+break;
+ case binop: @<Cases for |binop|@>@; @+break;
+ case cast: @<Cases for |cast|@>@; @+break;
+ case sizeof_like: @<Cases for |sizeof_like|@>@; @+break;
+ case int_like: @<Cases for |int_like|@>@; @+break;
+ case public_like: @<Cases for |public_like|@>@; @+break;
+ case colcol: @<Cases for |colcol|@>@; @+break;
+ case decl_head: @<Cases for |decl_head|@>@; @+break;
+ case decl: @<Cases for |decl|@>@; @+break;
+ case base: @<Cases for |base|@>@; @+break;
+ case struct_like: @<Cases for |struct_like|@>@; @+break;
+ case struct_head: @<Cases for |struct_head|@>@; @+break;
+ case fn_decl: @<Cases for |fn_decl|@>@; @+break;
+ case function: @<Cases for |function|@>@; @+break;
+ case lbrace: @<Cases for |lbrace|@>@; @+break;
+ case if_like: @<Cases for |if_like|@>@; @+break;
+ case else_like: @<Cases for |else_like|@>@; @+break;
+ case else_head: @<Cases for |else_head|@>@; @+break;
+ case if_clause: @<Cases for |if_clause|@>@; @+break;
+ case if_head: @<Cases for |if_head|@>@; @+break;
+ case do_like: @<Cases for |do_like|@>@; @+break;
+ case case_like: @<Cases for |case_like|@>@; @+break;
+ case catch_like: @<Cases for |catch_like|@>@; @+break;
+ case tag: @<Cases for |tag|@>@; @+break;
+ case stmt: @<Cases for |stmt|@>@; @+break;
+ case semi: @<Cases for |semi|@>@; @+break;
+ case lproc: @<Cases for |lproc|@>@; @+break;
+ case section_scrap: @<Cases for |section_scrap|@>@; @+break;
+ case insert: @<Cases for |insert|@>@; @+break;
+ case prelangle: @<Cases for |prelangle|@>@; @+break;
+ case prerangle: @<Cases for |prerangle|@>@; @+break;
+ case langle: @<Cases for |langle|@>@; @+break;
+ case template_like: @<Cases for |template_like|@>@; @+break;
+ case new_like: @<Cases for |new_like|@>@; @+break;
+ case new_exp: @<Cases for |new_exp|@>@; @+break;
+ case ftemplate: @<Cases for |ftemplate|@>@; @+break;
+ case for_like: @<Cases for |for_like|@>@; @+break;
+ case raw_ubin: @<Cases for |raw_ubin|@>@; @+break;
+ case const_like: @<Cases for |const_like|@>@; @+break;
+ case raw_int: @<Cases for |raw_int|@>@; @+break;
+ case operator_like: @<Cases for |operator_like|@>@; @+break;
+ case typedef_like: @<Cases for |typedef_like|@>@; @+break;
+ case delete_like: @<Cases for |delete_like|@>@; @+break;
+ case question: @<Cases for |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;
+@<Predecl...@>=
+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.
-@<Predecl...@>=
-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 && n<m) break;
q=q->xlink;
}
- @<Insert new cross-reference at |q|, not at beginning of list@>;
+ @<Insert new cross-reference at |q|, not at beginning of list@>@;
}
@ 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
@<Insert new cross-reference at |q|...@>=
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? */
-@<Cases for |stmt|@>=
+
+@<Set init...@>=
+force_lines=true;
+
+@ @<Cases for |stmt|@>=
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;
+@<Predecl...@>=
+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<scrap_base? scrap_base: pp+d);
- @<Print a snapshot of the scrap list if debugging @>;
+ @<Print a snapshot of the scrap list if debugging @>@;
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<scrap_base? scrap_base: pp+d);
- @<Print a snapshot...@>;
+ @<Print a snapshot...@>@;
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
@<Reduce the scraps using the productions until no more rules apply@>=
-while (1) {
- @<Make sure the entries |pp| through |pp+3| of |cat| are defined@>;
+while (true) {
+ @<Make sure the entries |pp| through |pp+3| of |cat| are defined@>@;
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;
- @<Match a production...@>;
+ @<Match a production...@>@;
}
@ 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.
-@<Global...@>=
-int tracing; /* can be used to show parsing details */
+@<Private...@>=
+static int tracing; /* can be used to show parsing details */
@ @<Print a snapsh...@>=
-{ 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;
- @<If tracing, print an indication of where we are@>;
- @<Reduce the scraps...@>;
- @<Combine the irreducible scraps that remain@>;
+ @<If tracing, print an indication of where we are@>@;
+ @<Reduce the scraps...@>@;
+ @<Combine the irreducible scraps that remain@>@;
}
+@ @<Predecl...@>=@+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.
@<Combine the irreducible...@>= {
- @<If semi-tracing, show the irreducible scraps@>;
+ @<If semi-tracing, show the irreducible scraps@>@;
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;
}
@ @<If semi-tracing, show the irreducible scraps@>=
@@ -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<format_code || next_control==spec_ctrl) {
- @<Append the scrap appropriate to |next_control|@>;
+ @<Append the scrap appropriate to |next_control|@>@;
next_control=get_next();
if (next_control=='|' || next_control==begin_comment ||
next_control==begin_short_comment) return;
}
}
+@ @<Predecl...@>=@+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:
}
@ @<Append the scr...@>=
-@<Make sure that there is room for the new scraps, tokens, and texts@>;
+@<Make sure that there is room for the new scraps, tokens, and texts@>@;
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: @<Append a string or constant@>;
- @+break;
- case identifier: app_cur_id(1);@+break;
- case TeX_string: @<Append a \TEX/ string, without forming a scrap@>;@+break;
+ case string: case constant: case verbatim:
+ @<Append a string or constant@>@;@+break;
+ case identifier: app_cur_id(true);@+break;
+ case TeX_string:
+ @<Append a \TEX/ string, without forming a scrap@>@;@+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@> @<Cases involving nonstandard characters@>@;
- 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.
@<Cases involving nonstandard...@>=
-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<id_loc)
app(@q{@>'}');
@ 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|.
@<Predec...@>=
-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 */
+@<Set init...@>=
+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);
- @<Make sure that there is room for the new...@>;
+ @<Make sure that there is room for the new...@>@;
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 */
-@<Global...@>=
-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| */
+@<Private...@>=
+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| */
@ @<Set init...@>=
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;
+@<Predecl...@>=
+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.
-@<Global...@>=
-name_pointer cur_name;
+@<Private...@>=
+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 */
+@<Predecl...@>=
+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.
-@<Predecl...@>=
-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: @<Output an identifier@>; break;
- case section_code: @<Output a section name@>; break;
+ case identifier: case res_word: @<Output an identifier@>@; break;
+ case section_code: @<Output a section name@>@; 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 ((a<indent && !(b==big_cancel&&a==' ')) || a>big_force) break;
if (a==indent) c++; else if (a==outdent) c--;
else if (a==opt) a=get_output();
}
- @<Output saved |indent| or |outdent| tokens@>;
+ @<Output saved |indent| or |outdent| tokens@>@;
goto reswitch;
case indent: case outdent: case opt: case backup: case break_space:
case force: case big_force: case preproc_line: @<Output a control,
- look ahead in case of line breaks, possibly |goto reswitch|@>; 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<break_space || a==preproc_line) {
@.\\8@>
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}').
@<Look ahead for st...@>= {
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) {
- @<Output saved |indent| or |outdent| tokens@>;
+ @<Output saved |indent| or |outdent| tokens@>@;
goto reswitch; /* |cancel| overrides everything */
}
if ((a!=' ' && a<indent) || a==backup || a>big_force) {
if (save_mode==outer) {
if (out_ptr>out_buf+3 && strncmp(out_ptr-3,"\\Y\\B",4)==0)
goto reswitch;
- @<Output saved |indent| or |outdent| tokens@>;
+ @<Output saved |indent| or |outdent| tokens@>@;
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}@>);
@.\\.@>
- @<Output the text of the section name@>;
+ @<Output the text of the section name@>@;
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<k_limit) {
b=*(k++);
- if (b=='@@') @<Skip next character, give error if not `\.{@@}'@>;
+ if (b=='@@') @<Skip next character, give error if not `\.{@@}'@>@;
if (an_output)
switch (b) {
case ' ':case '\\':case '#':case '%':case '$':case '^':
@@ -3891,18 +3924,18 @@ while (k<k_limit) {
@.\\\_@>
default: out(b);
}
- else if (b!='|') out(b)@;
+ else { if (b!='|') out(b)@;
else {
- @<Copy the \CEE/ text into the |buffer| array@>;
+ @<Copy the \CEE/ text into the |buffer| array@>@;
save_loc=loc; save_limit=limit; loc=limit+2; limit=j+1;
*limit='|'; output_C();
loc=save_loc; limit=save_limit;
- }
+ } }
}
@ @<Skip next char...@>=
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.
@<Copy the \CEE/ text into...@>=
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))
@<Copy a quoted character into the buffer@>@;
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.
-@<Predecl...@>=
-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) @<Translate the current section@>;
+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) @<Translate the current section@>@;
}
+@ @<Predecl...@>=@+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@>
-@<Global...@>=
-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? */
+@<Private...@>=
+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? */
@ @<Translate the current section@>= {
section_count++;
- @<Output the code for the beginning of a new section@>;
+ @<Output the code for the beginning of a new section@>@;
save_position;
- @<Translate the \TEX/ part of the current section@>;
- @<Translate the definition part of the current section@>;
- @<Translate the \CEE/ part of the current section@>;
- @<Show cross-references to this section@>;
- @<Output the code for the end of a section@>;
+ @<Translate the \TEX/ part of the current section@>@;
+ @<Translate the definition part of the current section@>@;
+ @<Translate the \CEE/ part of the current section@>@;
+ @<Show cross-references to this section@>@;
+ @<Output the code for the end of a section@>@;
}
@ 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.
@<Translate the d...@>=
-space_checked=0;
+space_checked=false;
while (next_control<=definition) { /* |format_code| or |definition| */
init_stack;
if (next_control==definition) @<Start a macro definition@>@;
- else @<Start a format definition@>;
- outer_parse(); finish_C(format_visible); format_visible=1;
- doing_format=0;
+ else @<Start a format definition@>@;
+ 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}.
-@<Predecl...@>=
-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 */
}
+@ @<Predecl...@>=@+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 `\.)'.
}
@ @<Start a format...@>= {
- 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.
-@<Global...@>=
-name_pointer this_section; /* the current section name, or zero */
+@<Private...@>=
+static name_pointer this_section; /* the current section name, or zero */
@ @<Translate the \CEE/...@>=
this_section=name_dir;
@@ -4169,13 +4202,13 @@ if (next_control<=section_name) {
else {
this_section=cur_section;
@<Check that '=' or '==' follows this section name, and
- emit the scraps to start the section definition@>;
+ emit the scraps to start the section definition@>@;
}
while (next_control<=section_name) {
outer_parse();
- @<Emit the scrap for a section name if present@>;
+ @<Emit the scrap for a section name if present@>@;
}
- finish_C(1);
+ finish_C(true);
}
@ The title of the section and an $\E$ or $\mathrel+\E$ are made
@@ -4196,8 +4229,8 @@ cur_xref=(xref_pointer)this_section->xref;
if(cur_xref->num==file_flag) cur_xref=cur_xref->xlink;
app_str("${}");
if (cur_xref->num!=section_count+def_flag) {
- app_str("\\mathrel+"); /*section name is multiply defined*/
- this_section=name_dir; /*so we won't give cross-reference info here*/
+ app_str("\\mathrel+"); /* section name is multiply defined */
+ this_section=name_dir; /* so we won't give cross-reference info here */
}
app_str("\\E"); /* output an equivalence sign */
@.\\E@>
@@ -4223,8 +4256,8 @@ after the section ends.
@<Show cross...@>=
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.
-@<Predecl...@>=
-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');
- @<Output all the section numbers on the reference list |cur_xref|@>;
+ @<Output all the section numbers on the reference list |cur_xref|@>@;
out('.');
}
+@ @<Predecl...@>=@+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.
@<Output all the section numbers...@>=
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) {
@ @<Output the code for the end of a section@>=
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.
-@<Predecl...@>=
-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) {
- @<Tell about changed sections@>; finish_line(); finish_line();
+ @<Tell about changed sections@>@; finish_line(); finish_line();
}
out_str("\\inx"); finish_line();
@.\\inx@>
active_file=idx_file; /* change active file to the index file */
- @<Do the first pass of sorting@>;
- @<Sort and output the index@>;
+ @<Do the first pass of sorting@>@;
+ @<Sort and output the index@>@;
finish_line(); fclose(active_file); /* finished with |idx_file| */
active_file=tex_file; /* switch back to |tex_file| for a tic */
out_str("\\fin"); finish_line();
@.\\fin@>
- if ((scn_file=fopen(scn_file_name,"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 */
- @<Output all the section names@>;
+ @<Output all the section names@>@;
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? */
}
+@ @<Predecl...@>=@+static void phase_three(void);
+
@ Just before the index comes a list of all the changed sections, including
the index section itself.
-@<Global...@>=
-sixteen_bits k_section; /* runs through the sections */
+@<Private...@>=
+static sixteen_bits k_section; /* runs through the sections */
@ @<Tell about changed 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.
-@<Global...@>=
-name_pointer bucket[256];
-name_pointer next_name; /* successor of |cur_name| when sorting */
-name_pointer blink[max_names]; /* links in the buckets */
+@<Private...@>=
+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.
@<Do the first pass...@>= {
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|.
-@ @<Rest of |trans_plus| union@>=
+@<Rest of |trans_plus| union@>=
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 */
-@<Global...@>=
-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| */
+@<Private...@>=
+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| */
@ @<Set init...@>=
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]$.
-@<Global...@>=
-eight_bits collate[102+128]; /* collation order */
+@<Private...@>=
+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.
@<Set init...@>=
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) */
-@<Predecl...@>=
-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;
}
}
+@ @<Predecl...@>=@+static void unbucket(eight_bits);
+
@ @<Sort and output...@>=
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)
@<Output index entries for the list at |sort_ptr|@>@;
- else @<Split the list at |sort_ptr| into further lists@>;
+ else @<Split the list at |sort_ptr| into further lists@>@;
}
@ @<Split the list...@>= {
@@ -4522,8 +4567,8 @@ while (sort_ptr>scrap_info) {
do {
out_str("\\I");
@.\\I@>
- @<Output the name at |cur_name|@>;
- @<Output the cross-references at |cur_name|@>;
+ @<Output the name at |cur_name|@>@;
+ @<Output the cross-references at |cur_name|@>@;
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\,$\.]'.
@<Output the cross-references...@>=
-@<Invert the cross-reference list at |cur_name|, making |cur_xref| the head@>;
+@<Invert the cross-reference list at |cur_name|, making |cur_xref| the head@>@;
do {
out_str(", "); cur_val=cur_xref->num;
if (cur_val<def_flag) out_section(cur_val);
@@ -4576,8 +4621,8 @@ out('.'); finish_line();
@ List inversion is best thought of as popping elements off one stack and
pushing them onto another. In this case |cur_xref| will be the head of
the stack that we push things onto.
-@<Global...@>=
-xref_pointer next_xref, this_xref;
+@<Private...@>=
+static xref_pointer next_xref, this_xref;
/* pointer variables for rearranging a list */
@ @<Invert the cross-reference list at |cur_name|, making |cur_xref| the head@>=
@@ -4591,13 +4636,10 @@ do {
prints them.
@^recursion@>
-@<Predecl...@>=
-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;
}
}
-@ @<Output all the section names@>=section_print(root)
+@ @<Predecl...@>=@+static void section_print(name_pointer);
+
+@ @<Output all the section names@>=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.
+
+@<Predecl...@>=
+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 */
- @<Skip over comment lines in the change file; |return| if end of file@>;
- @<Skip to the next nonblank line; |return| if end of file@>;
- @<Move |buffer| and |limit| to |change_buffer| and |change_limit|@>;
+ @<Skip over comment lines in the change file; |return| if end of file@>@;
+ @<Skip to the next nonblank line; |return| if end of file@>@;
+ @<Move |buffer| and |limit| to |change_buffer| and |change_limit|@>@;
}
@ 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).
@<Skip over comment lines in the change file...@>=
-while(1) {
+while(true) {
change_line++;
if (!!input_ln(change_file)) return;
if (limit<buffer+2) continue;
if (buffer[0]!!='@@') continue;
- if (xisupper(buffer[1])) buffer[1]=tolower(buffer[1]);
+ if (xisupper(buffer[1])) buffer[1]=tolower((eight_bits)buffer[1]);
if (buffer[1]=='x') break;
if (buffer[1]=='y' || buffer[1]=='z' || buffer[1]=='i') {
loc=buffer+2;
@@ -1249,10 +1257,9 @@ do {
@ @<Move |buffer| and |limit| to |change_buffer| and |change_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<buffer+2)continue;
if(buffer[0]!!='@')continue;
-if(xisupper(buffer[1]))buffer[1]= tolower(buffer[1]);
+if(xisupper(buffer[1]))buffer[1]= tolower((eight_bits)buffer[1]);
if(buffer[1]=='x')break;
if(buffer[1]=='y'||buffer[1]=='z'||buffer[1]=='i'){
loc= buffer+2;
@@ -1290,11 +1297,11 @@ err_print("!! Missing @x in change file");
}
}
-/*:13*/
-#line 252 "common.w"
-;
-/*14:*/
-#line 278 "common.w"
+/*:29*/
+#line 239 "common.w"
+
+/*30:*/
+#line 265 "common.w"
do{
change_line++;
@@ -1305,23 +1312,23 @@ return;
}
}while(limit==buffer);
-/*:14*/
-#line 253 "common.w"
-;
-/*15:*/
-#line 288 "common.w"
+/*:30*/
+#line 240 "common.w"
+
+/*31:*/
+#line 275 "common.w"
{
-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));
}
-/*:15*/
-#line 254 "common.w"
-;
+/*:31*/
+#line 241 "common.w"
+
}
-/*:12*//*16:*/
+/*:28*//*33:*/
!endgroup
\endgroup
\vfill\eject
@@ -1329,37 +1336,43 @@ strncpy(change_buffer,buffer,limit-buffer+1);
\def\runninghead{APPENDIX A --- TRANSLATION BY {\tentt CWEAVE}}
Here is the corresponding excerpt from \.{common.tex}.
+(Code for section 31 is omitted for space reasons.)
\vskip6pt
\begingroup \def\tt{\eighttt} \baselineskip9pt
\verbatim
-\M{12}Procedure \PB{\\{prime\_the\_change\_buffer}}
+\M{27}Procedure \PB{\\{prime\_the\_change\_buffer}}
sets \PB{\\{change\_buffer}} in preparation for the next matching operation.
Since blank lines in the change file are not used for matching, we have
\PB{$(\\{change\_limit}\E\\{change\_buffer}\W\R\\{changing})$} if and only if
the change file is exhausted. This procedure is called only when
-\PB{\\{changing}} is 1; hence error messages will be reported correctly.
-!vskip-.5!baselineskip
-\Y\B\&{void} \\{prime\_the\_change\_buffer}(\,)\1\1\2\2\6
+\PB{\\{changing}} is \PB{\\{true}}; hence error messages will be reported
+correctly.
+
+\Y\B\4\X7:Predeclaration of procedures\X${}\mathrel+\E{}$\6
+\&{static} \&{void} \\{prime\_the\_change\_buffer}(\&{void});\par
+\fi
+
+\M{28}\B\&{static} \&{void} \\{prime\_the\_change\_buffer}(\&{void})\1\1\2\2\6
${}\{{}$\1\6
${}\\{change\_limit}\K\\{change\_buffer}{}$;\C{ this value is used if the
change file ends }\6
-\X13:Skip over comment lines in the change file; \PB{\&{return}} if end of file%
-\X;\6
-\X14:Skip to the next nonblank line; \PB{\&{return}} if end of file\X;\6
-\X15:Move \PB{\\{buffer}} and \PB{\\{limit}} to \PB{\\{change\_buffer}} and %
-\PB{\\{change\_limit}}\X;\6
+\X29:Skip over comment lines in the change file; \PB{\&{return}} if end of file%
+\X\6
+\X30:Skip to the next nonblank line; \PB{\&{return}} if end of file\X\6
+\X31:Move \PB{\\{buffer}} and \PB{\\{limit}} to \PB{\\{change\_buffer}} and %
+\PB{\\{change\_limit}}\X\6
\4${}\}{}$\2\par
\fi
-!vskip-.5!baselineskip
-\M{13}While looking for a line that begins with \.{@x} in the change file, we
+
+\M{29}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).
-!vskip-.5!baselineskip
-\Y\B\4\X13:Skip over comment lines in the change file; \PB{\&{return}} if end
+
+\Y\B\4\X29:Skip over comment lines in the change file; \PB{\&{return}} if end
of file\X${}\E{}$\6
-\&{while} (\T{1})\5
+\&{while} (\\{true})\5
${}\{{}$\1\6
${}\\{change\_line}\PP;{}$\6
\&{if} ${}(\R\\{input\_ln}(\\{change\_file})){}$\1\5
@@ -1369,7 +1382,7 @@ ${}\\{change\_line}\PP;{}$\6
\&{if} ${}(\\{buffer}[\T{0}]\I\.{'@'}){}$\1\5
\&{continue};\2\6
\&{if} (\\{xisupper}(\\{buffer}[\T{1}]))\1\5
-${}\\{buffer}[\T{1}]\K\\{tolower}(\\{buffer}[\T{1}]);{}$\2\6
+${}\\{buffer}[\T{1}]\K\\{tolower}{}$((\&{eight\_bits}) \\{buffer}[\T{1}]);\2\6
\&{if} ${}(\\{buffer}[\T{1}]\E\.{'x'}){}$\1\5
\&{break};\2\6
\&{if} ${}(\\{buffer}[\T{1}]\E\.{'y'}\V\\{buffer}[\T{1}]\E\.{'z'}\V\\{buffer}[%
@@ -1379,11 +1392,11 @@ ${}\\{loc}\K\\{buffer}+\T{2};{}$\6
\\{err\_print}(\.{"!!\ Missing\ @x\ in\ cha}\)\.{nge\ file"});\6
\4${}\}{}$\2\6
\4${}\}{}$\2\par
-\U12.\fi
-!vskip-.5!baselineskip
-\M{14}Here we are looking at lines following the \.{@x}.
-!vskip-.5!baselineskip
-\Y\B\4\X14:Skip to the next nonblank line; \PB{\&{return}} if end of file\X${}%
+\U28.\fi
+
+\M{30}Here we are looking at lines following the \.{@x}.
+
+\Y\B\4\X30:Skip to the next nonblank line; \PB{\&{return}} if end of file\X${}%
\E{}$\6
\&{do}\5
${}\{{}$\1\6
@@ -1395,16 +1408,7 @@ ${}\{{}$\1\6
\4${}\}{}$\2\6
\4${}\}{}$\2\5
\&{while} ${}(\\{limit}\E\\{buffer}){}$;\par
-\U12.\fi
-!vskip-.5!baselineskip
-\M{15}\B\X15:Move \PB{\\{buffer}} and \PB{\\{limit}} to \PB{\\{change\_buffer}}
-and \PB{\\{change\_limit}}\X${}\E{}$\6
-${}\{{}$\1\6
-${}\\{change\_limit}\K\\{change\_buffer}-\\{buffer}+\\{limit};{}$\6
-${}\\{strncpy}(\\{change\_buffer},\39\\{buffer},\39\\{limit}-\\{buffer}+%
-\T{1});{}$\6
-\4${}\}{}$\2\par
-\Us12\ET16.\fi
+\U28.\fi
!endgroup
\endgroup
\vfil\eject
@@ -1412,33 +1416,41 @@ ${}\\{strncpy}(\\{change\_buffer},\39\\{buffer},\39\\{limit}-\\{buffer}+%
\def\runninghead{APPENDIX A --- FINAL DOCUMENT}
And here's what the same excerpt looks like when typeset.
+(Can you spot the typographical nicety used in the \.{CWEB} code?)
+\let\K=\leftarrow
-\M{12}Procedure \PB{\\{prime\_the\_change\_buffer}}
+\M{27}Procedure \PB{\\{prime\_the\_change\_buffer}}
sets \PB{\\{change\_buffer}} in preparation for the next matching operation.
Since blank lines in the change file are not used for matching, we have
\PB{$(\\{change\_limit}\E\\{change\_buffer}\W\R\\{changing})$} if and only if
the change file is exhausted. This procedure is called only when
-\PB{\\{changing}} is 1; hence error messages will be reported correctly.
+\PB{\\{changing}} is \PB{\\{true}}; hence error messages will be reported
+correctly.
-\Y\B\&{void} \\{prime\_the\_change\_buffer}(\,)\1\1\2\2\6
+\Y\B\4\X7:Predeclaration of procedures\X${}\mathrel+\E{}$\6
+\&{static} \&{void} \\{prime\_the\_change\_buffer}(\&{void});\par
+\fi
+
+\M{28}\B\&{static} \&{void} \\{prime\_the\_change\_buffer}(\&{void})\1\1\2\2\6
${}\{{}$\1\6
${}\\{change\_limit}\K\\{change\_buffer}{}$;\C{ this value is used if the
change file ends }\6
-\X13:Skip over comment lines in the change file; \PB{\&{return}} if end of file%
-\X;\6
-\X14:Skip to the next nonblank line; \PB{\&{return}} if end of file\X;\6
-\X15:Move \PB{\\{buffer}} and \PB{\\{limit}} to \PB{\\{change\_buffer}} and %
-\PB{\\{change\_limit}}\X;\6
+\X29:Skip over comment lines in the change file; \PB{\&{return}} if end of file%
+\X\6
+\X30:Skip to the next nonblank line; \PB{\&{return}} if end of file\X\6
+\X31:Move \PB{\\{buffer}} and \PB{\\{limit}} to \PB{\\{change\_buffer}} and %
+\PB{\\{change\_limit}}\X\6
\4${}\}{}$\2\par
\fi
-\M{13}While looking for a line that begins with \.{@x} in the change file, we
+\M{29}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).
+\.{@z}, or \.{@i} (which would probably mean that the change file is fouled
+up).
-\Y\B\4\X13:Skip over comment lines in the change file; \PB{\&{return}} if end
+\Y\B\4\X29:Skip over comment lines in the change file; \PB{\&{return}} if end
of file\X${}\E{}$\6
-\&{while} (\T{1})\5
+\&{while} (\\{true})\5
${}\{{}$\1\6
${}\\{change\_line}\PP;{}$\6
\&{if} ${}(\R\\{input\_ln}(\\{change\_file})){}$\1\5
@@ -1448,7 +1460,7 @@ ${}\\{change\_line}\PP;{}$\6
\&{if} ${}(\\{buffer}[\T{0}]\I\.{'@'}){}$\1\5
\&{continue};\2\6
\&{if} (\\{xisupper}(\\{buffer}[\T{1}]))\1\5
-${}\\{buffer}[\T{1}]\K\\{tolower}(\\{buffer}[\T{1}]);{}$\2\6
+${}\\{buffer}[\T{1}]\K\\{tolower}{}$((\&{eight\_bits}) \\{buffer}[\T{1}]);\2\6
\&{if} ${}(\\{buffer}[\T{1}]\E\.{'x'}){}$\1\5
\&{break};\2\6
\&{if} ${}(\\{buffer}[\T{1}]\E\.{'y'}\V\\{buffer}[\T{1}]\E\.{'z'}\V\\{buffer}[%
@@ -1458,11 +1470,11 @@ ${}\\{loc}\K\\{buffer}+\T{2};{}$\6
\\{err\_print}(\.{"!\ Missing\ @x\ in\ cha}\)\.{nge\ file"});\6
\4${}\}{}$\2\6
\4${}\}{}$\2\par
-\U12.\fi
+\U28.\fi
-\M{14}Here we are looking at lines following the \.{@x}.
+\M{30}Here we are looking at lines following the \.{@x}.
-\Y\B\4\X14:Skip to the next nonblank line; \PB{\&{return}} if end of file\X${}%
+\Y\B\4\X30:Skip to the next nonblank line; \PB{\&{return}} if end of file\X${}%
\E{}$\6
\&{do}\5
${}\{{}$\1\6
@@ -1474,17 +1486,17 @@ ${}\{{}$\1\6
\4${}\}{}$\2\6
\4${}\}{}$\2\5
\&{while} ${}(\\{limit}\E\\{buffer}){}$;\par
-\U12.\fi
+\U28.\fi
-\M{15}\B\X15:Move \PB{\\{buffer}} and \PB{\\{limit}} to \PB{\\{change\_buffer}}
+\M{31}\B\X31:Move \PB{\\{buffer}} and \PB{\\{limit}} to \PB{\\{change\_buffer}}
and \PB{\\{change\_limit}}\X${}\E{}$\6
${}\{{}$\1\6
-${}\\{change\_limit}\K\\{change\_buffer}-\\{buffer}+\\{limit};{}$\6
-${}\\{strncpy}(\\{change\_buffer},\39\\{buffer},\39\\{limit}-\\{buffer}+%
-\T{1});{}$\6
+${}\\{change\_limit}\K\\{change\_buffer}+(\&{ptrdiff\_t})(\\{limit}-%
+\\{buffer});{}$\6
+${}\\{strncpy}(\\{change\_buffer},\39\\{buffer},\39(\&{size\_t})(\\{limit}-%
+\\{buffer}+\T{1}));{}$\6
\4${}\}{}$\2\par
-\Us12\ET16.\fi
-
+\Us28\ET33.\fi
\vfil\eject\titletrue
\rightskip=0pt % get out of C mode (cf. \B)
\sfcode`;=1500 \pretolerance 200 \hyphenpenalty 50 \exhyphenpenalty 50
@@ -1579,7 +1591,7 @@ $$\lpile{\.{\\def\\topofcontents\{\\null\\vfill}\cr
\.{ { }\\titlefalse \% include headline on the contents page}\cr
\.{ { }\\def\\rheader\{\\mainfont The \{\\tt CWEAVE\}{ }processor\\hfil\}}\cr
\.{ { }\\centerline\{\\titlefont The \{\\ttitlefont CWEAVE\}{ }processor\}}\cr
- \.{ { }\\vskip 15pt \\centerline\{(Version 3.64)\}{ }\\vfill\}}\cr}$$
+ \.{ { }\\vskip 15pt \\centerline\{(Version 4.2)\}{ }\\vfill\}}\cr}$$
Redefining \.{\\rheader}, which is the headline for right-hand pages,
suffices in this case to put the desired information at the top of the
contents page.
@@ -1704,9 +1716,8 @@ with which one can say things like the following, anywhere in the \TeX\ parts
or the \CEE/ comments of a \.{CWEB} file:
$$\vbox{\halign{\.{#}\hfil\cr
You can send email to
- \\pdfURL\{the author\}\{mailto:andreas.scherer@@pobox.com\}\cr
-or visit \\pdfURL\{his home page\}\{http://www.pobox.com/%
- \\TILDE/scherer\}.\cr}}$$
+ \\pdfURL\{the author\}\{mailto:andreas\\UNDER/github@@freenet.de\}\cr
+or visit \\pdfURL\{his home page\}\{https://github.com/ascherer\}\cr}}$$
In a {\mc PDF} document, the first argument will appear in blue as
clickable text; the Acrobat reader, if correctly configured, will then
redirect those links to the user's browser and open either the
diff --git a/web/pwebmac/README.md b/web/pwebmac/README.md
index 5c3399b280..cfd345d978 100644
--- a/web/pwebmac/README.md
+++ b/web/pwebmac/README.md
@@ -3,8 +3,8 @@
The original [WEB](https://ctan.org/pkg/web) system by Donald Knuth has the
macros `webmac.tex` that produce DVI output only; for historic reasons, it
will never be modified (apart from catastrophic errors).
-Hàn Thế Thành has modified these macros in his `pdfwebmac.tex` for PDF output
-(only) with [pdfTeX](https://ctan.org/pkg/pdftex).
+Hàn Thế Thành has modified these macros in his (outdated?) `pdfwebmac.tex` for
+PDF output (only) with [pdfTeX](https://ctan.org/pkg/pdftex).
Jonathan Kew's [XeTeX](https://ctan.org/pkg/xetex) has similar macros
`xewebmac.tex` by Khaled Hosny that _modify_ `webmac.tex` for PDF output;
these macros can only be used with a specific “TeX engine” each.
@@ -29,4 +29,4 @@ clickable links and bookmarks (depending on your PDF viewer).
The `pwebmac` package is free software and may be used without constraints.
-This is version “4.5.7” of the `pwebmac` package — 2021-02-11, AS.
+This is version “4.6” of the `pwebmac` package — 2021-03-01, AS.
diff --git a/web/pwebmac/index.md b/web/pwebmac/index.md
index b7584641ce..e80680479c 100644
--- a/web/pwebmac/index.md
+++ b/web/pwebmac/index.md
@@ -1,6 +1,8 @@
---
title: C/WEB programs in “\TeX\ Live 2021”
colorlinks: true
+filecolor: blue
+urlcolor: blue
---
\raggedright
\vspace{-2\baselineskip}
diff --git a/web/pwebmac/makeall b/web/pwebmac/makeall
index b67a8af154..fbe95ae54d 100755
--- a/web/pwebmac/makeall
+++ b/web/pwebmac/makeall
@@ -235,6 +235,11 @@ FI
then $f $f # run TeX twice
else $TEX $f # run TeX twice
fi
+
+ # run TEX.WEB three times to fix table-of-contents
+ if [ tex = $f ]
+ then $TEX $f
+ fi
fi
# only XeTeX can process XETEX.WEB
@@ -353,6 +358,15 @@ then
$PAX "$OUTDIR/cweb.tar.gz" -s ,^,cweb/, \
cwebman.pdf common.pdf ctangle.pdf cweave.pdf ctwill.pdf
fi
+
+ # Notes to self:
+ # (1) Create a user-friendly central entrypoint with
+ # (a) pandoc index.md -o index.pdf
+ # (b) pandoc index.md -o index.tex;
+ # pandoc index.tex -s -o index.html;
+ # rm index.tex
+ # (2) Prepare a super-tarball from all the contents of these
+ # individual tarballs with 'pax -wzf knuth-lib.tar.gz'.
fi
exit 0
diff --git a/web/pwebmac/trapman.ch b/web/pwebmac/trapman.ch
new file mode 100644
index 0000000000..2467983cfe
--- /dev/null
+++ b/web/pwebmac/trapman.ch
@@ -0,0 +1,23 @@
+@x l.355
+\verbatim{trapin.log}
+@y
+\verbatim{mftrapin.log}
+@z
+
+@x l.365
+\verbatim{trap.log}
+@y
+\verbatim{mftrap.log}
+@z
+
+@x l.389
+\verbatim{trap.pl}
+@y
+\verbatim{mftrap.pl}
+@z
+
+@x l.398
+\verbatim{trap.fot}
+@y
+\verbatim{mftrap.fot}
+@z
diff --git a/web/pwebmac/webman.ch b/web/pwebmac/webman.ch
new file mode 100644
index 0000000000..af8b2e88ff
--- /dev/null
+++ b/web/pwebmac/webman.ch
@@ -0,0 +1,198 @@
+@x l.2
+\input webmac
+@y
+\input pwebmac
+\ifacro
+ \pdfpagewidth=\pagewidth \advance\pdfpagewidth by 2cm
+ \pdfpageheight=\pageheight \advance\pdfpageheight by 3cm
+ \ifpdftex \pdfhorigin=1cm \pdfvorigin=1cm
+ \else \advance\pdfpageheight by 1cm \global\pageshift=-1.54cm
+ \global\hoffset=-1.54cm \global\voffset=-1.54cm \fi
+\else\pageno=1\fi
+@z
+
+@x l.16
+\outer\def\section #1.{\penalty-50\vskip 12pt plus 3pt minus 3pt
+ \noindent{\bf #1.}\quad\ignorespaces}
+@y
+\newcount\destcount \destcount=1\relax
+
+\def\bkminfo{}
+\outer\def\section #1.{\penalty-50\vskip 12pt plus 3pt minus 3pt
+ \noindent\ifacro\vbox to 0pt{\kern-2.5ex\relax
+ \ifpdftex\pdfdest num \destcount fitbh\relax
+ \else\special{pdf: dest (\the\destcount) [ @thispage /FitBH @ypos ]}\fi
+ \def\.##1{##1}%
+ \ifx\bkminfo\empty\def\sectitle{#1}\else\def\sectitle{#1 (\bkminfo)}\fi
+ \ifpdftex\pdfoutline goto num \destcount {\sectitle}\relax
+ \else\special{pdf: outline 0 << /Title (\sectitle)
+ /A << /S /GoTo /D (\the\destcount) >> >>}\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