summaryrefslogtreecommitdiff
path: root/web
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2021-12-29 03:01:06 +0000
committerNorbert Preining <norbert@preining.info>2021-12-29 03:01:06 +0000
commitdce1a2a6ecd9971433b4ee24c9d36b124cc1280e (patch)
tree051072f1ec49fbe350e7f88309ab293d1806e121 /web
parentecdf859b6ce481abfd530425dcf6f0f764bd0001 (diff)
CTAN sync 202112290301
Diffstat (limited to 'web')
-rw-r--r--web/c_cpp/cweb/Makefile18
-rw-r--r--web/c_cpp/cweb/README8
-rw-r--r--web/c_cpp/cweb/comm-amiga.ch2
-rw-r--r--web/c_cpp/cweb/comm-bs.ch38
-rw-r--r--web/c_cpp/cweb/comm-mac.ch49
-rw-r--r--web/c_cpp/cweb/comm-os2.ch4
-rw-r--r--web/c_cpp/cweb/comm-pc.ch6
-rw-r--r--web/c_cpp/cweb/comm-ql.ch18
-rw-r--r--web/c_cpp/cweb/comm-vms.ch8
-rw-r--r--web/c_cpp/cweb/comm-w32.ch4
-rw-r--r--web/c_cpp/cweb/common.c427
-rw-r--r--web/c_cpp/cweb/common.h92
-rw-r--r--web/c_cpp/cweb/common.w221
-rw-r--r--web/c_cpp/cweb/ctang-bs.ch77
-rw-r--r--web/c_cpp/cweb/ctang-man.ch2
-rw-r--r--web/c_cpp/cweb/ctang-pc.ch17
-rw-r--r--web/c_cpp/cweb/ctang-ql.ch8
-rw-r--r--web/c_cpp/cweb/ctang-vms.ch10
-rw-r--r--web/c_cpp/cweb/ctang-w32.ch12
-rw-r--r--web/c_cpp/cweb/ctangle.c583
-rw-r--r--web/c_cpp/cweb/ctangle.w460
-rw-r--r--web/c_cpp/cweb/cweav-bs.ch37
-rw-r--r--web/c_cpp/cweb/cweav-man.ch2
-rw-r--r--web/c_cpp/cweb/cweav-pc.ch10
-rw-r--r--web/c_cpp/cweb/cweav-ql.ch8
-rw-r--r--web/c_cpp/cweb/cweav-vms.ch10
-rw-r--r--web/c_cpp/cweb/cweav-w32.ch12
-rw-r--r--web/c_cpp/cweb/cweave.w1375
-rw-r--r--web/c_cpp/cweb/cweb.123
-rw-r--r--web/c_cpp/cweb/cwebmac.tex32
-rw-r--r--web/c_cpp/cweb/cwebman.pdfbin335909 -> 344141 bytes
-rw-r--r--web/c_cpp/cweb/cwebman.tex123
-rw-r--r--web/c_cpp/cweb/iso_types.w95
-rw-r--r--web/c_cpp/cweb/prod.w272
34 files changed, 2201 insertions, 1862 deletions
diff --git a/web/c_cpp/cweb/Makefile b/web/c_cpp/cweb/Makefile
index 0c20d83c10..86db9f3bfc 100644
--- a/web/c_cpp/cweb/Makefile
+++ b/web/c_cpp/cweb/Makefile
@@ -1,6 +1,6 @@
# This file is part of CWEB.
# It is distributed WITHOUT ANY WARRANTY, express or implied.
-# Version 4.2 --- February 2021
+# Version 4.6 --- December 2021
# Copyright (C) 1987,1990,1993,2000 Silvio Levy and Donald E. Knuth
@@ -74,14 +74,14 @@ CWEAVE = ./cweave
CTANGLE = ./ctangle
SOURCES = cweave.w common.w ctangle.w
ALL = common.w ctangle.w cweave.w prod.w \
- Makefile common.c common.h ctangle.c \
+ Makefile README common.c common.h ctangle.c \
cwebman.tex cwebmac.tex comm-vms.ch ctang-vms.ch \
cweav-vms.ch comm-man.ch ctang-man.ch cweav-man.ch \
comm-pc.ch ctang-pc.ch cweav-pc.ch comm-amiga.ch \
- comm-bs.ch ctang-bs.ch cweav-bs.ch makefile.bs \
+ comm-bs.ch ctang-bs.ch cweav-bs.ch makefile.bs \
comm-ql.ch ctang-ql.ch cweav-ql.ch readme.ql \
comm-w32.ch ctang-w32.ch cweav-w32.ch \
- comm-os2.ch comm-mac.ch cweb.1 cweb.el c++lib.w README
+ comm-os2.ch comm-mac.ch cweb.1 cweb.el c++lib.w iso_types.w
.SUFFIXES: .dvi .tex .w .pdf
@@ -149,16 +149,16 @@ cweave.c: cweave.w $(WCHANGES) common.h prod.w
doc: $(SOURCES:.w=.dvi)
usermanual: cwebman.tex cwebmac.tex
- tex cwebman
+ $(PDF)tex cwebman
fullmanual: usermanual $(SOURCES) comm-man.ch ctang-man.ch cweav-man.ch
make cweave
./cweave common.w comm-man.ch
- tex common.tex
+ $(PDF)tex common.tex
./cweave ctangle.w ctang-man.ch
- tex ctangle.tex
+ $(PDF)tex ctangle.tex
./cweave cweave.w cweav-man.ch
- tex cweave.tex
+ $(PDF)tex cweave.tex
# be sure to leave ctangle.c and common.c for bootstrapping
clean:
@@ -183,6 +183,8 @@ install: all
- mkdir $(CWEBINPUTS)
$(CP) c++lib.w $(CWEBINPUTS)
chmod 644 $(CWEBINPUTS)/c++lib.w
+ $(CP) iso_types.w $(CWEBINPUTS)
+ chmod 644 $(CWEBINPUTS)/iso_types.w
floppy: $(ALL) examples
bar cvhf /dev/rfd0 $(ALL) examples
diff --git a/web/c_cpp/cweb/README b/web/c_cpp/cweb/README
index 081dc5aa0b..e2caca4133 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 February 2021 by Andreas Scherer
+% This README file last updated May 2021 by Andreas Scherer
% Copyright (C) 1987,1990,1993,2000,2016 Silvio Levy and Donald E. Knuth
@@ -66,14 +66,16 @@ makefile.bs
prod.w
readme.ql
c++lib.w
+iso_types.w
The file cwebman.tex is the user manual.
The examples directory contains additional examples of the use of CWEB.
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 240-page CWEB manual.
+The files c++lib.w and iso_types.w are for C++ users (say `@i c++lib.w'
+and/or `@i iso_types.w' at beginning of program).
+The files *-man.ch are used if you want to make the full 243-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.
diff --git a/web/c_cpp/cweb/comm-amiga.ch b/web/c_cpp/cweb/comm-amiga.ch
index f17c2d333b..fecfc9460c 100644
--- a/web/c_cpp/cweb/comm-amiga.ch
+++ b/web/c_cpp/cweb/comm-amiga.ch
@@ -10,7 +10,7 @@ An omitted change file argument means that |"/dev/null"| should be used,
An omitted change file argument means that |"nil:"| should be used,
@z
-@x section 76
+@x section 75
strcpy(change_file_name,"/dev/null");
@y
strcpy(change_file_name,"nil:");
diff --git a/web/c_cpp/cweb/comm-bs.ch b/web/c_cpp/cweb/comm-bs.ch
index b01b86799d..b5e1d21b9b 100644
--- a/web/c_cpp/cweb/comm-bs.ch
+++ b/web/c_cpp/cweb/comm-bs.ch
@@ -15,7 +15,7 @@ by using "huge" pointers.
(Update attempt by Andreas Scherer, 31 Jan 2021. Good luck!)
-@x Section 6.
+@x Section 9.
for section names */
@<Common code...@>=
@@ -50,7 +50,7 @@ typedef struct name_info {
union {
void huge* equiv_member;
void huge* xref_member;
- } ptr_union; /* info corresponding to names */
+ } 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 */
typedef name_pointer *hash_pointer;
@@ -136,23 +136,23 @@ name_pointer p)
@x Section 57.
static name_pointer
-add_section_name(@t\1\1@> /* install a new node in the tree */
+add_section_name( /* 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? */
+boolean ispref) /* are we adding a prefix or a full name? */
{
name_pointer p=name_ptr; /* new node */
char *s=first_chunk(p);
@y
static name_pointer
-add_section_name(@t\1\1@> /* install a new node in the tree */
+add_section_name( /* 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? */
+boolean ispref) /* are we adding a prefix or a full name? */
{
name_pointer p=name_ptr; /* new node */
char huge* s=first_chunk(p);
@@ -161,39 +161,39 @@ int ispref@t\2\2@>) /* are we adding a prefix or a full name? */
@x Section 58.
static void
-extend_section_name(@t\1\1@>
+extend_section_name(
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? */
+boolean ispref) /* are we adding a prefix or a full name? */
{
char *s;
@y
static void
-extend_section_name(@t\1\1@>
+extend_section_name(
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? */
+boolean ispref) /* are we adding a prefix or a full name? */
{
char huge* s;
@z
-@x Section 64.
-static int section_name_cmp(@t\1\1@>
+@x Section 63.
+static int section_name_cmp(
char **pfirst, /* pointer to beginning of comparison string */
-int len, /* length of string */
-name_pointer r@t\2\2@>) /* section name being compared */
+size_t len, /* length of string */
+name_pointer r) /* 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
-static int section_name_cmp(@t\1\1@>
+static int section_name_cmp(
char huge** pfirst, /* pointer to beginning of comparison string */
-int len, /* length of string */
-name_pointer r@t\2\2@>) /* section name being compared */
+size_t len, /* length of string */
+name_pointer r) /* section name being compared */
{
char huge* first=*pfirst; /* beginning of comparison string */
name_pointer q=r+1; /* access to subsequent chunks */
@@ -208,14 +208,14 @@ An omitted change file argument means that |"NUL"| should be used,
@z
-@x Section 76.
+@x Section 75.
strcpy(change_file_name,"/dev/null");
@y
strcpy(change_file_name,"NUL");
@z
-@x Section 76.
+@x Section 75.
else if (*s=='/') dot_pos=NULL,name_pos=++s;
@y
else if (*s == ':' || *s == '\\' || *s == '/')
diff --git a/web/c_cpp/cweb/comm-mac.ch b/web/c_cpp/cweb/comm-mac.ch
index aa3a77fed4..4d1382accd 100644
--- a/web/c_cpp/cweb/comm-mac.ch
+++ b/web/c_cpp/cweb/comm-mac.ch
@@ -4,27 +4,24 @@ No changes to CTANGLE or CWEAVE are needed.
(Contributed 13 Oct 2000 by AndPio@aol.com; slightly edited by Don Knuth)
@x in limbo, change the title page document to specify Mac version
- \centerline{(Version 4.2)}
+ \centerline{(Version 4.6)}
@y
- \centerline{(Version 4.2 for MacOS)}
+ \centerline{(Version 4.6 for MacOS)}
@z
-@x sections 23/24: Make input_ln accept \n, \r, \n\r, or \r\n as line endings
+@x section 23: Make input_ln accept \n, \r, \n\r, or \r\n as line endings
@ In the unlikely event that your standard I/O library does not
support |feof|, |getc|, and |ungetc| you may have to change things here.
@^system dependencies@>
-@<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 */
+@c
+static boolean input_ln( /* copies a line into |buffer| or returns |false| */
+FILE *fp) /* what file to read from */
{
- register int c=EOF; /* character read; initialized so some compilers won't complain */
- register char *k; /* where next character goes */
- if (feof(fp)) return false; /* we have hit end-of-file */
- limit = k = buffer; /* beginning of buffer */
+ register int c=EOF; /* character read; initialized so some compilers won't complain */
+ register char *k; /* where next character goes */
+ if (feof(fp)) return false; /* we have hit end-of-file */
+ limit = k = buffer; /* beginning of buffer */
while (k<=buffer_end && (c=getc(fp)) != EOF && c!='\n')
if ((*(k++) = c) != ' ') limit = k;
if (k>buffer_end)
@@ -32,7 +29,7 @@ FILE *fp@t\2\2@>) /* what file to read from */
ungetc(c,fp); loc=buffer; err_print("! Input line too long");
@.Input line too long@>
}
- if (c==EOF && limit==buffer) return false; /* there was nothing after
+ if (c==EOF && limit==buffer) return false; /* there was nothing after
the last newline */
return true;
}
@@ -45,17 +42,14 @@ line endings, so that \.{CWEB} will works with ASCII files stored in
\UNIX/, {\mc DOS} or {\mc MAC} format.
@^system dependencies@>
-@<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 */
+@c
+static boolean input_ln( /* copies a line into |buffer| or returns |false| */
+FILE *fp) /* what file to read from */
{
register int c=EOF; /* character read; initialized so some compilers won't complain */
- register char *k; /* where next character goes */
- if (feof(fp)) return false; /* we have hit end-of-file */
- limit = k = buffer; /* beginning of buffer */
+ register char *k; /* where next character goes */
+ if (feof(fp)) return false; /* we have hit end-of-file */
+ limit = k = buffer; /* beginning of buffer */
while (true) {
c = getc(fp);
if (c==EOF) return limit!=buffer; /* |false|, if there was nothing after
@@ -77,7 +71,7 @@ FILE *fp@t\2\2@>) /* what file to read from */
}
@z
-@x section 28, simply return if no change file was specified
+@x section 27, 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@>@;
@y
@@ -121,20 +115,19 @@ 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 76, make change file name empty when it is unspecified
+@x section 75, 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
+@x section 75, 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 76, use the path separator constant
+@x section 75, 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;
diff --git a/web/c_cpp/cweb/comm-os2.ch b/web/c_cpp/cweb/comm-os2.ch
index 2b85f8b1f6..d818863351 100644
--- a/web/c_cpp/cweb/comm-os2.ch
+++ b/web/c_cpp/cweb/comm-os2.ch
@@ -10,13 +10,13 @@ An omitted change file argument means that |"/dev/null"| should be used,
An omitted change file argument means that |"NUL"| should be used,
@z
-@x section 76
+@x section 75
strcpy(change_file_name,"/dev/null");
@y
strcpy(change_file_name,"NUL");
@z
-@x section 76 (this change copied from comm-pc.ch)
+@x section 75 (this change copied from comm-pc.ch)
else if (*s=='/') dot_pos=NULL,name_pos=++s;
@y
else if (*s == ':' || *s == '\\' || *s == '/')
diff --git a/web/c_cpp/cweb/comm-pc.ch b/web/c_cpp/cweb/comm-pc.ch
index 5f7d9c42ff..5a29188ed7 100644
--- a/web/c_cpp/cweb/comm-pc.ch
+++ b/web/c_cpp/cweb/comm-pc.ch
@@ -8,7 +8,7 @@ Note: The change to section 16 is not necessary if using a compiler
that allows >64K arrays.
@x section 16
-@d max_bytes 1000000 /* the number of bytes in identifiers,
+@d max_bytes 90000 /* the number of bytes in identifiers,
@y
@d max_bytes (unsigned)60000 /* the number of bytes in identifiers,
@z
@@ -19,13 +19,13 @@ An omitted change file argument means that |"/dev/null"| should be used,
An omitted change file argument means that |"NUL"| should be used,
@z
-@x section 76
+@x section 75
strcpy(change_file_name,"/dev/null");
@y
strcpy(change_file_name,"NUL");
@z
-@x section 76 (this change copied from comm-bs.ch, July 94)
+@x section 75 (this change copied from comm-bs.ch, July 94)
else if (*s=='/') dot_pos=NULL,name_pos=++s;
@y
else if (*s == ':' || *s == '\\' || *s == '/')
diff --git a/web/c_cpp/cweb/comm-ql.ch b/web/c_cpp/cweb/comm-ql.ch
index c03b9185cb..191fb51f1d 100644
--- a/web/c_cpp/cweb/comm-ql.ch
+++ b/web/c_cpp/cweb/comm-ql.ch
@@ -10,24 +10,24 @@ ex <dev_>cc;'-v -h -c -=500000 -DCWEBINPUTS=flp2_ common_c'
@x
\def\v{\char'174} % vertical (|) in typewriter font
-\def\title{Common code for CTANGLE and CWEAVE (Version 4.2)}
+\def\title{Common code for CTANGLE and CWEAVE (Version 4.6)}
\def\topofcontents{\null\vfill
\centerline{\titlefont Common code for {\ttitlefont CTANGLE} and
{\ttitlefont CWEAVE}}
\vskip 15pt
- \centerline{(Version 4.2)}
+ \centerline{(Version 4.6)}
\vfill}
\def\botofcontents{\vfill
\noindent
@y
\def\v{\char'174} % vertical (|) in typewriter font
-\def\title{Common code for CTANGLE and CWEAVE (QL Version 4.2)}
+\def\title{Common code for CTANGLE and CWEAVE (QL Version 4.6)}
\def\topofcontents{\null\vfill
\centerline{\titlefont Common code for {\ttitlefont CTANGLE} and
{\ttitlefont CWEAVE}}
\vskip 15pt
- \centerline{(Version 4.2)}
+ \centerline{(Version 4.6)}
\vfill}
\def\botofcontents{\vfill
\noindent
@@ -40,7 +40,7 @@ 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.
@x
-@d max_file_name_length 1024
+@d max_file_name_length 60
@y
@d max_file_name_length 42
@z
@@ -148,7 +148,7 @@ the routine as if it would work.
sprintf(web_file_name,"%s.w",*argv);
else {
strcpy(web_file_name,*argv);
- *dot_pos=0; /* string now ends where the dot was */
+ *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 */
@@ -166,7 +166,7 @@ the routine as if it would work.
sprintf(web_file_name,"%s_w",*argv);
else {
strcpy(web_file_name,*argv);
- *dot_pos=0; /* string now ends where the dot was */
+ *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 */
@@ -219,7 +219,7 @@ the routine as if it would work.
strcpy(tex_file_name,*argv);
strcpy(C_file_name,*argv);
if (make_xrefs) { /* indexes will be generated */
- *dot_pos=0;
+ *dot_pos='\0';
sprintf(idx_file_name,"%s.idx",*argv);
sprintf(scn_file_name,"%s.scn",*argv);
}
@@ -240,7 +240,7 @@ the routine as if it would work.
strcpy(tex_file_name,*argv);
strcpy(C_file_name,*argv);
if (make_xrefs) { /* indexes will be generated */
- *dot_pos=0;
+ *dot_pos='\0';
sprintf(idx_file_name,"%s_idx",*argv);
sprintf(scn_file_name,"%s_scn",*argv);
}
diff --git a/web/c_cpp/cweb/comm-vms.ch b/web/c_cpp/cweb/comm-vms.ch
index caf8ecef79..a5ddc252f3 100644
--- a/web/c_cpp/cweb/comm-vms.ch
+++ b/web/c_cpp/cweb/comm-vms.ch
@@ -18,8 +18,8 @@ modified:
#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 <stdlib.h> /* definition of |@!getenv| and |@!exit| */
#include <string.h> /* definition of |@!strlen|, |@!strcmp| and so on */
@y
#include ctype /* definition of |@!isalpha|, |@!isdigit| and so on */
@@ -27,14 +27,14 @@ modified:
#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 stdlib /* definition of |@!getenv| and |@!exit| */
#include string /* definition of |@!strlen|, |@!strcmp| and so on */
@z
@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.
+a status of |EXIT_SUCCESS| if and only if only harmless messages were printed.
@y
programs are started. Here, for instance, we pass VAX/VMS
a status of |SS$_NORMAL| if and only if only harmless
@@ -67,7 +67,7 @@ An omitted change file argument means that the
null device |"NL:"| should be used, when no changes are desired.
@z
-@x section 76 (1987 BL) (01-FEB-1992 ST) (05-APR-1992 DEK)
+@x section 75 (1987 BL) (01-FEB-1992 ST) (05-APR-1992 DEK)
strcpy(change_file_name,"/dev/null");
@y
strcpy(change_file_name,"NL:");
diff --git a/web/c_cpp/cweb/comm-w32.ch b/web/c_cpp/cweb/comm-w32.ch
index d256cedf12..38c209981a 100644
--- a/web/c_cpp/cweb/comm-w32.ch
+++ b/web/c_cpp/cweb/comm-w32.ch
@@ -52,13 +52,13 @@ An omitted change file argument means that |"/dev/null"| should be used,
An omitted change file argument means that |"NUL"| should be used,
@z
-@x section 76
+@x section 75
strcpy(change_file_name,"/dev/null");
@y
strcpy(change_file_name,"NUL");
@z
-@x section 76 (this change copied from comm-bs.ch, July 94)
+@x section 75 (this change copied from comm-bs.ch, July 94)
else if (*s=='/') dot_pos=NULL,name_pos=++s;
@y
else if (*s == ':' || *s == '\\' || *s == '/')
diff --git a/web/c_cpp/cweb/common.c b/web/c_cpp/cweb/common.c
index 7dd0f0c083..9e77c55f31 100644
--- a/web/c_cpp/cweb/common.c
+++ b/web/c_cpp/cweb/common.c
@@ -1,19 +1,19 @@
/*1:*/
-#line 66 "common.w"
+#line 62 "common.w"
/*3:*/
-#line 46 "common.h"
+#line 44 "common.h"
#include <ctype.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
-#include <stdlib.h>
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
/*:3*/
-#line 67 "common.w"
+#line 63 "common.w"
#define ctangle false
#define cweave true \
@@ -34,16 +34,22 @@
#define period_ast 026
#define minus_gt_ast 027 \
-#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 compress(c) if(loc++<=limit) return c \
+
+#define xisalpha(c) (isalpha((int) (c) ) &&((eight_bits) (c) <0200) )
+#define xisdigit(c) (isdigit((int) (c) ) &&((eight_bits) (c) <0200) )
+#define xisspace(c) (isspace((int) (c) ) &&((eight_bits) (c) <0200) )
+#define xislower(c) (islower((int) (c) ) &&((eight_bits) (c) <0200) )
+#define xisupper(c) (isupper((int) (c) ) &&((eight_bits) (c) <0200) )
+#define xisxdigit(c) (isxdigit((int) (c) ) &&((eight_bits) (c) <0200) )
+#define isxalpha(c) ((c) =='_'||(c) =='$') \
+
+#define ishigh(c) ((eight_bits) (c) > 0177) \
+ \
#define max_include_depth 10 \
-#define max_file_name_length 1024
+#define max_file_name_length 60
#define cur_file file[include_depth]
#define cur_file_name file_name[include_depth]
#define cur_line line[include_depth]
@@ -51,7 +57,7 @@
#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 print_id(c) term_write((c) ->byte_start,length(c) )
#define llink link
#define rlink dummy.Rlink
#define root name_dir->rlink \
@@ -61,55 +67,50 @@
#define harmless_message 1
#define error_message 2
#define fatal_message 3
-#define mark_harmless {if(history==spotless) history= harmless_message;}
+#define mark_harmless if(history==spotless) history= harmless_message
#define mark_error history= error_message
#define confusion(s) fatal("! This can't happen: ",s) \
\
#define show_banner flags['b']
#define show_progress flags['p']
-#define show_stats flags['s']
#define show_happiness flags['h']
+#define show_stats flags['s']
#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 term_write(a,b) fflush(stdout) ,fwrite(a,sizeof(char) ,b,stdout) \
-#define max_bytes 1000000 \
+#define buf_size 100
+#define longest_name 10000 \
-#define max_toks 1000000
-#define max_names 10239 \
+#define long_buf_size (buf_size+longest_name)
+#define max_bytes 90000 \
-#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 max_names 4000 \
+
+#define max_sections 2000 \
#define lines_dont_match (change_limit-change_buffer!=limit-buffer|| \
-strncmp(buffer,change_buffer,(size_t) (limit-buffer) ) ) \
+strncmp(buffer,change_buffer,(size_t) (limit-buffer) ) !=0) \
-#define if_section_start_make_pending(b) {*limit= '!'; \
+#define if_section_start_make_pending(b) \
+*limit= '!'; \
for(loc= buffer;xisspace(*loc) ;loc++) ; \
*limit= ' '; \
-if(*loc=='@'&&(xisspace(*(loc+1) ) ||*(loc+1) =='*') ) change_pending= b; \
-} \
+if(*loc=='@'&&(xisspace(*(loc+1) ) ||*(loc+1) =='*') ) change_pending= b \
#define too_long() {include_depth--; \
err_print("! Include file name too long") ;goto restart;} \
-#define hash_size 8501 \
+#define hash_size 353 \
#define first_chunk(p) ((p) ->byte_start+2)
-#define prefix_length(p) (int) ((eight_bits) *((p) ->byte_start) *256+ \
+#define prefix_length(p) (size_t) ((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) \
+#define set_prefix_length(p,m) (*((p) ->byte_start) = (char) ((m) /256) , \
+*((p) ->byte_start+1) = (char) ((m) %256) ) \
#define less 0
#define equal 1
@@ -121,10 +122,10 @@ err_print("! Include file name too long") ;goto restart;} \
#define flag_change (**argv!='-')
-#line 68 "common.w"
+#line 64 "common.w"
/*2:*/
-#line 37 "common.h"
+#line 35 "common.h"
typedef bool boolean;
typedef uint8_t eight_bits;
@@ -141,7 +142,7 @@ extern char*id_first;
extern char*id_loc;
/*:4*//*5:*/
-#line 88 "common.h"
+#line 92 "common.h"
extern char buffer[];
extern char*buffer_end;
@@ -149,7 +150,7 @@ extern char*loc;
extern char*limit;
/*:5*//*6:*/
-#line 105 "common.h"
+#line 109 "common.h"
extern int include_depth;
extern FILE*file[];
@@ -165,7 +166,7 @@ extern boolean changing;
extern boolean web_file_open;
/*:6*//*8:*/
-#line 125 "common.h"
+#line 129 "common.h"
extern sixteen_bits section_count;
extern boolean changed_section[];
@@ -173,7 +174,7 @@ extern boolean change_pending;
extern boolean print_where;
/*:8*//*9:*/
-#line 139 "common.h"
+#line 143 "common.h"
typedef struct name_info{
char*byte_start;
@@ -198,12 +199,12 @@ extern hash_pointer hash_end;
extern hash_pointer h;
/*:9*//*11:*/
-#line 183 "common.h"
+#line 187 "common.h"
extern int history;
/*:11*//*13:*/
-#line 199 "common.h"
+#line 203 "common.h"
extern int argc;
extern char**argv;
@@ -214,7 +215,7 @@ extern char scn_file_name[];
extern boolean flags[];
/*:13*//*14:*/
-#line 215 "common.h"
+#line 217 "common.h"
extern FILE*C_file;
extern FILE*tex_file;
@@ -223,20 +224,20 @@ extern FILE*scn_file;
extern FILE*active_file;
/*:14*/
-#line 69 "common.w"
+#line 65 "common.w"
/*18:*/
-#line 83 "common.w"
+#line 79 "common.w"
boolean program;
/*:18*//*19:*/
-#line 92 "common.w"
+#line 88 "common.w"
int phase;
/*:19*//*21:*/
-#line 130 "common.w"
+#line 126 "common.w"
char section_text[longest_name+1];
char*section_text_end= section_text+longest_name;
@@ -244,7 +245,7 @@ char*id_first;
char*id_loc;
/*:21*//*22:*/
-#line 150 "common.w"
+#line 146 "common.w"
char buffer[long_buf_size];
char*buffer_end= buffer+buf_size-2;
@@ -252,7 +253,7 @@ char*loc= buffer;
char*limit= buffer;
/*:22*//*25:*/
-#line 194 "common.w"
+#line 190 "common.w"
int include_depth;
FILE*file[max_include_depth];
@@ -269,13 +270,13 @@ boolean changing;
boolean web_file_open= false;
/*:25*//*26:*/
-#line 220 "common.w"
+#line 216 "common.w"
static char change_buffer[buf_size];
static char*change_limit;
/*:26*//*37:*/
-#line 399 "common.w"
+#line 393 "common.w"
sixteen_bits section_count;
boolean changed_section[max_sections];
@@ -284,7 +285,7 @@ boolean change_pending;
boolean print_where= false;
/*:37*//*43:*/
-#line 596 "common.w"
+#line 590 "common.w"
char byte_mem[max_bytes];
char*byte_mem_end= byte_mem+max_bytes-1;
@@ -292,25 +293,25 @@ name_info name_dir[max_names];
name_pointer name_dir_end= name_dir+max_names-1;
/*:43*//*44:*/
-#line 607 "common.w"
+#line 601 "common.w"
char*byte_ptr;
name_pointer name_ptr;
/*:44*//*46:*/
-#line 627 "common.w"
+#line 621 "common.w"
name_pointer hash[hash_size];
hash_pointer hash_end= hash+hash_size-1;
hash_pointer h;
/*:46*//*65:*/
-#line 1014 "common.w"
+#line 1003 "common.w"
int history= spotless;
/*:65*//*73:*/
-#line 1135 "common.w"
+#line 1126 "common.w"
int argc;
char**argv;
@@ -321,7 +322,7 @@ char scn_file_name[max_file_name_length];
boolean flags[128];
/*:73*//*83:*/
-#line 1282 "common.w"
+#line 1269 "common.w"
FILE*C_file;
FILE*tex_file;
@@ -330,22 +331,22 @@ FILE*scn_file;
FILE*active_file;
/*:83*/
-#line 70 "common.w"
+#line 66 "common.w"
/*7:*/
-#line 119 "common.h"
+#line 123 "common.h"
extern boolean get_line(void);
extern void check_complete(void);
extern void reset_input(void);
/*:7*//*10:*/
-#line 162 "common.h"
+#line 166 "common.h"
extern boolean names_match(name_pointer,const char*,size_t,eight_bits);
-extern name_pointer id_lookup(const char*,const char*,char);
+extern name_pointer id_lookup(const char*,const char*,eight_bits);
-extern name_pointer section_lookup(char*,char*,int);
+extern name_pointer section_lookup(char*,char*,boolean);
extern void init_node(name_pointer);
extern void init_p(name_pointer,eight_bits);
extern void print_prefix_name(name_pointer);
@@ -353,7 +354,7 @@ extern void print_section_name(name_pointer);
extern void sprint_section_name(char*,name_pointer);
/*:10*//*12:*/
-#line 186 "common.h"
+#line 190 "common.h"
extern int wrap_up(void);
extern void err_print(const char*);
@@ -361,50 +362,50 @@ extern void fatal(const char*,const char*);
extern void overflow(const char*);
/*:12*//*15:*/
-#line 223 "common.h"
+#line 225 "common.h"
extern void common_init(void);
extern void print_stats(void);
/*:15*//*24:*/
-#line 180 "common.w"
+#line 176 "common.w"
static boolean input_ln(FILE*);
/*:24*//*28:*/
-#line 241 "common.w"
+#line 237 "common.w"
static void prime_the_change_buffer(void);
/*:28*//*33:*/
-#line 340 "common.w"
+#line 334 "common.w"
static void check_change(void);
/*:33*//*55:*/
-#line 774 "common.w"
+#line 764 "common.w"
-static int web_strcmp(char*,int,char*,int);
-static name_pointer add_section_name(name_pointer,int,char*,char*,int);
-static void extend_section_name(name_pointer,char*,char*,int);
+static int web_strcmp(char*,size_t,char*,size_t);
+static name_pointer add_section_name(name_pointer,int,char*,char*,boolean);
+static void extend_section_name(name_pointer,char*,char*,boolean);
/*:55*//*64:*/
-#line 1002 "common.w"
-static int section_name_cmp(char**,int,name_pointer);
+#line 991 "common.w"
+static int section_name_cmp(char**,size_t,name_pointer);
/*:64*//*76:*/
-#line 1197 "common.w"
+#line 1186 "common.w"
static void scan_args(void);
/*:76*/
-#line 71 "common.w"
+#line 67 "common.w"
/*:1*//*20:*/
-#line 99 "common.w"
+#line 95 "common.w"
void
common_init(void)
{
/*45:*/
-#line 611 "common.w"
+#line 605 "common.w"
name_dir->byte_start= byte_ptr= byte_mem;
name_ptr= name_dir+1;
@@ -412,24 +413,23 @@ name_ptr->byte_start= byte_mem;
root= NULL;
/*:45*//*47:*/
-#line 634 "common.w"
+#line 628 "common.w"
for(h= hash;h<=hash_end;*h++= NULL);
/*:47*/
-#line 103 "common.w"
+#line 99 "common.w"
/*74:*/
-#line 1148 "common.w"
+#line 1139 "common.w"
show_banner= show_happiness= show_progress= make_xrefs= true;
-show_stats= false;
/*:74*/
-#line 104 "common.w"
+#line 100 "common.w"
/*84:*/
-#line 1289 "common.w"
+#line 1276 "common.w"
scan_args();
if(program==ctangle){
@@ -443,12 +443,12 @@ fatal("! Cannot open output file ",tex_file_name);
}
/*:84*/
-#line 105 "common.w"
+#line 101 "common.w"
}
/*:20*//*23:*/
-#line 160 "common.w"
+#line 156 "common.w"
static boolean input_ln(
FILE*fp)
@@ -470,21 +470,21 @@ return true;
}
/*:23*//*27:*/
-#line 231 "common.w"
+#line 227 "common.w"
static void
prime_the_change_buffer(void)
{
change_limit= change_buffer;
/*29:*/
-#line 247 "common.w"
+#line 243 "common.w"
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((eight_bits)buffer[1]);
+if(xisupper(buffer[1]))buffer[1]= tolower((int)buffer[1]);
if(buffer[1]=='x')break;
if(buffer[1]=='y'||buffer[1]=='z'||buffer[1]=='i'){
loc= buffer+2;
@@ -494,10 +494,10 @@ err_print("! Missing @x in change file");
}
/*:29*/
-#line 236 "common.w"
+#line 232 "common.w"
/*30:*/
-#line 264 "common.w"
+#line 260 "common.w"
do{
change_line++;
@@ -509,23 +509,21 @@ return;
}while(limit==buffer);
/*:30*/
-#line 237 "common.w"
+#line 233 "common.w"
/*31:*/
-#line 274 "common.w"
+#line 270 "common.w"
-{
change_limit= change_buffer+(ptrdiff_t)(limit-buffer);
strncpy(change_buffer,buffer,(size_t)(limit-buffer+1));
-}
/*:31*/
-#line 238 "common.w"
+#line 234 "common.w"
}
/*:27*//*32:*/
-#line 302 "common.w"
+#line 296 "common.w"
static void
check_change(void)
@@ -538,7 +536,7 @@ if_section_start_make_pending(true);
if(!change_pending)changed_section[section_count]= true;
}
while(true){
-changing= true;print_where= true;change_line++;
+changing= print_where= true;change_line++;
if(!input_ln(change_file)){
err_print("! Change file ended before @y");
@@ -546,9 +544,9 @@ change_limit= change_buffer;changing= false;
return;
}
if(limit> buffer+1&&buffer[0]=='@'){
-char xyz_code= xisupper(buffer[1])?tolower((eight_bits)buffer[1]):buffer[1];
+char xyz_code= xisupper(buffer[1])?tolower((int)buffer[1]):buffer[1];
/*34:*/
-#line 342 "common.w"
+#line 336 "common.w"
if(xyz_code=='x'||xyz_code=='z'){
loc= buffer+2;err_print("! Where is the matching @y?");
@@ -566,19 +564,17 @@ return;
}
/*:34*/
-#line 324 "common.w"
+#line 318 "common.w"
}
/*31:*/
-#line 274 "common.w"
+#line 270 "common.w"
-{
change_limit= change_buffer+(ptrdiff_t)(limit-buffer);
strncpy(change_buffer,buffer,(size_t)(limit-buffer+1));
-}
/*:31*/
-#line 326 "common.w"
+#line 320 "common.w"
changing= false;cur_line++;
while(!input_ln(cur_file)){
@@ -594,14 +590,14 @@ if(lines_dont_match)n++;
}
/*:32*//*35:*/
-#line 362 "common.w"
+#line 356 "common.w"
void
reset_input(void)
{
limit= buffer;loc= buffer+1;buffer[0]= ' ';
/*36:*/
-#line 377 "common.w"
+#line 371 "common.w"
if((web_file= fopen(web_file_name,"r"))==NULL){
strcpy(web_file_name,alt_web_file_name);
@@ -615,23 +611,23 @@ if((change_file= fopen(change_file_name,"r"))==NULL)
fatal("! Cannot open change file ",change_file_name);
/*:36*/
-#line 367 "common.w"
+#line 361 "common.w"
-include_depth= 0;cur_line= 0;change_line= 0;
+include_depth= cur_line= change_line= 0;
change_depth= include_depth;
-changing= 1;prime_the_change_buffer();changing= !changing;
+changing= true;prime_the_change_buffer();changing= !changing;
limit= buffer;loc= buffer+1;buffer[0]= ' ';input_has_ended= false;
}
/*:35*//*38:*/
-#line 406 "common.w"
+#line 400 "common.w"
boolean get_line(void)
{
restart:
if(changing&&include_depth==change_depth)
/*41:*/
-#line 514 "common.w"
+#line 508 "common.w"
{
change_line++;
if(!input_ln(change_file)){
@@ -648,7 +644,7 @@ changed_section[section_count]= true;change_pending= false;
}
*limit= ' ';
if(buffer[0]=='@'){
-if(xisupper(buffer[1]))buffer[1]= tolower((eight_bits)buffer[1]);
+if(xisupper(buffer[1]))buffer[1]= tolower((int)buffer[1]);
if(buffer[1]=='x'||buffer[1]=='y'){
loc= buffer+2;
err_print("! Where is the matching @z?");
@@ -662,11 +658,11 @@ prime_the_change_buffer();changing= !changing;print_where= true;
}
/*:41*/
-#line 411 "common.w"
+#line 405 "common.w"
if(!changing||include_depth> change_depth){
/*40:*/
-#line 497 "common.w"
+#line 491 "common.w"
{
cur_line++;
while(!input_ln(cur_file)){
@@ -685,7 +681,7 @@ if(change_limit> change_buffer)check_change();
}
/*:40*/
-#line 413 "common.w"
+#line 407 "common.w"
if(changing&&include_depth==change_depth)goto restart;
}
@@ -706,12 +702,12 @@ goto restart;
}
include_depth++;
/*39:*/
-#line 451 "common.w"
+#line 445 "common.w"
{
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;
-int l;
+char*kk,*k= cur_file_name;
+size_t l;
if(*loc=='"'){
loc++;
@@ -726,8 +722,8 @@ if((cur_file= fopen(cur_file_name,"r"))!=NULL){
cur_line= 0;print_where= true;
goto restart;
}
-kk= getenv("CWEBINPUTS");
-if(kk!=NULL){
+if((kk= getenv("CWEBINPUTS"))!=NULL){
+
if((l= strlen(kk))> max_file_name_length-2)too_long();
strcpy(temp_file_name,kk);
}
@@ -754,14 +750,14 @@ include_depth--;err_print("! Cannot open include file");goto restart;
}
/*:39*/
-#line 432 "common.w"
+#line 426 "common.w"
}
return true;
}
/*:38*//*42:*/
-#line 546 "common.w"
+#line 540 "common.w"
void
check_complete(void){
@@ -775,32 +771,32 @@ err_print("! Change file entry did not match");
}
/*:42*//*48:*/
-#line 639 "common.w"
+#line 633 "common.w"
name_pointer
id_lookup(
const char*first,
const char*last,
-char t)
+eight_bits t)
{
const char*i= first;
int h;
-int l;
+size_t l;
name_pointer p;
if(last==NULL)for(last= first;*last!='\0';last++);
-l= (int)(last-first);
+l= (size_t)(last-first);
/*49:*/
-#line 662 "common.w"
+#line 656 "common.w"
-h= (eight_bits)*i;
+h= (int)((eight_bits)*i);
while(++i<last)h= (h+h+(int)((eight_bits)*i))%hash_size;
/*:49*/
-#line 652 "common.w"
+#line 646 "common.w"
/*50:*/
-#line 670 "common.w"
+#line 664 "common.w"
p= hash[h];
while(p&&!names_match(p,first,l,t))p= p->link;
@@ -810,10 +806,10 @@ p->link= hash[h];hash[h]= p;
}
/*:50*/
-#line 653 "common.w"
+#line 647 "common.w"
if(p==name_ptr)/*51:*/
-#line 681 "common.w"
+#line 676 "common.w"
{
if(byte_ptr+l> byte_mem_end)overflow("byte memory");
if(name_ptr>=name_dir_end)overflow("name");
@@ -823,13 +819,13 @@ init_p(p,t);
}
/*:51*/
-#line 654 "common.w"
+#line 648 "common.w"
return p;
}
/*:48*//*52:*/
-#line 713 "common.w"
+#line 708 "common.w"
void
print_section_name(
@@ -839,18 +835,16 @@ 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,(size_t)(ss-s));p= q->link;q= p;
-}else{
-term_write(s,(size_t)(ss+1-s));p= name_dir;q= NULL;
-}
+if(*ss==' '&&ss>=s)p= q->link,q= p;
+else ss++,p= name_dir,q= NULL;
+term_write(s,(size_t)(ss-s));
s= p->byte_start;
}
if(q)term_write("...",3);
}
/*:52*//*53:*/
-#line 732 "common.w"
+#line 725 "common.w"
void
sprint_section_name(
@@ -861,11 +855,8 @@ 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){
-p= q->link;q= p;
-}else{
-ss++;p= name_dir;
-}
+if(*ss==' '&&ss>=s)p= q->link,q= p;
+else ss++,p= name_dir;
strncpy(dest,s,(size_t)(ss-s)),dest+= ss-s;
s= p->byte_start;
}
@@ -873,26 +864,26 @@ s= p->byte_start;
}
/*:53*//*54:*/
-#line 753 "common.w"
+#line 743 "common.w"
void
print_prefix_name(
name_pointer p)
{
char*s= first_chunk(p);
-int l= prefix_length(p);
+size_t l= prefix_length(p);
term_write(s,l);
if(s+l<(p+1)->byte_start)term_write("...",3);
}
/*:54*//*56:*/
-#line 779 "common.w"
+#line 769 "common.w"
static int web_strcmp(
char*j,
-int j_len,
+size_t j_len,
char*k,
-int k_len)
+size_t k_len)
{
char*j1= j+j_len,*k1= k+k_len;
while(k<k1&&j<j1&&*j==*k)k++,j++;
@@ -904,7 +895,7 @@ else return greater;
}
/*:56*//*57:*/
-#line 808 "common.w"
+#line 798 "common.w"
static name_pointer
add_section_name(
@@ -912,11 +903,11 @@ name_pointer par,
int c,
char*first,
char*last,
-int ispref)
+boolean ispref)
{
name_pointer p= name_ptr;
char*s= first_chunk(p);
-int name_len= (int)(last-first)+ispref;
+size_t name_len= (size_t)(last-first+(int)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;
@@ -928,25 +919,24 @@ name_ptr->link= name_dir;
}
set_prefix_length(p,name_len);
strncpy(s,first,name_len);
-p->llink= NULL;
-p->rlink= NULL;
+p->llink= p->rlink= NULL;
init_node(p);
return par==NULL?(root= p):c==less?(par->llink= p):(par->rlink= p);
}
/*:57*//*58:*/
-#line 837 "common.w"
+#line 826 "common.w"
static void
extend_section_name(
name_pointer p,
char*first,
char*last,
-int ispref)
+boolean ispref)
{
char*s;
name_pointer q= p+1;
-int name_len= (int)(last-first)+ispref;
+size_t name_len= (size_t)(last-first+(int)ispref);
if(name_ptr>=name_dir_end)overflow("name");
while(q->link!=name_dir)q= q->link;
q->link= name_ptr;
@@ -959,22 +949,22 @@ if(ispref)*(byte_ptr-1)= ' ';
}
/*:58*//*59:*/
-#line 865 "common.w"
+#line 854 "common.w"
name_pointer
section_lookup(
char*first,char*last,
-int ispref)
+boolean ispref)
{
-int c= 0;
+int c= less;
name_pointer p= root;
name_pointer q= NULL;
name_pointer r= NULL;
name_pointer par= NULL;
-int name_len= (int)(last-first)+1;
+size_t name_len= (size_t)(last-first+1);
/*60:*/
-#line 889 "common.w"
+#line 878 "common.w"
while(p){
c= web_strcmp(first,name_len,first_chunk(p),prefix_length(p));
@@ -1001,19 +991,19 @@ p= q,q= NULL;
}
/*:60*/
-#line 879 "common.w"
+#line 868 "common.w"
/*61:*/
-#line 914 "common.w"
+#line 903 "common.w"
if(r==NULL)
return add_section_name(par,c,first,last+1,ispref);
/*:61*/
-#line 880 "common.w"
+#line 869 "common.w"
/*62:*/
-#line 922 "common.w"
+#line 911 "common.w"
switch(section_name_cmp(&first,name_len,r)){
@@ -1026,16 +1016,16 @@ err_print(">");
}
else if(name_len<prefix_length(r))set_prefix_length(r,name_len);
-case equal:return r;
+case equal:break;
case extension:if(!ispref||first<=last)
extend_section_name(r,first,last+1,ispref);
-return r;
+break;
case bad_extension:
fputs("\n! New name extends <",stdout);
print_section_name(r);
err_print(">");
-return r;
+break;
default:
fputs("\n! Section name incompatible with <",stdout);
@@ -1043,32 +1033,32 @@ print_prefix_name(r);
fputs(">,\n which abbreviates <",stdout);
print_section_name(r);
err_print(">");
-return r;
}
+return r;
/*:62*/
-#line 881 "common.w"
+#line 870 "common.w"
}
/*:59*//*63:*/
-#line 970 "common.w"
+#line 959 "common.w"
static int section_name_cmp(
char**pfirst,
-int len,
+size_t len,
name_pointer r)
{
char*first= *pfirst;
name_pointer q= r+1;
char*ss,*s= first_chunk(r);
-int c;
-int ispref;
+int c= less;
+boolean ispref;
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)){
+if(*ss==' '&&ss>=r->byte_start)ispref= true,q= q->link;
+else ispref= false,ss++,q= name_dir;
+switch(c= web_strcmp(first,len,s,(size_t)(ss-s))){
case equal:if(q==name_dir)
if(ispref){
*pfirst= first+(ptrdiff_t)(ss-s);
@@ -1086,18 +1076,18 @@ default:return c;
}
/*:63*//*66:*/
-#line 1024 "common.w"
+#line 1013 "common.w"
void
err_print(
const char*s)
{
-char*k,*l;
-printf(*s=='!'?"\n%s":"%s",s);
+*s=='!'?printf("\n%s",s):printf("%s",s);
if(web_file_open)/*67:*/
-#line 1044 "common.w"
+#line 1032 "common.w"
-{if(changing&&include_depth==change_depth)
+{char*k,*l;
+if(changing&&include_depth==change_depth)
printf(". (l. %d of change file)\n",change_line);
else if(include_depth==0)printf(". (l. %d)\n",cur_line);
else printf(". (l. %d of include file %s)\n",cur_line,cur_file_name);
@@ -1106,7 +1096,7 @@ if(l> buffer){
for(k= buffer;k<l;k++)
if(*k=='\t')putchar(' ');
else putchar(*k);
-putchar('\n');
+new_line;
for(k= buffer;k<l;k++)putchar(' ');
}
for(k= l;k<limit;k++)putchar(*k);
@@ -1115,39 +1105,41 @@ putchar(' ');
}
/*:67*/
-#line 1031 "common.w"
+#line 1019 "common.w"
update_terminal;mark_error;
}
/*:66*//*68:*/
-#line 1076 "common.w"
+#line 1065 "common.w"
int wrap_up(void){
if(show_progress)new_line;
if(show_stats)
print_stats();
/*69:*/
-#line 1086 "common.w"
+#line 1075 "common.w"
switch(history){
-case spotless:if(show_happiness)puts("(No errors were found.)");break;
+case spotless:
+if(show_happiness)puts("(No errors were found.)");break;
case harmless_message:
puts("(Did you see the warning message above?)");break;
case error_message:
puts("(Pardon me, but I think I spotted something wrong.)");break;
-case fatal_message:puts("(That was a fatal error, my friend.)");
+case fatal_message:default:
+puts("(That was a fatal error, my friend.)");
}
/*:69*/
-#line 1081 "common.w"
+#line 1070 "common.w"
if(history> harmless_message)return EXIT_FAILURE;
else return EXIT_SUCCESS;
}
/*:68*//*70:*/
-#line 1102 "common.w"
+#line 1093 "common.w"
void
fatal(
const char*s,const char*t)
@@ -1158,7 +1150,7 @@ history= fatal_message;exit(wrap_up());
}
/*:70*//*71:*/
-#line 1113 "common.w"
+#line 1104 "common.w"
void
overflow(
const char*t)
@@ -1168,7 +1160,7 @@ printf("\n! Sorry, %s capacity exceeded",t);fatal("","");
/*:71*//*75:*/
-#line 1167 "common.w"
+#line 1157 "common.w"
static void
scan_args(void)
@@ -1182,41 +1174,38 @@ boolean found_web= false,found_change= false,found_out= false;
strcpy(change_file_name,"/dev/null");
while(--argc> 0){
if((**(++argv)=='-'||**argv=='+')&&*(*argv+1))/*80:*/
-#line 1258 "common.w"
+#line 1247 "common.w"
-{
for(dot_pos= *argv+1;*dot_pos> '\0';dot_pos++)
flags[(eight_bits)*dot_pos]= flag_change;
-}
/*:80*/
-#line 1179 "common.w"
+#line 1169 "common.w"
else{
s= name_pos= *argv;dot_pos= NULL;
-while(*s){
+while(*s)
if(*s=='.')dot_pos= s++;
else if(*s=='/')dot_pos= NULL,name_pos= ++s;
else s++;
-}
if(!found_web)/*77:*/
-#line 1206 "common.w"
+#line 1195 "common.w"
{
if(s-*argv> max_file_name_length-5)
/*82:*/
-#line 1276 "common.w"
+#line 1263 "common.w"
fatal("! Filename too long\n",*argv);
/*:82*/
-#line 1209 "common.w"
+#line 1198 "common.w"
if(dot_pos==NULL)
sprintf(web_file_name,"%s.w",*argv);
else{
strcpy(web_file_name,*argv);
-*dot_pos= 0;
+*dot_pos= '\0';
}
sprintf(alt_web_file_name,"%s.web",*argv);
sprintf(tex_file_name,"%s.tex",name_pos);
@@ -1227,21 +1216,21 @@ found_web= true;
}
/*:77*/
-#line 1188 "common.w"
+#line 1177 "common.w"
else if(!found_change)/*78:*/
-#line 1224 "common.w"
+#line 1213 "common.w"
{
if(strcmp(*argv,"-")!=0){
if(s-*argv> max_file_name_length-4)
/*82:*/
-#line 1276 "common.w"
+#line 1263 "common.w"
fatal("! Filename too long\n",*argv);
/*:82*/
-#line 1228 "common.w"
+#line 1217 "common.w"
if(dot_pos==NULL)
sprintf(change_file_name,"%s.ch",*argv);
@@ -1251,20 +1240,20 @@ found_change= true;
}
/*:78*/
-#line 1189 "common.w"
+#line 1178 "common.w"
else if(!found_out)/*79:*/
-#line 1236 "common.w"
+#line 1225 "common.w"
{
if(s-*argv> max_file_name_length-5)
/*82:*/
-#line 1276 "common.w"
+#line 1263 "common.w"
fatal("! Filename too long\n",*argv);
/*:82*/
-#line 1239 "common.w"
+#line 1228 "common.w"
if(dot_pos==NULL){
sprintf(tex_file_name,"%s.tex",*argv);
@@ -1275,7 +1264,7 @@ sprintf(C_file_name,"%s.c",*argv);
strcpy(tex_file_name,*argv);
strcpy(C_file_name,*argv);
if(make_xrefs){
-*dot_pos= 0;
+*dot_pos= '\0';
sprintf(idx_file_name,"%s.idx",*argv);
sprintf(scn_file_name,"%s.scn",*argv);
}
@@ -1284,10 +1273,10 @@ found_out= true;
}
/*:79*/
-#line 1190 "common.w"
+#line 1179 "common.w"
else/*81:*/
-#line 1264 "common.w"
+#line 1251 "common.w"
{
if(program==ctangle)
@@ -1301,12 +1290,12 @@ else fatal(
}
/*:81*/
-#line 1191 "common.w"
+#line 1180 "common.w"
}
}
if(!found_web)/*81:*/
-#line 1264 "common.w"
+#line 1251 "common.w"
{
if(program==ctangle)
@@ -1320,7 +1309,7 @@ else fatal(
}
/*:81*/
-#line 1194 "common.w"
+#line 1183 "common.w"
}
diff --git a/web/c_cpp/cweb/common.h b/web/c_cpp/cweb/common.h
index 425239f1c7..2a584ff442 100644
--- a/web/c_cpp/cweb/common.h
+++ b/web/c_cpp/cweb/common.h
@@ -2,7 +2,7 @@
% This program by Silvio Levy and Donald E. Knuth
% is based on a program by Knuth.
% It is distributed WITHOUT ANY WARRANTY, express or implied.
-% Version 4.2 --- February 2021 (works also with later versions)
+% Version 4.6 --- December 2021 (works also with later versions)
% Copyright (C) 1987,1990,1993 Silvio Levy and Donald E. Knuth
@@ -12,8 +12,8 @@
% Permission is granted to copy and distribute modified versions of this
% document under the conditions for verbatim copying, provided that the
-% entire resulting derived work is distributed under the terms of a
-% permission notice identical to this one.
+% 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.h' resulting in this updated version were created
% by numerous collaborators over the course of many years.
@@ -27,9 +27,7 @@
First comes general stuff:
-@s boolean int
-@s uint8_t int
-@s uint16_t int
+@i iso_types.w
@d ctangle false
@d cweave true
@@ -48,28 +46,30 @@ extern int phase; /* which phase are we in? */
#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 <stdlib.h> /* definition of |@!getenv| and |@!exit| */
#include <string.h> /* definition of |@!strlen|, |@!strcmp| and so on */
@ Code related to the character set:
@^ASCII code 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 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} */
-@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} */
+@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 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} */
+@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} */
+@#
+@d compress(c) if (loc++<=limit) return c
@<Common code...@>=
extern char section_text[]; /* text being sought for */
@@ -78,12 +78,16 @@ 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((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))
+@d xisalpha(c) (isalpha((int)(c))&&((eight_bits)(c)<0200))
+@d xisdigit(c) (isdigit((int)(c))&&((eight_bits)(c)<0200))
+@d xisspace(c) (isspace((int)(c))&&((eight_bits)(c)<0200))
+@d xislower(c) (islower((int)(c))&&((eight_bits)(c)<0200))
+@d xisupper(c) (isupper((int)(c))&&((eight_bits)(c)<0200))
+@d xisxdigit(c) (isxdigit((int)(c))&&((eight_bits)(c)<0200))
+@d isxalpha(c) ((c)=='_' || (c)=='$')
+ /* non-alpha characters allowed in identifier */
+@d ishigh(c) ((eight_bits)(c)>0177)
+@^high-bit character handling@>
@<Common code...@>=
extern char buffer[]; /* where each line of input goes */
@@ -95,7 +99,7 @@ extern char *limit; /* points to the last character in the buffer */
@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 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 */
@@ -130,7 +134,7 @@ extern boolean print_where; /* tells \.{CTANGLE} to print line and file info */
@ Code related to identifier and section name storage:
@d length(c) (size_t)((c+1)->byte_start-(c)->byte_start) /* the length of a name */
-@d print_id(c) term_write((c)->byte_start,length((c))) /* print identifier */
+@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
@@ -161,9 +165,9 @@ extern hash_pointer h; /* index into hash-head array */
@ @<Predecl...@>=
extern boolean names_match(name_pointer,const char *,size_t,eight_bits);@/
-extern name_pointer id_lookup(const char *,const char *,char);
+extern name_pointer id_lookup(const char *,const char *,eight_bits);
/* looks up a string in the identifier table */
-extern name_pointer section_lookup(char *,char *,int); /* finds section name */
+extern name_pointer section_lookup(char *,char *,boolean); /* finds section name */
extern void init_node(name_pointer);@/
extern void init_p(name_pointer,eight_bits);@/
extern void print_prefix_name(name_pointer);@/
@@ -175,7 +179,7 @@ extern void sprint_section_name(char *,name_pointer);
@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_harmless if (history==spotless) history=harmless_message
@d mark_error history=error_message
@d confusion(s) fatal("! This can't happen: ",s)
@.This can't happen@>
@@ -192,8 +196,8 @@ 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 show_stats flags['s'] /* should statistics be printed at end of run? */
@d make_xrefs flags['x'] /* should cross references be output? */
@<Common code...@>=
@@ -207,10 +211,8 @@ extern boolean flags[]; /* an option for each 7-bit code */
@ Code related to output:
@d update_terminal fflush(stdout) /* empty the terminal output buffer */
-@d new_line putchar('\n') @d putxchar putchar
+@d new_line putchar('\n')
@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? */
@<Common code...@>=
extern FILE *C_file; /* where output of \.{CTANGLE} goes */
@@ -228,16 +230,14 @@ extern void print_stats(void);
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 buf_size 100 /* maximum length of input line, plus one */
+@d longest_name 10000 /* file names, section names, and section texts
+ shouldn't be longer than this */
@d long_buf_size (buf_size+longest_name) /* for \.{CWEAVE} */
+@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 */
+@d max_sections 2000 /* greater than the total number of sections */
@ End of \.{COMMON} interface.
diff --git a/web/c_cpp/cweb/common.w b/web/c_cpp/cweb/common.w
index 15e93c2c5e..36f35f3cbc 100644
--- a/web/c_cpp/cweb/common.w
+++ b/web/c_cpp/cweb/common.w
@@ -2,7 +2,7 @@
% This program by Silvio Levy and Donald E. Knuth
% is based on a program by Knuth.
% It is distributed WITHOUT ANY WARRANTY, express or implied.
-% Version 4.2 --- February 2021
+% Version 4.6 --- December 2021
% Copyright (C) 1987,1990,1993,2000 Silvio Levy and Donald E. Knuth
@@ -22,12 +22,12 @@
\def\v{\char'174} % vertical (|) in typewriter font
-\def\title{Common code for CTANGLE and CWEAVE (Version 4.2)}
+\def\title{Common code for CTANGLE and CWEAVE (Version 4.6)}
\def\topofcontents{\null\vfill
\centerline{\titlefont Common code for {\ttitlefont CTANGLE} and
{\ttitlefont CWEAVE}}
\vskip 15pt
- \centerline{(Version 4.2)}
+ \centerline{(Version 4.6)}
\vfill}
\def\botofcontents{\vfill
\noindent
@@ -47,10 +47,6 @@ under the terms of a permission notice identical to this one.
\pageno=\contentspagenumber \advance\pageno by 1
\let\maybe=\iftrue
-@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
problems: character uniformity, input routines, error handling and
@@ -158,13 +154,13 @@ support |feof|, |getc|, and |ungetc| you may have to change things here.
@^system dependencies@>
@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 */
+static boolean input_ln( /* copies a line into |buffer| or returns |false| */
+FILE *fp) /* what file to read from */
{
- register int c=EOF; /* character read; initialized so some compilers won't complain */
- register char *k; /* where next character goes */
- if (feof(fp)) return false; /* we have hit end-of-file */
- limit = k = buffer; /* beginning of buffer */
+ register int c=EOF; /* character read; initialized so some compilers won't complain */
+ register char *k; /* where next character goes */
+ if (feof(fp)) return false; /* we have hit end-of-file */
+ limit = k = buffer; /* beginning of buffer */
while (k<=buffer_end && (c=getc(fp)) != EOF && c!='\n')
if ((*(k++) = c) != ' ') limit = k;
if (k>buffer_end)
@@ -172,7 +168,7 @@ FILE *fp@t\2\2@>) /* what file to read from */
ungetc(c,fp); loc=buffer; err_print("! Input line too long");
@.Input line too long@>
}
- if (c==EOF && limit==buffer) return false; /* there was nothing after
+ if (c==EOF && limit==buffer) return false; /* there was nothing after
the last newline */
return true;
}
@@ -182,7 +178,7 @@ FILE *fp@t\2\2@>) /* what file to read from */
@ Now comes the problem of deciding which file to read from next.
Recall that the actual text that \.{CWEB} should process comes from two
streams: a |web_file|, which can contain possibly nested include
-commands \.{@@i}, and a |change_file|, which might also contain
+commands~\.{@@i}, and a |change_file|, which might also contain
includes. The |web_file| together with the currently open include
files form a stack |file|, whose names are stored in a parallel stack
|file_name|. The boolean |changing| tells whether or not we're reading
@@ -214,8 +210,8 @@ 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, (size_t)(limit-buffer)))
+@d lines_dont_match (change_limit-change_buffer != limit-buffer @| ||
+ strncmp(buffer, change_buffer, (size_t)(limit-buffer)) != 0)
@<Global var...@>=
static char change_buffer[buf_size]; /* next line of |change_file| */
@@ -250,7 +246,7 @@ while(true) {
if (!input_ln(change_file)) return;
if (limit<buffer+2) continue;
if (buffer[0]!='@@') continue;
- if (xisupper(buffer[1])) buffer[1]=tolower((eight_bits)buffer[1]);
+ if (xisupper(buffer[1])) buffer[1]=tolower((int)buffer[1]);
if (buffer[1]=='x') break;
if (buffer[1]=='y' || buffer[1]=='z' || buffer[1]=='i') {
loc=buffer+2;
@@ -272,10 +268,8 @@ do {
} while (limit==buffer);
@ @<Move |buffer| and |limit| to |change_buffer| and |change_limit|@>=
-{
- change_limit=change_buffer+(ptrdiff_t)(limit-buffer);
- strncpy(change_buffer,buffer,(size_t)(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 |false|.
@@ -293,11 +287,11 @@ either `\.{@@*}' or `\.{@@\ }' (possibly preceded by whitespace).
This procedure is called only when |buffer<limit|, i.e., when the
current line is nonempty.
-@d if_section_start_make_pending(b) {@+*limit='!';
- for (loc=buffer;xisspace(*loc);loc++) ;
- *limit=' ';
- if (*loc=='@@' && (xisspace(*(loc+1)) || *(loc+1)=='*')) change_pending=b;
-}
+@d if_section_start_make_pending(b)@/
+ *limit='!';@+
+ for (loc=buffer;xisspace(*loc);loc++) ;@+
+ *limit=' ';@/
+ if (*loc=='@@' && (xisspace(*(loc+1)) || *(loc+1)=='*')) change_pending=b
@c
static void
@@ -311,7 +305,7 @@ check_change(void) /* switches to |change_file| if the buffers match */
if (!change_pending) changed_section[section_count]=true;
}
while (true) {
- changing=true; print_where=true; change_line++;
+ changing=print_where=true; change_line++;
if (!input_ln(change_file)) {
err_print("! Change file ended before @@y");
@.Change file ended...@>
@@ -319,7 +313,7 @@ check_change(void) /* switches to |change_file| if the buffers match */
return;
}
if (limit>buffer+1 && buffer[0]=='@@') {
- char xyz_code=xisupper(buffer[1])? tolower((eight_bits)buffer[1]): buffer[1];
+ char xyz_code=xisupper(buffer[1])? tolower((int)buffer[1]): buffer[1];
@<If the current line starts with \.{@@y},
report any discrepancies and |return|@>@;
}
@@ -365,9 +359,9 @@ reset_input(void)
{
limit=buffer; loc=buffer+1; buffer[0]=' ';
@<Open input files@>@;
- include_depth=0; cur_line=0; change_line=0;
+ include_depth=cur_line=change_line=0;
change_depth=include_depth;
- changing=1; prime_the_change_buffer(); changing=!changing;
+ changing=true; prime_the_change_buffer(); changing=!changing;
limit=buffer; loc=buffer+1; buffer[0]=' '; input_has_ended=false;
}
@@ -408,7 +402,7 @@ 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|@>@;
if (changing && include_depth==change_depth) goto restart;
@@ -448,11 +442,11 @@ 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;}
-@.CWEBINPUTS@>@<Try to open...@>= {
+@<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;
- int l; /* length of file name */
+ char *kk, *k=cur_file_name;
+ size_t l; /* length of file name */
if (*loc=='"') {
loc++;
@@ -467,8 +461,8 @@ The remainder of the \.{@@i} line after the file name is ignored.
cur_line=0; print_where=true;
goto restart; /* success */
}
- kk=getenv("CWEBINPUTS");
- if (kk!=NULL) {
+ if ((kk=getenv("CWEBINPUTS"))!=NULL) {
+@.CWEBINPUTS@>
if ((l=strlen(kk))>max_file_name_length-2) too_long();
strcpy(temp_file_name,kk);
}
@@ -481,9 +475,9 @@ The remainder of the \.{@@i} line after the file name is ignored.
#endif /* |CWEBINPUTS| */
}
if (l>0) {
- if (k+l+2>=cur_file_name_end) too_long();
+ if (k+l+2>=cur_file_name_end) too_long();
@.Include file name ...@>
- for (; k>= cur_file_name; k--) *(k+l+1)=*k;
+ for (; k>=cur_file_name; k--) *(k+l+1)=*k;
strcpy(cur_file_name,temp_file_name);
cur_file_name[l]='/'; /* \UNIX/ pathname separator */
if ((cur_file=fopen(cur_file_name,"r"))!=NULL) {
@@ -527,7 +521,7 @@ The remainder of the \.{@@i} line after the file name is ignored.
}
*limit=' ';
if (buffer[0]=='@@') {
- if (xisupper(buffer[1])) buffer[1]=tolower((eight_bits)buffer[1]);
+ if (xisupper(buffer[1])) buffer[1]=tolower((int)buffer[1]);
if (buffer[1]=='x' || buffer[1]=='y') {
loc=buffer+2;
err_print("! Where is the matching @@z?");
@@ -622,7 +616,7 @@ 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 8501 /* should be prime */
+@d hash_size 353 /* should be prime */
@<Global var...@>=
name_pointer hash[hash_size]; /* heads of hash lists */
@@ -638,17 +632,17 @@ for (h=hash; h<=hash_end; *h++=NULL) ;
@c
name_pointer
-id_lookup(@t\1\1@> /* looks up a string in the identifier table */
+id_lookup( /* 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 */
+eight_bits t) /* the |ilk|; used by \.{CWEAVE} only */
{
const char *i=first; /* position in |buffer| */
- int h; /* hash code */
- int l; /* length of the given identifier */
+ int h; /* hash code; shadows |hash_pointer h| */
+ size_t l; /* length of the given identifier */
name_pointer p; /* where the identifier is being sought */
if (last==NULL) for (last=first; *last!='\0'; last++);
- l=(int)(last-first); /* compute the length */
+ l=(size_t)(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|@>@;
@@ -660,7 +654,7 @@ 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=(eight_bits)*i;
+h=(int)((eight_bits)*i);
while (++i<last) h=(h+h+(int)((eight_bits)*i)) % hash_size;
@^high-bit character handling@>
@@ -678,6 +672,7 @@ 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.
+
@<Enter a new name...@>= {
if (byte_ptr+l>byte_mem_end) overflow("byte memory");
if (name_ptr>=name_dir_end) overflow("name");
@@ -704,11 +699,11 @@ and if it too is a prefix (ending with blank) its |link| will point
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)((eight_bits)*((p)->byte_start)*256 +
+@d first_chunk(p) ((p)->byte_start+2)
+@d prefix_length(p) (size_t)((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)
+@d set_prefix_length(p,m) (*((p)->byte_start)=(char)((m)/256),
+ *((p)->byte_start+1)=(char)((m)%256))
@c
void
@@ -719,11 +714,9 @@ name_pointer p)
name_pointer q = p+1;
while (p!=name_dir) {
ss = (p+1)->byte_start-1;
- if (*ss==' ' && ss>=s) {
- term_write(s,(size_t)(ss-s)); p=q->link; q=p;
- } else {
- term_write(s,(size_t)(ss+1-s)); p=name_dir; q=NULL;
- }
+ if (*ss==' ' && ss>=s) p=q->link,q=p;
+ else ss++,p=name_dir,q=NULL;
+ term_write(s,(size_t)(ss-s));
s = p->byte_start;
}
if (q) term_write("...",3); /* complete name not yet known */
@@ -739,11 +732,8 @@ sprint_section_name(
name_pointer q = p+1;
while (p!=name_dir) {
ss = (p+1)->byte_start-1;
- if (*ss==' ' && ss>=s) {
- p=q->link; q=p;
- } else {
- ss++; p=name_dir;
- }
+ if (*ss==' ' && ss>=s) p=q->link,q=p;
+ else ss++,p=name_dir;
strncpy(dest,s,(size_t)(ss-s)), dest+=ss-s;
s = p->byte_start;
}
@@ -756,7 +746,7 @@ print_prefix_name(
name_pointer p)
{
char *s = first_chunk(p);
- int l = prefix_length(p);
+ size_t l = prefix_length(p);
term_write(s,l);
if (s+l<(p+1)->byte_start) term_write("...",3);
}
@@ -772,16 +762,16 @@ are null-terminated, and we keep an eye open for prefixes and extensions.
@d extension 4 /* the first name is a proper extension of the second */
@<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);
+static int web_strcmp(char *,size_t,char *,size_t);@/
+static name_pointer add_section_name(name_pointer,int,char *,char *,boolean);@/
+static void extend_section_name(name_pointer,char *,char *,boolean);
@ @c
-static int web_strcmp(@t\1\1@> /* fuller comparison than |strcmp| */
+static int web_strcmp( /* fuller comparison than |strcmp| */
char *j, /* beginning of first string */
- int j_len, /* length of first string */
+ size_t j_len, /* length of first string */
char *k, /* beginning of second string */
- int k_len@t\2\2@>) /* length of second string */
+ size_t k_len) /* length of second string */
{
char *j1=j+j_len, *k1=k+k_len;
while (k<k1 && j<j1 && *j==*k) k++, j++;
@@ -807,16 +797,16 @@ and \.{ctangle.w}.
@c
static name_pointer
-add_section_name(@t\1\1@> /* install a new node in the tree */
+add_section_name( /* 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? */
+boolean ispref) /* are we adding a prefix or a full name? */
{
name_pointer p=name_ptr; /* new node */
char *s=first_chunk(p);
- int name_len=(int)(last-first)+ispref; /* length of section name */
+ size_t name_len=(size_t)(last-first+(int)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;
@@ -828,23 +818,22 @@ int ispref@t\2\2@>) /* are we adding a prefix or a full name? */
}
set_prefix_length(p,name_len);
strncpy(s,first,name_len);
- p->llink=NULL;
- p->rlink=NULL;
+ p->llink=p->rlink=NULL;
init_node(p);
return par==NULL ? (root=p) : c==less ? (par->llink=p) : (par->rlink=p);
}
@ @c
static void
-extend_section_name(@t\1\1@>
+extend_section_name(
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? */
+boolean ispref) /* are we adding a prefix or a full name? */
{
char *s;
name_pointer q=p+1;
- int name_len=(int)(last-first)+ispref;
+ size_t name_len=(size_t)(last-first+(int)ispref);
if (name_ptr>=name_dir_end) overflow("name");
while (q->link!=name_dir) q=q->link;
q->link=name_ptr;
@@ -864,17 +853,17 @@ exactly equals or is a prefix or extension of a name in the tree.
@c
name_pointer
-section_lookup(@t\1\1@> /* find or install section name in tree */
+section_lookup( /* 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? */
+boolean ispref) /* is the new name a prefix or a full name? */
{
- int c=0; /* comparison between two names; initialized so some compilers won't complain */
+ int c=less; /* comparison between two names; initialized so some compilers won't complain */
name_pointer p=root; /* current node of the search tree */
name_pointer q=NULL; /* another place to look in the tree */
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=(int)(last-first)+1;
+ size_t name_len=(size_t)(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@>@;
@@ -894,7 +883,7 @@ while (p) { /* compare shortest prefix of |p| with new name */
par=p;
p=(c==less?p->llink:p->rlink);
} else { /* new name matches |p| */
- if (r!=NULL) { /* and also |r|: illegal */
+ if (r!=NULL) { /* and also |r|: illegal */
fputs("\n! Ambiguous prefix: matches <",stdout);
@.Ambiguous prefix ... @>
print_prefix_name(p);
@@ -931,16 +920,16 @@ switch(section_name_cmp(&first,name_len,r)) {
}
else if (name_len<prefix_length(r)) set_prefix_length(r,name_len);
/* fall through */
- case equal: return r;
+ case equal: break;
case extension: if (!ispref || first<=last)
extend_section_name(r,first,last+1,ispref);
- return r;
+ break;
case bad_extension:
fputs("\n! New name extends <",stdout);
@.New name extends...@>
print_section_name(r);
err_print(">");
- return r;
+ break;
default: /* no match: illegal */
fputs("\n! Section name incompatible with <",stdout);
@.Section name incompatible...@>
@@ -948,8 +937,8 @@ switch(section_name_cmp(&first,name_len,r)) {
fputs(">,\n which abbreviates <",stdout);
print_section_name(r);
err_print(">");
- return r;
}
+return r;
@ The return codes of |section_name_cmp|, which compares a string with
the full name of a section, are those of |web_strcmp| plus
@@ -968,21 +957,21 @@ us to regard \.{@@<foo...@@>} as an ``extension'' of itself.
@d bad_extension 5
@c
-static int section_name_cmp(@t\1\1@>
+static int section_name_cmp(
char **pfirst, /* pointer to beginning of comparison string */
-int len, /* length of string */
-name_pointer r@t\2\2@>) /* section name being compared */
+size_t len, /* length of string */
+name_pointer r) /* 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? */
+ int c=less; /* comparison */
+ boolean ispref; /* is chunk |r| a prefix? */
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)) {
+ if (*ss==' ' && ss>=r->byte_start) ispref=true,q=q->link;
+ else ispref=false,ss++,q=name_dir;
+ switch(c=web_strcmp(first,len,s,(size_t)(ss-s))) {
case equal: if (q==name_dir)
if (ispref) {
*pfirst=first+(ptrdiff_t)(ss-s);
@@ -999,7 +988,7 @@ name_pointer r@t\2\2@>) /* section name being compared */
}
}
-@ @<Predec...@>=@+static int section_name_cmp(char **,int,name_pointer);
+@ @<Predec...@>=@+static int section_name_cmp(char **,size_t,name_pointer);
@** Reporting errors to the user.
A global variable called |history| will contain one of four values
@@ -1023,12 +1012,11 @@ if the string begins with |"!"|.
@c
void
-err_print(@t\1\1@> /* prints `\..' and location of error message */
-const char *s@t\2\2@>)
+err_print( /* prints `\..' and location of error message */
+const char *s)
{
- char *k,*l; /* pointers into |buffer| */
- printf(*s=='!'? "\n%s" : "%s",s);
- if(web_file_open) @<Print error location based on input buffer@>@;
+ *s=='!'? printf("\n%s",s) : printf("%s",s);
+ if (web_file_open) @<Print error location based on input buffer@>@;
update_terminal; mark_error;
}
@@ -1042,7 +1030,8 @@ has special line-numbering conventions.
@^system dependencies@>
@<Print error location based on input buffer@>=
-{if (changing && include_depth==change_depth)
+{char *k,*l; /* pointers into |buffer| */
+if (changing && include_depth==change_depth)
printf(". (l. %d of change file)\n", change_line);
else if (include_depth==0) printf(". (l. %d)\n", cur_line);
else printf(". (l. %d of include file %s)\n", cur_line, cur_file_name);
@@ -1051,7 +1040,7 @@ if (l>buffer) {
for (k=buffer; k<l; k++)
if (*k=='\t') putchar(' ');
else putchar(*k); /* print the characters already read */
- putchar('\n');
+ new_line;
for (k=buffer; k<l; k++) putchar(' '); /* space out the next line */
}
for (k=l; k<limit; k++) putchar(*k); /* print the part not yet read */
@@ -1070,7 +1059,7 @@ interface above and in the index.
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.
+a status of |EXIT_SUCCESS| if and only if only harmless messages were printed.
@^system dependencies@>
@c
@@ -1085,13 +1074,15 @@ int wrap_up(void) {
@ @<Print the job |history|@>=
switch (history) {
-case spotless: if (show_happiness) puts("(No errors were found.)"); break;
+case spotless:
+ if (show_happiness) puts("(No errors were found.)"); break;
case harmless_message:
puts("(Did you see the warning message above?)"); break;
case error_message:
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 */
+case fatal_message: default:
+ puts("(That was a fatal error, my friend.)");
+}
@ When there is no way to recover from an error, the |fatal| subroutine is
invoked. This happens most often when |overflow| occurs.
@@ -1146,8 +1137,7 @@ 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=make_xrefs=true;@/
-show_stats=false;
+show_banner=show_happiness=show_progress=make_xrefs=true;
@ 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}
@@ -1179,14 +1169,13 @@ scan_args(void)
if ((**(++argv)=='-'||**argv=='+')&&*(*argv+1)) @<Handle flag argument@>@;
else {
s=name_pos=*argv;@+dot_pos=NULL;
- while (*s) {
+ 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|@>@;
+ |web_file_name|, |tex_file_name|, and |C_file_name|@>@;
+ else if (!found_change) @<Make |change_file_name|@>@;
else if (!found_out) @<Override |tex_file_name| and |C_file_name|@>@;
else @<Print usage error message and quit@>@;
}
@@ -1211,7 +1200,7 @@ after the dot. We must check that there is enough room in
sprintf(web_file_name,"%s.w",*argv);
else {
strcpy(web_file_name,*argv);
- *dot_pos=0; /* string now ends where the dot was */
+ *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 */
@@ -1246,7 +1235,7 @@ after the dot. We must check that there is enough room in
strcpy(tex_file_name,*argv);
strcpy(C_file_name,*argv);
if (make_xrefs) { /* indexes will be generated */
- *dot_pos=0;
+ *dot_pos='\0';
sprintf(idx_file_name,"%s.idx",*argv);
sprintf(scn_file_name,"%s.scn",*argv);
}
@@ -1256,10 +1245,8 @@ after the dot. We must check that there is enough room in
@ @d flag_change (**argv!='-')
@<Handle flag...@>=
-{
- for(dot_pos=*argv+1;*dot_pos>'\0';dot_pos++)
- flags[(eight_bits)*dot_pos]=flag_change;
-}
+for(dot_pos=*argv+1;*dot_pos>'\0';dot_pos++)
+ flags[(eight_bits)*dot_pos]=flag_change;
@ @<Print usage error message and quit@>=
{
diff --git a/web/c_cpp/cweb/ctang-bs.ch b/web/c_cpp/cweb/ctang-bs.ch
index 55cc27cd00..ceaefa93e5 100644
--- a/web/c_cpp/cweb/ctang-bs.ch
+++ b/web/c_cpp/cweb/ctang-bs.ch
@@ -17,16 +17,16 @@ by using "huge" pointers.
The ``banner line'' defined here should be changed whenever \.{CTANGLE}
is modified.
-@d banner "This is CTANGLE (Version 4.2)"
+@d banner "This is CTANGLE (Version 4.6)"
@y
The ``banner line'' defined here should be changed whenever \.{CTANGLE}
is modified.
-@d banner "This is CTANGLE (Version 4.2pc/big)"
+@d banner "This is CTANGLE (Version 4.6pc/big)"
@z
-@x Section 9.
+@x Section 10.
for section names */
@<Common code...@>=
@@ -84,50 +84,7 @@ extern hash_pointer h; /* index into hash-head array */
@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
-
-
-@x Section 16.
+@x Section 19.
eight_bits *tok_start; /* pointer into |tok_mem| */
sixteen_bits text_link; /* relates replacement texts */
} text;
@@ -140,7 +97,23 @@ typedef text *text_pointer;
@z
-@x Section 17.
+@x Section 20.
+@ @d max_texts 2500 /* number of replacement texts, must be less than 10240 */
+@d max_toks 270000 /* number of bytes in compressed \CEE/ code */
+@y
+@ (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_texts 2500 /* number of replacement texts, must be less than 10240 */
+@d max_toks 170000 /* number of bytes in compressed \CEE/ code */
+@z
+@x
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| */
@@ -151,7 +124,7 @@ static eight_bits huge* tok_ptr; /* first unused position in |tok_mem| */
@z
-@x Section 18.
+@x Section 21.
text_info->tok_start=tok_ptr=tok_mem;
text_ptr=text_info+1; text_ptr->tok_start=tok_mem;
/* this makes replacement text 0 of length zero */
@@ -163,14 +136,14 @@ text_ptr=text_info+1; text_ptr->tok_start=tok_mem;
@z
-@x Section 19.
+@x Section 22.
@d equiv equiv_or_xref /* info corresponding to names */
@y
@d equiv ptr_union.equiv_member /* info corresponding to names */
@z
-@x Section 27.
+@x Section 31.
eight_bits *end_field; /* ending location of replacement text */
eight_bits *byte_field; /* present location within replacement text */
@y
@@ -179,7 +152,7 @@ text_ptr=text_info+1; text_ptr->tok_start=tok_mem;
@z
-@x Section 49.
+@x Section 55.
out_char(
eight_bits cur_char)
{
diff --git a/web/c_cpp/cweb/ctang-man.ch b/web/c_cpp/cweb/ctang-man.ch
index 5b4d06c88b..f90d5361ae 100644
--- a/web/c_cpp/cweb/ctang-man.ch
+++ b/web/c_cpp/cweb/ctang-man.ch
@@ -16,7 +16,7 @@ under the terms of a permission notice identical to this one.
}
@y
\def\botofcontents{\vfill\titlefalse}
-\def\contentspagenumber{66}
+\def\contentspagenumber{64}
\def\title{APPENDIX E: CTANGLE}
\let\K=\leftarrow
@z
diff --git a/web/c_cpp/cweb/ctang-pc.ch b/web/c_cpp/cweb/ctang-pc.ch
index ddf281b3fc..2fb9b90440 100644
--- a/web/c_cpp/cweb/ctang-pc.ch
+++ b/web/c_cpp/cweb/ctang-pc.ch
@@ -9,16 +9,19 @@ that allows >64K arrays. If you need lots of bytes and toks, try the
alternate change files with -bs suffix instead of -pc.
@x section 1
-@d banner "This is CTANGLE (Version 4.2)"
+@d banner "This is CTANGLE (Version 4.6)"
@y
-@d banner "This is CTANGLE (Version 4.2pc)"
+@d banner "This is CTANGLE (Version 4.6pc)"
@z
-@x section 4
-@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 */
+@x section 17
+@d max_bytes 90000 /* the number of bytes in identifiers,
+ index entries, and section names; must be less than $2^{24}$ */
@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 */
+ index entries, and section names; must be less than $2^{24}$ */
+@z
+@x section 20
+@d max_toks 270000 /* number of bytes in compressed \CEE/ code */
+@y
@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 64f0e81a72..2f4ff604b1 100644
--- a/web/c_cpp/cweb/ctang-ql.ch
+++ b/web/c_cpp/cweb/ctang-ql.ch
@@ -7,15 +7,15 @@ ex <dev_>cc;"-v -h -c -=500000 ctangle_c"
@x
-\def\title{CTANGLE (Version 4.2)}
+\def\title{CTANGLE (Version 4.6)}
@y
-\def\title{CTANGLE (QL Version 4.2)}
+\def\title{CTANGLE (QL Version 4.6)}
@z
@x section 1
-@d banner "This is CTANGLE (Version 4.2)"
+@d banner "This is CTANGLE (Version 4.6)"
@y
-@d banner "This is CTANGLE (QL Version 4.2)"
+@d banner "This is CTANGLE (QL Version 4.6)"
@z
@x
diff --git a/web/c_cpp/cweb/ctang-vms.ch b/web/c_cpp/cweb/ctang-vms.ch
index 5686c66b9a..9f5dd2a677 100644
--- a/web/c_cpp/cweb/ctang-vms.ch
+++ b/web/c_cpp/cweb/ctang-vms.ch
@@ -10,18 +10,18 @@ created:
(these changes not necessary for initial bootstrapping)
@x section 1 (01-FEB-1992 ST)
-@d banner "This is CTANGLE (Version 4.2)"
+@d banner "This is CTANGLE (Version 4.6)"
@y
-@d banner "This is CTANGLE (VAX/VMS Version 4.2)"
+@d banner "This is CTANGLE (VAX/VMS Version 4.6)"
@z
-@x section 3 (01-FEB-1992 ST)
+@x section 4 (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 <stdlib.h> /* definition of |@!getenv| and |@!exit| */
#include <string.h> /* definition of |@!strlen|, |@!strcmp| and so on */
@y
#include ctype /* definition of |@!isalpha|, |@!isdigit| and so on */
@@ -29,7 +29,7 @@ created:
#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 stdlib /* definition of |@!getenv| and |@!exit| */
#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 1c687e5eb6..d299f00683 100644
--- a/web/c_cpp/cweb/ctang-w32.ch
+++ b/web/c_cpp/cweb/ctang-w32.ch
@@ -4,23 +4,23 @@ This is the change file for CWEB's CTANGLE under Win32
Changes necessary for compiling with Borland C/C++
@x section 1
-@d banner "This is CTANGLE (Version 4.2)"
+@d banner "This is CTANGLE (Version 4.6)"
@y
-@d banner "This is CTANGLE (Version 4.2win32)"
+@d banner "This is CTANGLE (Version 4.6win32)"
@z
@x
-boolean names_match(@t\1\1@>
+boolean names_match(
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} */
+eight_bits t) /* not used by \.{TANGLE} */
@y
-boolean __cdecl names_match(@t\1\1@>
+boolean __cdecl names_match(
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} */
+eight_bits t) /* not used by \.{TANGLE} */
@z
@x
diff --git a/web/c_cpp/cweb/ctangle.c b/web/c_cpp/cweb/ctangle.c
index d955da9d57..0c6f8afe2a 100644
--- a/web/c_cpp/cweb/ctangle.c
+++ b/web/c_cpp/cweb/ctangle.c
@@ -2,20 +2,20 @@
#line 66 "ctangle.w"
/*4:*/
-#line 46 "common.h"
+#line 44 "common.h"
#include <ctype.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
-#include <stdlib.h>
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
/*:4*/
#line 67 "ctangle.w"
-#define banner "This is CTANGLE (Version 4.2)" \
+#define banner "This is CTANGLE (Version 4.6)" \
#define ctangle false
#define cweave true \
@@ -36,16 +36,22 @@
#define period_ast 026
#define minus_gt_ast 027 \
-#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 compress(c) if(loc++<=limit) return c \
+
+#define xisalpha(c) (isalpha((int) (c) ) &&((eight_bits) (c) <0200) )
+#define xisdigit(c) (isdigit((int) (c) ) &&((eight_bits) (c) <0200) )
+#define xisspace(c) (isspace((int) (c) ) &&((eight_bits) (c) <0200) )
+#define xislower(c) (islower((int) (c) ) &&((eight_bits) (c) <0200) )
+#define xisupper(c) (isupper((int) (c) ) &&((eight_bits) (c) <0200) )
+#define xisxdigit(c) (isxdigit((int) (c) ) &&((eight_bits) (c) <0200) )
+#define isxalpha(c) ((c) =='_'||(c) =='$') \
+
+#define ishigh(c) ((eight_bits) (c) > 0177) \
+ \
#define max_include_depth 10 \
-#define max_file_name_length 1024
+#define max_file_name_length 60
#define cur_file file[include_depth]
#define cur_file_name file_name[include_depth]
#define cur_line line[include_depth]
@@ -53,7 +59,7 @@
#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 print_id(c) term_write((c) ->byte_start,length(c) )
#define llink link
#define rlink dummy.Rlink
#define root name_dir->rlink \
@@ -63,44 +69,44 @@
#define harmless_message 1
#define error_message 2
#define fatal_message 3
-#define mark_harmless {if(history==spotless) history= harmless_message;}
+#define mark_harmless if(history==spotless) history= harmless_message
#define mark_error history= error_message
#define confusion(s) fatal("! This can't happen: ",s) \
\
#define show_banner flags['b']
#define show_progress flags['p']
-#define show_stats flags['s']
#define show_happiness flags['h']
+#define show_stats flags['s']
#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 term_write(a,b) fflush(stdout) ,fwrite(a,sizeof(char) ,b,stdout) \
+
+#define buf_size 100
+#define longest_name 10000 \
-#define max_bytes 1000000 \
+#define long_buf_size (buf_size+longest_name)
+#define max_bytes 90000 \
-#define max_toks 1000000
-#define max_names 10239 \
+#define max_names 4000 \
-#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 max_sections 2000 \
+#define max_texts 2500
+#define max_toks 270000
#define equiv equiv_or_xref \
+#define macro 0
#define section_flag max_texts \
#define string 02
+#define constant 03
#define join 0177
#define output_defs_flag (2*024000-1) \
+#define stack_size 50
#define cur_end cur_state.end_field
#define cur_byte cur_state.byte_field
#define cur_name cur_state.name_field
@@ -117,9 +123,12 @@
#define verbatim 4 \
#define max_files 256
+#define C_printf(c,a) fprintf(C_file,c,a)
+#define C_putc(c) putc((int) (c) ,C_file) \
+
#define translit_length 10 \
-#define ignore 0
+#define ignore 00
#define ord 0302
#define control_text 0303
#define translit_code 0304
@@ -130,23 +139,22 @@
#define section_name 0311
#define new_section 0312 \
-#define constant 03 \
-
-#define isxalpha(c) ((c) =='_'||(c) =='$') \
-
-#define ishigh(c) ((eight_bits) (c) > 0177) \
- \
+#define app_repl(c) { \
+if(tok_ptr==tok_mem_end) overflow("token") ; \
+else*(tok_ptr++) = (eight_bits) c; \
+} \
-#define compress(c) if(loc++<=limit) return c \
+#define store_id(a) a= id_lookup(id_first,id_loc,'\0') -name_dir; \
+app_repl((a/0400) +0200) ; \
+app_repl(a%0400) \
-#define macro 0
-#define app_repl(c) {if(tok_ptr==tok_mem_end) overflow("token") ;*tok_ptr++= c;} \
+#define keep_digit_separators flags['k'] \
#line 68 "ctangle.w"
/*3:*/
-#line 37 "common.h"
+#line 35 "common.h"
typedef bool boolean;
typedef uint8_t eight_bits;
@@ -163,7 +171,7 @@ extern char*id_first;
extern char*id_loc;
/*:5*//*6:*/
-#line 88 "common.h"
+#line 92 "common.h"
extern char buffer[];
extern char*buffer_end;
@@ -171,7 +179,7 @@ extern char*loc;
extern char*limit;
/*:6*//*7:*/
-#line 105 "common.h"
+#line 109 "common.h"
extern int include_depth;
extern FILE*file[];
@@ -187,7 +195,7 @@ extern boolean changing;
extern boolean web_file_open;
/*:7*//*9:*/
-#line 125 "common.h"
+#line 129 "common.h"
extern sixteen_bits section_count;
extern boolean changed_section[];
@@ -195,7 +203,7 @@ extern boolean change_pending;
extern boolean print_where;
/*:9*//*10:*/
-#line 139 "common.h"
+#line 143 "common.h"
typedef struct name_info{
char*byte_start;
@@ -220,12 +228,12 @@ extern hash_pointer hash_end;
extern hash_pointer h;
/*:10*//*12:*/
-#line 183 "common.h"
+#line 187 "common.h"
extern int history;
/*:12*//*14:*/
-#line 199 "common.h"
+#line 203 "common.h"
extern int argc;
extern char**argv;
@@ -236,7 +244,7 @@ extern char scn_file_name[];
extern boolean flags[];
/*:14*//*15:*/
-#line 215 "common.h"
+#line 217 "common.h"
extern FILE*C_file;
extern FILE*tex_file;
@@ -257,7 +265,7 @@ sixteen_bits text_link;
typedef text*text_pointer;
/*:19*//*31:*/
-#line 269 "ctangle.w"
+#line 274 "ctangle.w"
typedef struct{
eight_bits*end_field;
@@ -272,7 +280,7 @@ typedef output_state*stack_pointer;
#line 70 "ctangle.w"
/*20:*/
-#line 129 "ctangle.w"
+#line 131 "ctangle.w"
static text text_info[max_texts];
static text_pointer text_info_end= text_info+max_texts-1;
@@ -282,12 +290,12 @@ static eight_bits*tok_mem_end= tok_mem+max_toks-1;
static eight_bits*tok_ptr;
/*:20*//*26:*/
-#line 198 "ctangle.w"
+#line 200 "ctangle.w"
static text_pointer last_unnamed;
/*:26*//*32:*/
-#line 285 "ctangle.w"
+#line 291 "ctangle.w"
static output_state cur_state;
@@ -296,18 +304,18 @@ static stack_pointer stack_end= stack+stack_size;
static stack_pointer stack_ptr;
/*:32*//*37:*/
-#line 361 "ctangle.w"
+#line 367 "ctangle.w"
static int cur_val;
/*:37*//*42:*/
-#line 452 "ctangle.w"
+#line 459 "ctangle.w"
static eight_bits out_state;
static boolean protect;
/*:42*//*45:*/
-#line 483 "ctangle.w"
+#line 490 "ctangle.w"
static name_pointer output_files[max_files];
static name_pointer*cur_out_file,*end_output_files,*an_output_file;
@@ -315,33 +323,33 @@ static char cur_section_name_char;
static char output_file_name[longest_name+1];
/*:45*//*52:*/
-#line 582 "ctangle.w"
+#line 590 "ctangle.w"
static boolean output_defs_seen= false;
/*:52*//*57:*/
-#line 691 "ctangle.w"
+#line 703 "ctangle.w"
static char translit[128][translit_length];
/*:57*//*62:*/
-#line 770 "ctangle.w"
+#line 779 "ctangle.w"
static eight_bits ccode[256];
/*:62*//*66:*/
-#line 830 "ctangle.w"
+#line 839 "ctangle.w"
static boolean comment_continues= false;
/*:66*//*68:*/
-#line 869 "ctangle.w"
+#line 876 "ctangle.w"
static name_pointer cur_section_name;
static boolean no_where;
/*:68*//*82:*/
-#line 1182 "ctangle.w"
+#line 1193 "ctangle.w"
static text_pointer cur_text;
static eight_bits next_control;
@@ -350,19 +358,19 @@ static eight_bits next_control;
#line 71 "ctangle.w"
/*8:*/
-#line 119 "common.h"
+#line 123 "common.h"
extern boolean get_line(void);
extern void check_complete(void);
extern void reset_input(void);
/*:8*//*11:*/
-#line 162 "common.h"
+#line 166 "common.h"
extern boolean names_match(name_pointer,const char*,size_t,eight_bits);
-extern name_pointer id_lookup(const char*,const char*,char);
+extern name_pointer id_lookup(const char*,const char*,eight_bits);
-extern name_pointer section_lookup(char*,char*,int);
+extern name_pointer section_lookup(char*,char*,boolean);
extern void init_node(name_pointer);
extern void init_p(name_pointer,eight_bits);
extern void print_prefix_name(name_pointer);
@@ -370,7 +378,7 @@ extern void print_section_name(name_pointer);
extern void sprint_section_name(char*,name_pointer);
/*:11*//*13:*/
-#line 186 "common.h"
+#line 190 "common.h"
extern int wrap_up(void);
extern void err_print(const char*);
@@ -378,63 +386,63 @@ extern void fatal(const char*,const char*);
extern void overflow(const char*);
/*:13*//*16:*/
-#line 223 "common.h"
+#line 225 "common.h"
extern void common_init(void);
extern void print_stats(void);
/*:16*//*30:*/
-#line 241 "ctangle.w"
+#line 246 "ctangle.w"
static void store_two_bytes(sixteen_bits);
/*:30*//*35:*/
-#line 324 "ctangle.w"
+#line 330 "ctangle.w"
static void push_level(name_pointer);
static void pop_level(boolean);
/*:35*//*39:*/
-#line 397 "ctangle.w"
+#line 404 "ctangle.w"
static void get_output(void);
/*:39*//*44:*/
-#line 473 "ctangle.w"
+#line 480 "ctangle.w"
static void flush_buffer(void);
/*:44*//*49:*/
-#line 549 "ctangle.w"
+#line 557 "ctangle.w"
static void phase_two(void);
/*:49*//*53:*/
-#line 585 "ctangle.w"
+#line 593 "ctangle.w"
static void output_defs(void);
static void out_char(eight_bits);
/*:53*//*65:*/
-#line 810 "ctangle.w"
+#line 819 "ctangle.w"
static eight_bits skip_ahead(void);
static boolean skip_comment(boolean);
/*:65*//*70:*/
-#line 924 "ctangle.w"
+#line 926 "ctangle.w"
static eight_bits get_next(void);
/*:70*//*84:*/
-#line 1208 "ctangle.w"
+#line 1219 "ctangle.w"
static void scan_repl(eight_bits);
/*:84*//*91:*/
-#line 1379 "ctangle.w"
+#line 1404 "ctangle.w"
static void scan_section(void);
/*:91*//*99:*/
-#line 1460 "ctangle.w"
+#line 1481 "ctangle.w"
static void phase_one(void);
/*:99*//*101:*/
-#line 1494 "ctangle.w"
+#line 1514 "ctangle.w"
static void skip_limbo(void);
/*:101*/
@@ -451,28 +459,28 @@ char**av)
argc= ac;argv= av;
program= ctangle;
/*21:*/
-#line 137 "ctangle.w"
+#line 139 "ctangle.w"
text_info->tok_start= tok_ptr= tok_mem;
text_ptr= text_info+1;text_ptr->tok_start= tok_mem;
/*:21*//*23:*/
-#line 147 "ctangle.w"
+#line 149 "ctangle.w"
init_node(name_dir);
/*:23*//*27:*/
-#line 201 "ctangle.w"
-last_unnamed= text_info;text_info->text_link= 0;
+#line 203 "ctangle.w"
+last_unnamed= text_info;text_info->text_link= macro;
/*:27*//*46:*/
-#line 493 "ctangle.w"
+#line 500 "ctangle.w"
cur_out_file= end_output_files= output_files+max_files;
/*:46*//*58:*/
-#line 694 "ctangle.w"
+#line 706 "ctangle.w"
{
int i;
@@ -480,13 +488,14 @@ for(i= 0;i<128;i++)sprintf(translit[i],"X%02X",(unsigned int)(128+i));
}
/*:58*//*63:*/
-#line 773 "ctangle.w"
+#line 782 "ctangle.w"
{
int c;
for(c= 0;c<256;c++)ccode[c]= ignore;
+}
ccode[' ']= ccode['\t']= ccode['\n']= ccode['\v']= ccode['\r']= ccode['\f']
= ccode['*']= new_section;
-ccode['@']= '@';ccode['=']= string;
+ccode['@']= (eight_bits)'@';ccode['=']= string;
ccode['d']= ccode['D']= definition;
ccode['f']= ccode['F']= ccode['s']= ccode['S']= format_code;
ccode['c']= ccode['C']= ccode['p']= ccode['P']= begin_C;
@@ -497,10 +506,9 @@ ccode['l']= ccode['L']= translit_code;
ccode['&']= join;
ccode['<']= ccode['(']= section_name;
ccode['\'']= ord;
-}
/*:63*//*78:*/
-#line 1103 "ctangle.w"
+#line 1114 "ctangle.w"
section_text[0]= ' ';
/*:78*/
@@ -514,7 +522,7 @@ return wrap_up();
}
/*:2*//*24:*/
-#line 153 "ctangle.w"
+#line 155 "ctangle.w"
boolean names_match(
name_pointer p,
@@ -522,12 +530,11 @@ const char*first,
size_t l,
eight_bits t)
{(void)t;
-if(length(p)!=l)return false;
-return!strncmp(first,p->byte_start,l);
+return length(p)==l&&strncmp(first,p->byte_start,l)==0;
}
/*:24*//*25:*/
-#line 169 "ctangle.w"
+#line 170 "ctangle.w"
void
init_node(
@@ -539,7 +546,7 @@ void
init_p(name_pointer p,eight_bits t){(void)p;(void)t;}
/*:25*//*29:*/
-#line 231 "ctangle.w"
+#line 236 "ctangle.w"
static void
store_two_bytes(
@@ -551,7 +558,7 @@ if(tok_ptr+2> tok_mem_end)overflow("token");
}
/*:29*//*34:*/
-#line 309 "ctangle.w"
+#line 315 "ctangle.w"
static void
push_level(
@@ -568,7 +575,7 @@ cur_section= 0;
}
/*:34*//*36:*/
-#line 332 "ctangle.w"
+#line 338 "ctangle.w"
static void
pop_level(
@@ -584,7 +591,7 @@ if(stack_ptr> stack)cur_state= *stack_ptr;
}
/*:36*//*38:*/
-#line 368 "ctangle.w"
+#line 374 "ctangle.w"
static void
get_output(void)
@@ -604,10 +611,10 @@ else if(a<0200)out_char(a);
else{
a= (a-0200)*0400+*cur_byte++;
switch(a/024000){
-case 0:cur_val= a;out_char(identifier);break;
+case 0:cur_val= (int)a;out_char(identifier);break;
case 1:if(a==output_defs_flag)output_defs();
else/*40:*/
-#line 402 "ctangle.w"
+#line 409 "ctangle.w"
{
a-= 024000;
@@ -621,24 +628,25 @@ goto restart;
}
/*:40*/
-#line 389 "ctangle.w"
+#line 395 "ctangle.w"
break;
-default:cur_val= a-050000;if(cur_val> 0)cur_section= cur_val;
+default:cur_val= (int)a-050000;
+if(cur_val> 0)cur_section= (sixteen_bits)cur_val;
out_char(section_number);
}
}
}
/*:38*//*43:*/
-#line 460 "ctangle.w"
+#line 467 "ctangle.w"
static void
flush_buffer(void)
{
C_putc('\n');
if(cur_line%100==0&&show_progress){
-printf(".");
+putchar('.');
if(cur_line%500==0)printf("%d",cur_line);
update_terminal;
}
@@ -646,38 +654,41 @@ cur_line++;
}
/*:43*//*48:*/
-#line 514 "ctangle.w"
+#line 519 "ctangle.w"
static void
phase_two(void){
+phase= 2;
web_file_open= false;
cur_line= 1;
/*33:*/
-#line 298 "ctangle.w"
+#line 304 "ctangle.w"
stack_ptr= stack+1;cur_name= name_dir;cur_repl= text_info->text_link+text_info;
cur_byte= cur_repl->tok_start;cur_end= (cur_repl+1)->tok_start;cur_section= 0;
/*:33*/
-#line 519 "ctangle.w"
+#line 525 "ctangle.w"
/*51:*/
-#line 578 "ctangle.w"
+#line 586 "ctangle.w"
if(!output_defs_seen)
output_defs();
/*:51*/
-#line 520 "ctangle.w"
+#line 526 "ctangle.w"
-if(text_info->text_link==0&&cur_out_file==end_output_files){
+if(text_info->text_link==macro&&cur_out_file==end_output_files){
fputs("\n! No program text was specified.",stdout);mark_harmless;
}
else{
if(cur_out_file==end_output_files){
-if(show_progress)
+if(show_progress){
printf("\nWriting the output file (%s):",C_file_name);
+update_terminal;
+}
}
else{
if(show_progress){
@@ -686,24 +697,24 @@ fputs("\nWriting the output files:",stdout);
printf(" (%s)",C_file_name);
update_terminal;
}
-if(text_info->text_link==0)goto writeloop;
+if(text_info->text_link==macro)goto writeloop;
}
while(stack_ptr> stack)get_output();
flush_buffer();
writeloop:/*50:*/
-#line 555 "ctangle.w"
+#line 563 "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,"wb");
-if(C_file==0)fatal("! Cannot open output file ",output_file_name);
+if((C_file= fopen(output_file_name,"wb"))==NULL)
+fatal("! Cannot open output file ",output_file_name);
if(show_progress){printf("\n(%s)",output_file_name);update_terminal;}
cur_line= 1;
stack_ptr= stack+1;
-cur_name= (*an_output_file);
+cur_name= *an_output_file;
cur_repl= (text_pointer)cur_name->equiv;
cur_byte= cur_repl->tok_start;
cur_end= (cur_repl+1)->tok_start;
@@ -712,7 +723,7 @@ flush_buffer();
}
/*:50*/
-#line 541 "ctangle.w"
+#line 549 "ctangle.w"
if(show_happiness){
if(show_progress)new_line;
@@ -722,7 +733,7 @@ fputs("Done.",stdout);
}
/*:48*//*54:*/
-#line 589 "ctangle.w"
+#line 600 "ctangle.w"
static void
output_defs(void)
@@ -730,7 +741,7 @@ output_defs(void)
sixteen_bits a;
push_level(NULL);
for(cur_text= text_info+1;cur_text<text_ptr;cur_text++)
-if(cur_text->text_link==0){
+if(cur_text->text_link==macro){
cur_byte= cur_text->tok_start;
cur_end= (cur_text+1)->tok_start;
C_printf("%s","#define ");
@@ -746,11 +757,12 @@ else if(a<0200)out_char(a);
else{
a= (a-0200)*0400+*cur_byte++;
if(a<024000){
-cur_val= a;out_char(identifier);
+cur_val= (int)a;out_char(identifier);
}
-else if(a<050000){confusion("macro defs have strange char");}
+else if(a<050000)confusion("macro defs have strange char");
else{
-cur_val= a-050000;cur_section= cur_val;out_char(section_number);
+cur_val= (int)a-050000;cur_section= (sixteen_bits)cur_val;
+out_char(section_number);
}
}
@@ -762,7 +774,7 @@ pop_level(false);
}
/*:54*//*55:*/
-#line 632 "ctangle.w"
+#line 644 "ctangle.w"
static void
out_char(
@@ -775,55 +787,52 @@ case'\n':if(protect&&out_state!=verbatim)C_putc(' ');
if(protect||out_state==verbatim)C_putc('\\');
flush_buffer();if(out_state!=verbatim)out_state= normal;break;
/*59:*/
-#line 700 "ctangle.w"
+#line 712 "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){
+for(j= (cur_val+name_dir)->byte_start,k= (cur_val+name_dir+1)->byte_start;
+j<k;j++)
if((eight_bits)(*j)<0200)C_putc(*j);
else C_printf("%s",translit[(eight_bits)(*j)-0200]);
-j++;
-}
out_state= num_or_id;break;
/*:59*/
-#line 643 "ctangle.w"
+#line 655 "ctangle.w"
/*60:*/
-#line 713 "ctangle.w"
+#line 722 "ctangle.w"
case section_number:
if(cur_val> 0)C_printf("/*%d:*/",cur_val);
else if(cur_val<0)C_printf("/*:%d*/",-cur_val);
else if(protect){
cur_byte+= 4;
-cur_char= '\n';
+cur_char= (eight_bits)'\n';
goto restart;
}else{
sixteen_bits a;
-a= 0400**cur_byte++;
+a= *cur_byte++*0400;
a+= *cur_byte++;
-C_printf("\n#line %d \"",a);
+C_printf("\n#line %d \"",(int)a);
-cur_val= *cur_byte++;
-cur_val= 0400*(cur_val-0200)+*cur_byte++;
+cur_val= (int)(*cur_byte++-0200)*0400;
+cur_val+= *cur_byte++;
for(j= (cur_val+name_dir)->byte_start,k= (cur_val+name_dir+1)->byte_start;
j<k;j++){
if(*j=='\\'||*j=='"')C_putc('\\');
C_putc(*j);
}
-C_printf("%s","\"\n");
+C_putc('"');C_putc('\n');
}
break;
/*:60*/
-#line 644 "ctangle.w"
+#line 656 "ctangle.w"
/*56:*/
-#line 662 "ctangle.w"
+#line 674 "ctangle.w"
case plus_plus:C_putc('+');C_putc('+');out_state= normal;break;
case minus_minus:C_putc('-');C_putc('-');out_state= normal;break;
@@ -844,7 +853,7 @@ case minus_gt_ast:C_putc('-');C_putc('>');C_putc('*');out_state= normal;
break;
/*:56*/
-#line 645 "ctangle.w"
+#line 657 "ctangle.w"
case'=':case'>':C_putc(cur_char);C_putc(' ');
out_state= normal;break;
@@ -863,7 +872,7 @@ default:C_putc(cur_char);out_state= normal;break;
}
/*:55*//*64:*/
-#line 794 "ctangle.w"
+#line 803 "ctangle.w"
static eight_bits
skip_ahead(void)
@@ -881,7 +890,7 @@ if(c!=ignore||*(loc-1)=='>')return c;
}
/*:64*//*67:*/
-#line 833 "ctangle.w"
+#line 842 "ctangle.w"
static boolean skip_comment(
boolean is_long_comment)
@@ -915,22 +924,24 @@ else loc++;
}
/*:67*//*69:*/
-#line 881 "ctangle.w"
+#line 883 "ctangle.w"
static eight_bits
get_next(void)
{
-static int preprocessing= 0;
+static boolean preprocessing= false;
eight_bits c;
while(true){
if(loc> limit){
-if(preprocessing&&*(limit-1)!='\\')preprocessing= 0;
+if(preprocessing&&*(limit-1)!='\\')preprocessing= false;
if(get_line()==false)return new_section;
else if(print_where&&!no_where){
print_where= false;
/*85:*/
-#line 1214 "ctangle.w"
+#line 1229 "ctangle.w"
+{
+eight_bits a;
store_two_bytes(0150000);
if(changing&&include_depth==change_depth){
id_first= change_file_name;
@@ -940,41 +951,49 @@ id_first= cur_file_name;
store_two_bytes((sixteen_bits)cur_line);
}
id_loc= id_first+strlen(id_first);
-{int a_l= id_lookup(id_first,id_loc,0)-name_dir;app_repl((a_l/0400)+0200);
-app_repl(a_l%0400);}
+store_id(a);
+}
/*:85*/
-#line 893 "ctangle.w"
+#line 895 "ctangle.w"
}
-else return'\n';
+else return(eight_bits)'\n';
}
-c= *loc;
+c= (eight_bits)*loc;
if(comment_continues||(c=='/'&&(*(loc+1)=='*'||*(loc+1)=='/'))){
-skip_comment(comment_continues||*(loc+1)=='*');
+if(skip_comment(comment_continues||*(loc+1)=='*'))return'\n';
-if(comment_continues)return'\n';
else continue;
}
loc++;
if(xisdigit(c)||c=='.')/*73:*/
-#line 964 "ctangle.w"
+#line 967 "ctangle.w"
{
+boolean hex_flag= false;
id_first= loc-1;
if(*id_first=='.'&&!xisdigit(*loc))goto mistake;
if(*id_first=='0'){
if(*loc=='x'||*loc=='X'){
-loc++;while(xisxdigit(*loc))loc++;goto found;
+hex_flag= true;
+loc++;while(xisxdigit(*loc)||*loc=='\'')loc++;
+}
+else if(*loc=='b'||*loc=='B'){
+loc++;while(*loc=='0'||*loc=='1'||*loc=='\'')loc++;goto found;
}
}
-while(xisdigit(*loc))loc++;
+while(xisdigit(*loc)||*loc=='\'')loc++;
if(*loc=='.'){
loc++;
-while(xisdigit(*loc))loc++;
+while((hex_flag&&xisxdigit(*loc))||xisdigit(*loc)||*loc=='\'')loc++;
}
if(*loc=='e'||*loc=='E'){
if(*++loc=='+'||*loc=='-')loc++;
-while(xisdigit(*loc))loc++;
+while(xisdigit(*loc)||*loc=='\'')loc++;
+}
+else if(hex_flag&&(*loc=='p'||*loc=='P')){
+if(*++loc=='+'||*loc=='-')loc++;
+while(xisxdigit(*loc)||*loc=='\'')loc++;
}
found:while(*loc=='u'||*loc=='U'||*loc=='l'||*loc=='L'
||*loc=='f'||*loc=='F')loc++;
@@ -983,19 +1002,19 @@ return constant;
}
/*:73*/
-#line 905 "ctangle.w"
+#line 906 "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"
+#line 1004 "ctangle.w"
{
-char delim= c;
+char delim= (char)c;
id_first= section_text+1;
id_loc= section_text;*++id_loc= delim;
if(delim=='L'||delim=='u'||delim=='U'){
-if(delim=='u'&&*loc=='8'){*++id_loc= *loc++;}
+if(delim=='u'&&*loc=='8')*++id_loc= *loc++;
delim= *loc++;*++id_loc= delim;
}
while(true){
@@ -1011,16 +1030,16 @@ err_print("! Input ended in middle of string");loc= buffer;break;
else if(++id_loc<=section_text_end)*id_loc= '\n';
}
-if((c= *loc++)==delim){
-if(++id_loc<=section_text_end)*id_loc= c;
+if((c= (eight_bits)*loc++)==delim){
+if(++id_loc<=section_text_end)*id_loc= (char)c;
break;
}
if(c=='\\'){
if(loc>=limit)continue;
if(++id_loc<=section_text_end)*id_loc= '\\';
-c= *loc++;
+c= (eight_bits)*loc++;
}
-if(++id_loc<=section_text_end)*id_loc= c;
+if(++id_loc<=section_text_end)*id_loc= (char)c;
}
if(id_loc>=section_text_end){
fputs("\n! String too long: ",stdout);
@@ -1033,26 +1052,27 @@ return string;
}
/*:74*/
-#line 909 "ctangle.w"
+#line 910 "ctangle.w"
-else if(isalpha(c)||isxalpha(c)||ishigh(c))
+else if(isalpha((int)c)||isxalpha(c)||ishigh(c))
/*72:*/
-#line 957 "ctangle.w"
+#line 958 "ctangle.w"
{
id_first= --loc;
-while(isalpha((eight_bits)*++loc)||isdigit((eight_bits)*loc)
-||isxalpha((eight_bits)*loc)||ishigh((eight_bits)*loc));
+do
+++loc;
+while(isalpha((int)*loc)||isdigit((int)*loc)
+||isxalpha(*loc)||ishigh(*loc));
id_loc= loc;return identifier;
}
/*:72*/
-#line 911 "ctangle.w"
+#line 912 "ctangle.w"
else if(c=='@')/*75:*/
-#line 1037 "ctangle.w"
-{
-c= ccode[(eight_bits)*loc++];
-switch(c){
+#line 1049 "ctangle.w"
+
+switch(c= ccode[(eight_bits)*loc++]){
case ignore:continue;
case translit_code:err_print("! Use @l in limbo only");continue;
@@ -1065,25 +1085,24 @@ continue;
case section_name:
cur_section_name_char= *(loc-1);
/*77:*/
-#line 1085 "ctangle.w"
+#line 1094 "ctangle.w"
{
-char*k;
+char*k= section_text;
/*79:*/
-#line 1105 "ctangle.w"
+#line 1116 "ctangle.w"
-k= section_text;
while(true){
if(loc> limit&&get_line()==false){
err_print("! Input ended in section name");
loc= buffer+1;break;
}
-c= *loc;
+c= (eight_bits)*loc;
/*80:*/
-#line 1129 "ctangle.w"
+#line 1139 "ctangle.w"
if(c=='@'){
-c= *(loc+1);
+c= (eight_bits)*(loc+1);
if(c=='>'){
loc+= 2;break;
}
@@ -1099,13 +1118,13 @@ err_print("! Nesting of section names not allowed");break;
}
/*:80*/
-#line 1114 "ctangle.w"
+#line 1124 "ctangle.w"
loc++;if(k<section_text_end)k++;
if(xisspace(c)){
-c= ' ';if(*(k-1)==' ')k--;
+c= (eight_bits)' ';if(*(k-1)==' ')k--;
}
-*k= c;
+*k= (char)c;
}
if(k>=section_text_end){
fputs("\n! Section name too long: ",stdout);
@@ -1116,14 +1135,16 @@ printf("...");mark_harmless;
if(*k==' '&&k> section_text)k--;
/*:79*/
-#line 1087 "ctangle.w"
+#line 1096 "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);
+cur_section_name= section_lookup(section_text+1,k-3,true);
+
+else cur_section_name= section_lookup(section_text+1,k,false);
+
if(cur_section_name_char=='(')
/*47:*/
-#line 497 "ctangle.w"
+#line 504 "ctangle.w"
{
for(an_output_file= cur_out_file;
@@ -1132,42 +1153,38 @@ if(*an_output_file==cur_section_name)break;
if(an_output_file==end_output_files){
if(cur_out_file> output_files)
*--cur_out_file= cur_section_name;
-else{
-overflow("output files");
-}
+else overflow("output files");
}
}
/*:47*/
-#line 1093 "ctangle.w"
+#line 1104 "ctangle.w"
return section_name;
}
/*:77*/
-#line 1051 "ctangle.w"
+#line 1062 "ctangle.w"
case string:/*81:*/
-#line 1151 "ctangle.w"
-{
+#line 1161 "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;
-}
/*:81*/
-#line 1052 "ctangle.w"
+#line 1063 "ctangle.w"
case ord:/*76:*/
-#line 1064 "ctangle.w"
+#line 1074 "ctangle.w"
id_first= loc;
-if(*loc=='\\'){
+if(*loc=='\\')
if(*++loc=='\'')loc++;
-}
while(*loc!='\''){
if(*loc=='@'){
if(*(loc+1)!='@')
@@ -1185,34 +1202,35 @@ loc++;
return ord;
/*:76*/
-#line 1053 "ctangle.w"
+#line 1064 "ctangle.w"
default:return c;
}
-}
/*:75*/
-#line 912 "ctangle.w"
+#line 913 "ctangle.w"
else if(xisspace(c)){
if(!preprocessing||loc> limit)continue;
-else return' ';
+else return(eight_bits)' ';
+
}
-else if(c=='#'&&loc==buffer+1)preprocessing= 1;
+else if(c=='#'&&loc==buffer+1)preprocessing= true;
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);
-}
-break;
+}break;
case':':if(*loc==':')compress(colon_colon);break;
case'=':if(*loc=='=')compress(eq_eq);break;
case'>':if(*loc=='='){compress(gt_eq);}
@@ -1225,23 +1243,25 @@ case'!':if(*loc=='=')compress(non_eq);break;
}
/*:71*/
-#line 919 "ctangle.w"
+#line 921 "ctangle.w"
return c;
}
}
/*:69*//*83:*/
-#line 1186 "ctangle.w"
+#line 1197 "ctangle.w"
static void
scan_repl(
eight_bits t)
{
sixteen_bits a;
-if(t==section_name){/*85:*/
-#line 1214 "ctangle.w"
+if(t==section_name)/*85:*/
+#line 1229 "ctangle.w"
+{
+eight_bits a;
store_two_bytes(0150000);
if(changing&&include_depth==change_depth){
id_first= change_file_name;
@@ -1251,23 +1271,21 @@ id_first= cur_file_name;
store_two_bytes((sixteen_bits)cur_line);
}
id_loc= id_first+strlen(id_first);
-{int a_l= id_lookup(id_first,id_loc,0)-name_dir;app_repl((a_l/0400)+0200);
-app_repl(a_l%0400);}
+store_id(a);
+}
/*:85*/
-#line 1192 "ctangle.w"
-}
+#line 1203 "ctangle.w"
+
while(true)switch(a= get_next()){
/*86:*/
-#line 1227 "ctangle.w"
+#line 1244 "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 identifier:store_id(a);break;
case section_name:if(t!=section_name)goto done;
else{
/*87:*/
-#line 1260 "ctangle.w"
+#line 1278 "ctangle.w"
{
char*try_loc= loc;
while(*try_loc==' '&&try_loc<limit)try_loc++;
@@ -1280,14 +1298,16 @@ if(*try_loc=='=')err_print("! Missing `@ ' before a named section");
}
/*:87*/
-#line 1233 "ctangle.w"
+#line 1248 "ctangle.w"
a= cur_section_name-name_dir;
app_repl((a/0400)+0250);
app_repl(a%0400);
/*85:*/
-#line 1214 "ctangle.w"
+#line 1229 "ctangle.w"
+{
+eight_bits a;
store_two_bytes(0150000);
if(changing&&include_depth==change_depth){
id_first= change_file_name;
@@ -1297,13 +1317,14 @@ id_first= cur_file_name;
store_two_bytes((sixteen_bits)cur_line);
}
id_loc= id_first+strlen(id_first);
-{int a_l= id_lookup(id_first,id_loc,0)-name_dir;app_repl((a_l/0400)+0200);
-app_repl(a_l%0400);}
+store_id(a);
+}
/*:85*/
-#line 1237 "ctangle.w"
-break;
+#line 1252 "ctangle.w"
+
}
+break;
case output_defs_code:if(t!=section_name)err_print("! Misplaced @h");
else{
@@ -1312,8 +1333,10 @@ a= output_defs_flag;
app_repl((a/0400)+0200);
app_repl(a%0400);
/*85:*/
-#line 1214 "ctangle.w"
+#line 1229 "ctangle.w"
+{
+eight_bits a;
store_two_bytes(0150000);
if(changing&&include_depth==change_depth){
id_first= change_file_name;
@@ -1323,17 +1346,17 @@ id_first= cur_file_name;
store_two_bytes((sixteen_bits)cur_line);
}
id_loc= id_first+strlen(id_first);
-{int a_l= id_lookup(id_first,id_loc,0)-name_dir;app_repl((a_l/0400)+0200);
-app_repl(a_l%0400);}
+store_id(a);
+}
/*:85*/
-#line 1246 "ctangle.w"
+#line 1262 "ctangle.w"
}
break;
case constant:case string:
/*88:*/
-#line 1271 "ctangle.w"
+#line 1295 "ctangle.w"
app_repl(a);
while(id_first<id_loc){
@@ -1342,20 +1365,23 @@ if(*(id_first+1)=='@')id_first++;
else err_print("! Double @ should be used in string");
}
+else if(a==constant&&*id_first=='\''&&!keep_digit_separators)
+id_first++;
app_repl(*id_first++);
}
-app_repl(a);break;
+app_repl(a);
/*:88*/
-#line 1250 "ctangle.w"
+#line 1266 "ctangle.w"
+break;
case ord:
/*89:*/
-#line 1287 "ctangle.w"
+#line 1313 "ctangle.w"
{
-int c= (eight_bits)*id_first;
+int c= (int)((eight_bits)*id_first);
if(c=='\\'){
-c= *++id_first;
+c= (int)((eight_bits)*++id_first);
if(c>='0'&&c<='7'){
c-= '0';
if(*(id_first+1)>='0'&&*(id_first+1)<='7'){
@@ -1374,15 +1400,15 @@ case'r':c= '\r';break;
case'a':c= '\7';break;
case'?':c= '?';break;
case'x':
-if(xisdigit(*(id_first+1)))c= *(++id_first)-'0';
+if(xisdigit(*(id_first+1)))c= (int)(*(++id_first)-'0');
else if(xisxdigit(*(id_first+1))){
++id_first;
-c= toupper((eight_bits)*id_first)-'A'+10;
+c= toupper((int)*id_first)-'A'+10;
}
-if(xisdigit(*(id_first+1)))c= 16*c+*(++id_first)-'0';
+if(xisdigit(*(id_first+1)))c= 16*c+(int)(*(++id_first)-'0');
else if(xisxdigit(*(id_first+1))){
++id_first;
-c= 16*c+toupper((eight_bits)*id_first)-'A'+10;
+c= 16*c+toupper((int)*id_first)-(int)'A'+10;
}
break;
case'\\':c= '\\';break;
@@ -1394,16 +1420,16 @@ default:err_print("! Unrecognized escape sequence");
}
app_repl(constant);
-if(c>=100)app_repl('0'+c/100);
-if(c>=10)app_repl('0'+(c/10)%10);
-app_repl('0'+c%10);
+if(c>=100)app_repl((int)'0'+c/100);
+if(c>=10)app_repl((int)'0'+(c/10)%10);
+app_repl((int)'0'+c%10);
app_repl(constant);
}
-break;
/*:89*/
-#line 1252 "ctangle.w"
+#line 1269 "ctangle.w"
+break;
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;
@@ -1412,7 +1438,7 @@ err_print("! @d, @f and @c are ignored in C text");continue;
case new_section:goto done;
/*:86*/
-#line 1197 "ctangle.w"
+#line 1208 "ctangle.w"
case')':app_repl(a);
if(t==macro)app_repl(' ');
@@ -1425,7 +1451,7 @@ cur_text= text_ptr;(++text_ptr)->tok_start= tok_ptr;
}
/*:83*//*90:*/
-#line 1346 "ctangle.w"
+#line 1371 "ctangle.w"
static void
scan_section(void)
@@ -1435,12 +1461,12 @@ text_pointer q;
sixteen_bits a;
section_count++;no_where= true;
if(*(loc-1)=='*'&&show_progress){
-printf("*%d",section_count);update_terminal;
+printf("*%d",(int)section_count);update_terminal;
}
-next_control= 0;
+next_control= ignore;
while(true){
/*92:*/
-#line 1387 "ctangle.w"
+#line 1412 "ctangle.w"
while(next_control<definition)
@@ -1449,30 +1475,27 @@ loc-= 2;next_control= get_next();
}
/*:92*/
-#line 1360 "ctangle.w"
+#line 1385 "ctangle.w"
if(next_control==definition){
/*93:*/
-#line 1394 "ctangle.w"
-{
+#line 1419 "ctangle.w"
+
while((next_control= get_next())=='\n');
if(next_control!=identifier){
err_print("! Definition flushed, must start with identifier");
continue;
}
-app_repl(((a= id_lookup(id_first,id_loc,0)-name_dir)/0400)+0200);
-
-app_repl(a%0400);
+store_id(a);
if(*loc!='('){
app_repl(string);app_repl(' ');app_repl(string);
}
scan_repl(macro);
cur_text->text_link= macro;
-}
/*:93*/
-#line 1362 "ctangle.w"
+#line 1387 "ctangle.w"
continue;
}
@@ -1482,14 +1505,14 @@ p= name_dir;break;
if(next_control==section_name){
p= cur_section_name;
/*94:*/
-#line 1419 "ctangle.w"
+#line 1441 "ctangle.w"
while((next_control= get_next())=='+');
if(next_control!='='&&next_control!=eq_eq)
continue;
/*:94*/
-#line 1370 "ctangle.w"
+#line 1395 "ctangle.w"
break;
}
@@ -1497,23 +1520,23 @@ return;
}
no_where= print_where= false;
/*95:*/
-#line 1424 "ctangle.w"
+#line 1446 "ctangle.w"
/*96:*/
-#line 1429 "ctangle.w"
+#line 1451 "ctangle.w"
store_two_bytes((sixteen_bits)(0150000+section_count));
/*:96*/
-#line 1425 "ctangle.w"
+#line 1447 "ctangle.w"
scan_repl(section_name);
/*97:*/
-#line 1433 "ctangle.w"
+#line 1455 "ctangle.w"
-if(p==name_dir||p==0){
-(last_unnamed)->text_link= cur_text-text_info;last_unnamed= cur_text;
+if(p==name_dir||p==NULL){
+last_unnamed->text_link= cur_text-text_info;last_unnamed= cur_text;
}
else if(p->equiv==(void*)text_info)p->equiv= (void*)cur_text;
@@ -1527,16 +1550,16 @@ cur_text->text_link= section_flag;
/*:97*/
-#line 1427 "ctangle.w"
+#line 1449 "ctangle.w"
/*:95*/
-#line 1376 "ctangle.w"
+#line 1401 "ctangle.w"
}
/*:90*//*98:*/
-#line 1448 "ctangle.w"
+#line 1470 "ctangle.w"
static void
phase_one(void){
@@ -1546,26 +1569,24 @@ reset_input();
skip_limbo();
while(!input_has_ended)scan_section();
check_complete();
-phase= 2;
}
/*:98*//*100:*/
-#line 1465 "ctangle.w"
+#line 1486 "ctangle.w"
static void
skip_limbo(void)
{
-char c;
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;
+char c= *loc++;
switch(ccode[(eight_bits)c]){
+case new_section:return;
case translit_code:/*102:*/
-#line 1496 "ctangle.w"
+#line 1516 "ctangle.w"
while(xisspace(*loc)&&loc<limit)loc++;
loc+= 3;
@@ -1590,11 +1611,11 @@ translit[i-0200][loc-beg]= '\0';
}
/*:102*/
-#line 1478 "ctangle.w"
+#line 1498 "ctangle.w"
break;
case format_code:case'@':break;
case control_text:if(c=='q'||c=='Q'){
-while((c= skip_ahead())=='@');
+while((c= (char)skip_ahead())=='@');
if(*(loc-1)!='>')
err_print("! Double @ should be used in control text");
@@ -1608,18 +1629,18 @@ default:err_print("! Double @ should be used in limbo");
}
/*:100*//*103:*/
-#line 1522 "ctangle.w"
+#line 1542 "ctangle.w"
void
print_stats(void){
puts("\nMemory usage statistics:");
-printf("%ld names (out of %ld)\n",
+printf("%td names (out of %ld)\n",
(ptrdiff_t)(name_ptr-name_dir),(long)max_names);
-printf("%ld replacement texts (out of %ld)\n",
+printf("%td replacement texts (out of %ld)\n",
(ptrdiff_t)(text_ptr-text_info),(long)max_texts);
-printf("%ld bytes (out of %ld)\n",
+printf("%td bytes (out of %ld)\n",
(ptrdiff_t)(byte_ptr-byte_mem),(long)max_bytes);
-printf("%ld tokens (out of %ld)\n",
+printf("%td tokens (out of %ld)\n",
(ptrdiff_t)(tok_ptr-tok_mem),(long)max_toks);
}
diff --git a/web/c_cpp/cweb/ctangle.w b/web/c_cpp/cweb/ctangle.w
index e7e2d311fe..1a9e8065af 100644
--- a/web/c_cpp/cweb/ctangle.w
+++ b/web/c_cpp/cweb/ctangle.w
@@ -2,7 +2,7 @@
% This program by Silvio Levy and Donald E. Knuth
% is based on a program by Knuth.
% It is distributed WITHOUT ANY WARRANTY, express or implied.
-% Version 4.2 --- February 2021
+% Version 4.6 --- December 2021
% Copyright (C) 1987,1990,1993,2000 Silvio Levy and Donald E. Knuth
@@ -27,11 +27,11 @@
\mathchardef\RA="3221 % right arrow
\mathchardef\BA="3224 % double arrow
-\def\title{CTANGLE (Version 4.2)}
+\def\title{CTANGLE (Version 4.6)}
\def\topofcontents{\null\vfill
\centerline{\titlefont The {\ttitlefont CTANGLE} processor}
\vskip 15pt
- \centerline{(Version 4.2)}
+ \centerline{(Version 4.6)}
\vfill}
\def\botofcontents{\vfill
\noindent
@@ -61,7 +61,7 @@ Joachim Schrod, Lee Wittenberg, and others who have contributed improvements.
The ``banner line'' defined here should be changed whenever \.{CTANGLE}
is modified.
-@d banner "This is CTANGLE (Version 4.2)"
+@d banner "This is CTANGLE (Version 4.6)"
@c
@<Include files@>@/
@@ -75,7 +75,7 @@ is modified.
two phases: First it reads the source file, saving the \CEE/ code in
compressed form; then it shuffles and outputs the code.
-Please read the documentation for \.{common}, the set of routines common
+Please read the documentation for \.{COMMON}, the set of routines common
to \.{CTANGLE} and \.{CWEAVE}, before proceeding further.
@c
@@ -126,7 +126,9 @@ typedef struct {
} text;
typedef text *text_pointer;
-@ @<Private...@>=
+@ @d max_texts 2500 /* number of replacement texts, must be less than 10240 */
+@d max_toks 270000 /* number of bytes in compressed \CEE/ code */
+@<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| */
@@ -151,14 +153,13 @@ init_node(name_dir); /* the undefined section has no replacement text */
starting at position |first| equals the identifier pointed to by |p|:
@c
-boolean names_match(@t\1\1@>
+boolean names_match(
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);
+eight_bits t) /* not used by \.{TANGLE} */
+{@+(void)t;@/
+ return length(p)==l && strncmp(first,p->byte_start,l)==0;
}
@ The common lookup routine refers to separate routines |init_node| and
@@ -193,12 +194,13 @@ name, and they also tie together all the \CEE/ texts of unnamed sections.
The replacement text pointer for the first unnamed section appears in
|text_info->text_link|, and the most recent such pointer is |last_unnamed|.
+@d macro 0
@d section_flag max_texts /* final |text_link| in section replacement texts */
@<Private...@>=
static text_pointer last_unnamed; /* most recent replacement text of unnamed section */
-@ @<Set init...@>= last_unnamed=text_info; text_info->text_link=0;
+@ @<Set init...@>= last_unnamed=text_info; text_info->text_link=macro;
@ If the first byte of a token is less than |0200|, the token occupies a
single byte. Otherwise we make a sixteen-bit token by combining two consecutive
@@ -214,16 +216,19 @@ Codes less than |0200| are 7-bit |char| codes that represent themselves.
Some of the 7-bit codes will not be present, however, so we can
use them for special purposes. The following symbolic names are used:
-\yskip \hang |join| denotes the concatenation of adjacent items with no
-space or line breaks allowed between them (the \.{@@\&} operation of \.{CWEB}).
+\yskip \hang |string| denotes the beginning or end of a string
+or a verbatim construction.
+
+\hang |constant| denotes a numerical constant.
-\hang |string| denotes the beginning or end of a string, verbatim
-construction or numerical constant.
+\hang |join| denotes the concatenation of adjacent items with no space
+or line breaks allowed between them (the \.{@@\&} operation of \.{CWEB}).
@^ASCII code dependencies@>
-@d string 02 /* takes the place of extended ASCII \.{\char2} */
-@d join 0177 /* takes the place of ASCII delete */
-@d output_defs_flag (2*024000-1)
+@d string 02 /* takes the place of ASCII \.{STX} */
+@d constant 03 /* takes the place of ASCII \.{ETX} */
+@d join 0177 /* takes the place of ASCII \.{DEL} */
+@d output_defs_flag (2*024000-1) /* |024000==(0250-0200)*0400| */
@ The following procedure is used to enter a two-byte value into
|tok_mem| when a replacement text is being generated.
@@ -276,7 +281,8 @@ typedef struct {
} output_state;
typedef output_state *stack_pointer;
-@ @d cur_end cur_state.end_field /* current ending location in |tok_mem| */
+@ @d stack_size 50 /* number of simultaneous levels of macro expansion */
+@d cur_end cur_state.end_field /* current ending location in |tok_mem| */
@d cur_byte cur_state.byte_field /* location of next output byte in |tok_mem|*/
@d cur_name cur_state.name_field /* pointer to current name being expanded */
@d cur_repl cur_state.repl_field /* pointer to current replacement text */
@@ -308,8 +314,8 @@ We assume that the \CEE/ compiler can copy structures.
@c
static void
-push_level(@t\1\1@> /* suspends the current level */
-name_pointer p@t\2\2@>)
+push_level( /* suspends the current level */
+name_pointer p)
{
if (stack_ptr==stack_end) overflow("stack");
*stack_ptr=cur_state;
@@ -331,8 +337,8 @@ text or returns the state to the most recently stacked level.
@c
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| */
+pop_level( /* do this when |cur_byte| reaches |cur_end| */
+boolean flag) /* |flag==false| means we are in |output_defs| */
{
if (flag && cur_repl->text_link<section_flag) { /* link to a continuation */
cur_repl=cur_repl->text_link+text_info; /* stay on the same level */
@@ -350,7 +356,7 @@ necessary stacking and unstacking. It sends the value |section_number|
if the next output begins or ends the replacement text of some section,
in which case |cur_val| is that section's number (if beginning) or the
negative of that value (if ending). (A section number of 0 indicates
-not the beginning or ending of a section, but a \&{\#line} command.)
+not the beginning or ending of a section, but a \#\&{line} command.)
And it sends the value |identifier|
if the next output is an identifier, in which case
|cur_val| points to that identifier name.
@@ -384,11 +390,12 @@ get_output(void) /* sends next token to |out_char| */
else {
a=(a-0200)*0400+*cur_byte++;
switch (a/024000) { /* |024000==(0250-0200)*0400| */
- case 0: cur_val=a; out_char(identifier); break;
+ case 0: cur_val=(int)a; out_char(identifier); break;
case 1: if (a==output_defs_flag) output_defs();
else @<Expand section |a-024000|, |goto restart|@>@;
break;
- default: cur_val=a-050000; if (cur_val>0) cur_section=cur_val;
+ default: cur_val=(int)a-050000;
+ if (cur_val>0) cur_section=(sixteen_bits)cur_val;
out_char(section_number);
}
}
@@ -463,7 +470,7 @@ flush_buffer(void) /* writes one line to output file */
{
C_putc('\n');
if (cur_line % 100 == 0 && show_progress) {
- printf(".");
+ putchar('.');
if (cur_line % 500 == 0) printf("%d",cur_line);
update_terminal; /* progress report */
}
@@ -502,9 +509,7 @@ complain we're out of room@>=
if (an_output_file==end_output_files) {
if (cur_out_file>output_files)
*--cur_out_file=cur_section_name;
- else {
- overflow("output files");
- }
+ else overflow("output files");
}
}
@@ -514,18 +519,21 @@ output.
@c
static void
phase_two (void) {
+ phase=2;
web_file_open=false;
cur_line=1;
@<Initialize the output stacks@>@;
@<Output macro definitions if appropriate@>@;
- if (text_info->text_link==0 && cur_out_file==end_output_files) {
+ if (text_info->text_link==macro && cur_out_file==end_output_files) {
fputs("\n! No program text was specified.",stdout); mark_harmless;
@.No program text...@>
}
else {
- if(cur_out_file==end_output_files) {
- if(show_progress)
+ if (cur_out_file==end_output_files) {
+ if (show_progress) {
printf("\nWriting the output file (%s):",C_file_name);
+ update_terminal;
+ }
}
else {
if (show_progress) {
@@ -534,7 +542,7 @@ phase_two (void) {
printf(" (%s)",C_file_name);
update_terminal;
}
- if (text_info->text_link==0) goto writeloop;
+ if (text_info->text_link==macro) goto writeloop;
}
while (stack_ptr>stack) get_output();
flush_buffer();
@@ -557,14 +565,14 @@ 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,"wb");
- if (C_file ==0) fatal("! Cannot open output file ",output_file_name);
+ if ((C_file=fopen(output_file_name,"wb"))==NULL)
+ fatal("! Cannot open output file ",output_file_name);
@.Cannot open output file@>
if (show_progress) { printf("\n(%s)",output_file_name); update_terminal; }
cur_line=1;
stack_ptr=stack+1;
- cur_name= (*an_output_file);
- cur_repl= (text_pointer)cur_name->equiv;
+ cur_name=*an_output_file;
+ cur_repl=(text_pointer)cur_name->equiv;
cur_byte=cur_repl->tok_start;
cur_end=(cur_repl+1)->tok_start;
while (stack_ptr > stack) get_output();
@@ -586,14 +594,17 @@ static boolean output_defs_seen=false;
static void output_defs(void);@/
static void out_char(eight_bits);
-@ @c
+@ @d C_printf(c,a) fprintf(C_file,c,a)
+@d C_putc(c) putc((int)(c),C_file) /* isn't \CEE/ wonderfully consistent? */
+
+@c
static void
output_defs(void)
{
sixteen_bits a;
push_level(NULL);
for (cur_text=text_info+1; cur_text<text_ptr; cur_text++)
- if (cur_text->text_link==0) { /* |cur_text| is the text for a macro */
+ if (cur_text->text_link==macro) { /* |cur_text| is the text for a |macro| */
cur_byte=cur_text->tok_start;
cur_end=(cur_text+1)->tok_start;
C_printf("%s","#define ");
@@ -609,11 +620,12 @@ output_defs(void)
else {
a=(a-0200)*0400+*cur_byte++;
if (a<024000) { /* |024000==(0250-0200)*0400| */
- cur_val=a; out_char(identifier);
+ cur_val=(int)a; out_char(identifier);
}
- else if (a<050000) { confusion("macro defs have strange char");}
+ else if (a<050000) confusion("macro defs have strange char");
else {
- cur_val=a-050000; cur_section=cur_val; out_char(section_number);
+ cur_val=(int)a-050000; cur_section=(sixteen_bits)cur_val;
+ out_char(section_number);
}
/* no other cases */
}
@@ -643,7 +655,7 @@ restart:
@/@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(' ');
+ case '=': case '>': C_putc(cur_char);@+C_putc(' ');
out_state=normal; break;
case join: out_state=unbreakable; break;
case constant: if (out_state==verbatim) {
@@ -659,7 +671,7 @@ restart:
}
}
-@ @<Cases like \.{!=}@>=
+@ @<Cases like \.{!=}@>=@t\1\quad@>
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;
@@ -697,41 +709,38 @@ static char translit[128][translit_length];
for (i=0;i<128;i++) sprintf(translit[i],"X%02X",(unsigned int)(128+i));
}
-@ @<Case of an identifier@>=
+@ @<Case of an identifier@>=@t\1\quad@>
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) {
+ for (j=(cur_val+name_dir)->byte_start, k=(cur_val+name_dir+1)->byte_start;
+ j<k; j++)
if ((eight_bits)(*j)<0200) C_putc(*j);
@^high-bit character handling@>
else C_printf("%s",translit[(eight_bits)(*j)-0200]);
- j++;
- }
out_state=num_or_id; break;
-@ @<Case of a sec...@>=
+@ @<Case of a sec...@>=@t\1\quad@>
case section_number:
if (cur_val>0) C_printf("/*%d:*/",cur_val);
else if(cur_val<0) C_printf("/*:%d*/",-cur_val);
else if (protect) {
cur_byte +=4; /* skip line number and file name */
- cur_char = '\n';
+ cur_char = (eight_bits)'\n';
goto restart;
} else {
sixteen_bits a;
- a=0400* *cur_byte++;
+ a=*cur_byte++ *0400;
a+=*cur_byte++; /* gets the line number */
- C_printf("\n#line %d \"",a);
+ C_printf("\n#line %d \"",(int)a);
@:line}{\.{\#line}@>
- cur_val=*cur_byte++;
- cur_val=0400*(cur_val-0200)+ *cur_byte++; /* points to the file name */
+ cur_val=(int)(*cur_byte++-0200)*0400;
+ cur_val+=*cur_byte++; /* points to the file name */
for (j=(cur_val+name_dir)->byte_start, k=(cur_val+name_dir+1)->byte_start;
j<k; j++) {
if (*j=='\\' || *j=='"') C_putc('\\');
C_putc(*j);
}
- C_printf("%s","\"\n");
+ C_putc('"');@+C_putc('\n');
}
break;
@@ -756,7 +765,7 @@ of these internal code numbers has been chosen to simplify the program logic;
larger numbers are given to the control codes that denote more significant
milestones.
-@d ignore 0 /* control code of no interest to \.{CTANGLE} */
+@d ignore 00 /* control code of no interest to \.{CTANGLE} */
@d ord 0302 /* control code for `\.{@@'}' */
@d control_text 0303 /* control code for `\.{@@t}', `\.{@@\^}', etc. */
@d translit_code 0304 /* control code for `\.{@@l}' */
@@ -773,20 +782,20 @@ static eight_bits ccode[256]; /* meaning of a char following \.{@@} */
@ @<Set ini...@>= {
int c; /* must be |int| so the |for| loop will end */
for (c=0; c<256; c++) ccode[c]=ignore;
- ccode[' ']=ccode['\t']=ccode['\n']=ccode['\v']=ccode['\r']=ccode['\f']
- =ccode['*']=new_section;
- ccode['@@']='@@'; ccode['=']=string;
- ccode['d']=ccode['D']=definition;
- ccode['f']=ccode['F']=ccode['s']=ccode['S']=format_code;
- ccode['c']=ccode['C']=ccode['p']=ccode['P']=begin_C;
- ccode['^']=ccode[':']=ccode['.']=ccode['t']=ccode['T']=
- ccode['q']=ccode['Q']=control_text;
- ccode['h']=ccode['H']=output_defs_code;
- ccode['l']=ccode['L']=translit_code;
- ccode['&']=join;
- ccode['<']=ccode['(']=section_name;
- ccode['\'']=ord;
}
+ccode[' ']=ccode['\t']=ccode['\n']=ccode['\v']=ccode['\r']=ccode['\f']
+ =ccode['*']=new_section;
+ccode['@@']=(eight_bits)'@@'; ccode['=']=string;
+ccode['d']=ccode['D']=definition;
+ccode['f']=ccode['F']=ccode['s']=ccode['S']=format_code;
+ccode['c']=ccode['C']=ccode['p']=ccode['P']=begin_C;
+ccode['^']=ccode[':']=ccode['.']=ccode['t']=ccode['T']=
+ccode['q']=ccode['Q']=control_text;
+ccode['h']=ccode['H']=output_defs_code;
+ccode['l']=ccode['L']=translit_code;
+ccode['&']=join;
+ccode['<']=ccode['(']=section_name;
+ccode['\'']=ord;
@ The |skip_ahead| procedure reads through the input at fairly high speed
until finding the next non-ignorable control code, which it returns.
@@ -817,7 +826,7 @@ to the output. If the comment is introduced by \.{/*}, |skip_comment|
proceeds until finding the end-comment token \.{*/} or a newline; in the
latter case |skip_comment| will be called again by |get_next|, since the
comment is not finished. This is done so that each newline in the
-\CEE/ part of a section is copied to the output; otherwise the \&{\#line}
+\CEE/ part of a section is copied to the output; otherwise the \#\&{line}
commands inserted into the \CEE/ file by the output routines become useless.
On the other hand, if the comment is introduced by \.{//} (i.e., if it
is a \CPLUSPLUS/ ``short comment''), it always is simply delimited by the next
@@ -831,15 +840,15 @@ No comment, long or short, is allowed to contain `\.{@@\ }' or `\.{@@*}'.
static boolean comment_continues=false; /* are we scanning a comment? */
@ @c
-static boolean skip_comment(@t\1\1@> /* skips over comments */
-boolean is_long_comment@t\2\2@>)
+static boolean skip_comment( /* skips over comments */
+boolean is_long_comment)
{
char c; /* current character */
while (true) {
if (loc>limit) {
if (is_long_comment) {
- if(get_line()) return comment_continues=true;
- else{
+ if (get_line()) return comment_continues=true;
+ else {
err_print("! Input ended in mid-comment");
@.Input ended in mid-comment@>
return comment_continues=false;
@@ -864,8 +873,6 @@ boolean is_long_comment@t\2\2@>)
@* Inputting the next token.
-@d constant 03
-
@<Private...@>=
static name_pointer cur_section_name; /* name of section just scanned */
static boolean no_where; /* suppress |print_where|? */
@@ -873,32 +880,26 @@ 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) ((eight_bits)(c)>0177)
-@^high-bit character handling@>
-
@c
static eight_bits
get_next(void) /* produces the next input token */
{
- static int preprocessing=0;
+ static boolean preprocessing=false;
eight_bits c; /* the current character */
while (true) {
if (loc>limit) {
- if (preprocessing && *(limit-1)!='\\') preprocessing=0;
+ if (preprocessing && *(limit-1)!='\\') preprocessing=false;
if (get_line()==false) return new_section;
else if (print_where && !no_where) {
print_where=false;
@<Insert the line number into |tok_mem|@>@;
}
- else return '\n';
+ else return (eight_bits)'\n';
}
- c=*loc;
+ c=(eight_bits)*loc;
if (comment_continues || (c=='/' && (*(loc+1)=='*' || *(loc+1)=='/'))) {
- skip_comment(comment_continues||*(loc+1)=='*');
+ if (skip_comment(comment_continues||*(loc+1)=='*')) return '\n';
/* scan to end of comment or newline */
- if (comment_continues) return '\n';
else continue;
}
loc++;
@@ -907,15 +908,16 @@ get_next(void) /* produces the next input token */
|| ((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))
+ else if (isalpha((int)c) || isxalpha(c) || ishigh(c))
@<Get an identifier@>@;
else if (c=='@@') @<Get control code and possible section name@>@;
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 (eight_bits)' ';
+ /* ignore spaces and tabs, unless |preprocessing| */
}
- else if (c=='#' && loc==buffer+1) preprocessing=1;
+ else if (c=='#' && loc==buffer+1) preprocessing=true;
mistake: @<Compress two-symbol operator@>@;
return c;
}
@@ -924,30 +926,29 @@ get_next(void) /* produces the next input token */
@ @<Predecl...@>=@+static eight_bits get_next(void);
@ The following code assigns values to the combinations \.{++},
-\.{--}, \.{->}, \.{>=}, \.{<=}, \.{==}, \.{<<}, \.{>>}, \.{!=}, \.{||} and
-\.{\&\&}, and to the \CPLUSPLUS/
+\.{--}, \.{->}, \.{>=}, \.{<=}, \.{==}, \.{<<}, \.{>>}, \.{!=}, %\.{||}
+\.{\v\v} and~\.{\&\&}, and to the \CPLUSPLUS/
combinations \.{...}, \.{::}, \.{.*} and \.{->*}.
The compound assignment operators (e.g., \.{+=}) are
treated as separate tokens.
-@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;
- case '.': if (*loc=='*') {compress(period_ast);}
+ case '-': if (*loc=='-') {@+compress(minus_minus);@+}
+ 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);
- }
- break;
+ loc++;@+compress(dot_dot_dot);
+ } break;
case ':': if (*loc==':') compress(colon_colon); break;
case '=': if (*loc=='=') compress(eq_eq); break;
- case '>': if (*loc=='=') {compress(gt_eq);}
+ case '>': if (*loc=='=') {@+compress(gt_eq);@+}
else if (*loc=='>') compress(gt_gt); break;
- case '<': if (*loc=='=') {compress(lt_eq);}
+ 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;
@@ -956,30 +957,41 @@ switch(c) {
@ @<Get an identifier@>= {
id_first=--loc;
- while (isalpha((eight_bits)*++loc) || isdigit((eight_bits)*loc) @|
- || isxalpha((eight_bits)*loc) || ishigh((eight_bits)*loc));
+ do
+ ++loc;
+ while (isalpha((int)*loc) || isdigit((int)*loc) @|
+ || isxalpha(*loc) || ishigh(*loc));
id_loc=loc; return identifier;
}
@ @<Get a constant@>= {
+ boolean hex_flag = false; /* are we reading a hexadecimal literal? */
id_first=loc-1;
if (*id_first=='.' && !xisdigit(*loc)) goto mistake; /* not a constant */
if (*id_first=='0') {
if (*loc=='x' || *loc=='X') { /* hex constant */
- loc++; while (xisxdigit(*loc)) loc++; goto found;
+ hex_flag = true;
+ loc++; while (xisxdigit(*loc) || *loc=='\'') loc++;
+ }
+ else if (*loc=='b' || *loc=='B') { /* binary constant */
+ loc++; while (*loc=='0' || *loc=='1' || *loc=='\'') loc++; goto found;
}
}
- while (xisdigit(*loc)) loc++;
+ while (xisdigit(*loc) || *loc=='\'') loc++;
if (*loc=='.') {
- loc++;
- while (xisdigit(*loc)) loc++;
+ loc++;
+ while ((hex_flag && xisxdigit(*loc)) || xisdigit(*loc) || *loc=='\'') loc++;
}
if (*loc=='e' || *loc=='E') { /* float constant */
if (*++loc=='+' || *loc=='-') loc++;
- while (xisdigit(*loc)) loc++;
+ while (xisdigit(*loc) || *loc=='\'') loc++;
}
- found: while (*loc=='u' || *loc=='U' || *loc=='l' || *loc=='L'
- || *loc=='f' || *loc=='F') loc++;
+ else if (hex_flag && (*loc=='p' || *loc=='P')) { /* hex float constant */
+ if (*++loc=='+' || *loc=='-') loc++;
+ while (xisxdigit(*loc) || *loc=='\'') loc++;
+ }
+found: while (*loc=='u' || *loc=='U' || *loc=='l' || *loc=='L'
+ || *loc=='f' || *loc=='F') loc++;
id_loc=loc;
return constant;
}
@@ -990,11 +1002,11 @@ delimiters if they are protected by a backslash. We follow this
convention, but do not allow the string to be longer than |longest_name|.
@<Get a string@>= {
- char delim = c; /* what started the string */
+ char delim = (char)c; /* what started the string */
id_first = section_text+1;
id_loc = section_text; *++id_loc=delim;
if (delim=='L' || delim=='u' || delim=='U') { /* wide character constant */
- if (delim=='u' && *loc=='8') { *++id_loc=*loc++; }
+ if (delim=='u' && *loc=='8') *++id_loc=*loc++;
delim=*loc++; *++id_loc=delim;
}
while (true) {
@@ -1010,16 +1022,16 @@ convention, but do not allow the string to be longer than |longest_name|.
else if (++id_loc<=section_text_end) *id_loc='\n'; /* will print as
\.{"\\\\\\n"} */
}
- if ((c=*loc++)==delim) {
- if (++id_loc<=section_text_end) *id_loc=c;
+ if ((c=(eight_bits)*loc++)==delim) {
+ if (++id_loc<=section_text_end) *id_loc=(char)c;
break;
}
if (c=='\\') {
if (loc>=limit) continue;
if (++id_loc<=section_text_end) *id_loc = '\\';
- c=*loc++;
+ c=(eight_bits)*loc++;
}
- if (++id_loc<=section_text_end) *id_loc=c;
+ if (++id_loc<=section_text_end) *id_loc=(char)c;
}
if (id_loc>=section_text_end) {
fputs("\n! String too long: ",stdout);
@@ -1034,25 +1046,23 @@ convention, but do not allow the string to be longer than |longest_name|.
@ After an \.{@@} sign has been scanned, the next character tells us
whether there is more work to do.
-@<Get control code and possible section name@>= {
- c=ccode[(eight_bits)*loc++];
- switch(c) {
- case ignore: continue;
- case translit_code: err_print("! Use @@l in limbo only"); continue;
+@<Get control code and possible section name@>=
+switch(c=ccode[(eight_bits)*loc++]) {
+ case ignore: continue;
+ case translit_code: err_print("! Use @@l in limbo only"); continue;
@.Use @@l in limbo...@>
- case control_text: while ((c=skip_ahead())=='@@');
- /* only \.{@@@@} and \.{@@>} are expected */
- if (*(loc-1)!='>')
- err_print("! Double @@ should be used in control text");
+ case control_text: while ((c=skip_ahead())=='@@');
+ /* only \.{@@@@} and \.{@@>} are expected */
+ if (*(loc-1)!='>')
+ err_print("! Double @@ should be used in control text");
@.Double @@ should be used...@>
- 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;
- }
+ 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;
}
@ After scanning a valid ASCII constant that follows
@@ -1063,9 +1073,8 @@ thus, \.{@@'\\nopq'} gives the same result as \.{@@'\\n'}.
@<Scan an ASCII constant@>=
id_first=loc;
- if (*loc=='\\') {
+ if (*loc=='\\')
if (*++loc=='\'') loc++;
- }
while (*loc!='\'') {
if (*loc=='@@') {
if (*(loc+1)!='@@')
@@ -1083,11 +1092,13 @@ thus, \.{@@'\\nopq'} gives the same result as \.{@@'\\n'}.
return ord;
@ @<Scan the section name...@>= {
- char *k; /* pointer into |section_text| */
+ char *k=section_text; /* pointer 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);
+ cur_section_name=section_lookup(section_text+1,k-3,true);
+ /* |true| means it's a prefix */
+ else cur_section_name=section_lookup(section_text+1,k,false);
+ /* |false| means it's not */
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@>@;
@@ -1103,20 +1114,19 @@ character of the name.)
@<Set init...@>=section_text[0]=' ';
@ @<Put section name...@>=
-k=section_text;
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;
+ c=(eight_bits)*loc;
@<If end of name or erroneous nesting, |break|@>@;
loc++; if (k<section_text_end) k++;
if (xisspace(c)) {
- c=' '; if (*(k-1)==' ') k--;
+ c=(eight_bits)' '; if (*(k-1)==' ') k--;
}
-*k=c;
+*k=(char)c;
}
if (k>=section_text_end) {
fputs("\n! Section name too long: ",stdout);
@@ -1128,7 +1138,7 @@ if (*k==' ' && k>section_text) k--;
@ @<If end of name or erroneous nesting,...@>=
if (c=='@@') {
- c=*(loc+1);
+ c=(eight_bits)*(loc+1);
if (c=='>') {
loc+=2; break;
}
@@ -1148,14 +1158,13 @@ have |*(loc-1)==string|; we set |id_first| to the beginning
of the string itself, and |id_loc| to its ending-plus-one location in the
buffer. We also set |loc| to the position just after the ending delimiter.
-@<Scan a verbatim string@>= {
- id_first=loc++; *(limit+1)='@@'; *(limit+2)='>';
- while (*loc!='@@' || *(loc+1)!='>') loc++;
- if (loc>=limit) err_print("! Verbatim string didn't end");
+@<Scan a verbatim string@>=
+id_first=loc++; *(limit+1)='@@'; *(limit+2)='>';
+while (*loc!='@@' || *(loc+1)!='>') loc++;
+if (loc>=limit) err_print("! Verbatim string didn't end");
@.Verbatim string didn't end@>
- id_loc=loc; loc+=2;
- return string;
-}
+id_loc=loc; loc+=2;
+return string;
@* Scanning a macro definition.
The rules for generating the replacement texts corresponding to macros and
@@ -1176,8 +1185,10 @@ ANSI \CEE/ preprocessor sometimes requires it.
acted, |cur_text| will point to the replacement text just generated, and
|next_control| will contain the control code that terminated the activity.
-@d macro 0
-@d app_repl(c) {if (tok_ptr==tok_mem_end) overflow("token"); *tok_ptr++=c;}
+@d app_repl(c) {
+ if (tok_ptr==tok_mem_end) overflow("token");
+ else *(tok_ptr++)=(eight_bits)c;
+}
@<Private...@>=
static text_pointer cur_text; /* replacement text formed by |scan_repl| */
@@ -1185,13 +1196,13 @@ static eight_bits next_control;
@ @c
static void
-scan_repl(@t\1\1@> /* creates a replacement text */
-eight_bits t@t\2\2@>)
+scan_repl( /* creates a replacement text */
+eight_bits t)
{
sixteen_bits a; /* the current token */
- if (t==section_name) {@<Insert the line number into |tok_mem|@>@;}
+ 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|,
+ @/@t\4@>@<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,
or |goto done| if |a| signals the end of this replacement text@>@;
@@ -1211,31 +1222,36 @@ eight_bits t@t\2\2@>)
to |0150000|; then the numeric line number; then a pointer to the
file name.
+@d store_id(a) a=id_lookup(id_first,id_loc,'\0')-name_dir;@/
+ app_repl((a / 0400)+0200);
+ app_repl(a % 0400)
+
@<Insert the line...@>=
-store_two_bytes(0150000);
-if (changing && include_depth==change_depth) { /* correction made Feb 2017 */
- id_first=change_file_name;
- store_two_bytes((sixteen_bits)change_line);
-}@+else {
- id_first=cur_file_name;
- store_two_bytes((sixteen_bits)cur_line);
+{
+ eight_bits a; /* shadow variable |a| */
+ store_two_bytes(0150000);
+ if (changing && include_depth==change_depth) { /* correction made Feb 2017 */
+ id_first=change_file_name;
+ store_two_bytes((sixteen_bits)change_line);
+ }@+else {
+ id_first=cur_file_name;
+ store_two_bytes((sixteen_bits)cur_line);
+ }
+ id_loc=id_first+strlen(id_first);
+ store_id(a);
}
-id_loc=id_first+strlen(id_first);
-{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;
- app_repl((a / 0400)+0200);
- app_repl(a % 0400); break;
+@ @<In cases that |a| is...@>=@t\1\quad@>
+case identifier: store_id(a); break;
case section_name: if (t!=section_name) goto done;
else {
@<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 {
@@ -1245,11 +1261,13 @@ case output_defs_code: if (t!=section_name) err_print("! Misplaced @@h");
app_repl(a % 0400);
@<Insert the line number into |tok_mem|@>@;
}
- break;
+ break;
case constant: case string:
@<Copy a string or verbatim construction or numerical constant@>@;
+ break;
case ord:
@<Copy an ASCII constant@>@;
+ break;
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 +1286,13 @@ case new_section: goto done;
as explained in the manual */
}
-@ @<Copy a string...@>=
+@ By default, \.{CTANGLE} purges single-quote characters from \CPLUSPLUS/-style
+literals, e.g., \.{1'000'000}, so that you can use this notation also in \CEE/
+code. The \.{+k} switch will `keep' the single quotes in the output.
+
+@d keep_digit_separators flags['k']
+
+@<Copy a string...@>=
app_repl(a); /* |string| or |constant| */
while (id_first < id_loc) { /* simplify \.{@@@@} pairs */
if (*id_first=='@@') {
@@ -1276,18 +1300,20 @@ case new_section: goto done;
else err_print("! Double @@ should be used in string");
@.Double @@ should be used...@>
}
+ else if (a==constant && *id_first=='\'' && !keep_digit_separators)
+ id_first++;
app_repl(*id_first++);
}
- app_repl(a); break;
+ app_repl(a);
@ This section should be rewritten on machines that don't use ASCII
code internally.
@^ASCII code dependencies@>
@<Copy an ASCII constant@>= {
- int c=(eight_bits) *id_first;
+ int c=(int)((eight_bits) *id_first);
if (c=='\\') {
- c=*++id_first;
+ c=(int)((eight_bits) *++id_first);
if (c>='0' && c<='7') {
c-='0';
if (*(id_first+1)>='0' && *(id_first+1)<='7') {
@@ -1306,15 +1332,15 @@ code internally.
case 'a':c='\7';@+break;
case '?':c='?';@+break;
case 'x':
- if (xisdigit(*(id_first+1))) c=*(++id_first)-'0';
+ if (xisdigit(*(id_first+1))) c=(int)(*(++id_first)-'0');
else if (xisxdigit(*(id_first+1))) {
++id_first;
- c=toupper((eight_bits)*id_first)-'A'+10;
+ c=toupper((int)*id_first)-'A'+10;
}
- if (xisdigit(*(id_first+1))) c=16*c+*(++id_first)-'0';
+ if (xisdigit(*(id_first+1))) c=16*c+(int)(*(++id_first)-'0');
else if (xisxdigit(*(id_first+1))) {
++id_first;
- c=16*c+toupper((eight_bits)*id_first)-'A'+10;
+ c=16*c+toupper((int)*id_first)-(int)'A'+10;
}
break;
case '\\':c='\\';@+break;
@@ -1326,12 +1352,11 @@ code internally.
}@/
/* at this point |c| should have been converted to its ASCII code number */
app_repl(constant);
- if (c>=100) app_repl('0'+c/100);
- if (c>=10) app_repl('0'+(c/10)%10);
- app_repl('0'+c%10);
+ if (c>=100) app_repl((int)'0'+c/100);
+ if (c>=10) app_repl((int)'0'+(c/10)%10);
+ app_repl((int)'0'+c%10);
app_repl(constant);
}
-break;
@* Scanning a section.
The |scan_section| procedure starts when `\.{@@\ }' or `\.{@@*}' has been
@@ -1352,17 +1377,17 @@ scan_section(void)
sixteen_bits a; /* token for left-hand side of definition */
section_count++; @+ no_where=true;
if (*(loc-1)=='*' && show_progress) { /* starred section */
- printf("*%d",section_count); update_terminal;
+ printf("*%d",(int)section_count); update_terminal;
}
- next_control=0;
+ next_control=ignore;
while (true) {
@<Skip ahead until |next_control| corresponds to \.{@@d}, \.{@@<},
\.{@@\ } or the like@>@;
- if (next_control == definition) { /* \.{@@d} */
+ if (next_control == definition) { /* \.{@@d} */
@<Scan a definition@>@;
continue;
}
- if (next_control == begin_C) { /* \.{@@c} or \.{@@p} */
+ if (next_control == begin_C) { /* \.{@@c} or \.{@@p} */
p=name_dir; break;
}
if (next_control == section_name) { /* \.{@@<} or \.{@@(} */
@@ -1391,22 +1416,19 @@ while (next_control<definition)
loc-=2; next_control=get_next();
}
-@ @<Scan a definition@>= {
- while ((next_control=get_next())=='\n'); /* allow newline before definition */
- if (next_control!=identifier) {
- err_print("! Definition flushed, must start with identifier");
+@ @<Scan a 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...@>
- continue;
- }
- app_repl(((a=id_lookup(id_first,id_loc,0)-name_dir) / 0400)+0200);
- /* append the lhs */
- app_repl(a % 0400);
- if (*loc!='(') { /* identifier must be separated from replacement text */
- app_repl(string); app_repl(' '); app_repl(string);
- }
- scan_repl(macro);
- cur_text->text_link=macro;
+ continue;
}
+store_id(a); /* append the lhs */
+if (*loc!='(') { /* identifier must be separated from replacement text */
+ app_repl(string); app_repl(' '); app_repl(string);
+}
+scan_repl(macro);
+cur_text->text_link=macro;
@ If the section name is not followed by \.{=} or \.{+=}, no \CEE/
code is forthcoming: the section is being cited, not being
@@ -1431,8 +1453,8 @@ store_two_bytes((sixteen_bits)(0150000+section_count));
/* |0150000==0320*0400| */
@ @<Update the data...@>=
-if (p==name_dir||p==0) { /* unnamed section, or bad section name */
- (last_unnamed)->text_link=cur_text-text_info; last_unnamed=cur_text;
+if (p==name_dir||p==NULL) { /* unnamed section, or bad section name */
+ last_unnamed->text_link=cur_text-text_info; last_unnamed=cur_text;
}
else if (p->equiv==(void *)text_info) p->equiv=(void *)cur_text;
/* first section of this name */
@@ -1454,7 +1476,6 @@ phase_one(void) {
skip_limbo();
while (!input_has_ended) scan_section();
check_complete();
- phase=2;
}
@ @<Predec...@>=@+static void phase_one(void);
@@ -1466,19 +1487,18 @@ processing is straightforward.
static void
skip_limbo(void)
{
- char c;
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;
+ char c=*loc++;
switch (ccode[(eight_bits)c]) {
+ case new_section: return;
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())=='@@');
+ while ((c=(char)skip_ahead())=='@@');
if (*(loc-1)!='>')
err_print("! Double @@ should be used in control text");
@.Double @@ should be used...@>
@@ -1517,19 +1537,19 @@ skip_limbo(void)
}
@ Because on some systems the difference between two pointers is a |ptrdiff_t|
-but not an |int|, we use \.{\%ld} to print these quantities.
+but not an |int|, we use \.{\%td} to print these quantities.
@c
void
print_stats(void) {
puts("\nMemory usage statistics:");
- printf("%ld names (out of %ld)\n",
+ printf("%td names (out of %ld)\n",
(ptrdiff_t)(name_ptr-name_dir),(long)max_names);
- printf("%ld replacement texts (out of %ld)\n",
+ printf("%td replacement texts (out of %ld)\n",
(ptrdiff_t)(text_ptr-text_info),(long)max_texts);
- printf("%ld bytes (out of %ld)\n",
+ printf("%td bytes (out of %ld)\n",
(ptrdiff_t)(byte_ptr-byte_mem),(long)max_bytes);
- printf("%ld tokens (out of %ld)\n",
+ printf("%td tokens (out of %ld)\n",
(ptrdiff_t)(tok_ptr-tok_mem),(long)max_toks);
}
diff --git a/web/c_cpp/cweb/cweav-bs.ch b/web/c_cpp/cweb/cweav-bs.ch
index bf2752881e..5aa05c8b8c 100644
--- a/web/c_cpp/cweb/cweav-bs.ch
+++ b/web/c_cpp/cweb/cweav-bs.ch
@@ -20,16 +20,16 @@ This file contributed by Barry Schwartz, trashman@crud.mn.org, 28 Jun 94.
The ``banner line'' defined here should be changed whenever \.{CWEAVE}
is modified.
-@d banner "This is CWEAVE (Version 4.2)"
+@d banner "This is CWEAVE (Version 4.6)"
@y
The ``banner line'' defined here should be changed whenever \.{CWEAVE}
is modified.
-@d banner "This is CWEAVE (Version 4.2pc/big)"
+@d banner "This is CWEAVE (Version 4.6pc/big)"
@z
-@x Section 7.
+@x Section 10.
for section names */
@<Common code...@>=
@@ -119,11 +119,11 @@ static xref_pointer xmem_end;
@x Section 24.
-xref_ptr=xmem; init_node(name_dir); xref_switch=0; section_xref_switch=0;
+xref_ptr=xmem; init_node(name_dir); xref_switch=section_xref_switch=0;
xmem->num=0; /* sentinel value */
@y
xmem_end = xmem + max_refs - 1;
-xref_ptr=xmem; init_node(name_dir); xref_switch=0; section_xref_switch=0;
+xref_ptr=xmem; init_node(name_dir); xref_switch=section_xref_switch=0;
xmem->num=0; /* sentinel value */
@z
@@ -165,7 +165,7 @@ max_tok_ptr=tok_mem+1; max_text_ptr=tok_start+1;
@z
-@x Section 74.
+@x Section 78.
if (unindexed(lhs)) { /* retain only underlined entries */
xref_pointer q,r=NULL;
for (q=(xref_pointer)lhs->xref;q>xmem;q=q->xlink)
@@ -186,7 +186,7 @@ max_tok_ptr=tok_mem+1; max_text_ptr=tok_start+1;
@z
-@x Section 93.
+@x Section 97.
char *k, *k_end=(p+1)->byte_start; /* pointers into |byte_mem| */
out('{');
for (k=p->byte_start; k<k_end; k++) {
@@ -197,40 +197,29 @@ max_tok_ptr=tok_mem+1; max_text_ptr=tok_start+1;
@z
-@x Section 209.
+@x Section 218.
char *p; /* index into |byte_mem| */
@y
char huge *p; /* index into |byte_mem| */
@z
-@x Section 244.
+@x Section 253.
if (cur_name->xref!=(void *)xmem) {
@y
if (cur_name->xref!=(void huge*)xmem) {
@z
-@x Section 246.
+@x Section 255.
static char *cur_byte; /* index into |byte_mem| */
@y
static char huge* cur_byte; /* index into |byte_mem| */
@z
-@x Section 255.
-switch (cur_name->ilk) {
- case normal: case func_template: if (is_tiny(cur_name)) out_str("\\|");
- else {char *j;
-@y
-switch (cur_name->ilk) {
- case normal: case func_template: if (is_tiny(cur_name)) out_str("\\|");
- else {char huge* j;
-@z
-
-
-@x Section 255.
- case custom: {char *j; out_str("$\\");
+@x Section 264.
+switch (cur_name->ilk) {@+char *j;@+@t}\6{\4@>
@y
- case custom: {char huge* j; out_str("$\\");
+switch (cur_name->ilk) {@+char huge* j;@+@t}\6{\4@>
@z
diff --git a/web/c_cpp/cweb/cweav-man.ch b/web/c_cpp/cweb/cweav-man.ch
index b72360944a..366cda6f11 100644
--- a/web/c_cpp/cweb/cweav-man.ch
+++ b/web/c_cpp/cweb/cweav-man.ch
@@ -16,7 +16,7 @@ under the terms of a permission notice identical to this one.
}
@y
\def\botofcontents{\vfill\titlefalse}
-\def\contentspagenumber{111}
+\def\contentspagenumber{108}
\def\title{APPENDIX F: CWEAVE}
\let\K=\leftarrow
@z
diff --git a/web/c_cpp/cweb/cweav-pc.ch b/web/c_cpp/cweb/cweav-pc.ch
index b37f9f2ec3..23b37416a8 100644
--- a/web/c_cpp/cweb/cweav-pc.ch
+++ b/web/c_cpp/cweb/cweav-pc.ch
@@ -11,18 +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 4.2)"
+@d banner "This is CWEAVE (Version 4.6)"
@y
-@d banner "This is CWEAVE (Version 4.2pc)"
+@d banner "This is CWEAVE (Version 4.6pc)"
@z
-@x section 4
-@d max_bytes 1000000 /* the number of bytes in identifiers,
+@x section 17
+@d max_bytes 90000 /* the number of bytes in identifiers,
@y
@d max_bytes (unsigned)60000 /* the number of bytes in identifiers,
@z
@x
-@d max_refs 65535 /* number of cross-references; must be less than 65536 */
+@d max_refs 20000 /* number of cross-references; must be less than 65536 */
@y
@d max_refs 10000 /* number of cross-references; must be less than 65536 */
@z
diff --git a/web/c_cpp/cweb/cweav-ql.ch b/web/c_cpp/cweb/cweav-ql.ch
index 28053eb158..4525b8006d 100644
--- a/web/c_cpp/cweb/cweav-ql.ch
+++ b/web/c_cpp/cweb/cweav-ql.ch
@@ -7,15 +7,15 @@ ex <dev_>cc;"-v -h -c =500000 cweave_c"
@x
-\def\title{CWEAVE (Version 4.2)}
+\def\title{CWEAVE (Version 4.6)}
@y
-\def\title{CWEAVE (QL Version 4.2)}
+\def\title{CWEAVE (QL Version 4.6)}
@z
@x section 1
-@d banner "This is CWEAVE (Version 4.2)"
+@d banner "This is CWEAVE (Version 4.6)"
@y
-@d banner "This is CWEAVE (QL Version 4.2)"
+@d banner "This is CWEAVE (QL Version 4.6)"
@z
@x
diff --git a/web/c_cpp/cweb/cweav-vms.ch b/web/c_cpp/cweb/cweav-vms.ch
index 7d80d57c1e..f6d786da4a 100644
--- a/web/c_cpp/cweb/cweav-vms.ch
+++ b/web/c_cpp/cweb/cweav-vms.ch
@@ -13,18 +13,18 @@ modified:
(also modified by Don Knuth to keep version numbers uptodate)
@x section 1 (01-FEB-1992 ST)
-@d banner "This is CWEAVE (Version 4.2)"
+@d banner "This is CWEAVE (Version 4.6)"
@y
-@d banner "This is CWEAVE (VAX/VMS Version 4.2)"
+@d banner "This is CWEAVE (VAX/VMS Version 4.6)"
@z
-@x section 3 (01-FEB-1992 ST)
+@x section 4 (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 <stdlib.h> /* definition of |@!getenv| and |@!exit| */
#include <string.h> /* definition of |@!strlen|, |@!strcmp| and so on */
@y
#include ctype /* definition of |@!isalpha|, |@!isdigit| and so on */
@@ -32,7 +32,7 @@ modified:
#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 stdlib /* definition of |@!getenv| and |@!exit| */
#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 346d00771a..1fc91f1a88 100644
--- a/web/c_cpp/cweb/cweav-w32.ch
+++ b/web/c_cpp/cweb/cweav-w32.ch
@@ -2,23 +2,23 @@ This is the change file for CWEB's CWEAVE under Win32
(Contributed by Fabrice Popineau, February 2002)
@x section 1
-@d banner "This is CWEAVE (Version 4.2)"
+@d banner "This is CWEAVE (Version 4.6)"
@y
-@d banner "This is CWEAVE (Version 4.2win32)"
+@d banner "This is CWEAVE (Version 4.6win32)"
@z
@x
-boolean names_match(@t\1\1@>
+boolean names_match(
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| */
+eight_bits t) /* desired |ilk| */
@y
-boolean __cdecl names_match(@t\1\1@>
+boolean __cdecl names_match(
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| */
+eight_bits t) /* desired |ilk| */
@z
@x
diff --git a/web/c_cpp/cweb/cweave.w b/web/c_cpp/cweb/cweave.w
index a8e31055b2..bcc8efcfb7 100644
--- a/web/c_cpp/cweb/cweave.w
+++ b/web/c_cpp/cweb/cweave.w
@@ -2,7 +2,7 @@
% This program by Silvio Levy and Donald E. Knuth
% is based on a program by Knuth.
% It is distributed WITHOUT ANY WARRANTY, express or implied.
-% Version 4.2 --- February 2021
+% Version 4.6 --- December 2021
% Copyright (C) 1987,1990,1993,2000 Silvio Levy and Donald E. Knuth
@@ -32,11 +32,11 @@
\def\skipxTeX{\\{skip\_\TEX/}}
\def\copyxTeX{\\{copy\_\TEX/}}
-\def\title{CWEAVE (Version 4.2)}
+\def\title{CWEAVE (Version 4.6)}
\def\topofcontents{\null\vfill
\centerline{\titlefont The {\ttitlefont CWEAVE} processor}
\vskip 15pt
- \centerline{(Version 4.2)}
+ \centerline{(Version 4.6)}
\vfill}
\def\botofcontents{\vfill
\noindent
@@ -67,9 +67,10 @@ Crusius, and others who have contributed improvements.
The ``banner line'' defined here should be changed whenever \.{CWEAVE}
is modified.
-@d banner "This is CWEAVE (Version 4.2)"
+@d banner "This is CWEAVE (Version 4.6)"
-@c @<Include files@>@/
+@c
+@<Include files@>@/
@h
@<Common code for \.{CWEAVE} and \.{CTANGLE}@>@/
@<Typedef declarations@>@/
@@ -81,13 +82,13 @@ 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
file, finally it sorts and outputs the index.
-Please read the documentation for \.{common}, the set of routines common
+Please read the documentation for \.{COMMON}, the set of routines common
to \.{CTANGLE} and \.{CWEAVE}, before proceeding further.
@c
-int main (@t\1\1@>
+int main (
int ac, /* argument count */
-char **av@t\2\2@>) /* argument values */
+char **av) /* argument values */
{
argc=ac; argv=av;
program=cweave;
@@ -99,7 +100,7 @@ char **av@t\2\2@>) /* argument values */
phase_one(); /* read all the user's text and store the cross-references */
phase_two(); /* read all the text again and translate it to \TEX/ form */
phase_three(); /* output the cross-reference index */
- if (tracing==2 && !show_progress) new_line;
+ if (tracing==fully && !show_progress) new_line;
return wrap_up(); /* and exit gracefully */
}
@@ -115,10 +116,8 @@ handle \TEX/, so they should be sufficient for most applications of \.{CWEAVE}.
@d line_length 80 /* lines of \TEX/ output have at most this many characters;
should be less than 256 */
-@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 10000 /* number of tokens in \CEE/ texts being parsed */
+@d max_refs 20000 /* number of cross-references; must be less than 65536 */
+@d max_scraps 2000 /* 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
@@ -143,7 +142,7 @@ will be typeset in special ways.
\yskip\hang |typewriter| identifiers are index entries that appear after
\.{@@.} in the \.{CWEB} file.
-\yskip\hang |alfop|, \dots, |template_like|
+\yskip\hang |alfop|, \dots, |attr|
identifiers are \CEE/ or \CPLUSPLUS/ reserved words whose |ilk|
explains how they are to be treated when \CEE/ code is being
formatted.
@@ -153,7 +152,7 @@ formatted.
@d roman 1 /* normal index entries have |roman| ilk */
@d wildcard 2 /* user-formatted index entries have |wildcard| ilk */
@d typewriter 3 /* `typewriter type' entries have |typewriter| ilk */
-@d abnormal(a) (a->ilk>typewriter) /* tells if a name is special */
+@d abnormal(a) ((a)->ilk>typewriter) /* tells if a name is special */
@d func_template 4 /* identifiers that can be followed by optional template */
@d custom 5 /* identifiers with user-given control sequence */
@d alfop 22 /* alphabetic operators like \&{and} or \&{not\_eq} */
@@ -168,7 +167,7 @@ formatted.
@d delete_like 48 /* \&{delete} */
@d raw_ubin 49 /* `\.\&' or `\.*' when looking for \&{const} following */
@d const_like 50 /* \&{const}, \&{volatile} */
-@d raw_int 51 /* \&{int}, \&{char}, \dots; also structure and class names */
+@d raw_int 51 /* \&{int}, \&{char}, \dots; also structure and class names */
@d int_like 52 /* same, when not followed by left parenthesis or \DC\ */
@d case_like 53 /* \&{case}, \&{return}, \&{goto}, \&{break}, \&{continue} */
@d sizeof_like 54 /* \&{sizeof} */
@@ -176,6 +175,10 @@ formatted.
@d typedef_like 56 /* \&{typedef} */
@d define_like 57 /* \&{define} */
@d template_like 58 /* \&{template} */
+@d alignas_like 59 /* \&{alignas} */
+@d using_like 60 /* \&{using} */
+@d default_like 61 /* \&{default} */
+@d attr 62 /* \&{noexcept} and attributes */
@ We keep track of the current section number in |section_count|, which
is the total number of sections that have started. Sections which have
@@ -229,7 +232,7 @@ has a special first cross-reference whose |num| field is |file_flag|.
@d xref equiv_or_xref
@<Set init...@>=
-xref_ptr=xmem; init_node(name_dir); xref_switch=0; section_xref_switch=0;
+xref_ptr=xmem; init_node(name_dir); xref_switch=section_xref_switch=0;
xmem->num=0; /* sentinel value */
@ A new cross-reference for an identifier is formed by calling |new_xref|,
@@ -239,13 +242,13 @@ to one-letter identifiers or \CEE/'s reserved words.
If the user has sent the |no_xref| flag (the \.{-x} option of the command line),
it is unnecessary to keep track of cross-references for identifiers.
If one were careful, one could probably make more changes around section
-100 to avoid a lot of identifier looking up.
+115 to avoid a lot of identifier looking up.
@d append_xref(c) if (xref_ptr==xmem_end) overflow("cross-reference");
- else (++xref_ptr)->num=c;
-@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)
+ else (++xref_ptr)->num=c
+@d no_xref !make_xrefs
+@d is_tiny(p) length(p)==1
+@d unindexed(a) ((a)<res_wd_end && (a)->ilk>=custom)
/* tells if uses of a name are to be indexed */
@<Predecl...@>=
@@ -289,9 +292,9 @@ static void
new_section_xref(
name_pointer p)
{
- xref_pointer q,r; /* pointers to previous cross-references */
- q=(xref_pointer)p->xref; r=xmem;
- if (q>xmem)
+ xref_pointer q=(xref_pointer)p->xref;
+ xref_pointer r=xmem; /* pointers to previous cross-references */
+ if (q>r)
while (q->num>section_xref_switch) {r=q; q=q->xlink;}
if (r->num==section_count+section_xref_switch)
return; /* don't duplicate entries */
@@ -309,8 +312,7 @@ static void
set_file_flag(
name_pointer p)
{
- xref_pointer q;
- q=(xref_pointer)p->xref;
+ xref_pointer q=(xref_pointer)p->xref;
if (q->num==file_flag) return;
append_xref(file_flag);
xref_ptr->xlink = q;
@@ -333,6 +335,11 @@ 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|.
+@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;
+ must be less than 10240 */
+
@<Private...@>=
static token tok_mem[max_toks]; /* tokens */
static token_pointer tok_mem_end = tok_mem+max_toks-1; /* end of |tok_mem| */
@@ -350,11 +357,11 @@ text_ptr=max_text_ptr=tok_start+1;
@ Here are the three procedures needed to complete |id_lookup|:
@c
-boolean names_match(@t\1\1@>
+boolean names_match(
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| */
+eight_bits t) /* desired |ilk| */
{
if (length(p)!=l) return false;
if (p->ilk!=t && !(t==normal && abnormal(p))) return false;
@@ -376,23 +383,22 @@ name_pointer p)
p->xref=(void *)xmem;
}
-static void
-update_node(
-name_pointer p)
-{
- p->xref=(void *)xref_ptr;
-}
+@ And here's a small helper function to simplify the code.
-@ @<Predecl...@>=@+static void update_node(name_pointer p);
+@d update_node(p) (p)->xref=(void *)xref_ptr
-@ We have to get \CEE/'s
+@ We have to get \CEE/'s and \CPLUSPLUS/'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
few reserved words. (Some of these are not strictly ``reserved,'' but
-are defined in header files of the ISO Standard \CEE/ Library.)
+are defined in header files of the ISO Standard \CEE/ Library.
+An ever growing list of \CPLUSPLUS/ keywords can be found here:
+\.{https://en.cppreference.com/w/cpp/keyword}.)
@^reserved words@>
@<Store all the reserved words@>=
+id_lookup("alignas",NULL,alignas_like);
+id_lookup("alignof",NULL,sizeof_like);
id_lookup("and",NULL,alfop);
id_lookup("and_eq",NULL,alfop);
id_lookup("asm",NULL,sizeof_like);
@@ -404,13 +410,24 @@ id_lookup("break",NULL,case_like);
id_lookup("case",NULL,case_like);
id_lookup("catch",NULL,catch_like);
id_lookup("char",NULL,raw_int);
+id_lookup("char8_t",NULL,raw_int);
+id_lookup("char16_t",NULL,raw_int);
+id_lookup("char32_t",NULL,raw_int);
id_lookup("class",NULL,struct_like);
id_lookup("clock_t",NULL,raw_int);
id_lookup("compl",NULL,alfop);
+id_lookup("concept",NULL,int_like);
id_lookup("const",NULL,const_like);
+id_lookup("consteval",NULL,const_like);
+id_lookup("constexpr",NULL,const_like);
+id_lookup("constinit",NULL,const_like);
id_lookup("const_cast",NULL,raw_int);
id_lookup("continue",NULL,case_like);
-id_lookup("default",NULL,case_like);
+id_lookup("co_await",NULL,case_like);
+id_lookup("co_return",NULL,case_like);
+id_lookup("co_yield",NULL,case_like);
+id_lookup("decltype",NULL,sizeof_like);
+id_lookup("default",NULL,default_like);
id_lookup("define",NULL,define_like);
id_lookup("defined",NULL,sizeof_like);
id_lookup("delete",NULL,delete_like);
@@ -427,6 +444,7 @@ id_lookup("explicit",NULL,int_like);
id_lookup("export",NULL,int_like);
id_lookup("extern",NULL,int_like);
id_lookup("FILE",NULL,raw_int);
+id_lookup("false",NULL,normal);
id_lookup("float",NULL,raw_int);
id_lookup("for",NULL,for_like);
id_lookup("fpos_t",NULL,raw_int);
@@ -445,9 +463,11 @@ id_lookup("long",NULL,raw_int);
id_lookup("mutable",NULL,int_like);
id_lookup("namespace",NULL,struct_like);
id_lookup("new",NULL,new_like);
+id_lookup("noexcept",NULL,attr);
id_lookup("not",NULL,alfop);
id_lookup("not_eq",NULL,alfop);
id_lookup("NULL",NULL,custom);
+id_lookup("nullptr",NULL,custom);
id_lookup("offsetof",NULL,raw_int);
id_lookup("operator",NULL,operator_like);
id_lookup("or",NULL,alfop);
@@ -459,6 +479,8 @@ id_lookup("ptrdiff_t",NULL,raw_int);
id_lookup("public",NULL,public_like);
id_lookup("register",NULL,int_like);
id_lookup("reinterpret_cast",NULL,raw_int);
+id_lookup("requires",NULL,int_like);
+id_lookup("restrict",NULL,int_like);
id_lookup("return",NULL,case_like);
id_lookup("short",NULL,raw_int);
id_lookup("sig_atomic_t",NULL,raw_int);
@@ -466,21 +488,24 @@ id_lookup("signed",NULL,raw_int);
id_lookup("size_t",NULL,raw_int);
id_lookup("sizeof",NULL,sizeof_like);
id_lookup("static",NULL,int_like);
+id_lookup("static_assert",NULL,sizeof_like);
id_lookup("static_cast",NULL,raw_int);
id_lookup("struct",NULL,struct_like);
id_lookup("switch",NULL,for_like);
id_lookup("template",NULL,template_like);
id_lookup("this",NULL,custom);
+id_lookup("thread_local",NULL,raw_int);
id_lookup("throw",NULL,case_like);
id_lookup("time_t",NULL,raw_int);
+id_lookup("true",NULL,normal);
id_lookup("try",NULL,else_like);
id_lookup("typedef",NULL,typedef_like);
-id_lookup("typeid",NULL,raw_int);
+id_lookup("typeid",NULL,sizeof_like);
id_lookup("typename",NULL,struct_like);
id_lookup("undef",NULL,if_like);
id_lookup("union",NULL,struct_like);
id_lookup("unsigned",NULL,raw_int);
-id_lookup("using",NULL,int_like);
+id_lookup("using",NULL,using_like);@/
id_lookup("va_dcl",NULL,decl); /* Berkeley's variable-arg-list convention */
id_lookup("va_list",NULL,raw_int); /* ditto */
id_lookup("virtual",NULL,int_like);
@@ -491,6 +516,8 @@ id_lookup("while",NULL,for_like);
id_lookup("xor",NULL,alfop);
id_lookup("xor_eq",NULL,alfop);@+ res_wd_end=name_ptr;
id_lookup("TeX",NULL,custom);
+id_lookup("complex",NULL,int_like);
+id_lookup("imaginary",NULL,int_like);
id_lookup("make_pair",NULL,func_template);
@* Lexical scanning.
@@ -513,11 +540,11 @@ scanning routines.
@^ASCII code dependencies@>
@d ignore 00 /* control code of no interest to \.{CWEAVE} */
-@d verbatim 02 /* takes the place of extended ASCII \.{\char2} */
+@d verbatim 02 /* takes the place of ASCII \.{STX} */
@d begin_short_comment 03 /* \CPLUSPLUS/ short comment */
@d begin_comment '\t' /* tab marks will not appear */
@d underline '\n' /* this code will be intercepted without confusion */
-@d noop 0177 /* takes the place of ASCII delete */
+@d noop 0177 /* takes the place of ASCII \.{DEL} */
@d xref_roman 0203 /* control code for `\.{@@\^}' */
@d xref_wildcard 0204 /* control code for `\.{@@:}' */
@d xref_typewriter 0205 /* control code for `\.{@@.}' */
@@ -548,10 +575,12 @@ representation by means of the table |ccode|.
@<Private...@>=
static eight_bits ccode[256]; /* meaning of a char following \.{@@} */
-@ @<Set ini...@>=
-{int c; for (c=0; c<256; c++) ccode[c]=0;}
+@ @<Set ini...@>= {
+ int c; /* must be |int| so the |for| loop will end */
+ for (c=0; c<256; c++) ccode[c]=ignore;
+}
ccode[' ']=ccode['\t']=ccode['\n']=ccode['\v']=ccode['\r']=ccode['\f']
- =ccode['*']=new_section;
+ =ccode['*']=new_section;
ccode['@@']='@@'; /* `quoted' at sign */
ccode['=']=verbatim;
ccode['d']=ccode['D']=definition;
@@ -571,8 +600,8 @@ ccode['\'']=ord;
@<Special control codes for debugging@>@;
@ Users can write
-\.{@@2}, \.{@@1}, and \.{@@0} to turn tracing fully on, partly on,
-and off, respectively.
+\.{@@2}, \.{@@1}, and \.{@@0} to turn tracing |fully| on, |partly| on,
+and |off|, respectively.
@<Special control codes...@>=
ccode['0']=ccode['1']=ccode['2']=trace;
@@ -597,11 +626,12 @@ skip_limbo(void) {
if (loc>limit && get_line()==false) return;
*(limit+1)='@@';
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@>@;
- }
+ if (loc++ <=limit)
+ switch (ccode[(eight_bits)*loc++]) {
+ case new_section: return;
+ case noop: skip_restricted(); break;
+ case format_code: @<Process simple format in limbo@>@;
+ }
}
}
@@ -620,7 +650,7 @@ skip_TeX(void) /* skip past pure \TEX/ code */
if (loc>limit && get_line()==false) return new_section;
*(limit+1)='@@';
while (*loc!='@@' && *loc!='|') loc++;
- if (*loc++ =='|') return '|';
+ if (*loc++ =='|') return (eight_bits)'|';
if (loc<=limit) return ccode[(eight_bits)*(loc++)];
}
}
@@ -671,13 +701,6 @@ 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.
-\CEE/ allows underscores to appear in identifiers, and some \CEE/
-compilers even allow the dollar sign.
-
-@d isxalpha(c) ((c)=='_' || (c)=='$')
- /* non-alpha characters allowed in identifier */
-@d ishigh(c) ((eight_bits)(c)>0177)
-@^high-bit character handling@>
@c
static eight_bits
@@ -688,13 +711,13 @@ get_next(void) /* produces the next input token */
@<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@>@;
+ if (xisdigit((int)c) || c=='.') @<Get a constant@>@;
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))
+ else if (isalpha((int)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 */
@@ -733,7 +756,8 @@ a file name in lines that start with \.{\#include}. We must treat this file
name as a string.
@<Private...@>=
-static boolean sharp_include_line=false; /* are we scanning a \&{\#include} line? */
+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++;
@@ -752,32 +776,31 @@ the last character was a \.\\.
}
@ The following code assigns values to the combinations \.{++},
-\.{--}, \.{->}, \.{>=}, \.{<=}, \.{==}, \.{<<}, \.{>>}, \.{!=}, \.{\v\v}, and
-\.{\&\&}, and to the \CPLUSPLUS/
+\.{--}, \.{->}, \.{>=}, \.{<=}, \.{==}, \.{<<}, \.{>>}, \.{!=}, %\.{||}
+\.{\v\v} and~\.{\&\&}, and to the \CPLUSPLUS/
combinations \.{...}, \.{::}, \.{.*} and \.{->*}.
The compound assignment operators (e.g., \.{+=}) are
treated as separate tokens.
-@d compress(c) if (loc++<=limit) return c
-
@<Compress tw...@>=
switch(c) {
- case '/': if (*loc=='*') {compress(begin_comment);}
+ case '/': if (*loc=='*') {@+compress(begin_comment);@+}
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;
- case '.': if (*loc=='*') {compress(period_ast);}
+ case '-': if (*loc=='-') {@+compress(minus_minus);@+}
+ 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);
- }
- break;
+ loc++;@+compress(dot_dot_dot);
+ } break;
case ':': if (*loc==':') compress(colon_colon); break;
case '=': if (*loc=='=') compress(eq_eq); break;
- case '>': if (*loc=='=') {compress(gt_eq);}
+ case '>': if (*loc=='=') {@+compress(gt_eq);@+}
else if (*loc=='>') compress(gt_gt); break;
- case '<': if (*loc=='=') {compress(lt_eq);}
+ 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;
@@ -786,8 +809,10 @@ switch(c) {
@ @<Get an identifier@>= {
id_first=--loc;
- while (isalpha((eight_bits)*++loc) || isdigit((eight_bits)*loc) @|
- || isxalpha((eight_bits)*loc) || ishigh((eight_bits)*loc));
+ do
+ ++loc;
+ while (isalpha((int)*loc) || isdigit((int)*loc) @|
+ || isxalpha(*loc) || ishigh(*loc));
id_loc=loc; return identifier;
}
@@ -798,51 +823,77 @@ introduced by \.0 and hexadecimals by \.{0x}, but \.{CWEAVE} will print
with \TEX/ macros that the user can redefine to fit the context.
In order to simplify such macros, we replace some of the characters.
+On output, the \.{\ } that replaces \.{'} in \CPLUSPLUS/ literals will become
+``\.{\\\ }''.
+
Notice that in this section and the next, |id_first| and |id_loc|
are pointers into the array |section_text|, not into |buffer|.
+@d gather_digits_while(t) while ((t) || *loc=='\'')
+ if (*loc=='\'') { /* \CPLUSPLUS/-style digit separator */
+ *id_loc++=' ';@+ loc++; /* insert a little white space */
+@.\\\ @>
+ }@+else *id_loc++=*loc++
+
@<Get a constant@>= {
id_first=id_loc=section_text+1;
+ if (*(loc-1)=='.' && !xisdigit(*loc)) goto mistake; /* not a constant */
if (*(loc-1)=='0') {
- if (*loc=='x' || *loc=='X') {*id_loc++='^'; loc++;
- while (xisxdigit(*loc)) *id_loc++=*loc++;} /* hex constant */
- else if (xisdigit(*loc)) {*id_loc++='~';
- while (xisdigit(*loc)) *id_loc++=*loc++;} /* octal constant */
- else goto dec; /* decimal constant */
- }
- else { /* decimal constant */
- if (*(loc-1)=='.' && !xisdigit(*loc)) goto mistake; /* not a constant */
- dec: *id_loc++=*(loc-1);
- while (xisdigit(*loc) || *loc=='.') *id_loc++=*loc++;
- if (*loc=='e' || *loc=='E') { /* float constant */
- *id_loc++='_'; loc++;
- if (*loc=='+' || *loc=='-') *id_loc++=*loc++;
- while (xisdigit(*loc)) *id_loc++=*loc++;
- }
+ if (*loc=='x' || *loc=='X') @<Get a hexadecimal constant@>@;
+ else if (*loc=='b' || *loc=='B') @<Get a binary constant@>@;
+ else if (xisdigit(*loc)) @<Get an octal constant@>@;
}
+ *id_loc++=*(loc-1); /* decimal constant */
+ gather_digits_while(xisdigit(*loc) || *loc=='.');
+get_exponent:
+ if (*loc=='e' || *loc=='E')
+ *id_loc++='_';
+ else if (*loc=='p' || *loc=='P')
+ *id_loc++='%';
+ else
+ goto digit_suffix;
+ loc++;
+ if (*loc=='+' || *loc=='-') *id_loc++=*loc++;
+ gather_digits_while(xisdigit(*loc));
+digit_suffix:
while (*loc=='u' || *loc=='U' || *loc=='l' || *loc=='L'
|| *loc=='f' || *loc=='F') {
- *id_loc++='$'; *id_loc++=toupper((eight_bits)*loc); loc++;
+ *id_loc++='$'; *id_loc++=toupper((int)*loc); loc++;
}
return constant;
}
+@ @<Get a hex...@>={
+ *id_loc++='^'; loc++;
+ gather_digits_while(xisxdigit(*loc) || *loc=='.');
+ goto get_exponent;
+}
+
+@ @<Get a bin...@>={
+ *id_loc++='\\'; loc++;
+ gather_digits_while(*loc=='0' || *loc=='1');
+ goto digit_suffix;
+}
+
+@ @<Get an oct...@>={
+ *id_loc++='~'; gather_digits_while(xisdigit(*loc));
+ goto digit_suffix;
+}
+
@ \CEE/ strings and character constants, delimited by double and single
quotes, respectively, can contain newlines or instances of their own
delimiters if they are protected by a backslash. We follow this
convention, but do not allow the string to be longer than |longest_name|.
-@<Get a string@>= {
+@<Get a string@>= {@+
char delim = c; /* what started the string */
id_first = section_text+1;
id_loc = section_text;
if (delim=='\'' && *(loc-2)=='@@') {*++id_loc='@@'; *++id_loc='@@';}
*++id_loc=delim;
- 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 */
+ if (delim=='L' || delim=='u' || delim=='U')
+ @<Get a wide character constant@>@;
+ if (delim=='<') delim='>'; /* for file names in \#\&{include} lines */
while (true) {
if (loc>=limit) {
if(*(limit-1)!='\\') {
@@ -858,10 +909,14 @@ 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) {
- *id_loc = '\\'; c=*loc++;
- } } }
+ 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) {
@@ -874,36 +929,40 @@ convention, but do not allow the string to be longer than |longest_name|.
return string;
}
+@ @<Get a wide...@>={
+ if (delim=='u' && *loc=='8') *++id_loc=*loc++;
+ delim=*loc++; *++id_loc=delim;
+}
+
@ After an \.{@@} sign has been scanned, the next character tells us
whether there is more work to do.
-@<Get control code and possible section name@>= {
- c=*loc++;
- switch(ccode[(eight_bits)c]) {
- case translit_code: err_print("! Use @@l in limbo only"); continue;
+@<Get control code and possible section name@>=
+switch(ccode[c=*loc++]) {
+ case translit_code: err_print("! Use @@l in limbo only"); continue;
@.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[(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];
- }
+ case underline: xref_switch=def_flag; continue;
+ case trace: tracing=c-'0'; continue;
+ 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@>@;
+ case xref_roman: case xref_wildcard: case xref_typewriter: case noop:
+ case TeX_string: skip_restricted(); /* fall through */
+ default: return ccode[c];
}
@ The occurrence of a section name sets |xref_switch| to zero,
because the section name might (for example) follow \&{int}.
@<Scan the section name...@>= {
- char *k; /* pointer into |section_text| */
+ char *k=section_text; /* pointer into |section_text| */
cur_section_char=*(loc-1);
@<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);
+ cur_section=section_lookup(section_text+1,k-3,true);
+ /* |true| indicates a prefix */
+ else cur_section=section_lookup(section_text+1,k,false);
xref_switch=0; return section_name;
}
@@ -916,7 +975,6 @@ character of the name.)
@<Set init...@>=section_text[0]=' ';
@ @<Put section name...@>=
-k=section_text;
while (true) {
if (loc>limit && get_line()==false) {
err_print("! Input ended in section name");
@@ -945,7 +1003,7 @@ if (c=='@@') {
if (c=='>') {
loc+=2; break;
}
- if (ccode[(eight_bits)c]==new_section) {
+ if (ccode[c]==new_section) {
err_print("! Section name didn't end"); break;
@.Section name didn't end@>
}
@@ -969,8 +1027,7 @@ false_alarm:
if (loc++>limit) {
err_print("! Control text didn't end"); loc=limit;
@.Control text didn't end@>
- }
- else {
+ } else {
if (*loc=='@@'&&loc<=limit) {loc++; goto false_alarm;}
if (*loc++!='>')
err_print("! Control codes are forbidden in control text");
@@ -985,14 +1042,13 @@ 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
buffer. We also set |loc| to the position just after the ending delimiter.
-@<Scan a verbatim string@>= {
- id_first=loc++; *(limit+1)='@@'; *(limit+2)='>';
- while (*loc!='@@' || *(loc+1)!='>') loc++;
- if (loc>=limit) err_print("! Verbatim string didn't end");
+@<Scan a verbatim string@>=
+id_first=loc++; *(limit+1)='@@'; *(limit+2)='>';
+while (*loc!='@@' || *(loc+1)!='>') loc++;
+if (loc>=limit) err_print("! Verbatim string didn't end");
@.Verbatim string didn't end@>
- id_loc=loc; loc+=2;
- return verbatim;
-}
+id_loc=loc; loc+=2;
+return verbatim;
@** Phase one processing.
We now have accumulated enough subroutines to make it possible to carry out
@@ -1019,7 +1075,6 @@ phase_one(void) {
@<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@>@;
}
@@ -1031,7 +1086,7 @@ phase_one(void) {
changed_section[section_count]=changing;
/* it will become |true| if any line changes */
if (*(loc-1)=='*' && show_progress) {
- printf("*%d",section_count);
+ printf("*%d",(int)section_count);
update_terminal; /* print a progress report */
}
@<Store cross-references in the \TEX/ part of a section@>@;
@@ -1067,14 +1122,13 @@ static void outer_xref(void);
@ @c
static void
-C_xref(@t\1\1@> /* makes cross-references for \CEE/ identifiers */
- eight_bits spec_ctrl@t\2\2@>)
+C_xref( /* makes cross-references for \CEE/ identifiers */
+ eight_bits spec_ctrl)
{
- name_pointer p; /* a referenced name */
while (next_control<format_code || next_control==spec_ctrl) {
if (next_control>=identifier && next_control<=xref_typewriter) {
- if (next_control>identifier) @<Replace |"@@@@"| by |"@@"| @>@;
- p=id_lookup(id_first, id_loc,next_control-identifier); new_xref(p);
+ if (next_control>identifier) @<Replace `\.{@@@@}' by `\.{@@}'@>@;
+ new_xref(id_lookup(id_first,id_loc,next_control-identifier));
}
if (next_control==section_name) {
section_xref_switch=cite_flag;
@@ -1126,15 +1180,15 @@ while (true) {
case noop: case section_name:
loc-=2; next_control=get_next(); /* scan to \.{@@>} */
if (next_control>=xref_roman && next_control<=xref_typewriter) {
- @<Replace |"@@@@"| by |"@@"| @>@;
- new_xref(id_lookup(id_first, id_loc,next_control-identifier));
+ @<Replace `\.{@@@@}' by `\.{@@}'@>@;
+ new_xref(id_lookup(id_first,id_loc,next_control-identifier));
}
break;
}
if (next_control>=format_code) break;
}
-@ @<Replace |"@@@@"| by |"@@"| @>=
+@ @<Replace `\.{@@@@}' by `\.{@@}'@>=
{
char *src=id_first,*dst=id_first;
while(src<id_loc){
@@ -1203,19 +1257,17 @@ discover should be unindexed.
definition is found in limbo.
@<Process simple format in limbo@>=
-{
- if (get_next()!=identifier)
- err_print("! Missing left identifier of @@s");
+if (get_next()!=identifier)
+ err_print("! Missing left identifier of @@s");
@.Missing left identifier...@>
- else {
- lhs=id_lookup(id_first,id_loc,normal);
- if (get_next()!=identifier)
- err_print("! Missing right identifier of @@s");
+else {
+ lhs=id_lookup(id_first,id_loc,normal);
+ if (get_next()!=identifier)
+ err_print("! Missing right identifier of @@s");
@.Missing right identifier...@>
- else {
- rhs=id_lookup(id_first,id_loc,normal);
- lhs->ilk=rhs->ilk;
- }
+ else {
+ rhs=id_lookup(id_first,id_loc,normal);
+ lhs->ilk=rhs->ilk;
}
}
@@ -1223,7 +1275,7 @@ definition is found in limbo.
|next_control>=begin_C|.
@<Store cross-references in the \CEE/...@>=
-if (next_control<=section_name) { /* |begin_C| or |section_name| */
+if (next_control<=section_name) { /* |begin_C| or |section_name| */
if (next_control==begin_C) section_xref_switch=0;
else {
section_xref_switch=def_flag;
@@ -1257,8 +1309,7 @@ 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=true; cur_xref=cur_xref->xlink;}
- else an_output=false;
+ if ((an_output=(cur_xref->num==file_flag))==true) cur_xref=cur_xref->xlink;
if (cur_xref->num <def_flag) {
fputs("\n! Never defined: <",stdout);
print_section_name(p); putchar('>'); mark_harmless;
@@ -1297,7 +1348,7 @@ that is being output; in this case the breakpoint |b| should be strictly
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
+if the |carryover| parameter is |true|, a |"%"| in that line will be
carried over to the next line (so that \TEX/ will ignore the completion
of commented-out text).
@@ -1313,11 +1364,11 @@ static void finish_line(void);
@ @c
static void
-flush_buffer(@t\1\1@>
+flush_buffer(
char *b, /* outputs from |out_buf+1| to |b|, where |b<=out_ptr| */
-boolean per_cent,boolean carryover@t\2\2@>)
+boolean per_cent,boolean carryover)
{
- char *j; j=b; /* pointer into |out_buf| */
+ char *j=b; /* pointer into |out_buf| */
if (! per_cent) /* remove trailing blanks */
while (j>out_buf && *j==' ') j--;
c_line_write(j-out_buf);
@@ -1360,7 +1411,7 @@ tricky way so that the first line of the output file will be
@<Start \TEX/...@>=
out_ptr=out_buf+1; out_line=1; active_file=tex_file;
-*out_ptr='c'; tex_printf("\\input cwebma");
+tex_printf("\\input cwebma"); *out_ptr='c';
@ When we wish to append one character |c| to the output buffer, we write
`|out(c)|'; this will cause the buffer to be emptied if it was already
@@ -1378,8 +1429,8 @@ 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@>)
+out_str( /* output characters from |s| to end of string */
+const char*s)
{
while (*s) out(*s++);
}
@@ -1440,8 +1491,8 @@ out_section(
sixteen_bits n)
{
char s[6];
- sprintf(s,"%d",n); out_str(s);
- if(changed_section[n]) out_str ("\\*");
+ sprintf(s,"%d",(int)n); out_str(s);
+ if (changed_section[n]) out_str("\\*");
@.\\*@>
}
@@ -1485,15 +1536,13 @@ static int copy_comment(boolean,int);
static void
copy_limbo(void)
{
- char c;
while (true) {
if (loc>limit && (finish_line(), get_line()==false)) return;
*(limit+1)='@@';
while (*loc!='@@') out(*(loc++));
if (loc++<=limit) {
- c=*loc++;
- if (ccode[(eight_bits)c]==new_section) break;
- switch (ccode[(eight_bits)c]) {
+ switch (ccode[(eight_bits)*loc++]) {
+ case new_section: return;
case translit_code: out_str("\\ATL"); break;
@.\\ATL@>
case '@@': out('@@'); break;
@@ -1546,9 +1595,9 @@ one further token without overflow.
@d app_tok(c) {if (tok_ptr+2>tok_mem_end) overflow("token"); *(tok_ptr++)=c;}
@c
-static int copy_comment(@t\1\1@> /* copies \TeX\ code in comments */
+static int copy_comment( /* copies \TeX\ code in comments */
boolean is_long_comment, /* is this a traditional \CEE/ comment? */
-int bal@t\2\2@>) /* brace balance */
+int bal) /* brace balance */
{
char c; /* current character being copied */
while (true) {
@@ -1559,8 +1608,7 @@ int bal@t\2\2@>) /* brace balance */
@.Input ended in mid-comment@>
loc=buffer+1; goto done;
}
- }
- else {
+ } else {
if (bal>1) err_print("! Missing } in comment");
@.Missing \} in comment@>
goto done;
@@ -1583,7 +1631,7 @@ int bal@t\2\2@>) /* brace balance */
}
}
}
-done:@<Clear |bal| and |return|@>@;
+done: @<Clear |bal| and |return|@>@;
}
@ @<Check for end of comment@>=
@@ -1601,9 +1649,11 @@ if (c=='@@') {
@.Illegal use of @@...@>
loc-=2; if (phase==2) *(tok_ptr-1)=' '; goto done;
}
+} else {
+ if (c=='\\' && *loc!='@@') {
+ if (phase==2) app_tok(*(loc++))@t;@>@; else loc++;
+ }
}
-else { if (c=='\\' && *loc!='@@') {
- if (phase==2) app_tok(*(loc++))@; else loc++; } }
@ We output
enough right braces to keep \TEX/ happy.
@@ -1683,8 +1733,8 @@ same initial letter; these subscripts are assigned from left to right.
@d rbrace 8 /* denotes a right brace */
@d decl_head 9 /* denotes an incomplete declaration */
@d comma 10 /* denotes a comma */
-@d lpar 11 /* denotes a left parenthesis or left bracket */
-@d rpar 12 /* denotes a right parenthesis or right bracket */
+@d lpar 11 /* denotes a left parenthesis */
+@d rpar 12 /* denotes a right parenthesis */
@d prelangle 13 /* denotes `$<$' before we know what it is */
@d prerangle 14 /* denotes `$>$' before we know what it is */
@d langle 15 /* denotes `$<$' when it's used as angle bracket in a template */
@@ -1706,13 +1756,16 @@ same initial letter; these subscripts are assigned from left to right.
@d insert 37 /* a scrap that gets combined with its neighbor */
@d section_scrap 38 /* section name */
@d dead 39 /* scrap that won't combine */
-@d ftemplate 59 /* \\{make\_pair} */
-@d new_exp 60 /* \&{new} and a following type identifier */
-@d begin_arg 61 /* \.{@@[} */
-@d end_arg 62 /* \.{@@]} */
+@d ftemplate 63 /* \\{make\_pair} */
+@d new_exp 64 /* \&{new} and a following type identifier */
+@d begin_arg 65 /* \.{@@[} */
+@d end_arg 66 /* \.{@@]} */
+@d lbrack 67 /* denotes a left bracket */
+@d rbrack 68 /* denotes a right bracket */
+@d attr_head 69 /* denotes beginning of attribute */
@<Private...@>=
-static char cat_name[256][12];
+static char cat_name[256][12]; /* |12==strlen("struct_head")+1| */
@ @<Set in...@>=
{int c; for (c=0;c<256;c++) strcpy(cat_name[c],"UNKNOWN");}
@@ -1774,19 +1827,18 @@ static char cat_name[256][12];
strcpy(cat_name[new_exp],"new_exp");
strcpy(cat_name[begin_arg],"@@["@q]@>);
strcpy(cat_name[end_arg],@q[@>"@@]");
+ strcpy(cat_name[lbrack],"[");
+ strcpy(cat_name[rbrack],"]");
+ strcpy(cat_name[attr_head],"attr_head");
+ strcpy(cat_name[attr],"attr");
+ strcpy(cat_name[alignas_like],"alignas");
+ strcpy(cat_name[using_like],"using");
+ strcpy(cat_name[default_like],"default");
strcpy(cat_name[0],"zero");
@ This code allows \.{CWEAVE} to display its parsing steps.
-@c
-static void
-print_cat(@t\1\1@> /* symbolic printout of a category */
-eight_bits c@t\2\2@>)
-{
- fputs(cat_name[c],stdout);
-}
-
-@ @<Predecl...@>=@+static void print_cat(eight_bits);
+@d print_cat(c) fputs(cat_name[c],stdout) /* symbolic printout of a category */
@ The token lists for translated \TEX/ output contain some special control
symbols as well as ordinary characters. These control symbols are
@@ -1813,7 +1865,9 @@ $10n$;
\yskip\hang |indent| causes future lines to be indented one more em;
-\yskip\hang |outdent| causes future lines to be indented one less em.
+\yskip\hang |outdent| causes future lines to be indented one less em;
+
+\yskip\hang |dindent| causes future lines to be indented two more ems.
\yskip\noindent All of these tokens are removed from the \TEX/ output that
comes from \CEE/ text between \pb\ signs; |break_space| and |force| and
@@ -1827,6 +1881,10 @@ However, a sequence of consecutive `\.\ ', |break_space|,
|force|, and/or |big_force| tokens is first replaced by a single token
(the maximum of the given ones).
+A |dindent| token becomes \.{\\1\\1}. It is equivalent to a pair of |indent|
+tokens. However, if |dindent| immediately precedes |big_force|, the two tokens
+are swapped, so that the indentation happens after the line break.
+
The token |math_rel| will be translated into
\.{\\MRL\{}, and it will get a matching \.\} later.
Other control sequences in the \TEX/ output will be
@@ -1854,6 +1912,7 @@ reserved words, `\.{\\.\{}$\,\ldots\,$\.\}' surrounding strings,
@d end_translation 0223 /* special sentinel token at end of list */
@d inserted 0224 /* sentinel to mark translations of inserts */
@d qualifier 0225 /* introduces an explicit namespace qualifier */
+@d dindent 0226 /* two more tabs (\.{\\1\\1}) */
@ The raw input is converted into scraps according to the following table,
which gives category codes followed by the translations.
@@ -1894,9 +1953,12 @@ with discretionary breaks in between.
\.{@@'7'}&|exp|: \.{\\.\{@@'7'\}}&maybe\cr
\.{077} or \.{\\77}&|exp|: \.{\\T\{\\\~77\}}&maybe\cr
\.{0x7f}&|exp|: \.{\\T\{\\\^7f\}}&maybe\cr
+\.{0b10111}&|exp|: \.{\\T\{\\\\10111\}}&maybe\cr
\.{77}&|exp|: \.{\\T\{77\}}&maybe\cr
\.{77L}&|exp|: \.{\\T\{77\\\$L\}}&maybe\cr
\.{0.1E5}&|exp|: \.{\\T\{0.1\\\_5\}}&maybe\cr
+\.{0x10p3}&|exp|: \.{\\T\{\\\^10\}\\p\{3\}}&maybe\cr
+\.{1'000'000}&|exp|: \.{\\T\{1\\\ 000\\\ 000\}}&maybe\cr
\.+&|ubinop|: \.+&yes\cr
\.-&|ubinop|: \.-&yes\cr
\.*&|raw_ubin|: \.*&yes\cr
@@ -1913,19 +1975,21 @@ with discretionary breaks in between.
\.\~&|unop|: \.{\\CM}&yes\cr
\.\&&|raw_ubin|: \.{\\AND}&yes\cr
\.(&|lpar|: \.(&maybe\cr
-\.[&|lpar|: \.[&maybe\cr
\.)&|rpar|: \.)&maybe\cr
-\.]&|rpar|: \.]&maybe\cr
+\.[&|lbrack|: \.[&maybe\cr
+\.]&|rbrack|: \.]&maybe\cr
\.\{&|lbrace|: \.\{&yes\cr
\.\}&|lbrace|: \.\}&yes\cr
\.,&|comma|: \.,&yes\cr
\.;&|semi|: \.;&maybe\cr
\.:&|colon|: \.:&no\cr
\.\# (within line)&|ubinop|: \.{\\\#}&yes\cr
-\.\# (at beginning)&|lproc|: |force| |preproc_line| \.{\\\#}&no\cr
-end of \.\# line&|rproc|: |force|&no\cr
+\.\# (at beginning)&|lproc|: |force| |preproc_line| \.{\\\#}&no\cr
+end of \.\# line&|rproc|: |force|&no\cr
identifier&|exp|: \.{\\\\\{}identifier with underlines and
dollar signs quoted\.\}&maybe\cr
+\.{alignas}&|alignas_like|: \stars&maybe\cr
+\.{alignof}&|sizeof_like|: \stars&maybe\cr
\.{and}&|alfop|: \stars&yes\cr
\.{and\_eq}&|alfop|: \stars&yes\cr
\.{asm}&|sizeof_like|: \stars&maybe\cr
@@ -1937,13 +2001,25 @@ identifier&|exp|: \.{\\\\\{}identifier with underlines and
\.{case}&|case_like|: \stars&maybe\cr
\.{catch}&|catch_like|: \stars&maybe\cr
\.{char}&|raw_int|: \stars&maybe\cr
+\.{char8\_t}&|raw_int|: \stars&maybe\cr
+\.{char16\_t}&|raw_int|: \stars&maybe\cr
+\.{char32\_t}&|raw_int|: \stars&maybe\cr
\.{class}&|struct_like|: \stars&maybe\cr
\.{clock\_t}&|raw_int|: \stars&maybe\cr
\.{compl}&|alfop|: \stars&yes\cr
+\.{complex}&|int_like|: \stars&yes\cr
+\.{concept}&|int_like|: \stars&maybe\cr
\.{const}&|const_like|: \stars&maybe\cr
+\.{consteval}&|const_like|: \stars&maybe\cr
+\.{constexpr}&|const_like|: \stars&maybe\cr
+\.{constinit}&|const_like|: \stars&maybe\cr
\.{const\_cast}&|raw_int|: \stars&maybe\cr
\.{continue}&|case_like|: \stars&maybe\cr
-\.{default}&|case_like|: \stars&maybe\cr
+\.{co\_await}&|case_like|: \stars&maybe\cr
+\.{co\_return}&|case_like|: \stars&maybe\cr
+\.{co\_yield}&|case_like|: \stars&maybe\cr
+\.{decltype}&|sizeof_like|: \stars&maybe\cr
+\.{default}&|default_like|: \stars&maybe\cr
\.{define}&|define_like|: \stars&maybe\cr
\.{defined}&|sizeof_like|: \stars&maybe\cr
\.{delete}&|delete_like|: \stars&maybe\cr
@@ -1960,6 +2036,7 @@ identifier&|exp|: \.{\\\\\{}identifier with underlines and
\.{export}&|int_like|: \stars&maybe\cr
\.{extern}&|int_like|: \stars&maybe\cr
\.{FILE}&|raw_int|: \stars&maybe\cr
+\.{false}&|normal|: \stars&maybe\cr
\.{float}&|raw_int|: \stars&maybe\cr
\.{for}&|for_like|: \stars&maybe\cr
\.{fpos\_t}&|raw_int|: \stars&maybe\cr
@@ -1968,6 +2045,7 @@ identifier&|exp|: \.{\\\\\{}identifier with underlines and
\.{if}&|if_like|: \stars&maybe\cr
\.{ifdef}&|if_like|: \stars&maybe\cr
\.{ifndef}&|if_like|: \stars&maybe\cr
+\.{imaginary}&|int_like|: \stars&maybe\cr
\.{include}&|if_like|: \stars&maybe\cr
\.{inline}&|int_like|: \stars&maybe\cr
\.{int}&|raw_int|: \stars&maybe\cr
@@ -1979,9 +2057,11 @@ identifier&|exp|: \.{\\\\\{}identifier with underlines and
\.{mutable}&|int_like|: \stars&maybe\cr
\.{namespace}&|struct_like|: \stars&maybe\cr
\.{new}&|new_like|: \stars&maybe\cr
+\.{noexcept}&|attr|: \stars&maybe\cr
\.{not}&|alfop|: \stars&yes\cr
\.{not\_eq}&|alfop|: \stars&yes\cr
\.{NULL}&|exp|: \.{\\NULL}&yes\cr
+\.{nullptr}&|exp|: \.{\\NULL}&yes\cr
\.{offsetof}&|raw_int|: \stars&maybe\cr
\.{operator}&|operator_like|: \stars&maybe\cr
\.{or}&|alfop|: \stars&yes\cr
@@ -1993,6 +2073,8 @@ identifier&|exp|: \.{\\\\\{}identifier with underlines and
\.{public}&|public_like|: \stars&maybe\cr
\.{register}&|int_like|: \stars&maybe\cr
\.{reinterpret\_cast}&|raw_int|: \stars&maybe\cr
+\.{requires}&|int_like|: \stars&maybe\cr
+\.{restrict}&|int_like|: \stars&maybe\cr
\.{return}&|case_like|: \stars&maybe\cr
\.{short}&|raw_int|: \stars&maybe\cr
\.{sig\_atomic\_t}&|raw_int|: \stars&maybe\cr
@@ -2000,22 +2082,24 @@ identifier&|exp|: \.{\\\\\{}identifier with underlines and
\.{size\_t}&|raw_int|: \stars&maybe\cr
\.{sizeof}&|sizeof_like|: \stars&maybe\cr
\.{static}&|int_like|: \stars&maybe\cr
+\.{static\_assert}&|sizeof_like|: \stars&maybe\cr
\.{static\_cast}&|raw_int|: \stars&maybe\cr
\.{struct}&|struct_like|: \stars&maybe\cr
\.{switch}&|for_like|: \stars&maybe\cr
\.{template}&|template_like|: \stars&maybe\cr
\.{TeX}&|exp|: \.{\\TeX}&yes\cr
\.{this}&|exp|: \.{\\this}&yes\cr
+\.{thread\_local}&|raw_int|: \stars&maybe\cr
\.{throw}&|case_like|: \stars&maybe\cr
\.{time\_t}&|raw_int|: \stars&maybe\cr
\.{try}&|else_like|: \stars&maybe\cr
\.{typedef}&|typedef_like|: \stars&maybe\cr
-\.{typeid}&|raw_int|: \stars&maybe\cr
+\.{typeid}&|sizeof_like|: \stars&maybe\cr
\.{typename}&|struct_like|: \stars&maybe\cr
\.{undef}&|if_like|: \stars&maybe\cr
\.{union}&|struct_like|: \stars&maybe\cr
\.{unsigned}&|raw_int|: \stars&maybe\cr
-\.{using}&|int_like|: \stars&maybe\cr
+\.{using}&|using_like|: \stars&maybe\cr
\.{va\_dcl}&|decl|: \stars&maybe\cr
\.{va\_list}&|raw_int|: \stars&maybe\cr
\.{virtual}&|int_like|: \stars&maybe\cr
@@ -2026,10 +2110,10 @@ identifier&|exp|: \.{\\\\\{}identifier with underlines and
\.{xor}&|alfop|: \stars&yes\cr
\.{xor\_eq}&|alfop|: \stars&yes\cr
\.{@@,}&|insert|: \.{\\,}&maybe\cr
-\.{@@\v}&|insert|: |opt| \.0&maybe\cr
-\.{@@/}&|insert|: |force|&no\cr
-\.{@@\#}&|insert|: |big_force|&no\cr
-\.{@@+}&|insert|: |big_cancel| \.{\{\}} |break_space|
+\.{@@\v}&|insert|: |opt| \.0&maybe\cr
+\.{@@/}&|insert|: |force|&no\cr
+\.{@@\#}&|insert|: |big_force|&no\cr
+\.{@@+}&|insert|: |big_cancel| \.{\{\}} |break_space|
\.{\{\}} |big_cancel|&no\cr
\.{@@;}&|semi|: &maybe\cr
\.{@@[@q]@>}&|begin_arg|: &maybe\cr
@@ -2041,15 +2125,15 @@ identifier&|exp|: \.{\\\\\{}identifier with underlines and
\.{@@(@q)@>}\thinspace section name\thinspace\.{@@>}&|section_scrap|:
\.{\\X}$n$\.{:\\.\{}section name with special characters
quoted\.{\ \}\\X}&maybe\cr
-\.{/*}comment\.{*/}&|insert|: |cancel|
+\.{/*}\thinspace comment\thinspace\.{*/}&|insert|: |cancel|
\.{\\C\{}translated comment\.\} |force|&no\cr
-\.{//}comment&|insert|: |cancel|
+\.{//}\thinspace comment&|insert|: |cancel|
\.{\\SHC\{}translated comment\.\} |force|&no\cr
}
\smallskip
The construction \.{@@t}\thinspace stuff\/\thinspace\.{@@>} contributes
-\.{\\hbox\{}\thinspace stuff\/\thinspace\.\} to the following scrap.
+\.{\\hbox\{}\thinspace stuff\/\thinspace\.\} to the following scrap.
@i prod.w
@@ -2090,7 +2174,7 @@ typedef struct {
eight_bits cat;
eight_bits mathness;
union {
- text_pointer Trans;
+ text_pointer Trans;@+@t}\6{@>
@<Rest of |trans_plus| union@>@;
} trans_plus;
} scrap;
@@ -2130,30 +2214,33 @@ items for \TEX/ output.
translated without line-break controls.
@d id_flag 10240 /* signifies an identifier */
-@d res_flag 2*id_flag /* signifies a reserved word */
-@d section_flag 3*id_flag /* signifies a section name */
-@d tok_flag 4*id_flag /* signifies a token list */
-@d inner_tok_flag 5*id_flag /* signifies a token list in `\pb' */
+@d res_flag (2*id_flag) /* signifies a reserved word */
+@d section_flag (3*id_flag) /* signifies a section name */
+@d tok_flag (4*id_flag) /* signifies a token list */
+@d inner_tok_flag (5*id_flag) /* signifies a token list in `\pb' */
@c
static void
-print_text(@t\1\1@> /* prints a token list for debugging; not used in |main| */
-text_pointer p@t\2\2@>)
+print_text( /* prints a token list for debugging; not used in |main| */
+text_pointer p)
{
token_pointer j; /* index into |tok_mem| */
sixteen_bits r; /* remainder of token after the flag has been stripped off */
if (p>=text_ptr) printf("BAD");
else for (j=*p; j<*(p+1); j++) {
r=*j%id_flag;
- switch (*j/id_flag) {
- case 1: printf("\\\\{"@q}@>); print_id((name_dir+r)); printf(@q{@>"}");
- break; /* |id_flag| */
- case 2: printf("\\&{"@q}@>); print_id((name_dir+r)); printf(@q{@>"}");
- break; /* |res_flag| */
- case 3: printf("<"); print_section_name((name_dir+r)); printf(">");
- break; /* |section_flag| */
- case 4: printf("[[%d]]",r); break; /* |tok_flag| */
- case 5: printf("|[[%d]]|",r); break; /* |inner_tok_flag| */
+ switch (*j) {
+ case id_flag:
+ printf("\\\\{"@q}@>); print_id((name_dir+r)); putchar(@q{@>'}');
+ break;
+ case res_flag:
+ printf("\\&{"@q}@>); print_id((name_dir+r)); putchar(@q{@>'}');
+ break;
+ case section_flag:
+ putchar('<'); print_section_name((name_dir+r)); putchar('>');
+ break;
+ case tok_flag: printf("[[%d]]",(int)r); break;
+ case inner_tok_flag: printf("|[[%d]]|",(int)r); break;
default: @<Print token |r| in symbolic form@>@;
}
}
@@ -2169,6 +2256,7 @@ switch (r) {
case cancel: printf("[cancel]"); break;
case indent: printf("[indent]"); break;
case outdent: printf("[outdent]"); break;
+ case dindent: printf("[dindent]"); break;
case backup: printf("[backup]"); break;
case opt: printf("[opt]"); break;
case break_space: printf("[break]"); break;
@@ -2178,7 +2266,7 @@ switch (r) {
case quoted_char: j++; printf("[%o]",(unsigned int)*j); break;
case end_translation: printf("[quit]"); break;
case inserted: printf("[inserted]"); break;
- default: putxchar(r);
+ default: putchar((int)r);
}
@ The production rules listed above are embedded directly into \.{CWEAVE},
@@ -2213,77 +2301,79 @@ the production just mentioned.
Before calling |reduce|, the program should have appended the tokens of
the new translation to the |tok_mem| array. We commonly want to append
copies of several existing translations, and macros are defined to
-simplify these common cases. For example, \\{app2}|(pp)| will append the
+simplify these common cases. For example, |big_app2(pp)| will append the
translations of two consecutive scraps, |pp->trans| and |(pp+1)->trans|, to
the current token list. If the entire new translation is formed in this
way, we write `|squash(j,k,c,d,n)|' instead of `|reduce(j,k,c,d,n)|'. For
-example, `|squash(pp,3,exp,-2,3)|' is an abbreviation for `\\{app3}|(pp);
+example, `|squash(pp,3,exp,-2,3)|' is an abbreviation for `|big_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_app3|
+Both |big_app| and |app| append a token (while |big_app1| to |big_app4|
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
tokens, and intercalates a `\.{\$}' token if necessary. When in
doubt what to use, use |big_app|.
-The |mathness| is an attribute of scraps that says whether they are
+@d app(a) *(tok_ptr++)=(token)(a)
+@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 big_app1_insert(p,c) big_app1(p);@+big_app(c);@+big_app1(p+1)
+
+@<Predecl...@>=
+static void app_str(const char *);@/
+static void big_app(token);@/
+static void big_app1(scrap_pointer);
+
+@ The |mathness| is an attribute of scraps that says whether they are
to be printed in a math mode context or not. It is separate from the
``part of speech'' (the |cat|) because to make each |cat| have
a fixed |mathness| (as in the original \.{WEAVE}) would multiply the
number of necessary production rules.
-The low two bits (i.e. |mathness % 4|) control the left boundary.
+The low two bits (i.e., |mathness % 4|) control the left boundary.
(We need two bits because we allow cases |yes_math|, |no_math| and
|maybe_math|, which can go either way.)
-The next two bits (i.e. |mathness / 4|) control the right boundary.
+The next two bits (i.e., |mathness / 4|) control the right boundary.
If we combine two scraps and the right boundary of the first has
a different mathness from the left boundary of the second, we
insert a \.{\$} in between. Similarly, if at printing time some
irreducible scrap has a |yes_math| boundary the scrap gets preceded
-or followed by a \.{\$}. The left boundary is |maybe_math| if and
+or followed by a~\.{\$}. The left boundary is |maybe_math| if and
only if the right boundary is.
-The code below is an exact translation of the production rules into
-\CEE/, using such macros, and the reader should have no difficulty
-understanding the format by comparing the code with the symbolic
-productions as they were listed earlier.
-
@d no_math 2 /* should be in horizontal mode */
@d yes_math 1 /* should be in math mode */
@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 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;
-@ @<Predecl...@>=
-static void app_str(const char *);@/
-static void big_app(token);@/
-static void big_app1(scrap_pointer);
+@ The code below is an exact translation of the production rules into
+\CEE/, using such macros, and the reader should have no difficulty
+understanding the format by comparing the code with the symbolic
+productions as they were listed earlier.
-@ @c
+@c
static void
app_str(
const char *s)
{
- while (*s) app_tok(*(s++));
+ while (*s) app_tok(*s++);
}
static void
big_app(
token a)
{
- if (a==' ' || (a>=big_cancel && a<=big_force)) /* non-math token */ {
+ if (a==' ' || (a>=big_cancel && a<=big_force) || a==dindent)
+ /* non-math token */ {
if (cur_mathness==maybe_math) init_mathness=no_math;
else if (cur_mathness==yes_math) app_str("{}$");
cur_mathness=no_math;
- }
- else {
+ } else {
if (cur_mathness==maybe_math) init_mathness=yes_math;
else if (cur_mathness==no_math) app_str("${}");
cur_mathness=yes_math;
@@ -2320,7 +2410,7 @@ code needs to be provided with a proper environment.
@d cat2 (pp+2)->cat
@d cat3 (pp+3)->cat
@d lhs_not_simple (pp->cat!=public_like
- && pp->cat!=semi
+ && pp->cat!=semi
&& pp->cat!=prelangle
&& pp->cat!=prerangle @|
&& pp->cat!=template_like
@@ -2333,14 +2423,16 @@ code needs to be provided with a proper environment.
&& pp->cat!=operator_like)
/* not a production with left side length 1 */
-@<Match a production at |pp|, or increase |pp| if there is no match@>= {
- if (cat1==end_arg && lhs_not_simple)
- if (pp->cat==begin_arg) squash(pp,2,exp,-2,124);
- else squash(pp,2,end_arg,-1,125);
- else if (cat1==insert) squash(pp,2,pp->cat,-2,0);
- else if (cat2==insert) squash(pp+1,2,(pp+1)->cat,-1,0);
- else if (cat3==insert) squash(pp+2,2,(pp+2)->cat,0,0);
- else
+@<Match a production at |pp|, or increase |pp| if there is no match@>=
+if (cat1==end_arg && lhs_not_simple)
+ if (pp->cat==begin_arg) squash(pp,2,exp,-2,124);
+ else squash(pp,2,end_arg,-1,125);
+else if (pp->cat==rbrack) reduce(pp,0,rpar,-3,130);
+else if (pp->cat==using_like) reduce(pp,0,int_like,-3,140);
+else if (cat1==insert) squash(pp,2,pp->cat,-2,0);
+else if (cat2==insert) squash(pp+1,2,(pp+1)->cat,-1,0);
+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;
@@ -2389,9 +2481,13 @@ code needs to be provided with a proper environment.
case typedef_like: @<Cases for |typedef_like|@>@; @+break;
case delete_like: @<Cases for |delete_like|@>@; @+break;
case question: @<Cases for |question|@>@; @+break;
+ case alignas_like: @<Cases for |alignas_like|@>@; @+break;
+ case lbrack: @<Cases for |lbrack|@>@; @+break;
+ case attr_head: @<Cases for |attr_head|@>@; @+break;
+ case attr: @<Cases for |attr|@>@; @+break;
+ case default_like: @<Cases for |default_like|@>@; @+break;
}
- pp++; /* if no match was found, we move to the right */
-}
+pp++; /* if no match was found, we move to the right */
@ In \CEE/, new specifier names can be defined via |typedef|, and we want
to make the parser recognize future occurrences of the identifier thus
@@ -2457,22 +2553,20 @@ the |for| loop below.
@c
static void
-make_reserved(@t\1\1@> /* make the first identifier in |p->trans| like |int| */
-scrap_pointer p@t\2\2@>)
+make_reserved( /* make the first identifier in |p->trans| like |int| */
+scrap_pointer p)
{
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 */
tok_value=*tok_loc;
- for (;p<=scrap_ptr; p==lo_ptr? p=hi_ptr: p++) {
- if (p->cat==exp) {
+ for (;p<=scrap_ptr; p==lo_ptr? p=hi_ptr: p++)
+ if (p->cat==exp)
if (**(p->trans)==tok_value) {
p->cat=raw_int;
**(p->trans)=tok_value%id_flag+res_flag;
}
- }
- }
(name_dir+(sixteen_bits)(tok_value%id_flag))->ilk=raw_int;
*tok_loc=tok_value%id_flag+res_flag;
}
@@ -2488,9 +2582,9 @@ it has been swallowed up by an |exp|.
@c
static void
-make_underlined(@t\1\1@>
+make_underlined(
/* underline the entry for the first identifier in |p->trans| */
-scrap_pointer p@t\2\2@>)
+scrap_pointer p)
{
token_pointer tok_loc; /* where the first identifier appears */
if ((tok_loc=find_first_ident(p->trans))<=operator_found)
@@ -2535,20 +2629,20 @@ to insert the new cross-reference not at the beginning of the list
(namely, at |p->xref|), but rather right before |q|.
@<Insert new cross-reference at |q|...@>=
- append_xref(0); /* this number doesn't matter */
- xref_ptr->xlink=(xref_pointer)p->xref; r=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 */
+append_xref(0); /* this number doesn't matter */
+xref_ptr->xlink=(xref_pointer)p->xref; r=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 */
@ Now comes the code that tries to match each production starting
with a particular type of scrap. Whenever a match is discovered,
-the |squash| or |reduce| macro will cause the appropriate action
-to be performed, followed by |goto found|.
+the |squash| or |reduce| function will cause the appropriate action
+to be performed.
@<Cases for |exp|@>=
if (cat1==lbrace || cat1==int_like || cat1==decl) {
- make_underlined(pp); big_app1(pp); big_app(indent); app(indent);
+ make_underlined(pp); big_app1(pp); big_app(dindent);
reduce(pp,1,fn_decl,0,1);
}
else if (cat1==unop) squash(pp,2,exp,-2,2);
@@ -2558,25 +2652,29 @@ else if (cat1==comma && cat2==exp) {
big_app2(pp);
app(opt); app('9'); big_app1(pp+2); reduce(pp,3,exp,-2,4);
}
-else if (cat1==lpar && cat2==rpar && cat3==colon) squash(pp+3,1,base,0,5);
-else if (cat1==cast && cat2==colon) squash(pp+2,1,base,0,5);
+else if (cat1==lpar && cat2==rpar && cat3==colon) reduce(pp+3,0,base,0,5);
+else if (cat1==cast && cat2==colon) reduce(pp+2,0,base,0,5);
else if (cat1==semi) squash(pp,2,stmt,-1,6);
else if (cat1==colon) {
- make_underlined (pp); squash(pp,2,tag,-1,7);
+ make_underlined (pp); squash(pp,2,tag,-1,7);
}
-else if (cat1==rbrace) squash(pp,1,stmt,-1,8);
+else if (cat1==rbrace) reduce(pp,0,stmt,-1,8);
else if (cat1==lpar && cat2==rpar && (cat3==const_like || cat3==case_like)) {
- big_app1(pp+2); big_app(' '); big_app1(pp+3); reduce(pp+2,2,rpar,0,9);
+ big_app1_insert(pp+2,' '); reduce(pp+2,2,rpar,0,9);
}
else if (cat1==cast && (cat2==const_like || cat2==case_like)) {
- big_app1(pp+1); big_app(' '); big_app1(pp+2); reduce(pp+1,2,cast,0,9);
+ big_app1_insert(pp+1,' '); reduce(pp+1,2,cast,0,9);
}
else if (cat1==exp || cat1==cast) squash(pp,2,exp,-2,10);
+else if (cat1==attr) {
+ big_app1_insert(pp,' '); reduce(pp,2,exp,-2,142);
+}
+else if (cat1==colcol && cat2==int_like) squash(pp,3,int_like,-2,152);
@ @<Cases for |lpar|@>=
if ((cat1==exp||cat1==ubinop) && cat2==rpar) squash(pp,3,exp,-2,11);
else if (cat1==rpar) {
- big_app1(pp); app('\\'); app(','); big_app1(pp+1);
+ big_app1(pp); app_str("\\,"); big_app1(pp+1);
@.\\,@>
reduce(pp,2,exp,-2,12);
}
@@ -2594,15 +2692,13 @@ if (cat1==exp || cat1==int_like) squash(pp,2,exp,-2,16);
@ @<Cases for |ubinop|@>=
if (cat1==cast && cat2==rpar) {
- big_app('{'); big_app1(pp); big_app('}'); big_app1(pp+1);
- reduce(pp,2,cast,-2,17);
+ big_app('{'); big_app1_insert(pp,'}'); reduce(pp,2,cast,-2,17);
}
else if (cat1==exp || cat1==int_like) {
- big_app('{'); big_app1(pp); big_app('}'); big_app1(pp+1);
- reduce(pp,2,cat1,-2,18);
+ big_app('{'); big_app1_insert(pp,'}'); reduce(pp,2,cat1,-2,18);
}
else if (cat1==binop) {
- big_app(math_rel); big_app1(pp); big_app('{'); big_app1(pp+1); big_app('}');
+ big_app(math_rel); big_app1_insert(pp,'{'); big_app('}');
big_app('}'); reduce(pp,2,binop,-1,19);
}
@@ -2616,45 +2712,45 @@ if (cat1==binop) {
@ @<Cases for |cast|@>=
if (cat1==lpar) squash(pp,2,lpar,-1,21);
else if (cat1==exp) {
- big_app1(pp); big_app(' '); big_app1(pp+1); reduce(pp,2,exp,-2,21);
+ big_app1_insert(pp,' '); reduce(pp,2,exp,-2,21);
}
-else if (cat1==semi) squash(pp,1,exp,-2,22);
+else if (cat1==semi) reduce(pp,0,exp,-2,22);
@ @<Cases for |sizeof_like|@>=
if (cat1==cast) squash(pp,2,exp,-2,23);
else if (cat1==exp) {
- big_app1(pp); big_app(' '); big_app1(pp+1); reduce(pp,2,exp,-2,24);
+ big_app1_insert(pp,' '); reduce(pp,2,exp,-2,24);
}
@ @<Cases for |int_like|@>=
if (cat1==int_like|| cat1==struct_like) {
- big_app1(pp); big_app(' '); big_app1(pp+1); reduce(pp,2,cat1,-2,25);
+ big_app1_insert(pp,' '); reduce(pp,2,cat1,-2,25);
}
else if (cat1==exp && (cat2==raw_int||cat2==struct_like))
squash(pp,2,int_like,-2,26);
else if (cat1==exp || cat1==ubinop || cat1==colon) {
big_app1(pp); big_app(' '); reduce(pp,1,decl_head,-1,27);
}
-else if (cat1==semi || cat1==binop) squash(pp,1,decl_head,0,28);
+else if (cat1==semi || cat1==binop) reduce(pp,0,decl_head,0,28);
@ @<Cases for |public_like|@>=
if (cat1==colon) squash(pp,2,tag,-1,29);
-else squash(pp,1,int_like,-2,30);
+else reduce(pp,0,int_like,-2,30);
@ @<Cases for |colcol|@>=
if (cat1==exp||cat1==int_like) {
app(qualifier); squash(pp,2,cat1,-2,31);
-}@+else if (cat1==colcol) squash(pp,2,colcol,-1,32);
+}
+else if (cat1==colcol) squash(pp,2,colcol,-1,32);
@ @<Cases for |decl_head|@>=
if (cat1==comma) {
big_app2(pp); big_app(' '); reduce(pp,2,decl_head,-1,33);
}
else if (cat1==ubinop) {
- big_app1(pp); big_app('{'); big_app1(pp+1); big_app('}');
- reduce(pp,2,decl_head,-1,34);
+ big_app1_insert(pp,'{'); big_app('}'); reduce(pp,2,decl_head,-1,34);
}
-else if (cat1==exp && cat2!=lpar && cat2!=exp && cat2!=cast) {
+else if (cat1==exp && cat2!=lpar && cat2!=lbrack && cat2!=exp && cat2!=cast) {
make_underlined(pp+1); squash(pp,2,decl_head,-1,35);
}
else if ((cat1==binop||cat1==colon) && cat2==exp && (cat3==comma ||
@@ -2662,18 +2758,19 @@ else if ((cat1==binop||cat1==colon) && cat2==exp && (cat3==comma ||
squash(pp,3,decl_head,-1,36);
else if (cat1==cast) squash(pp,2,decl_head,-1,37);
else if (cat1==lbrace || cat1==int_like || cat1==decl) {
- big_app1(pp); big_app(indent); app(indent); reduce(pp,1,fn_decl,0,38);
+ big_app(dindent); squash(pp,1,fn_decl,0,38);
}
else if (cat1==semi) squash(pp,2,decl,-1,39);
+else if (cat1==attr) {
+ big_app1_insert(pp,' '); reduce(pp,2,decl_head,-1,139);
+}
@ @<Cases for |decl|@>=
if (cat1==decl) {
- big_app1(pp); big_app(force); big_app1(pp+1);
- reduce(pp,2,decl,-1,40);
+ big_app1_insert(pp,force); reduce(pp,2,decl,-1,40);
}
else if (cat1==stmt || cat1==function) {
- big_app1(pp); big_app(big_force);
- big_app1(pp+1); reduce(pp,2,cat1,-1,41);
+ big_app1_insert(pp,big_force); reduce(pp,2,cat1,-1,41);
}
@ @<Cases for |base|@>=
@@ -2683,34 +2780,40 @@ if (cat1==int_like || cat1==exp) {
app(opt); app('9'); reduce(pp,3,base,0,42);
}
else if (cat2==lbrace) {
- big_app1(pp); big_app(' '); big_app1(pp+1); big_app(' '); big_app1(pp+2);
+ big_app1_insert(pp,' '); big_app(' '); big_app1(pp+2);
reduce(pp,3,lbrace,-2,43);
}
}
@ @<Cases for |struct_like|@>=
if (cat1==lbrace) {
- big_app1(pp); big_app(' '); big_app1(pp+1); reduce(pp,2,struct_head,0,44);
+ big_app1_insert(pp,' '); reduce(pp,2,struct_head,0,44);
}
else if (cat1==exp||cat1==int_like) {
if (cat2==lbrace || cat2==semi) {
make_underlined(pp+1); make_reserved(pp+1);
- big_app1(pp); big_app(' '); big_app1(pp+1);
+ big_app1_insert(pp,' ');
if (cat2==semi) reduce(pp,2,decl_head,0,45);
else {
big_app(' '); big_app1(pp+2);reduce(pp,3,struct_head,0,46);
}
}
- else if (cat2==colon) squash(pp+2,1,base,2,47);
+ else if (cat2==colon) reduce(pp+2,0,base,2,47);
else if (cat2!=base) {
- big_app1(pp); big_app(' '); big_app1(pp+1); reduce(pp,2,int_like,-2,48);
+ big_app1_insert(pp,' '); reduce(pp,2,int_like,-2,48);
}
}
+else if (cat1==attr) {
+ big_app1_insert(pp,' '); reduce(pp,2,struct_like,-3,141);
+}
+else if (cat1==struct_like) {
+ big_app1_insert(pp,' '); reduce(pp,2,struct_like,-3,151);
+}
@ @<Cases for |struct_head|@>=
if ((cat1==decl || cat1==stmt || cat1==function) && cat2==rbrace) {
big_app1(pp); big_app(indent); big_app(force); big_app1(pp+1);
- big_app(outdent); big_app(force); big_app1(pp+2);
+ big_app(outdent); big_app(force); big_app1(pp+2);
reduce(pp,3,int_like,-2,49);
}
else if (cat1==rbrace) {
@@ -2721,27 +2824,30 @@ else if (cat1==rbrace) {
@ @<Cases for |fn_decl|@>=
if (cat1==decl) {
- big_app1(pp); big_app(force); big_app1(pp+1); reduce(pp,2,fn_decl,0,51);
+ big_app1_insert(pp,force); reduce(pp,2,fn_decl,0,51);
}
else if (cat1==stmt) {
big_app1(pp); app(outdent); app(outdent); big_app(force);
big_app1(pp+1); reduce(pp,2,function,-1,52);
}
+else if (cat1==attr) {
+ big_app1_insert(pp,' '); reduce(pp,2,fn_decl,0,157);
+}
@ @<Cases for |function|@>=
if (cat1==function || cat1==decl || cat1==stmt) {
- big_app1(pp); big_app(big_force); big_app1(pp+1); reduce(pp,2,cat1,-1,53);
+ big_app1_insert(pp,big_force); reduce(pp,2,cat1,-1,53);
}
@ @<Cases for |lbrace|@>=
if (cat1==rbrace) {
- big_app1(pp); app('\\'); app(','); big_app1(pp+1);
+ big_app1(pp); app_str("\\,"); big_app1(pp+1);
@.\\,@>
reduce(pp,2,stmt,-1,54);
}
else if ((cat1==stmt||cat1==decl||cat1==function) && cat2==rbrace) {
- big_app(force); big_app1(pp); big_app(indent); big_app(force);
- big_app1(pp+1); big_app(force); big_app(backup); big_app1(pp+2);
+ big_app(force); big_app1(pp); big_app(indent); big_app(force);
+ big_app1(pp+1); big_app(force); big_app(backup); big_app1(pp+2);
big_app(outdent); big_app(force); reduce(pp,3,stmt,-1,55);
}
else if (cat1==exp) {
@@ -2751,12 +2857,12 @@ else if (cat1==exp) {
@ @<Cases for |if_like|@>=
if (cat1==exp) {
- big_app1(pp); big_app(' '); big_app1(pp+1); reduce(pp,2,if_clause,0,57);
+ big_app1_insert(pp,' '); reduce(pp,2,if_clause,0,57);
}
@ @<Cases for |else_like|@>=
-if (cat1==colon) squash(pp+1,1,base,1,58);
-else if (cat1==lbrace) squash(pp,1,else_head,0,59);
+if (cat1==colon) reduce(pp+1,0,base,1,58);
+else if (cat1==lbrace) reduce(pp,0,else_head,0,59);
else if (cat1==stmt) {
big_app(force); big_app1(pp); big_app(indent); big_app(break_space);
big_app1(pp+1); big_app(outdent); big_app(force);
@@ -2771,28 +2877,33 @@ if (cat1==stmt || cat1==exp) {
}
@ @<Cases for |if_clause|@>=
-if (cat1==lbrace) squash(pp,1,if_head,0,62);
+if (cat1==lbrace) reduce(pp,0,if_head,0,62);
else if (cat1==stmt) {
if (cat2==else_like) {
big_app(force); big_app1(pp); big_app(indent); big_app(break_space);
big_app1(pp+1); big_app(outdent); big_app(force); big_app1(pp+2);
if (cat3==if_like) {
big_app(' '); big_app1(pp+3); reduce(pp,4,if_like,0,63);
- }@+else reduce(pp,3,else_like,0,64);
+ }
+ else reduce(pp,3,else_like,0,64);
}
- else squash(pp,1,else_like,0,65);
+ else reduce(pp,0,else_like,0,65);
+}
+else if (cat1==attr) {
+ big_app1_insert(pp,' '); reduce(pp,2,if_head,0,146);
}
@ @<Cases for |if_head|@>=
if (cat1==stmt || cat1==exp) {
if (cat2==else_like) {
big_app(force); big_app1(pp); big_app(break_space); app(noop);
- big_app(cancel); big_app1(pp+1); big_app(force); big_app1(pp+2);
+ big_app(cancel); big_app1_insert(pp+1,force);
if (cat3==if_like) {
big_app(' '); big_app1(pp+3); reduce(pp,4,if_like,0,66);
- }@+else reduce(pp,3,else_like,0,67);
+ }
+ else reduce(pp,3,else_like,0,67);
}
- else squash(pp,1,else_head,0,68);
+ else reduce(pp,0,else_head,0,68);
}
@ @<Cases for |do_like|@>=
@@ -2806,22 +2917,23 @@ if (cat1==stmt && cat2==else_like && cat3==semi) {
if (cat1==semi) squash(pp,2,stmt,-1,70);
else if (cat1==colon) squash(pp,2,tag,-1,71);
else if (cat1==exp) {
- big_app1(pp); big_app(' '); big_app1(pp+1); reduce(pp,2,exp,-2,72);
+ big_app1_insert(pp,' '); reduce(pp,2,exp,-2,72);
}
@ @<Cases for |catch_like|@>=
if (cat1==cast || cat1==exp) {
- big_app2(pp); big_app(indent); big_app(indent); reduce(pp,2,fn_decl,0,73);
+ big_app1_insert(pp,dindent); reduce(pp,2,fn_decl,0,73);
}
@ @<Cases for |tag|@>=
if (cat1==tag) {
- big_app1(pp); big_app(break_space); big_app1(pp+1); reduce(pp,2,tag,-1,74);
+ big_app1_insert(pp,break_space); reduce(pp,2,tag,-1,74);
}
else if (cat1==stmt||cat1==decl||cat1==function) {
- big_app(force); big_app(backup); big_app1(pp); big_app(break_space);
- big_app1(pp+1); reduce(pp,2,cat1,-1,75);
+ big_app(force); big_app(backup); big_app1_insert(pp,break_space);
+ reduce(pp,2,cat1,-1,75);
}
+else if (cat1==rbrace) reduce(pp,0,decl,-1,156);
@ The user can decide at run-time whether short statements should be
grouped together on the same line.
@@ -2833,30 +2945,26 @@ force_lines=true;
@ @<Cases for |stmt|@>=
if (cat1==stmt||cat1==decl||cat1==function) {
- big_app1(pp);
- if (cat1==function) big_app(big_force);
- else if (cat1==decl) big_app(big_force);
- else if (force_lines) big_app(force);
- else big_app(break_space);
- big_app1(pp+1); reduce(pp,2,cat1,-1,76);
+ big_app1_insert(pp, (cat1==function || cat1==decl) ? big_force :
+ force_lines ? force : break_space); reduce(pp,2,cat1,-1,76);
}
@ @<Cases for |semi|@>=
-big_app(' '); big_app1(pp); reduce(pp,1,stmt,-1,77);
+big_app(' '); squash(pp,1,stmt,-1,77);
@ @<Cases for |lproc|@>=
if (cat1==define_like) make_underlined(pp+2);
-if (cat1==else_like || cat1==if_like ||cat1==define_like)
+if (cat1==else_like || cat1==if_like || cat1==define_like)
squash(pp,2,lproc,0,78);
else if (cat1==rproc) {
- app(inserted); big_app2(pp); reduce(pp,2,insert,-1,79);
+ app(inserted); squash(pp,2,insert,-1,79);
} else if (cat1==exp || cat1==function) {
if (cat2==rproc) {
app(inserted); big_app1(pp); big_app(' '); big_app2(pp+1);
reduce(pp,3,insert,-1,80);
}
- else if (cat2==exp && cat3==rproc && cat1==exp) {
- app(inserted); big_app1(pp); big_app(' '); big_app1(pp+1); app_str(" \\5");
+ else if (cat1==exp && cat2==exp && cat3==rproc) {
+ app(inserted); big_app1_insert(pp,' '); app_str("\\5");
@.\\5@>
big_app2(pp+2); reduce(pp,4,insert,-1,80);
}
@@ -2866,7 +2974,7 @@ else if (cat1==rproc) {
if (cat1==semi) {
big_app2(pp); big_app(force); reduce(pp,2,stmt,-2,81);
}
-else squash(pp,1,exp,-2,82);
+else reduce(pp,0,exp,-2,82);
@ @<Cases for |insert|@>=
if (cat1)
@@ -2880,9 +2988,12 @@ app('<'); reduce(pp,1,binop,-2,84);
init_mathness=cur_mathness=yes_math;
app('>'); reduce(pp,1,binop,-2,85);
-@ @<Cases for |langle|@>=
+@ @d reserve_typenames flags['t']
+ /* should we treat \&{typename} in a template like \&{typedef}? */
+
+@<Cases for |langle|@>=
if (cat1==prerangle) {
- big_app1(pp); app('\\'); app(','); big_app1(pp+1);
+ big_app1(pp); app_str("\\,"); big_app1(pp+1);
@.\\,@>
reduce(pp,2,cast,-1,86);
}
@@ -2892,103 +3003,114 @@ else if (cat1==decl_head || cat1==int_like || cat1==exp) {
big_app3(pp); app(opt); app('9'); reduce(pp,3,langle,0,88);
}
}
+else if ((cat1==struct_like) @|
+ && (cat2==exp || cat2==int_like) @|
+ && (cat3==comma || cat3==prerangle)) {
+ make_underlined(pp+2); if (reserve_typenames) make_reserved(pp+2);
+ big_app2(pp); big_app(' '); big_app2(pp+2);
+ if (cat3==comma) reduce(pp,4,langle,0,153);
+ else reduce(pp,4,cast,-1,154);
+ }
@ @<Cases for |template_like|@>=
-if (cat1==exp && cat2==prelangle) squash(pp+2,1,langle,2,89);
+if (cat1==exp && cat2==prelangle) reduce(pp+2,0,langle,2,89);
else if (cat1==exp || cat1==raw_int) {
- big_app1(pp); big_app(' '); big_app1(pp+1); reduce(pp,2,cat1,-2,90);
-}@+ else squash(pp,1,raw_int,0,91);
+ big_app1_insert(pp,' '); reduce(pp,2,cat1,-2,90);
+}
+else if (cat1==cast && cat2==struct_like) {
+ big_app1_insert(pp,' '); reduce(pp,2,struct_like,0,155);
+}
+else reduce(pp,0,raw_int,0,91);
@ @<Cases for |new_like|@>=
if (cat1==lpar && cat2==exp && cat3==rpar) squash(pp,4,new_like,0,92);
else if (cat1==cast) {
- big_app1(pp); big_app(' '); big_app1(pp+1); reduce(pp,2,exp,-2,93);
+ big_app1_insert(pp,' '); reduce(pp,2,exp,-2,93);
}
-else if (cat1!=lpar) squash(pp,1,new_exp,0,94);
+else if (cat1!=lpar) reduce(pp,0,new_exp,0,94);
@ @<Cases for |new_exp|@>=
if (cat1==int_like || cat1==const_like) {
- big_app1(pp); big_app(' '); big_app1(pp+1); reduce(pp,2,new_exp,0,95);
+ big_app1_insert(pp,' '); reduce(pp,2,new_exp,0,95);
}
else if (cat1==struct_like && (cat2==exp || cat2==int_like)) {
- big_app1(pp); big_app(' '); big_app1(pp+1); big_app(' ');
+ big_app1_insert(pp,' '); big_app(' ');
big_app1(pp+2); reduce(pp,3,new_exp,0,96);
}
else if (cat1==raw_ubin) {
- big_app1(pp); big_app('{'); big_app1(pp+1); big_app('}');
- reduce(pp,2,new_exp,0,97);
+ big_app1_insert(pp,'{'); big_app('}'); reduce(pp,2,new_exp,0,97);
}
-else if (cat1==lpar) squash(pp,1,exp,-2,98);
+else if (cat1==lpar) reduce(pp,0,exp,-2,98);
else if (cat1==exp) {
big_app1(pp); big_app(' '); reduce(pp,1,exp,-2,98);
}
else if (cat1!=raw_int && cat1!=struct_like && cat1!=colcol)
- squash(pp,1,exp,-2,99);
+ reduce(pp,0,exp,-2,99);
@ @<Cases for |ftemplate|@>=
-if (cat1==prelangle) squash(pp+1,1,langle,1,100);
-else squash(pp,1,exp,-2,101);
+if (cat1==prelangle) reduce(pp+1,0,langle,1,100);
+else reduce(pp,0,exp,-2,101);
@ @<Cases for |for_like|@>=
if (cat1==exp) {
- big_app1(pp); big_app(' '); big_app1(pp+1); reduce(pp,2,else_like,-2,102);
+ big_app1_insert(pp,' '); reduce(pp,2,else_like,-2,102);
}
@ @<Cases for |raw_ubin|@>=
if (cat1==const_like) {
big_app2(pp); app_str("\\ "); reduce(pp,2,raw_ubin,0,103);
@.\\\ @>
-} else squash(pp,1,ubinop,-2,104);
+}
+else reduce(pp,0,ubinop,-2,104);
@ @<Cases for |const_like|@>=
-squash(pp,1,int_like,-2,105);
+reduce(pp,0,int_like,-2,105);
@ @<Cases for |raw_int|@>=
-if (cat1==prelangle) squash(pp+1,1,langle,1,106);
+if (cat1==prelangle) reduce(pp+1,0,langle,1,106);
else if (cat1==colcol) squash(pp,2,colcol,-1,107);
else if (cat1==cast) squash(pp,2,raw_int,0,108);
-else if (cat1==lpar) squash(pp,1,exp,-2,109);
-else if (cat1!=langle) squash(pp,1,int_like,-3,110);
+else if (cat1==lpar) reduce(pp,0,exp,-2,109);
+else if (cat1==lbrack) reduce(pp,0,exp,-2,144);
+else if (cat1!=langle) reduce(pp,0,int_like,-3,110);
@ @<Cases for |operator_like|@>=
if (cat1==binop || cat1==unop || cat1==ubinop) {
if (cat2==binop) break;
- big_app1(pp); big_app('{'); big_app1(pp+1); big_app('}');
- reduce(pp,2,exp,-2,111);
+ big_app1_insert(pp,'{'); big_app('}'); reduce(pp,2,exp,-2,111);
}
else if (cat1==new_like || cat1==delete_like) {
- big_app1(pp); big_app(' '); big_app1(pp+1); reduce(pp,2,exp,-2,112);
+ big_app1_insert(pp,' '); reduce(pp,2,exp,-2,112);
}
else if (cat1==comma) squash(pp,2,exp,-2,113);
-else if (cat1!=raw_ubin) squash(pp,1,new_exp,0,114);
+else if (cat1!=raw_ubin) reduce(pp,0,new_exp,0,114);
@ @<Cases for |typedef_like|@>=
if ((cat1==int_like || cat1==cast) && (cat2==comma || cat2==semi))
- squash(pp+1,1,exp,-1,115);
+ reduce(pp+1,0,exp,-1,115);
else if (cat1==int_like) {
- big_app1(pp); big_app(' '); big_app1(pp+1); reduce(pp,2,typedef_like,0,116);
+ big_app1_insert(pp,' '); reduce(pp,2,typedef_like,0,116);
}
else if (cat1==exp && cat2!=lpar && cat2!=exp && cat2!=cast) {
make_underlined(pp+1); make_reserved(pp+1);
- big_app1(pp); big_app(' '); big_app1(pp+1); reduce(pp,2,typedef_like,0,117);
+ big_app1_insert(pp,' '); reduce(pp,2,typedef_like,0,117);
}
else if (cat1==comma) {
big_app2(pp); big_app(' '); reduce(pp,2,typedef_like,0,118);
}
else if (cat1==semi) squash(pp,2,decl,-1,119);
else if (cat1==ubinop && (cat2==ubinop || cat2==cast)) {
- big_app('{'); big_app1(pp+1); big_app('}'); big_app1(pp+2);
- reduce(pp+1,2,cat2,0,120);
+ big_app('{'); big_app1_insert(pp+1,'}'); reduce(pp+1,2,cat2,0,120);
}
@ @<Cases for |delete_like|@>=
if (cat1==lpar && cat2==rpar) {
- big_app2(pp); app('\\'); app(','); big_app1(pp+2);
+ big_app2(pp); app_str("\\,"); big_app1(pp+2);
@.\\,@>
reduce(pp,3,delete_like,0,121);
}
else if (cat1==exp) {
- big_app1(pp); big_app(' '); big_app1(pp+1); reduce(pp,2,exp,-2,122);
+ big_app1_insert(pp,' '); reduce(pp,2,exp,-2,122);
}
@ @<Cases for |question|@>=
@@ -2997,9 +3119,52 @@ if (cat1==exp && (cat2==colon || cat2==base)) {
squash(pp,3,binop,-2,123);
}
-@ Now here's the |reduce| procedure used in our code for productions.
+@ @<Cases for |alignas_like|@>=
+if (cat1==decl_head) squash(pp,2,attr,-1,126);
+else if (cat1==exp) squash(pp,2,attr,-1,127);
+else if (cat1==cast) squash(pp,2,attr,-1,158);
+
+@ @<Cases for |lbrack|@>=
+if (cat1==lbrack)
+ if (cat2==rbrack && cat3==rbrack) squash(pp,4,exp,-2,147);
+ else squash(pp,2,attr_head,-1,128);
+else reduce(pp,0,lpar,-1,129);
-The `|freeze_text|' macro is used to give official status to a token list.
+@ @<Cases for |attr_head|@>=
+if (cat1==rbrack && cat2==rbrack) squash(pp,3,attr,-1,131);
+else if (cat1==exp) squash(pp,2,attr_head,0,132);
+else if (cat1==using_like && cat2==exp && cat3==colon) {
+ big_app2(pp); big_app(' '); big_app2(pp+2); big_app(' ');
+ reduce(pp,4,attr_head,0,133);
+}
+else if (cat1==comma) squash(pp,2,attr_head,0,145);
+
+@ @<Cases for |attr|@>=
+if (cat1==lbrace || cat1==stmt) {
+ big_app1_insert(pp,' '); reduce(pp,2,cat1,-2,134);
+}
+else if (cat1==tag) {
+ big_app1_insert(pp,' '); reduce(pp,2,tag,-1,135);
+}
+else if (cat1==semi) squash(pp,2,stmt,-2,136);
+else if (cat1==attr) {
+ big_app1_insert(pp,' '); reduce(pp,2,attr,-1,137);
+}
+else if (cat1==decl_head) {
+ big_app1_insert(pp,' '); reduce(pp,2,decl_head,-1,138);
+}
+else if (cat1==typedef_like) {
+ big_app1_insert(pp,' '); reduce(pp,2,typedef_like,0,143);
+}
+else if (cat1==function) {
+ big_app1_insert(pp,' '); reduce(pp,2,function,-1,148);
+}
+
+@ @<Cases for |default_like|@>=
+if (cat1==colon) reduce(pp,0,case_like,-3,149);
+else reduce(pp,0,exp,-2,150);
+
+@ The `|freeze_text|' macro is used to give official status to a token list.
Before saying |freeze_text|, items are appended to the current token list,
and we know that the eventual number of this token list will be the current
value of |text_ptr|. But no list of that number really exists as yet,
@@ -3007,7 +3172,7 @@ because no ending point for the current list has been
stored in the |tok_start| array. After saying |freeze_text|, the
old current token list becomes legitimate, and its number is the current
value of |text_ptr-1| since |text_ptr| has been increased. The new
-current token list is empty and ready to be appended to.
+current token list is empty and ready to be appended~to.
Note that |freeze_text| does not check to see that |text_ptr| hasn't gotten
too large, since it is assumed that this test was done beforehand.
@@ -3017,7 +3182,10 @@ too large, since it is assumed that this test was done beforehand.
static void reduce(scrap_pointer,short,eight_bits,short,short);@/
static void squash(scrap_pointer,short,eight_bits,short,short);
-@ @c
+@ Now here's the |reduce| procedure used in our code for productions,
+which takes advantage of the simplification that occurs when |k==0|.
+
+@c
static void
reduce(
scrap_pointer j, short k,
@@ -3025,9 +3193,12 @@ eight_bits c,
short d, short n)
{
scrap_pointer i, i1; /* pointers into scrap memory */
- j->cat=c; j->trans=text_ptr;
- j->mathness=4*cur_mathness+init_mathness;
- freeze_text;
+ j->cat=c;
+ if (k>0) {
+ j->trans=text_ptr;
+ j->mathness=4*cur_mathness+init_mathness;
+ freeze_text;
+ }
if (k>1) {
for (i=j+k, i1=j+1; i<=lo_ptr; i++, i1++) {
i1->cat=i->cat; i1->trans=i->trans;
@@ -3040,8 +3211,8 @@ short d, short n)
pp--; /* we next say |pp++| */
}
-@ Here's the |squash| procedure, which
-takes advantage of the simplification that occurs when |k==1|.
+@ And here's the |squash| procedure, which combines |big_app|${}_k$ and
+|reduce| for matching numbers~|k|.
@c
static void
@@ -3050,14 +3221,13 @@ 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...@>@;
- pp--; /* we next say |pp++| */
- return;
+ switch (k) {
+ case 1: big_app1(j); break;
+ case 2: big_app2(j); break;
+ case 3: big_app3(j); break;
+ case 4: big_app4(j); break;
+ default: confusion("squash");
}
- for (i=j; i<j+k; i++) big_app1(i);
reduce(j,k,c,d,n);
}
@@ -3096,34 +3266,37 @@ stored, since zero does not match anything in a production.
@<Make sure the entries...@>=
if (lo_ptr<pp+3) {
while (hi_ptr<=scrap_ptr && lo_ptr!=pp+3) {
- (++lo_ptr)->cat=hi_ptr->cat; lo_ptr->mathness=(hi_ptr)->mathness;
+ (++lo_ptr)->cat=hi_ptr->cat; lo_ptr->mathness=hi_ptr->mathness;
lo_ptr->trans=(hi_ptr++)->trans;
}
for (i=lo_ptr+1;i<=pp+3;i++) i->cat=0;
}
@ If \.{CWEAVE} is being run in debugging mode, the production numbers and
-current stack categories will be printed out when |tracing| is set to 2;
+current stack categories will be printed out when |tracing| is set to |fully|;
a sequence of two or more irreducible scraps will be printed out when
-|tracing| is set to 1.
+|tracing| is set to |partly|.
+
+@d off 0
+@d partly 1
+@d fully 2
@<Private...@>=
-static int tracing; /* can be used to show parsing details */
+static int tracing=off; /* can be used to show parsing details */
@ @<Print a snapsh...@>=
-{ scrap_pointer k_l; /* pointer into |scrap_info| */
- if (tracing==2) {
- printf("\n%d:",n);
- 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) fputs("...",stdout); /* indicate that more is coming */
+if (tracing==fully) {
+ scrap_pointer k; /* pointer into |scrap_info|; shadows |short k| */
+ printf("\n%d:",n);
+ for (k=scrap_base; k<=lo_ptr; k++) {
+ if (k==pp) putchar('*'); else putchar(' ');
+ if (k->mathness %4 == yes_math) putchar('+');
+ else if (k->mathness %4 == no_math) putchar('-');
+ print_cat(k->cat);
+ if (k->mathness /4 == yes_math) putchar('+');
+ else if (k->mathness /4 == no_math) putchar('-');
}
+ if (hi_ptr<=scrap_ptr) printf("..."); /* indicate that more is coming */
}
@ The |translate| function assumes that scraps have been stored in
@@ -3143,8 +3316,8 @@ for overflow.
static text_pointer
translate(void) /* converts a sequence of scraps */
{
- scrap_pointer i, /* index into |cat| */
- j; /* runs through final scraps */
+ scrap_pointer i; /* index into |cat| */
+ scrap_pointer j; /* runs through final scraps */
pp=scrap_base; lo_ptr=pp-1; hi_ptr=pp;
@<If tracing, print an indication of where we are@>@;
@<Reduce the scraps...@>@;
@@ -3158,30 +3331,29 @@ 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@>@;
- for (j=scrap_base; j<=lo_ptr; j++) {
- if (j!=scrap_base) app(' ');
- if (j->mathness % 4 == yes_math) app('$');
- app1(j);
- if (j->mathness / 4 == yes_math) app('$');
- if (tok_ptr+6>tok_mem_end) overflow("token");
- }
- freeze_text; return text_ptr-1;
+@<Combine the irreducible...@>=
+@<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('$');
+ app(tok_flag+(int)(j->trans-tok_start));
+ if (j->mathness / 4 == yes_math) app('$');
+ if (tok_ptr+6>tok_mem_end) overflow("token");
}
+freeze_text; return text_ptr-1;
@ @<If semi-tracing, show the irreducible scraps@>=
-if (lo_ptr>scrap_base && tracing==1) {
- printf("\nIrreducible scrap sequence in section %d:",section_count);
+if (lo_ptr>scrap_base && tracing==partly) {
+ printf("\nIrreducible scrap sequence in section %d:",(int)section_count);
@.Irreducible scrap sequence...@>
mark_harmless;
for (j=scrap_base; j<=lo_ptr; j++) {
- printf(" "); print_cat(j->cat);
+ putchar(' '); print_cat(j->cat);
}
}
@ @<If tracing,...@>=
-if (tracing==2) {
+if (tracing==fully) {
printf("\nTracing after l. %d:\n",cur_line); mark_harmless;
@.Tracing after...@>
if (loc>buffer+50) {
@@ -3208,10 +3380,9 @@ is advanced.
@c
static void
-C_parse(@t\1\1@> /* creates scraps from \CEE/ tokens */
- eight_bits spec_ctrl@t\2\2@>)
+C_parse( /* creates scraps from \CEE/ tokens */
+ eight_bits spec_ctrl)
{
- int count; /* characters remaining before string break */
while (next_control<format_code || next_control==spec_ctrl) {
@<Append the scrap appropriate to |next_control|@>@;
next_control=get_next();
@@ -3236,7 +3407,7 @@ been appended:
switch (next_control) {
case section_name:
app(section_flag+(int)(cur_section-name_dir));
- app_scrap(section_scrap,maybe_math);
+ app_scrap(section_scrap,maybe_math);@+
app_scrap(exp,yes_math);@+break;
case string: case constant: case verbatim:
@<Append a string or constant@>@;@+break;
@@ -3271,8 +3442,10 @@ switch (next_control) {
@.\\\#@>
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(next_control);@+app_scrap(lpar,maybe_math);@+break;
+ case ')': app(next_control);@+app_scrap(rpar,maybe_math);@+break;
+ case '[': app(next_control);@+app_scrap(lbrack,maybe_math);@+break;
+ case ']': app(next_control);@+app_scrap(rbrack,maybe_math);@+break;
case '{': app_str("\\{"@q}@>);@+app_scrap(lbrace,yes_math);@+break;
@.\\\{@>@q}@>
case '}': app_str(@q{@>"\\}");@+app_scrap(rbrace,yes_math);@+break;
@@ -3280,10 +3453,10 @@ switch (next_control) {
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@>@;
+ @t\4@> @<Cases involving nonstandard characters@>@;
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('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("\\#");
@@ -3320,7 +3493,7 @@ if (scrap_ptr+safe_scrap_incr>scrap_info_end ||
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...@>=
+@<Cases involving nonstandard...@>=@t\1\quad@>
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;
@@ -3362,34 +3535,26 @@ Many of the special characters in a string must be prefixed by `\.\\' so that
\TEX/ will print them properly.
@^special string characters@>
-@<Append a string or...@>=
-count= -1;
-if (next_control==constant) app_str("\\T{"@q}@>);
+@<Append a string or...@>={@+ int count=-1; /* characters remaining before string break */
+switch (next_control) {
+ case constant: app_str("\\T{"@q}@>); break;
@.\\T@>
-else if (next_control==string) {
- count=20; app_str("\\.{"@q}@>);
-}
+ case string: count=20; app_str("\\.{"@q}@>); break;
@.\\.@>
-else app_str("\\vb{"@q}@>);
+ default: app_str("\\vb{"@q}@>);
@.\\vb@>
+}
while (id_first<id_loc) {
if (count==0) { /* insert a discretionary break in a long string */
app_str(@q(@>@q{@>"}\\)\\.{"@q}@>); count=20;
@q(@>@.\\)@>
}
-@^high-bit character handling@>
- if((eight_bits)(*id_first)>0177) {
- app_tok(quoted_char);
- app_tok((eight_bits)(*id_first++));
- }
- else {
- switch (*id_first) {
- case ' ':case '\\':case '#':case '%':case '$':case '^':
- case '{': case '}': case '~': case '&': case '_': app('\\'); break;
+ switch (*id_first) {
+ case ' ':case '\\':case '#':case '$':case '^':case '{':case '}':
+ case '~':case '&':case '_': app('\\'); break;
@.\\\ @>
@.\\\\@>
@.\\\#@>
-@.\\\%@>
@.\\\$@>
@.\\\^@>
@.\\\{@>@q}@>
@@ -3397,16 +3562,29 @@ while (id_first<id_loc) {
@.\\\~@>
@.\\\&@>
@.\\\_@>
- case '@@': if (*(id_first+1)=='@@') id_first++;
- else err_print("! Double @@ should be used in strings");
+ case '%': if (next_control==constant) {
+ app_str("}\\p{"); /* special macro for `hex exponent' */
+ id_first++; /* skip |'%'| */
+ }
+ else app('\\');
+ break;
+@.\\p@>
+@.\\\%@>
+ case '@@': if (*(id_first+1)=='@@') id_first++;
+ else err_print("! Double @@ should be used in strings");
@.Double @@ should be used...@>
+ break;
+ default: /* high-bit character handling */
+@^high-bit character handling@>
+ if((eight_bits)(*id_first)>0177)
+ app_tok(quoted_char)@t;@>@;
}
- app_tok(*id_first++);
- }
+ app_tok(*id_first++);
count--;
}
app(@q{@>'}');
app_scrap(exp,maybe_math);
+}
@ We do not make the \TEX/ string into a scrap, because there is no
telling what the user will be putting into it; instead we leave it
@@ -3426,15 +3604,13 @@ the \TEX/ string is treated as an expression.
@<Append a \TEX/ string, without forming a scrap@>=
app_str("\\hbox{"@q}@>);
@^high-bit character handling@>
-while (id_first<id_loc)
- if((eight_bits)(*id_first)>0177) {
- app_tok(quoted_char);
- app_tok((eight_bits)(*id_first++));
- }
- else {
+while (id_first<id_loc) {
+ if((eight_bits)(*id_first)>0177)
+ app_tok(quoted_char)@t;@>@;
+ else
if (*id_first=='@@') id_first++;
- app_tok(*id_first++);
- }
+ app_tok(*id_first++);
+}
app(@q{@>'}');
@ The function |app_cur_id| appends the current identifier to the
@@ -3447,8 +3623,8 @@ static void outer_parse(void);
@ @c
static void
-app_cur_id(@t\1\1@>
-boolean scrapping@t\2\2@>) /* are we making this into a scrap? */
+app_cur_id(
+boolean scrapping) /* 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 */
@@ -3459,7 +3635,7 @@ boolean scrapping@t\2\2@>) /* are we making this into a scrap? */
} else {
app(res_flag+(int)(p-name_dir));
if (scrapping) {
- if (p->ilk==alfop) app_scrap(ubinop,yes_math)@;
+ if (p->ilk==alfop) app_scrap(ubinop,yes_math)@t;@>@;
else app_scrap(p->ilk,maybe_math);
}
}
@@ -3475,8 +3651,8 @@ static text_pointer
C_translate(void)
{
text_pointer p; /* points to the translation */
- scrap_pointer save_base; /* holds original value of |scrap_base| */
- save_base=scrap_base; scrap_base=scrap_ptr+1;
+ scrap_pointer save_base=scrap_base; /* holds original value of |scrap_base| */
+ scrap_base=scrap_ptr+1;
C_parse(section_name); /* get the scraps together */
if (next_control!='|') err_print("! Missing '|' after C text");
@.Missing '|'...@>
@@ -3493,8 +3669,7 @@ is to |C_xref|: It constructs a sequence of scraps for \CEE/ text
until |next_control>=format_code|. Thus, it takes care of embedded comments.
The token list created from within `\pb' brackets is output as an argument
-to \.{\\PB}, if the user has invoked \.{CWEAVE} with the \.{+e} flag.
-Although \.{cwebmac} ignores \.{\\PB}, other macro packages
+to \.{\\PB}. Although \.{cwebmac} ignores \.{\\PB}, other macro packages
might use it to localize the special meaning of the macros that mark up
program text.
@@ -3528,7 +3703,7 @@ outer_parse(void) /* makes scraps from \CEE/ tokens and comments */
if (make_pb) app_str("\\PB{");
@.\\PB@>
app(inner_tok_flag+(int)(q-tok_start));
- if (make_pb) app_tok('}');
+ if (make_pb) app_tok('}');
if (next_control=='|') {
bal=copy_comment(is_long_comment,bal);
next_control=ignore;
@@ -3546,7 +3721,7 @@ So far our programs have only built up multi-layered token lists in
the desired final form. The job of converting token lists to characters in
the \TEX/ output file is not difficult, although it is an implicitly
recursive process. Four main considerations had to be kept in mind when
-this part of \.{CWEAVE} was designed. (a) There are two modes of output:
+this part of \.{CWEAVE} was designed. (a) There are two modes of output:
|outer| mode, which translates tokens like |force| into line-breaking
control sequences, and |inner| mode, which ignores them except that blank
spaces take the place of line breaks. (b) The |cancel| instruction applies
@@ -3554,7 +3729,7 @@ to adjacent token or tokens that are output, and this cuts across levels
of recursion since `|cancel|' occurs at the beginning or end of a token
list on one level. (c) The \TEX/ output file will be semi-readable if line
breaks are inserted after the result of tokens like |break_space| and
-|force|. (d) The final line break should be suppressed, and there should
+|force|. (d) The final line break should be suppressed, and there should
be no |force| token output immediately after `\.{\\Y\\B}'.
@ The output process uses a stack to keep track of what is going on at
@@ -3579,8 +3754,8 @@ currently in progress. The end of output occurs when an |end_translation|
token is found, so the stack is never empty except when we first begin the
output process.
-@d inner 0 /* value of |mode| for \CEE/ texts within \TEX/ texts */
-@d outer 1 /* value of |mode| for \CEE/ texts in sections */
+@d inner false /* value of |mode| for \CEE/ texts within \TEX/ texts */
+@d outer true /* value of |mode| for \CEE/ texts in sections */
@<Typed...@>= typedef int mode;
typedef struct {
@@ -3590,7 +3765,8 @@ typedef struct {
} output_state;
typedef output_state *stack_pointer;
-@ @d cur_end cur_state.end_field /* current ending location in |tok_mem| */
+@ @d stack_size 400 /* number of simultaneous output levels */
+@d cur_end cur_state.end_field /* current ending location in |tok_mem| */
@d cur_tok cur_state.tok_field /* location of next output token in |tok_mem| */
@d cur_mode cur_state.mode_field /* current mode of interpretation */
@d init_stack stack_ptr=stack;cur_mode=outer /* initialize the stack */
@@ -3615,8 +3791,8 @@ static void pop_level(void);
@ @c
static void
-push_level(@t\1\1@> /* suspends the current level */
-text_pointer p@t\2\2@>)
+push_level( /* suspends the current level */
+text_pointer p)
{
if (stack_ptr==stack_end) overflow("stack");
if (stack_ptr>stack) { /* save current state */
@@ -3701,12 +3877,11 @@ while outputting the name of a section.
static void
output_C(void) /* outputs the current token list */
{
- token_pointer save_tok_ptr;
- text_pointer save_text_ptr;
- sixteen_bits save_next_control; /* values to be restored */
+ token_pointer save_tok_ptr=tok_ptr;
+ text_pointer save_text_ptr=text_ptr;
+ sixteen_bits save_next_control=next_control; /* values to be restored */
text_pointer p; /* translation of the \CEE/ text */
- save_tok_ptr=tok_ptr; save_text_ptr=text_ptr;
- save_next_control=next_control; next_control=ignore; p=C_translate();
+ next_control=ignore; p=C_translate();
app(inner_tok_flag+(int)(p-tok_start));
if (make_pb) {
out_str("\\PB{"); make_output(); out('}');
@@ -3724,8 +3899,8 @@ output_C(void) /* outputs the current token list */
static void
make_output(void) /* outputs the equivalents of tokens */
{
- eight_bits a=0, /* current output byte */
- b; /* next output byte */
+ eight_bits a=0; /* current output byte */
+ eight_bits b; /* next output byte */
int c; /* count of |indent| and |outdent| tokens */
char scratch[longest_name+1]; /* scratch area for section names */
char *k, *k_limit; /* indices into |scratch| */
@@ -3735,6 +3910,7 @@ make_output(void) /* outputs the equivalents of tokens */
char *save_loc, *save_limit; /* |loc| and |limit| to be restored */
name_pointer cur_section_name; /* name of section being output */
boolean save_mode; /* value of |cur_mode| before a sequence of breaks */
+ boolean dindent_pending=false; /* should a |dindent| be output? */
app(end_translation); /* append a sentinel */
freeze_text; push_level(text_ptr-1);
while (true) {
@@ -3743,23 +3919,33 @@ make_output(void) /* outputs the equivalents of tokens */
case end_translation: return;
case identifier: case res_word: @<Output an identifier@>@; break;
case section_code: @<Output a section name@>@; break;
- case math_rel: out_str("\\MRL{"@q}@>);
+ case math_rel: out_str("\\MRL{"@q}@>); /* fall through */
@.\\MRL@>
case noop: case inserted: break;
case cancel: case big_cancel: c=0; b=a;
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();
+ if ((a<indent && !(b==big_cancel&&a==' ')) @|
+ || (a>big_force && a!=dindent)) break;
+ switch (a) {
+ case indent: c++; break;
+ case outdent: c--; break;
+ case dindent: c+=2; break;
+ case opt: a=get_output();
+ }
}
@<Output saved |indent| or |outdent| tokens@>@;
goto reswitch;
+ case dindent: a=get_output();
+ if (a!=big_force) {
+ out_str("\\1\\1"); goto reswitch;
+ }
+ else dindent_pending=true; /* fall through */
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;
- case quoted_char: out(*(cur_tok++));
+ case quoted_char: out(*(cur_tok++)); /* fall through */
case qualifier: break;
default: out(a); /* otherwise |a| is an ordinary character */
}
@@ -3779,7 +3965,8 @@ if (a==identifier) {
for (p=cur_name->byte_start;p<(cur_name+1)->byte_start;p++)
out(*p=='_'? 'x': *p=='$'? 'X': *p);
break;
- } else if (is_tiny(cur_name)) out('|')@;
+ }
+ else if (is_tiny(cur_name)) out('|')@t;@>@;
@.\\|@>
else { delim='.';
for (p=cur_name->byte_start;p<(cur_name+1)->byte_start;p++)
@@ -3790,10 +3977,12 @@ if (a==identifier) {
}
@.\\\\@>
@.\\.@>
-}@+else if (cur_name->ilk==alfop) {
+}
+else if (cur_name->ilk==alfop) {
out('X');
goto custom_out;
-}@+else out('&'); /* |a==res_word| */
+}
+else out('&'); /* |a==res_word| */
@.\\\&@>
if (is_tiny(cur_name)) {
if (isxalpha((cur_name->byte_start)[0]))
@@ -3816,11 +4005,11 @@ 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==false) out(b)@;
+ if (b!='0' || force_lines==false) out(b)@t;@>@;
else out_str("{-1}"); /* |force_lines| encourages more \.{@@\v} breaks */
}
} else if (a==opt) b=get_output(); /* ignore digit following |opt| */
- }
+}
else @<Look ahead for strongest line break, |goto reswitch|@>
@ If several of the tokens |break_space|, |force|, |big_force| occur in a
@@ -3830,7 +4019,10 @@ except at the very end of the translation. The very first line break
is suppressed (i.e., a line break that follows `\.{\\Y\\B}').
@<Look ahead for st...@>= {
- b=a; save_mode=cur_mode; c=0;
+ b=a; save_mode=cur_mode;
+ if (dindent_pending) {
+ c=2; dindent_pending=false;
+ } else c=0;
while (true) {
a=get_output();
if (a==inserted) continue;
@@ -3872,31 +4064,29 @@ routines, since the name may contain \CEE/ code embedded in
input buffer and the translation process uses the end of the active
|tok_mem| area.
-@<Output a section name@>= {
- out_str("\\X");
+@<Output a section name@>=
+out_str("\\X");
@.\\X@>
- cur_xref=(xref_pointer)cur_name->xref;
- 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) {
- cur_xref=cur_xref->xlink;
- while (cur_xref->num>=def_flag) {
- out_str(", ");
- out_section(cur_xref->num-def_flag);
- cur_xref=cur_xref->xlink;
- }
+cur_xref=(xref_pointer)cur_name->xref;
+if ((an_output=(cur_xref->num==file_flag))==true) cur_xref=cur_xref->xlink;
+if (cur_xref->num>=def_flag) {
+ out_section(cur_xref->num-def_flag);
+ if (phase==3) {
+ cur_xref=cur_xref->xlink;
+ while (cur_xref->num>=def_flag) {
+ out_str(", ");
+ out_section(cur_xref->num-def_flag);
+ cur_xref=cur_xref->xlink;
}
}
- else out('0'); /* output the section number, or zero if it was undefined */
- out(':');
- if (an_output) out_str("\\.{"@q}@>);
-@.\\.@>
- @<Output the text of the section name@>@;
- if (an_output) out_str(@q{@>" }");
- out_str("\\X");
}
+else out('0'); /* output the section number, or zero if it was undefined */
+out(':');
+if (an_output) out_str("\\.{"@q}@>);
+@.\\.@>
+@<Output the text of the section name@>@;
+if (an_output) out_str(@q{@>" }");
+out_str("\\X");
@ @<Output the text...@>=
sprint_section_name(scratch,cur_name);
@@ -3908,9 +4098,9 @@ while (k<k_limit) {
if (b=='@@') @<Skip next character, give error if not `\.{@@}'@>@;
if (an_output)
switch (b) {
- case ' ':case '\\':case '#':case '%':case '$':case '^':
- case '{': case '}': case '~': case '&': case '_':
- out('\\'); /* falls through */
+ case ' ': case '\\': case '#': case '%': case '$': case '^':
+ case '{': case '}': case '~': case '&': case '_':
+ out('\\'); /* falls through */
@.\\\ @>
@.\\\\@>
@.\\\#@>
@@ -3922,15 +4112,16 @@ while (k<k_limit) {
@.\\\~@>
@.\\\&@>
@.\\\_@>
- default: out(b);
+ default: out(b);
+ }
+ else
+ if (b!='|') out(b)@t;@>@;
+ else {
+ @<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;
}
- else { if (b!='|') out(b)@;
- else {
- @<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...@>=
@@ -3984,10 +4175,12 @@ actually output the \TEX/ material instead of merely looking at the
@c
static void
phase_two(void) {
-reset_input(); if (show_progress) fputs("\nWriting the output file...",stdout);
+phase=2; reset_input();
+if (show_progress) fputs("\nWriting the output file...",stdout);
@.Writing the output file...@>
section_count=0; format_visible=true; copy_limbo();
-finish_line(); flush_buffer(out_buf,false,false); /* insert a blank line, it looks nice */
+finish_line(); flush_buffer(out_buf,false,false);
+ /* insert a blank line, it looks nice */
while (!input_has_ended) @<Translate the current section@>@;
}
@@ -4031,7 +4224,7 @@ static boolean group_found=false; /* has a starred section occurred? */
output with the \TEX/ control sequence `\.{\\M}', followed by the section
number. Similarly, `\.{@@*}' sections lead to the control sequence `\.{\\N}'.
In this case there's an additional parameter, representing one plus the
-specified depth, immediately after the \.{\\N}.
+specified depth, immediately after the~\.{\\N}.
If the section has changed, we put \.{\\*} just after the section number.
@<Output the code for the beginning...@>=
@@ -4053,16 +4246,15 @@ else {
@.\\N@>
{@+ char s[32];@+sprintf(s,"{%d}",sec_depth+1);@+out_str(s);@+}
if (show_progress)
- printf("*%d",section_count); update_terminal; /* print a progress report */
+ printf("*%d",(int)section_count); update_terminal; /* print a progress report */
}
-out_str("{");out_section(section_count); out_str("}");
+out('{'); out_section(section_count); out('}');
@ In the \TEX/ part of a section, we simply copy the source text, except that
index entries are not copied and \CEE/ text within \pb\ is translated.
-@<Translate the \T...@>= do {
- next_control=copy_TeX();
- switch (next_control) {
+@<Translate the \T...@>= do
+ switch (next_control=copy_TeX()) {
case '|': init_stack; output_C(); break;
case '@@': out('@@'); break;
case TeX_string: case noop:
@@ -4078,7 +4270,7 @@ index entries are not copied and \CEE/ text within \pb\ is translated.
err_print("! You can't do that in TeX text"); break;
@.You can't do that...@>
}
-} while (next_control<format_code);
+while (next_control<format_code);
@ When we get to the following code we have |next_control>=format_code|, and
the token memory is in its initial empty state.
@@ -4105,8 +4297,8 @@ takes place, so that the translation will normally end with \.{\\6} or
@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 */
+finish_C( /* finishes a definition or a \CEE/ part */
+ boolean visible) /* |true| if we should produce \TeX\ output */
{
text_pointer p; /* translation of the scraps */
if (visible) {
@@ -4114,7 +4306,7 @@ finish_C(@t\1\1@> /* 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>out_buf+1)
if (*(out_ptr-1)=='\\') {
@.\\6@>
@.\\7@>
@@ -4122,7 +4314,6 @@ finish_C(@t\1\1@> /* finishes a definition or a \CEE/ part */
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;
@@ -4145,22 +4336,30 @@ it starts after we scan the matching `\.)'.
@<Start a macro...@>= {
if (save_line!=out_line || save_place!=out_ptr || space_checked) app(backup);
if(!space_checked){emit_space_if_needed;save_position;}
- app_str("\\D"); /* this will produce `\&{define }' */
+ app_str("\\D"); /* this will produce `\#\&{define }' */
@.\\D@>
if ((next_control=get_next())!=identifier)
err_print("! Improper macro definition");
@.Improper macro definition@>
else {
- app('$'); app_cur_id(false);
- if (*loc=='(')
+ app_cur_id(false);
+ if (*loc=='(') {
+ app('$');
reswitch: switch (next_control=get_next()) {
case '(': case ',': app(next_control); goto reswitch;
case identifier: app_cur_id(false); goto reswitch;
case ')': app(next_control); next_control=get_next(); break;
+ case dot_dot_dot: app_str("\\,\\ldots\\,"); @.\\,@> @.\\ldots@>
+ app_scrap(raw_int,no_math);
+ if ((next_control=get_next())==')') {
+ app(next_control); next_control=get_next(); break;
+ } /* otherwise fall through */
default: err_print("! Improper macro definition"); break;
+ }
+ app('$');
}
else next_control=get_next();
- app_str("$ "); app(break_space);
+ app(break_space);
app_scrap(dead,no_math); /* scrap won't take part in the parsing */
}
}
@@ -4174,7 +4373,6 @@ it starts after we scan the matching `\.)'.
next_control=get_next();
if (next_control==identifier) {
app(id_flag+(int)(id_lookup(id_first, id_loc,normal)-name_dir));
- app(' ');
app(break_space); /* this is syntactically separate from what follows */
next_control=get_next();
if (next_control==identifier) {
@@ -4201,10 +4399,10 @@ if (next_control<=section_name) {
if (next_control==begin_C) next_control=get_next();
else {
this_section=cur_section;
- @<Check that '=' or '==' follows this section name, and
+ @<Check that `\.{=}' or `\.{==}' follows this section name, and
emit the scraps to start the section definition@>@;
}
- while (next_control<=section_name) {
+ while (next_control<=section_name) {
outer_parse();
@<Emit the scrap for a section name if present@>@;
}
@@ -4214,13 +4412,13 @@ if (next_control<=section_name) {
@ The title of the section and an $\E$ or $\mathrel+\E$ are made
into a scrap that should not take part in the parsing.
-@<Check that '='...@>=
+@<Check that `\.{=}'...@>=
do next_control=get_next();
while (next_control=='+'); /* allow optional `\.{+=}' */
if (next_control!='=' && next_control!=eq_eq)
err_print("! You need an = sign after the section name");
@.You need an = sign...@>
- else next_control=get_next();
+else next_control=get_next();
if (out_ptr>out_buf+1 && *out_ptr=='Y' && *(out_ptr-1)=='\\') app(backup);
/* the section name will be flush left */
@.\\Y@>
@@ -4256,8 +4454,7 @@ 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=true;cur_xref=cur_xref->xlink;}
- else an_output=false;
+ if ((an_output=(cur_xref->num==file_flag))==true) cur_xref=cur_xref->xlink;
if (cur_xref->num>def_flag)
cur_xref=cur_xref->xlink; /* bypass current section number */
footnote(def_flag); footnote(cite_flag); footnote(0);
@@ -4277,11 +4474,11 @@ supply new definitions for the macros \.{\\A}, \.{\\As}, etc.
@c
static void
-footnote(@t\1\1@> /* outputs section cross-references */
-sixteen_bits flag@t\2\2@>)
+footnote( /* outputs section cross-references */
+sixteen_bits flag)
{
- xref_pointer q; /* cross-reference pointer variable */
- if (cur_xref->num<=flag) return;
+ xref_pointer q=cur_xref; /* cross-reference pointer variable */
+ if (q->num<=flag) return;
finish_line(); out('\\');
@.\\A@>
@.\\Q@>
@@ -4298,7 +4495,7 @@ 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 */
+if (q->xlink->num>flag) out('s'); /* plural */
while (true) {
out_section(cur_xref->num-flag);
cur_xref=cur_xref->xlink; /* point to the next cross-reference to output */
@@ -4379,19 +4576,18 @@ the index section itself.
@<Private...@>=
static sixteen_bits k_section; /* runs through the sections */
-@ @<Tell about changed sections@>= {
- /* remember that the index is already marked as changed */
- k_section=0;
- while (!changed_section[++k_section]);
- out_str("\\ch ");
+@ @<Tell about changed sections@>=
+/* remember that the index is already marked as changed */
+k_section=0;
+while (!changed_section[++k_section]);
+out_str("\\ch ");
@.\\ch@>
- out_section(k_section);
- while (k_section<section_count) {
- while (!changed_section[++k_section]);
- out_str(", "); out_section(k_section);
- }
- out('.');
+out_section(k_section);
+while (k_section<section_count) {
+ while (!changed_section[++k_section]);
+ out_str(", "); out_section(k_section);
}
+out('.');
@ 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
@@ -4418,7 +4614,7 @@ for (h=hash; h<=hash_end; h++) {
while (next_name) {
cur_name=next_name; next_name=cur_name->link;
if (cur_name->xref!=(void *)xmem) {
- c=(eight_bits)((cur_name->byte_start)[0]);
+ c=(cur_name->byte_start)[0];
if (xisupper(c)) c=tolower(c);
blink[cur_name-name_dir]=bucket[c]; bucket[c]=cur_name;
}
@@ -4443,7 +4639,6 @@ name_pointer Head;
@f sort_pointer int
@d sort_pointer scrap_pointer /* ditto */
@d sort_ptr scrap_ptr /* ditto */
-@d max_sorts max_scraps /* ditto */
@<Private...@>=
static eight_bits cur_depth; /* depth of current buckets */
@@ -4519,8 +4714,8 @@ regarded as identical.
@c
static void
-unbucket(@t\1\1@> /* empties buckets having depth |d| */
-eight_bits d@t\2\2@>)
+unbucket( /* empties buckets having depth |d| */
+eight_bits d)
{
int c; /* index into |bucket|; cannot be a simple |char| because of sign
comparison below */
@@ -4547,14 +4742,14 @@ while (sort_ptr>scrap_info) {
}
@ @<Split the list...@>= {
- eight_bits c;
+ int c;
next_name=sort_ptr->head;
do {
cur_name=next_name; next_name=blink[cur_name-name_dir];
cur_byte=cur_name->byte_start+cur_depth;
if (cur_byte==(cur_name+1)->byte_start) c=0; /* hit end of the name */
else {
- c=(eight_bits) *cur_byte;
+ c=*cur_byte;
if (xisupper(c)) c=tolower(c);
}
blink[cur_name-name_dir]=bucket[c]; bucket[c]=cur_name;
@@ -4575,15 +4770,16 @@ while (sort_ptr>scrap_info) {
}
@ @<Output the name...@>=
-switch (cur_name->ilk) {
- case normal: case func_template: if (is_tiny(cur_name)) out_str("\\|");
- else {char *j;
+switch (cur_name->ilk) {@+char *j;@+@t}\6{\4@>
+ case normal: case func_template:
+ if (is_tiny(cur_name)) out_str("\\|");
+ else {
for (j=cur_name->byte_start;j<(cur_name+1)->byte_start;j++)
if (xislower(*j)) goto lowcase;
out_str("\\."); break;
lowcase: out_str("\\\\");
}
- break;
+ break;
@.\\|@>
@.\\.@>
@.\\\\@>
@@ -4592,12 +4788,12 @@ lowcase: out_str("\\\\");
case typewriter: out_str("\\.");
@.\\.@>
case roman: not_an_identifier: out_name(cur_name,false); goto name_done;
- case custom: {char *j; out_str("$\\");
+ case custom:
+ out_str("$\\");
for (j=cur_name->byte_start;j<(cur_name+1)->byte_start;j++)
out(*j=='_'? 'x': *j=='$'? 'X': *j);
out('$');
goto name_done;
- }
default: out_str("\\&");
@.\\\&@>
}
@@ -4621,6 +4817,7 @@ 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.
+
@<Private...@>=
static xref_pointer next_xref, this_xref;
/* pointer variables for rearranging a list */
@@ -4638,14 +4835,14 @@ prints them.
@c
static void
-section_print(@t\1\1@> /* print all section names in subtree |p| */
-name_pointer p@t\2\2@>)
+section_print( /* print all section names in subtree |p| */
+name_pointer p)
{
if (p) {
section_print(p->llink); out_str("\\I");
@.\\I@>
tok_ptr=tok_mem+1; text_ptr=tok_start+1; scrap_ptr=scrap_info; init_stack;
- app(p-name_dir+section_flag); make_output();
+ app(section_flag+(int)(p-name_dir)); make_output();
footnote(cite_flag);
footnote(0); /* |cur_xref| was set by |make_output| */
finish_line();@/
@@ -4658,30 +4855,30 @@ name_pointer p@t\2\2@>)
@ @<Output all the section names@>=section_print(root);
@ Because on some systems the difference between two pointers is a |ptrdiff_t|
-rather than an |int|, we use \.{\%ld} to print these quantities.
+rather than an |int|, we use \.{\%td} to print these quantities.
@c
void
print_stats(void) {
puts("\nMemory usage statistics:");
@.Memory usage statistics:@>
- printf("%ld names (out of %ld)\n",
+ printf("%td names (out of %ld)\n",
(ptrdiff_t)(name_ptr-name_dir),(long)max_names);
- printf("%ld cross-references (out of %ld)\n",
+ printf("%td cross-references (out of %ld)\n",
(ptrdiff_t)(xref_ptr-xmem),(long)max_refs);
- printf("%ld bytes (out of %ld)\n",
+ printf("%td bytes (out of %ld)\n",
(ptrdiff_t)(byte_ptr-byte_mem),(long)max_bytes);
puts("Parsing:");
- printf("%ld scraps (out of %ld)\n",
+ printf("%td scraps (out of %ld)\n",
(ptrdiff_t)(max_scr_ptr-scrap_info),(long)max_scraps);
- printf("%ld texts (out of %ld)\n",
+ printf("%td texts (out of %ld)\n",
(ptrdiff_t)(max_text_ptr-tok_start),(long)max_texts);
- printf("%ld tokens (out of %ld)\n",
+ printf("%td tokens (out of %ld)\n",
(ptrdiff_t)(max_tok_ptr-tok_mem),(long)max_toks);
- printf("%ld levels (out of %ld)\n",
+ printf("%td levels (out of %ld)\n",
(ptrdiff_t)(max_stack_ptr-stack),(long)stack_size);
puts("Sorting:");
- printf("%ld levels (out of %ld)\n",
+ printf("%td levels (out of %ld)\n",
(ptrdiff_t)(max_sort_ptr-scrap_info),(long)max_scraps);
}
diff --git a/web/c_cpp/cweb/cweb.1 b/web/c_cpp/cweb/cweb.1
index a9aa69bf43..4c35edb754 100644
--- a/web/c_cpp/cweb/cweb.1
+++ b/web/c_cpp/cweb/cweb.1
@@ -1,4 +1,4 @@
-.TH CWEB 1 2018-Dec-16
+.TH CWEB 1 2021-Apr-24
.
.SH NAME
ctangle, cweave \- translate CWEB to C and/or TeX
@@ -9,14 +9,14 @@ ctangle, cweave \- translate CWEB to C and/or TeX
[
.B \-bhp
] [
-.B +s
+.B +ks
] webfile[.w] [{changefile[.ch]|-} [outputfile[.c]]]
.br
.B cweave
[
.B \-befhpx
] [
-.B +s
+.B +st
] webfile[.w] [{changefile[.ch]|-} [outputfile[.tex]]]
.ad
.
@@ -80,7 +80,13 @@ The
.B +s
option prints statistics about memory usage at the end of a run.
.PP
-There are three other options applicable to
+There is one other option applicable to
+.I ctangle
+only:
+.B +k
+means keep '-separators in numeric literals in the C/C++\ output.
+.PP
+There are four other options applicable to
.I cweave
only:
.B \-f
@@ -89,13 +95,15 @@ means do not force a newline after every statement in the formatted output.
inhibits the enclosure of C\ material formatted by
.I cweave
in brackets
-\ePB{...}.
-Such brackets are normally inserted so that special hooks
+\ePB{...};
+such brackets are normally inserted so that special hooks
can be used by
.I cweb-latex
and similar programs.
.B \-x
-means omit the index and table of contents.
+means omit the index, the names of the sections, and the table of contents.
+.B +t
+means treat 'typename' in templates like 'typedef'.
.
.SH FILES
The location of the files mentioned below varies from system to system.
@@ -129,4 +137,5 @@ Silvio Levy designed and developed CWEB
by adapting the WEB conventions to\ C and by recoding everything in CWEB.
Knuth began using CWEB and made further refinements.
Many other helpers are acknowledged in the CWEB manual.
+Contemporary development on https://github.com/ascherer/cweb.
diff --git a/web/c_cpp/cweb/cwebmac.tex b/web/c_cpp/cweb/cwebmac.tex
index 385dc474e7..586e7bb30f 100644
--- a/web/c_cpp/cweb/cwebmac.tex
+++ b/web/c_cpp/cweb/cwebmac.tex
@@ -1,8 +1,8 @@
% standard macros for CWEB listings (in addition to plain.tex)
-% Version 4.2 --- February 2021
+% Version 4.6 --- December 2021
\ifx\renewenvironment\undefined\else\endinput\fi % LaTeX will use other macros
-\xdef\fmtversion{\fmtversion+CWEB4.2}
-\chardef\cwebversion=4 \chardef\cwebrevision=1
+\xdef\fmtversion{\fmtversion+CWEB4.6}
+\chardef\cwebversion=4 \chardef\cwebrevision=6
\newif\ifpdf
\ifx\pdf+\pdftrue\fi
% Uncomment the following line if you want PDF goodies to be the default
@@ -31,6 +31,7 @@
\def\TEX/{\TeX}
\def\CPLUSPLUS/{{\mc C\PP\spacefactor1000}}
\def\Cee{\CEE/} % for backward compatibility
+\def\Cpp{\CPLUSPLUS/} % for backward compatibility
\def\9#1{}
% with this definition of \9 you can say @:sort key}{TeX code@>
% to alphabetize an index entry by the sort key but format with the TeX code
@@ -124,6 +125,7 @@
\newskip\intersecskip \intersecskip=12pt minus 3pt % space between sections
\let\yskip=\smallskip
\def\?{\mathrel?}
+\def\,{\relax\ifmmode\mskip\thinmuskip\else\thinspace\fi}
\def\note#1#2.{\Y\noindent{\hangindent2em%
\baselineskip10pt\eightrm#1~\ifacro{\pdfnote#2.}\else#2\fi.\par}}
@@ -232,11 +234,12 @@
\else\ifx\nxt\~\ifTnum\addF{0}\else\addF\tildechar\fi % 077->\T{\~77}
\else\ifx\nxt\_\ifTnum\addF{E}\else\addF_\fi % 0.1E5->\T{0.1\_5}
\else\ifx\nxt\^\ifTnum\addF{0x}\else\addF^\fi % 0x77 -> \T{\^77}
+ \else\ifx\nxt\\\\\ifTnum\addF{0b}\else\addF\\\fi % 0b10111 -> \T{\\10111}
\else\ifx\nxt\$\ifTnum\tokprocessedtrue\else\addF$\fi % \T{77\$L}
\else\ifx\nxt\{\addF\lbchar \else\ifx\nxt\}\addF\rbchar
\else\ifx\nxt\ \addF\space \else\ifx\nxt\#\addF{\string\#}%
\else\ifx\nxt\PP\addF{++}\else\ifx\nxt\MM\addF{--}%
- \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi
+ \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi
}
\def\makeolproctokctlii{%
\ifx\nxt\MG\addF{->}\else\ifx\nxt\GG\addF{>>}%
@@ -287,7 +290,7 @@
\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\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
\def\As{\note{See also sections}} % xref for multiply defined section name
\def\B{\rightskip=0pt plus 100pt minus 10pt % go into C mode
@@ -300,7 +303,7 @@
\let\SHC\C % "// short comments" treated like "/* ordinary comments */"
%\def\C#1{\5\5\quad$\triangleright\,${\cmntfont#1}$\,\triangleleft$}
%\def\SHC#1{\5\5\quad$\diamond\,${\cmntfont#1}}
-\def\D{\defin{\#define}} % macro definition
+\def\D{\defin{{\rm\#}define}} % macro definition
\let\E=\equiv % equivalence sign
\def\ET{ and~} % conjunction between two section numbers
\def\ETs{, and~} % conjunction between the last two of several section numbers
@@ -343,10 +346,11 @@
% \S is section sign
\def\T#1{\leavevmode % octal, hex or decimal constant
\hbox{$\def\?{\kern.2em}%
+ \let\ \, % C++ digit separator becomes a little white space
% \def\$##1{\egroup_{\,\rm##1}\bgroup}% suffix to constant % versions < 3.67
\def\$##1{\egroup_{\rm##1}\bgroup}% suffix to constant % in version 3.67
\def\_{\cdot 10^{\aftergroup}}% power of ten (via dirty trick)
- \let\~=\oct \let\^=\hex {#1}$}}
+ \let\~=\oct \let\^=\hex \let\\=\bin {#1}$}}
\def\U{\note{This code is used in section}} % xref for use of a section
\def\Us{\note{This code is used in sections}} % xref for uses of a section
\let\V=\lor % logical or
@@ -365,11 +369,13 @@
%\def\oct{\hbox{\rm\char'23\kern-.2em\it\aftergroup\?\aftergroup}} % WEB style
%\def\hex{\hbox{\rm\char"7D\tt\aftergroup}} % WEB style
-\def\oct{\hbox{$^\circ$\kern-.1em\it\aftergroup\?\aftergroup}}% CWEB style
+\def\oct{\hbox{$^\circ$\kern-.1em\it\aftergroup\?\aftergroup}} % CWEB style
\def\hex{\hbox{$^{\scriptscriptstyle\#}$\tt\aftergroup}} % CWEB style
+\def\bin{\hbox{$^{\scriptscriptstyle b}$\tt\aftergroup}} % new in CWEB 4.3
\def\vb#1{\leavevmode\hbox{\kern2pt\vrule\vtop{\vbox{\hrule
\hbox{\strut\kern2pt\.{#1}\kern2pt}}
\hrule}\vrule\kern2pt}} % verbatim string
+\def\p#1{\cdot 2^{#1}} % power of two (hex exponent)
\def\onmaybe{\let\ifon=\maybe} \let\maybe=\iftrue
\newif\ifon \newif\iftitle \newif\ifpagesaved
@@ -439,7 +445,7 @@
\write\cont{\catcode `\noexpand\@=12\relax} % \makeatother
\closeout\cont % the contents information has been fully gathered
\output{\ifpagesaved\normaloutput{\box\sbox}\lheader\rheader\fi
- \global\setbox\sbox=\page \global\pagesavedtrue}
+ \global\setbox\sbox=\page \global\pagesavedtrue \mark{\topmark}}
\pagesavedfalse \eject % eject the page-so-far and predecessors
\setbox\sbox\vbox{\unvbox\sbox} % take it out of its box
\vsize=\pageheight \advance\vsize by -\ht\sbox % the remaining height
@@ -482,14 +488,13 @@
\def\X##1:##2\X{\Xpdf##1:##2\X \firstsecno##1.%
{\toksF={}\makeoutlinetoks##2\outlinedone\outlinedone}%
\pdfoutline goto num \the\toksA \expandafter{\the\toksE}}
- \else\ifpdf
- \special{pdf: outline -1 << /Title (\outsecname)
+ \else \special{pdf: outline -1 << /Title (\outsecname)
/Dest [ @thispage /FitH @ypos ] >>}
\def\X##1:##2\X{\Xpdf##1:##2\X \firstsecno##1.%
{\toksF={}\makeoutlinetoks##2\outlinedone\outlinedone}%
\special{pdf: outline 0 << /Title (\the\toksE)
/A << /S /GoTo /D (\romannumeral\the\toksA) >> >>}}
- \fi\fi\fi
+ \fi\fi
\readsections}
\def\makebookmarks{\let\ZZ=\writebookmarkline \readcontents\relax}
\def\expnumber#1{\expandafter\ifx\csname#1\endcsname\relax 0%
@@ -536,9 +541,6 @@
\def\printtwodigits{\advance\twodigits100
\expandafter\gobbleone\number\twodigits
\advance\twodigits-100 }
-\def\TeX{{\ifmmode\it\fi
- \leavevmode\hbox{T\kern-.1667em\lower.424ex\hbox{E}\hskip-.125em X}}}
-\def\,{\relax\ifmmode\mskip\thinmuskip\else\thinspace\fi}
\def\datethis{\def\startsection{\leftline{\sc\today\ at \hours}\bigskip
\let\startsection=\stsec\stsec}}
% say `\datethis' in limbo, to get your listing timestamped before section 1
diff --git a/web/c_cpp/cweb/cwebman.pdf b/web/c_cpp/cweb/cwebman.pdf
index 034674005d..83f0707c13 100644
--- a/web/c_cpp/cweb/cwebman.pdf
+++ b/web/c_cpp/cweb/cwebman.pdf
Binary files differ
diff --git a/web/c_cpp/cweb/cwebman.tex b/web/c_cpp/cweb/cwebman.tex
index df652232b7..476b526a60 100644
--- a/web/c_cpp/cweb/cwebman.tex
+++ b/web/c_cpp/cweb/cwebman.tex
@@ -1,5 +1,4 @@
% This file generates the user manual; TeX it, don't read it!
-% update 14 Nov 2016 by DEK: corrected obsolete remarks re debugging info
\def\tangref{3} % where the main explanation of CTANGLing is given
\input cwebmac
@@ -36,7 +35,7 @@
\def\lheader{\mainfont\the\pageno\hfill\sc\runninghead\hfill}
\def\rheader{\hfill\sc\runninghead\hfill\mainfont\the\pageno}
-\def\runninghead{{\tentt CWEB} USER MANUAL (VERSION 4.2)}
+\def\runninghead{{\tentt CWEB} USER MANUAL (VERSION 4.6)}
% This verbatim mode assumes that ! marks are !! in the text being copied.
\def\verbatim{\begingroup
@@ -50,7 +49,7 @@
\null\vfill
\centerline{\titlefont The {\ttitlefont CWEB} System of
Structured Documentation}
-\vskip 18pt\centerline{(Version 4.2 --- February 2021)}
+\vskip 18pt\centerline{(Version 4.6 --- December 2021)}
\vskip 24pt
\centerline{\authorfont Donald E. Knuth and Silvio Levy}
\vfill
@@ -140,7 +139,7 @@ for \CEE/ if you so desire.
The philosophy behind \.{CWEB} is
that programmers who want to provide the best
possible documentation for their programs need two things
-simultaneously: a language like \TEX/ for formatting, and a language like
+simultaneously: a language like \TEX/ for formatting, and a language like
\CEE/ for programming. Neither type of language can provide the
best documentation by itself. But when both are appropriately combined, we
obtain a system that is much more useful than either language separately.
@@ -394,9 +393,9 @@ program. Therefore the \.{CWEB} language allows you to get the effect of
\CEE/ editing within \TEX/ text, if you place `\.|' marks before and
after the \CEE/ material. For example, suppose you want to say something
like this:
-$$\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.}$$
+$$\hbox{If \PB{\\{pa}} is declared as `\PB{\&{int} ${}{*}\\{pa}$}',
+the assignment \PB{$\\{pa}\K{\AND}\|a[\T{0}]$} makes \PB{\\{pa}}
+point to the zeroth element of \PB{\|a}.}$$
The \TEX/ text would look like this in your \.{CWEB} file:
$$\lpile{\.{If |pa| is declared as `|int *pa|', the assignment}\cr
\.{|pa=\&a[0]| makes |pa| point to the zeroth element of |a|.}\cr}$$
@@ -433,7 +432,7 @@ examples:
$$
\displaylines{
\hbox{\.{if} \.{(x==0)} \.{@<Empty} \.{the} \.{|buffer|} \.{array@>}} \cr
-\hbox{\.{...} \.{using} \.{the} \.{algorithm}
+\hbox{\.{...} \.{using} \.{the} \.{algorithm}
\.{in} \.{|@<Empty} \.{the} \.{|buffer|} \.{array@>|.}} }
$$
The first of these excerpts
@@ -481,9 +480,12 @@ the compiler's benefit) and which \.{CWEAVE} prints as $\T{\~40}$.
Similarly, \.{CWEAVE} prints the hexadecimal \CEE/ constant `\.{0x20}'
as \T{\^20}. The use of italic font for octal digits and typewriter font
for hexadecimal digits makes the meaning of such constants clearer in
-a document. For consistency, then, you
-should type `\.{|040|}' or `\.{|0x20|}'
-in the \TEX/ part of the section.
+a document. For consistency, then, you should type `\.{|040|}' or
+`\.{|0x20|}' in the \TEX/ part of the section.
+
+And if you type a binary constant like `\.{0b00101010}', \.{CWEAVE} prints
+it as $\T{\\00101010}$. In all numeric literals you may add \.' separators
+for improved readability.
\section Control codes.
A \.{CWEB} {\sl control code\/}
@@ -843,7 +845,8 @@ with a semicolon. Consider constructions like
$$\lpile{\.{if (condition) macro @;}\cr
\.{else break;}\cr}$$
where \\{macro} is defined to be a compound statement (enclosed in braces).
-This is a well-known infelicity of \CEE/ syntax.
+This is a well-known infelicity of \CEE/ syntax. You can add a visible
+semicolon with \.{@t;@>} (before \.{@;}).
\@{[} [MC] See \.{@]}.
@@ -1042,7 +1045,7 @@ by default.)
\option e Enclose \CEE/ material formatted by \.{CWEAVE} in
brackets \.{\\PB\{...\}}, so that special hooks can be used.
-(On 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
@@ -1051,13 +1054,18 @@ to some people.) (Has no effect on \.{CTANGLE}.)
\option h Print a happy message at the conclusion of a successful
run. (On by default.)
+\option k Keep single quotes (\.') in numeric literals in the
+\CEE//\CPLUSPLUS/ output. (Off by default.) (\.{CTANGLE} only.)
+
\option p Give progress reports as the program runs. (On by default.)
\option s Show statistics about memory usage after the program
runs to completion. (Off by default.)
-If you
-have large \.{CWEB} files or sections, you may need to see
-how close you come to exceeding the capacity of \.{CTANGLE} and/or \.{CWEAVE}.
+If you have large \.{CWEB} files or sections, you may need to see how close
+you come to exceeding the capacity of \.{CTANGLE} and/or \.{CWEAVE}.
+
+\option t Treat \&{typename} in a template like \&{typedef}.
+(Off by default.) (Has no effect on \.{CTANGLE}.)
\option x Include indexes and a table of contents in the \TEX/ file
output by \.{CWEAVE}. (On by default.) (Has no effect on \.{CTANGLE}.)
@@ -1155,7 +1163,7 @@ 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
+And 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
@@ -1211,10 +1219,7 @@ Since blank lines in the change file are not used for matching, we have
the change file is exhausted. This procedure is called only when
|changing| is |true|; hence error messages will be reported correctly.
-@<Predecl...@>=
-static void prime_the_change_buffer(void);@/
-
-@ @c
+@c
static void
prime_the_change_buffer(void)
{
@@ -1224,6 +1229,8 @@ prime_the_change_buffer(void)
@<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).
@@ -1234,7 +1241,7 @@ while(true) {
if (!!input_ln(change_file)) return;
if (limit<buffer+2) continue;
if (buffer[0]!!='@@') continue;
- if (xisupper(buffer[1])) buffer[1]=tolower((eight_bits)buffer[1]);
+ if (xisupper(buffer[1])) buffer[1]=tolower((int)buffer[1]);
if (buffer[1]=='x') break;
if (buffer[1]=='y' || buffer[1]=='z' || buffer[1]=='i') {
loc=buffer+2;
@@ -1256,39 +1263,37 @@ do {
} while (limit==buffer);
@ @<Move |buffer| and |limit| to |change_buffer| and |change_limit|@>=
-{
- change_limit=change_buffer+(ptrdiff_t)(limit-buffer);
- strncpy(change_buffer,buffer,(size_t)(limit-buffer+1));
-}
+change_limit=change_buffer+(ptrdiff_t)(limit-buffer);
+strncpy(change_buffer,buffer,(size_t)(limit-buffer+1));
!endgroup
\endgroup
\vfill\eject
-\def\runninghead{APPENDIX A --- TRANSLATION BY {\tentt CTANGLE}}
+\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~29, 30 and~31
-have been tangled into section~28.
+have been tangled into section~27.
\vskip6pt
\begingroup \def\tt{\eighttt} \baselineskip9pt
\verbatim
-/*:24*//*28:*/
-#line 234 "common.w"
+/*:23*//*27:*/
+#line 227 "common.w"
static void
prime_the_change_buffer(void)
{
change_limit= change_buffer;
/*29:*/
-#line 248 "common.w"
+#line 243 "common.w"
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((eight_bits)buffer[1]);
+if(xisupper(buffer[1]))buffer[1]= tolower((int)buffer[1]);
if(buffer[1]=='x')break;
if(buffer[1]=='y'||buffer[1]=='z'||buffer[1]=='i'){
loc= buffer+2;
@@ -1298,10 +1303,10 @@ err_print("!! Missing @x in change file");
}
/*:29*/
-#line 239 "common.w"
+#line 232 "common.w"
/*30:*/
-#line 265 "common.w"
+#line 260 "common.w"
do{
change_line++;
@@ -1313,22 +1318,20 @@ return;
}while(limit==buffer);
/*:30*/
-#line 240 "common.w"
+#line 233 "common.w"
/*31:*/
-#line 275 "common.w"
+#line 270 "common.w"
-{
change_limit= change_buffer+(ptrdiff_t)(limit-buffer);
strncpy(change_buffer,buffer,(size_t)(limit-buffer+1));
-}
/*:31*/
-#line 241 "common.w"
+#line 234 "common.w"
}
-/*:28*//*33:*/
+/*:27*//*32:*/
!endgroup
\endgroup
\vfill\eject
@@ -1349,11 +1352,7 @@ the change file is exhausted. This procedure is called only when
\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
+\Y\B\1\1\&{static} \&{void} \\{prime\_the\_change\_buffer}(\&{void})\2\2\6
${}\{{}$\1\6
${}\\{change\_limit}\K\\{change\_buffer}{}$;\C{ this value is used if the
change file ends }\6
@@ -1365,6 +1364,10 @@ change file ends }\6
\4${}\}{}$\2\par
\fi
+\M{28}\B\X7:Predeclaration of procedures\X${}\mathrel+\E{}$\5
+\&{static} \&{void} \\{prime\_the\_change\_buffer}(\&{void});\par
+\fi
+
\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
@@ -1382,7 +1385,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}{}$((\&{eight\_bits}) \\{buffer}[\T{1}]);\2\6
+${}\\{buffer}[\T{1}]\K\\{tolower}{}$((\&{int}) \\{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}[%
@@ -1392,7 +1395,7 @@ ${}\\{loc}\K\\{buffer}+\T{2};{}$\6
\\{err\_print}(\.{"!!\ Missing\ @x\ in\ cha}\)\.{nge\ file"});\6
\4${}\}{}$\2\6
\4${}\}{}$\2\par
-\U28.\fi
+\U27.\fi
\M{30}Here we are looking at lines following the \.{@x}.
@@ -1408,7 +1411,7 @@ ${}\{{}$\1\6
\4${}\}{}$\2\6
\4${}\}{}$\2\5
\&{while} ${}(\\{limit}\E\\{buffer}){}$;\par
-\U28.\fi
+\U27.\fi
!endgroup
\endgroup
\vfil\eject
@@ -1427,11 +1430,7 @@ the change file is exhausted. This procedure is called only when
\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
+\Y\B\1\1\&{static} \&{void} \\{prime\_the\_change\_buffer}(\&{void})\2\2\6
${}\{{}$\1\6
${}\\{change\_limit}\K\\{change\_buffer}{}$;\C{ this value is used if the
change file ends }\6
@@ -1443,6 +1442,10 @@ change file ends }\6
\4${}\}{}$\2\par
\fi
+\M{28}\B\X7:Predeclaration of procedures\X${}\mathrel+\E{}$\5
+\&{static} \&{void} \\{prime\_the\_change\_buffer}(\&{void});\par
+\fi
+
\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
@@ -1470,7 +1473,7 @@ ${}\\{loc}\K\\{buffer}+\T{2};{}$\6
\\{err\_print}(\.{"!\ Missing\ @x\ in\ cha}\)\.{nge\ file"});\6
\4${}\}{}$\2\6
\4${}\}{}$\2\par
-\U28.\fi
+\U27.\fi
\M{30}Here we are looking at lines following the \.{@x}.
@@ -1486,17 +1489,15 @@ ${}\{{}$\1\6
\4${}\}{}$\2\6
\4${}\}{}$\2\5
\&{while} ${}(\\{limit}\E\\{buffer}){}$;\par
-\U28.\fi
+\U27.\fi
\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}+(\&{ptrdiff\_t})(\\{limit}-%
+$\\{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
-\Us28\ET33.\fi
+\\{buffer}+\T{1})){}$;\par
+\Us27\ET32.\fi
\vfil\eject\titletrue
\rightskip=0pt % get out of C mode (cf. \B)
\sfcode`;=1500 \pretolerance 200 \hyphenpenalty 50 \exhyphenpenalty 50
@@ -1591,7 +1592,7 @@ $$\lpile{\.{\\def\\topofcontents\{\\null\\vfill}\cr
\.{ { }\\titlefalse \% include headline on the contents page}\cr
\.{ { }\\def\\rheader\{\\mainfont The \{\\tt CWEAVE\}{ }processor\\hfil\}}\cr
\.{ { }\\centerline\{\\titlefont The \{\\ttitlefont CWEAVE\}{ }processor\}}\cr
- \.{ { }\\vskip 15pt \\centerline\{(Version 4.2)\}{ }\\vfill\}}\cr}$$
+ \.{ { }\\vskip 15pt \\centerline\{(Version 4.6)\}{ }\\vfill\}}\cr}$$
Redefining \.{\\rheader}, which is the headline for right-hand pages,
suffices in this case to put the desired information at the top of the
contents page.
diff --git a/web/c_cpp/cweb/iso_types.w b/web/c_cpp/cweb/iso_types.w
new file mode 100644
index 0000000000..c88e76b7f9
--- /dev/null
+++ b/web/c_cpp/cweb/iso_types.w
@@ -0,0 +1,95 @@
+@q This file defines type names introduced in modern dialects @>
+@q of C and C++ as special entities for TeX formatting @>
+
+@q C99 and C11 underscore keywords @>
+@q http://en.cppreference.com/w/c/keyword @>
+
+@s _Alignas alignas
+@s _Alignof alignof
+@s _Atomic int
+@s _Bool bool
+@s _Complex complex
+@s _Generic class
+@s _Imaginary imaginary
+@s _Noreturn noreturn
+@s _Static_assert static_assert
+@s _Thread_local thread_local
+
+@q C99 and C11 core language atomic types @>
+@q http://en.cppreference.com/w/c/atomic @>
+
+@s atomic_bool bool
+@s atomic_char char
+@s atomic_schar char
+@s atomic_uchar char
+@s atomic_short short
+@s atomic_ushort short
+@s atomic_int int
+@s atomic_uint int
+@s atomic_long long
+@s atomic_ulong long
+@s atomic_llong long
+@s atomic_ullong long
+@s atomic_char8_t char8_t
+@s atomic_char16_t char16_t
+@s atomic_char32_t char32_t
+@s atomic_wchar_t wchar_t
+@s atomic_int_least8_t int
+@s atomic_uint_least8_t int
+@s atomic_int_least16_t int
+@s atomic_uint_least16_t int
+@s atomic_int_least32_t int
+@s atomic_uint_least32_t int
+@s atomic_int_least64_t int
+@s atomic_uint_least64_t int
+@s atomic_int_fast8_t int
+@s atomic_uint_fast8_t int
+@s atomic_int_fast16_t int
+@s atomic_uint_fast16_t int
+@s atomic_int_fast32_t int
+@s atomic_uint_fast32_t int
+@s atomic_int_fast64_t int
+@s atomic_uint_fast64_t int
+@s atomic_intptr_t int
+@s atomic_uintptr_t int
+@s atomic_ptrdiff_t ptrdiff_t
+@s atomic_size_t size_t
+@s atomic_intmax_t int
+@s atomic_uintmax_t int
+
+@q C99 preprocessor @>
+
+@s _Pragma pragma
+
+@q Integral types of C99 and C++, see @>
+@q http://en.cppreference.com/w/c/types/integer and @>
+@q http://en.cppreference.com/w/cpp/types/integer @>
+
+@s int8_t int
+@s int16_t int
+@s int32_t int
+@s int64_t int
+@s int_fast8_t int
+@s int_fast16_t int
+@s int_fast32_t int
+@s int_fast64_t int
+@s int_least8_t int
+@s int_least16_t int
+@s int_least32_t int
+@s int_least64_t int
+@s intmax_t int
+@s intptr_t int
+@s uint8_t int
+@s uint16_t int
+@s uint32_t int
+@s uint64_t int
+@s uint_fast8_t int
+@s uint_fast16_t int
+@s uint_fast32_t int
+@s uint_fast64_t int
+@s uint_least8_t int
+@s uint_least16_t int
+@s uint_least32_t int
+@s uint_least64_t int
+@s uintmax_t int
+@s uintptr_t int
diff --git a/web/c_cpp/cweb/prod.w b/web/c_cpp/cweb/prod.w
index 5f76a19379..cba9473fd0 100644
--- a/web/c_cpp/cweb/prod.w
+++ b/web/c_cpp/cweb/prod.w
@@ -2,7 +2,7 @@
% This program by Silvio Levy and Donald E. Knuth
% is based on a program by Knuth.
% It is distributed WITHOUT ANY WARRANTY, express or implied.
-% Version 3.6 --- May 2000
+% Version 4.6 --- December 2021
%
@ Here is a table of all the productions. Each production that
combines two or more consecutive scraps implicitly inserts a {\tt \$}
@@ -26,9 +26,8 @@ identifier's ilk becomes |raw_int|. A dagger \dag\ before the
production number refers to the notes at the end of this section,
which deal with various exceptional cases.
-We use \\{in}, \\{out}, \\{back} and
-\\{bsp} as shorthands for |indent|, |outdent|, |backup| and
-|break_space|, respectively.
+We use \\{in}, \\{out}, \\{back}, \\{bsp}, and \\{din} as shorthands for
+|indent|, |outdent|, |backup|, |break_space|, and |dindent|, respectively.
\begingroup \lineskip=4pt
\def\alt #1 #2
@@ -38,9 +37,9 @@ We use \\{in}, \\{out}, \\{back} and
{$\displaystyle\Biggl\{\!\matrix{\strut\hbox{#1}\cr\hbox{#2}\cr
\strut\hbox{#3}\cr}\!\Biggr\}$ }
\def\malt #1 #2
-{$\displaystyle\matrix{\strut\hbox{#1}\hfill\cr\strut\hbox{#2}\hfill\cr}$}
+{$\displaystyle\!\matrix{\strut\hbox{#1}\hfill\cr\strut\hbox{#2}\hfill\cr}$}
\def\maltt #1 #2 #3
-{$\displaystyle\matrix{\strut\hbox{#1}\hfill\cr\hbox{#2}\hfill\cr
+{$\displaystyle\!\matrix{\strut\hbox{#1}\hfill\cr\hbox{#2}\hfill\cr
\strut\hbox{#3}\hfill\cr}$}
\yskip
\prodno=0 \midcol=2.5in
@@ -55,101 +54,104 @@ We use \\{in}, \\{out}, \\{back} and
\yskip
\+& \altt\\{any} {\\{any} \\{any}} {\\{any} \\{any} \\{any}}
|insert| & \altt\\{any} {\\{any} \\{any}} {\\{any} \\{any} \\{any}}
-& stmt; \ /$\ast\,$comment$\,*$/\cr
+& stmt; \4\4 \C{comment}\cr
\+& |exp| \altt|lbrace| |int_like| |decl|
- & |fn_decl| \altt|lbrace| |int_like| |decl|
- \hfill $F=E^*\,|in|\,|in|$ & \malt {\\{main}()$\{$}
- {\\{main}$(\\{ac},\\{av})$ \&{int} \\{ac};} \cr
-\+& |exp| |unop| & |exp| & |x++|\cr
-\+& |exp| \alt |binop| |ubinop| |exp| & |exp| & \malt {|x/y|} {|x+y|} \cr
-\+& |exp| |comma| |exp| & |exp| \hfill $EC\,|opt|9\,E$& |f(x,y)|\cr
-\+& |exp| \alt {|lpar| |rpar|} |cast| |colon| &
- |exp| \alt {|lpar| |rpar|} |cast| |base| &
- \malt \&C|()|: {\&C|int i)|:} \cr
-\+& |exp| |semi| & |stmt| & |x=0;|\cr
-\+& |exp| |colon| & |tag| \hfill $E^*C$ & |found:|\cr
+ & |fn_decl| \altt|lbrace| |int_like| |decl| \hfill $F=E^*\,\\{din}$
+ & \malt {\\{main}(\,) $\{$}
+ {$\\{main}(\\{ac},\\{av}){}$ \&{int} \\{ac};} \cr
+\+& |exp| |unop| & |exp| & $x\PP$ \cr
+\+& |exp| \alt |binop| |ubinop| |exp| & |exp| & \malt {$x/y$} {$x+y$} \cr
+\+& |exp| |comma| |exp| & |exp| \hfill $E_1C\,|opt|9\,E_2$ & $f(x,y)$ \cr
+\+& |exp| \alt {|lpar| |rpar|} |cast| |colon|
+ & |exp| \alt {|lpar| |rpar|} |cast| |base|
+ & \malt {\&C(\,) :} {\&C(\&{int} $i$) :} \cr
+\+& |exp| |semi| & |stmt| & $x=0;$ \cr
+\+& |exp| |colon| & |tag| \hfill $E^*C$ & \\{found}: \cr
\+& |exp| |rbrace| & |stmt| |rbrace| & end of \&{enum} list\cr
-\+& |exp| \alt {|lpar| |rpar|} |cast| \alt|const_like| |case_like| &
- |exp| \alt {|lpar| |rpar|} |cast| \hfill
- \alt $R=R\.\ C$ $C_1=C_1\.\ C_2$ &
- \malt {|f() const|} {|f(int) throw|} \cr
-\+& |exp| \alt |exp| |cast| & |exp| & |time()|\cr
-\+& |lpar| \alt |exp| |ubinop| |rpar| & |exp| & \malt{|(x)|} {|(*)|} \cr
+\+& |exp| \alt {|lpar| |rpar|} |cast| \alt|const_like| |case_like|
+ & |exp| \alt {|lpar| |rpar|} |cast| \hfill
+ \alt $R=R\.\ C$ $C_1=C_1\.\ C_2$
+ & \malt {$f$(\,) \&{const}} {$f$(\&{int}) \&{throw}} \cr
+\+& |exp| \alt |exp| |cast| & |exp| & \\{time}(\,) \cr
+\+& |lpar| \alt |exp| |ubinop| |rpar| & |exp| & \malt{($x$)} {$(*)$} \cr
\+& |lpar| |rpar| & |exp| \hfill $L\.{\\,}R$ & functions, declarations\cr
\+& |lpar| \altt |decl_head| |int_like| |cast| |rpar| & |cast| & |(char*)|\cr
\+& |lpar| \altt |decl_head| |int_like| |exp| |comma| & |lpar| \hfill
- $L$\,\altt $D$ $I$ $E$ $C$\,|opt|9 & |(int,|\cr
-\+& |lpar| \alt |stmt| |decl| & |lpar| \hfill \alt {$LS\.\ $} {$LD\.\ $} &
- \malt {|(k=5;|} {|(int k=5;|} \cr
-\+& |unop| \alt |exp| |int_like| & |exp| &
- \malt |!x| |~|\&C \cr
+ $L$\,\altt $D$ $I$ $E$ \unskip $C$\,|opt|9 & |(int,|\cr
+\+& |lpar| \alt |stmt| |decl| & |lpar| \hfill \alt {$LS\.\ $} {$LD\.\ $}
+ & \malt {$(k=5;$} {(\&{int} $k=5;$} \cr
+\+& |unop| \alt |exp| |int_like| & |exp|
+ & \malt {$\R x$} {$\CM\&C$} \cr
\+& |ubinop| |cast| |rpar| & |cast| |rpar| \hfill
$C=\.\{U\.\}C$ & |*|\&{CPtr}) \cr
\+& |ubinop| \alt|exp| |int_like| & \alt|exp| |int_like| \hfill
- \.\{$U$\.\}\alt$E$ $I$ & \malt |*x| |*|\&{CPtr} \cr
+ \.\{$U$\.\}\alt$E$ $I$ & \malt {${*}x$} {${*}\&{CPtr}$} \cr
\+& |ubinop| |binop| & |binop| \hfill $|math_rel|\,U\.\{B\.\}\.\}$ & |*=|\cr
\+& |binop| |binop| & |binop| \hfill
$|math_rel|\,\.\{B_1\.\}\.\{B_2\.\}\.\}$ & |>>=|\cr
\+& |cast| \alt |lpar| |exp| & \alt |lpar| |exp| \hfill
- \alt $CL$ $C\.\ E$ & \malt |(double)(x+2)| |(double)x| \cr
+ \alt $CL$ $C\.\ E$ & \malt {$(\&{double})(x+2)$} {(\&{double}) $x$} \cr
\+& |cast| |semi| & |exp| |semi| & |(int);|\cr
\+& |sizeof_like| |cast| & |exp| & |sizeof (double)|\cr
-\+& |sizeof_like| |exp| & |exp| \hfill $S\.\ E$ & |sizeof x|\cr
+\+& |sizeof_like| |exp| & |exp| \hfill $S\.\ E$ & \&{sizeof} $x$\cr
\+& |int_like| \alt|int_like| |struct_like| &
\alt|int_like| |struct_like| \hfill $I\.\ $\alt $I$ $S$
- \unskip& |extern char|\cr
+ \unskip & |extern char|\cr
\+& |int_like| |exp| \alt|raw_int| |struct_like| &
|int_like| \alt|raw_int| |struct_like| & |extern "Ada" int|\cr
\+& |int_like| \altt|exp| |ubinop| |colon| &
- |decl_head| \altt|exp| |ubinop| |colon| \hfill
- $D=I$\.\ & \maltt|int x| |int*x| |unsigned:| \cr
-\+& |int_like| \alt |semi| |binop| & |decl_head| \alt |semi| |binop| &
- \malt |int x;| {\&{int} $f(\&{int}=4)$} \cr
-\+& |public_like| |colon| & |tag| & \&{private}:\cr
-\+& |public_like| & |int_like| & \&{private}\cr
+ |decl_head| \altt|exp| |ubinop| |colon| \hfill $D=I$\.\ %
+ & \maltt {\&{int} $x$} {\&{int} ${}{*}x$} {\&{unsigned} :} \cr
+\+& |int_like| \alt |semi| |binop| & |decl_head| \alt |semi| |binop|
+ & \malt {\&{int} $x$;} {\&{int} $f(\&{int}=4)$} \cr
+\+& |public_like| |colon| & |tag| & |private:|\cr
+\+& |public_like| & |int_like| & |private|\cr
\+& |colcol| \alt|exp| |int_like| & \alt|exp| |int_like| \hfill
- |qualifier| $C$ \alt$E$ $I$ & \&C\DC$x$\cr
+ |qualifier| $C$\alt$E$ $I$ & \&C\DC$x$\cr
\+& |colcol| |colcol| & |colcol| & \&C\DC\&B\DC\cr
-\+& |decl_head| |comma| & |decl_head| \hfill $DC\.\ $ & |int x,|\cr
+\+& |decl_head| |comma| & |decl_head| \hfill $DC\.\ $ & \&{int} $x,{}$ \cr
\+& |decl_head| |ubinop| & |decl_head| \hfill $D\.\{U\.\}$ & |int *|\cr
-\+\dagit& |decl_head| |exp| & |decl_head| \hfill $DE^*$ & |int x|\cr
+\+\dagit& |decl_head| |exp| & |decl_head| \hfill $DE^*$ & \&{int} $x$ \cr
\+& |decl_head| \alt|binop| |colon| |exp| \altt|comma| |semi| |rpar| &
|decl_head| \altt|comma| |semi| |rpar| \hfill
- $D=D$\alt $B$ $C$ \unskip$E$ & \malt {\&{int} $f(\&{int}\ x=2)$} |int b:1| \cr
-\+& |decl_head| |cast| & |decl_head| & |int f(int)|\cr
+ $D=D$\alt $B$ $C$ \unskip $E$
+ & \malt {\&{int} $f(\&{int}\ x=2)$} {\&{int} $b$ : 1} \cr
+\+& |decl_head| |cast| & |decl_head| & \&{int} $f$(\&{int})\cr
\+& |decl_head| \altt|int_like| |lbrace| |decl| & |fn_decl|
- \altt|int_like| |lbrace| |decl| \hfill $F=D\,|in|\,|in|$
- & |long time () {|\cr
-\+& |decl_head| |semi| & |decl| & |int n;|\cr
-\+& |decl| |decl| & |decl| \hfill $D_1\,|force|\,D_2$ & |int n;double x;|\cr
+ \altt|int_like| |lbrace| |decl| \hfill $F=D\,\\{din}$
+ & \&{long} \\{time}(\,) $\{$\cr
+\+& |decl_head| |semi| & |decl| & \&{int} $n$;\cr
+\+& |decl| |decl| & |decl| \hfill $D_1\,|force|\,D_2$
+ & \&{int} $n$; \&{double} $x$;\cr
\+& |decl| \alt|stmt| |function| & \alt|stmt| |function|
- \hfill $D\,|big_force|\,$\alt $S$ $F$ \unskip& \&{extern} $n$;
- \\{main} ()|{}|\cr
+ \hfill $D\,|big_force|\,$\alt $S$ $F$ \unskip
+ & \&{extern} $n$; \\{main}(\,) $\{\,\}$\cr
\+& |base| \alt |int_like| |exp| |comma| & |base| \hfill
- $B$\.\ \alt $I$ $E$ \unskip$C$\,|opt|9
- & \malt {: \&{public} \&A,} {: $i(5)$,} \cr
+ $B$\.\ \alt $I$ $E$ \unskip $C$\,|opt|9
+ & \malt {: \&{public} \&A,} {: $i$(5),} \cr
\+& |base| \alt |int_like| |exp| |lbrace| & |lbrace| \hfill
- $B$\.\ \alt $I$ $E$ \unskip\.\ $L$ & \&D : \&{public} \&A $\{$\cr
+ $B$\.\ \alt $I$ $E$ \unskip \.\ $L$ & \&D : \&{public} \&A $\{$\cr
\+& |struct_like| |lbrace| & |struct_head| \hfill $S\.\ L$ & |struct {|\cr
\+& |struct_like| \alt|exp| |int_like| |semi| & |decl_head| |semi|
\hfill $S\.\ $\alt $E^{**}$ $I^{**}$ & \&{struct} \&{forward};\cr
\+& |struct_like| \alt|exp| |int_like| |lbrace| & |struct_head| \hfill
- $S\.\ $\alt $E^{**}$ $I^{**}$ \unskip $\.\ L$ &
- \&{struct} \&{name\_info} $\{$\cr
+ $S\.\ $\alt $E^{**}$ $I^{**}$ \unskip $\.\ L$
+ & \&{struct} \&{name\_info} $\{$\cr
\+& |struct_like| \alt|exp| |int_like| |colon| &
|struct_like| \alt|exp| |int_like| |base| & |class| \&C :\cr
\+\dagit& |struct_like| \alt|exp| |int_like| & |int_like|
- \hfill $S\.\ $\alt$E$ $I$ & \&{struct} \&{name\_info} $z$;\cr
+ \hfill $S\.\ $\alt$E$ $I$ \unskip & \&{struct} \&{name\_info} $z$;\cr
\+& |struct_head| \altt|decl| |stmt| |function| |rbrace| & |int_like|\hfill
- $S\,\\{in}\,|force|$\altt$D$ $S$ $F$ $\\{out}\,|force|\,R$ &
- |struct {| declaration |}|\cr
-\+& |struct_head| |rbrace| & |int_like|\hfill $S\.{\\,}R$ & |class C{}|\cr
+ $S\,\\{in}\,|force|$\altt$D$ $S$ $F$ \unskip $\\{out}\,|force|\,R$
+ & |struct {| declaration |}|\cr
+\+& |struct_head| |rbrace| & |int_like|\hfill $S\.{\\,}R$
+ & \&{class} \&C $\{\,\}$\cr
\+& |fn_decl| |decl| & |fn_decl| \hfill $F\,|force|\,D$
- & $f(z)$ \&{double} $z$; \cr
+ & $f(z)$ \&{double} $z$; \cr
\+& |fn_decl| |stmt| & |function| \hfill $F\,|out|\,|out|\,|force|\,S$
- & \\{main}() {\dots}\cr
+ & \\{main}() {\dots}\cr
\+& |function| \altt|stmt| |decl| |function| & \altt |stmt| |decl| |function|
- \hfill $F\,|big_force|\,$\altt $S$ $D$ $F$ & outer block\cr
+ \hfill $F\,|big_force|\,$\altt $S$ $D$ $F$ \unskip & outer block\cr
\+& |lbrace| |rbrace| & |stmt| \hfill $L\.{\\,}R$ & empty statement\cr
\advance\midcol35pt
\+& |lbrace| \altt|stmt| |decl| |function| |rbrace| & |stmt| \hfill
@@ -157,93 +159,97 @@ We use \\{in}, \\{out}, \\{back} and
|force|\,\\{back}\,R\,\\{out}\,|force|$ & compound statement\cr
\advance\midcol-20pt
\+& |lbrace| |exp| [|comma|] |rbrace| & |exp| & initializer\cr
-\+& |if_like| |exp| & |if_clause| \hfill $I\.{\ }E$ & |if (z)|\cr
-\+& |else_like| |colon| & |else_like| |base| & \&{try} :\cr
-\+& |else_like| |lbrace| & |else_head| |lbrace| & \&{else} $\{$\cr
+\+& |if_like| |exp| & |if_clause| \hfill $I\.{\ }E$ & \&{if} ($z$)\cr
+\+& |else_like| |colon| & |else_like| |base| & |try :|\cr
+\+& |else_like| |lbrace| & |else_head| |lbrace| & |else {|\cr
\+& |else_like| |stmt| & |stmt| \hfill
- $|force|\,E\,\\{in}\,\\{bsp}\,S\,\\{out}\,|force|$ & |else x=0;|\cr
-\+& |else_head| \alt|stmt| |exp| & |stmt| \hfill
- $|force|\,E\,\\{bsp}\,|noop|\,|cancel|\,S\,\\{bsp}$ & |else{x=0;}|\cr
-\+& |if_clause| |lbrace| & |if_head| |lbrace| & |if (x) {|\cr
+ $|force|\,E\,\\{in}\,\\{bsp}\,S\,\\{out}\,|force|$
+ & \&{else} $x=0;$\cr
+\+& |else_head| \alt|stmt| |exp| & |stmt| \hfill
+ $|force|\,E\,\\{bsp}\,|noop|\,|cancel|\,S\,\\{bsp}$
+ & $\!\!$ \&{else} $\{x=0;\}$\cr
+\+& |if_clause| |lbrace| & |if_head| |lbrace| & \&{if} ($x$) $\{$\cr
\+& |if_clause| |stmt| |else_like| |if_like| & |if_like| \hfill
- $|force|\,I\,\\{in}\,\\{bsp}\,S\,\\{out}\,|force|\,E\,\.\ I$ &
- |if (x) y; else if|\cr
+ $|force|\,I\,\\{in}\,\\{bsp}\,S\,\\{out}\,|force|\,E\,\.\ I$
+ & $\!\!$ \&{if} ($x$) $y$; \&{else} \&{if}\cr
\+& |if_clause| |stmt| |else_like| & |else_like| \hfill
- $|force|\,I\,\\{in}\,\\{bsp}\,S\,\\{out}\,|force|\,E$ &
- |if (x) y; else|\cr
-\+& |if_clause| |stmt| & |else_like| |stmt| & |if (x)|\cr
+ $|force|\,I\,\\{in}\,\\{bsp}\,S\,\\{out}\,|force|\,E$
+ & $\!\!$ \&{if} ($x$) $y$; \&{else}\cr
+\+& |if_clause| |stmt| & |else_like| |stmt| & $\!\!$ \&{if} ($x$) $y$;\cr
\+& |if_head| \alt|stmt| |exp| |else_like| |if_like| & |if_like| \hfill
- $|force|\,I\,\\{bsp}\,|noop|\,|cancel|\,S\,|force|\,E\,\.\ I$ &
- |if (x){y;}else if|\cr
+ $|force|\,I\,\\{bsp}\,|noop|\,|cancel|\,S\,|force|\,E\,\.\ I$
+ & $\!\!$ \&{if} ($x$) $\{\,y;\,\}$ \&{else} \&{if}\cr
\+& |if_head| \alt|stmt| |exp| |else_like| & |else_like| \hfill
- $|force|\,I\,\\{bsp}\,|noop|\,|cancel|\,S\,|force|\,E$ &
- |if (x){y;}else|\cr
-\+& |if_head| \alt|stmt| |exp| & |else_head| \alt|stmt| |exp| & |if (x){y;}|\cr
+ $|force|\,I\,\\{bsp}\,|noop|\,|cancel|\,S\,|force|\,E$
+ & $\!\!$ \&{if} ($x$) $\{\,y;\,\}$ \&{else}\cr
+\+& |if_head| \alt|stmt| |exp| & |else_head| \alt|stmt| |exp|
+ & $\!\!$ \&{if} ($x$) ${}\{\,y\,\}{}$\cr
\advance\midcol20pt
\+& |do_like| |stmt| |else_like| |semi| & |stmt| \hfill
$D\,\\{bsp}\,|noop|\,|cancel|\,S\,|cancel|\,|noop|\,\\{bsp}\,ES$%
- & |do f(x); while (g(x));|\cr
+ & \&{do} $f$($x$); \&{while} ($g$($x$));\cr
\advance\midcol-20pt
\+& |case_like| |semi| & |stmt| & |return;|\cr
\+& |case_like| |colon| & |tag| & |default:|\cr
\+& |case_like| |exp| & |exp| \hfill $C\.\ E$ & |return 0|\cr
\+& |catch_like| \alt|cast| |exp| & |fn_decl| \hfill
- $C$\alt $C$ $E$ \\{in}\,\\{in} & |catch (...)|\cr
+ $C$\alt $C$ $E$ \unskip \\{din} & |catch (...)|\cr
\+& |tag| |tag| & |tag| \hfill $T_1\,\\{bsp}\,T_2$ & |case 0: case 1:|\cr
\+& |tag| \altt|stmt| |decl| |function| & \altt|stmt| |decl| |function|
- \hfill $|force|\,\\{back}\,T\,\\{bsp}\,S$ & |case 0: z=0;|\cr
+ \hfill $|force|\,\\{back}\,T\,\\{bsp}\,S$
+ & $\!\!$ \&{case} 0: $z=0;$\cr
\+\dagit& |stmt| \altt|stmt| |decl| |function| &
\altt|stmt| |decl| |function|
- \hfill $S\,$\altt$|force|\,S$ $|big_force|\,D$ $|big_force|\,F$ &
- |x=1;y=2;|\cr
+ \hfill $S\,$\altt$|force|\,S$ $|big_force|\,D$ $|big_force|\,F$ \unskip
+ & $x=1;$ $y=2;$\cr
\+& |semi| & |stmt| \hfill \.\ $S$& empty statement\cr
\+\dagit& |lproc| \altt |if_like| |else_like| |define_like| & |lproc| &
- \maltt {{\bf \#include}} {\bf\#else} {\bf\#define} \cr
-\+& |lproc| |rproc| & |insert| & {\bf\#endif} \cr
+ \maltt {\#\&{include}} \#\&{else} \#\&{define} \cr
+\+& |lproc| |rproc| & |insert| & \#\&{endif} \cr
\+& |lproc| \alt {|exp| [|exp|]} |function| |rproc| & |insert| \hfill
$I$\.\ \alt {$E{[\.{\ \\5}E]}$} {$F$} &
- \malt{{\bf\#define} $a$\enspace 1} {{\bf\#define} $a$\enspace$\{\,b;\,\}$} \cr
+ \malt{\#\&{define} $a$\enspace 1} {\#\&{define} $a$\enspace$\{\,b;\,\}$} \cr
\+& |section_scrap| |semi| & |stmt|\hfill $MS$ |force|
&$\langle\,$section name$\,\rangle$;\cr
\+& |section_scrap| & |exp| &$\langle\,$section name$\,\rangle$\cr
-\+& |insert| |any| & |any| & \.{\v\#include\v}\cr
+\+& |insert| \\{any} & \\{any} & \.{\v\#include\v}\cr
\+& |prelangle| & |binop| \hfill \.< & $<$ not in template\cr
\+& |prerangle| & |binop| \hfill \.> & $>$ not in template\cr
\+& |langle| |prerangle| & |cast| \hfill $L\.{\\,}P$ & $\langle\,\rangle$\cr
\+& |langle| \altt|decl_head| |int_like| |exp| |prerangle| & |cast| &
$\langle\&{class}\,\&C\rangle$\cr
\+& |langle| \altt|decl_head| |int_like| |exp| |comma| & |langle| \hfill
- $L$\,\altt $D$ $I$ $E$ $C$\,|opt|9 & $\langle\&{class}\,\&C,$\cr
+ $L$\,\altt $D$ $I$ $E$ \unskip $C$\,|opt|9 & $\langle\&{class}\,\&C,$\cr
\+& |template_like| |exp| |prelangle| & |template_like| |exp| |langle| &
\&{template} $a\langle100\rangle$\cr
\+& |template_like| \alt|exp| |raw_int| & \alt|exp| |raw_int| \hfill
- $T$\.\ \alt$E$ $R$ & \&C\DC\&{template} |a()|\cr
+ $T$\.\ \alt$E$ $R$ & \&C\DC\&{template} $a$(\,)\cr
\+& |template_like| & |raw_int| & \&{template}$\langle\&{class}\,\&T\rangle$\cr
\+& |new_like| |lpar| |exp| |rpar| & |new_like| & \&{new}(\\{nothrow})\cr
\+& |new_like| |cast| & |exp| \hfill $N\.\ C$ & |new(int*)|\cr
-\+\dagit& |new_like| & |new_exp| & \&{new} \&C|()|\cr
+\+\dagit& |new_like| & |new_exp| & \&{new} \&C(\,)\cr
\+& |new_exp| \alt|int_like| |const_like| & |new_exp| \hfill
$N$\.\ \alt $I$ $C$ & |new const int|\cr
\+& |new_exp| |struct_like| \alt |exp| |int_like| & |new_exp| \hfill
$N\.\ S$\.\ \alt $E$ $I$ & \&{new} \&{struct} \&S\cr
\+& |new_exp| |raw_ubin| & |new_exp| \hfill $N\.\{R\.\}$ & |new int*[2]|\cr
\+& |new_exp| \alt |lpar| |exp| & |exp| \alt |lpar| |exp| \hfill
- $E=N$\,\alt {} {\.\ } & \malt |operator[](int)| {|new int(2)|} \cr
+ $E=N$\,\alt {} {\.\ } & \malt {|operator[](int)|} {|new int(2)|} \cr
\+\dagit& |new_exp| & |exp| & |new int;|\cr
\+& |ftemplate| |prelangle| & |ftemplate| |langle| & |make_pair<int,int>|\cr
\+& |ftemplate| & |exp| & |make_pair(1,2)|\cr
\+& |for_like| |exp| & |else_like| \hfill $F\.\ E$ & |while (1)|\cr
\+& |raw_ubin| |const_like| & |raw_ubin| \hfill $RC$\.{\\\ }
- & $*$\&{const} |x|\cr
-\+& |raw_ubin| & |ubinop| & $*$ |x|\cr
-\+& |const_like| & |int_like| & \&{const} |x|\cr
+ & $*$\&{const} $x$\cr
+\+& |raw_ubin| & |ubinop| & $*$ $x$\cr
+\+& |const_like| & |int_like| & \&{const} $x$\cr
\+& |raw_int| |prelangle| & |raw_int| |langle| & \&C$\langle$\cr
\+& |raw_int| |colcol| & |colcol| & \&C\DC\cr
\+& |raw_int| |cast| & |raw_int| & \&C$\langle\&{class}\ \&T\rangle$\cr
\+& |raw_int| |lpar| & |exp| |lpar| & \&{complex}$(x,y)$\cr
-\+\dagit& |raw_int| & |int_like| & \&{complex} |z|\cr
+\+\dagit& |raw_int| & |int_like| & \&{complex} $z$\cr
\+\dagit& |operator_like| \altt|binop| |unop| |ubinop| & |exp|
- \hfill $O$\.\{\altt $B$ $U$ $U$ \unskip\.\} & |operator+|\cr
+ \hfill $O$\.\{\altt $B$ $U$ $U$ \unskip \.\} & |operator+|\cr
\+& |operator_like| \alt|new_like| |delete_like| & |exp| \hfill
$O$\.\ \alt $N$ $S$ & |operator delete|\cr
\+& |operator_like| |comma| & |exp| & \&{operator},\cr
@@ -263,21 +269,68 @@ We use \\{in}, \\{out}, \\{back} and
|typedef_like| \alt |cast| |ubinop| \hfill
\alt $C=\.\{U\.\}C$ $U_2=\.\{U_1\.\}U_2$ \unskip &
\&{typedef} |*|{}|*|(\&{CPtr})\cr
-\+& |delete_like| |lpar| |rpar| & |delete_like|\hfill $DL\.{\\,}R$ &
- \&{delete}|[]| \cr
-\+& |delete_like| |exp| & |exp| \hfill $D\.\ E$ & |delete p| \cr
-\+\dagit& |question| |exp| \alt |colon| |base| & |binop| &
- \malt |?x:| |?f():| \cr
+\+& |delete_like| |lpar| |rpar| & |delete_like|\hfill $DL\.{\\,}R$
+ & \&{delete}[\,] \cr
+\+& |delete_like| |exp| & |exp| \hfill $D\.\ E$ & \&{delete} $p$ \cr
+\+\dagit& |question| |exp| \alt |colon| |base| & |binop|
+ & \malt {$\?x:$} {$\?f(\,):$} \cr
\+& |begin_arg| |end_arg| & |exp| & \.{@@[}\&{char}$*$\.{@@]}\cr
-\+& |any_other| |end_arg| & |end_arg| & \&{char}$*$\.{@@]}\cr
-\yskip
-\yskip
-\yskip
+\+& \\{any\_other} |end_arg| & |end_arg| & \&{char}$*$\.{@@]}\cr
+\+& |alignas_like| |decl_head| & |attr| & \&{alignas}(\&{struct} $s$ ${*})$ \cr
+\+& |alignas_like| |exp| & |attr| & |alignas(8)| \cr
+\+& |lbrack| |lbrack| & |attr_head| & attribute begins \cr
+\+& |lbrack| & |lpar| & |[| elsewhere \cr
+\+& |rbrack| & |rpar| & |]| elsewhere \cr
+\+& |attr_head| |rbrack| |rbrack| & |attr| & |[[@t\dots@>]]| \cr
+\+& |attr_head| |exp| & |attr_head| & |[[deprecated| \cr
+\+& |attr_head| |using_like| |exp| |colon| & |attr_head|
+ & [[\&{using} \.{NS}: \cr
+\+& |attr| \alt|lbrace| |stmt| & \alt|lbrace| |stmt| \hfill
+ $A$\.\ \alt $S$ $L$ & |[[likely]] {|\cr
+\+& |attr| |tag| & |tag| \hfill $A\.\ T$ & |[[likely]] case 0:| \cr
+\+& |attr| |semi| & |stmt| & |[[fallthrough]];| \cr
+\+& |attr| |attr| & |attr| \hfill $A_1\.\ A_2$
+ & \&{alignas}($x$) [[\hbox{\dots}]] \cr
+\+& |attr| |decl_head| & |decl_head| & [[\\{nodiscard}]] $f$(\,) \cr
+\+& |decl_head| |attr| & |decl_head| & (\&{int} $x$ [[\\{deprecated}]])\cr
+\+& |using_like| & |int_like| & \&{using} not in attributes \cr
+\+& |struct_like| |attr| & |struct_like| \hfill $S\.\ A$
+ & \&{struct} [[\\{deprecated}]]\cr
+\+& |exp| |attr| & |attr| \hfill $E\.\ A$ & \&{enum} $\{x\ [[\ldots]]\}$ \cr
+\+& |attr| |typedef_like| & |typedef_like| \hfill $A\.\ T$
+ & |[[deprecated]] typedef| \cr
+\+& |raw_int| |lbrack| & |exp| & |int[3]| \cr
+\+& |attr_head| |comma| & |attr_head| & $[[x,y$ \cr
+\+& |if_head| |attr| & |if_head| \hfill $I\.\ A$
+ & \&{if} ($x$) [[\\{unlikely}]] $\{$ \cr
+\+& |lbrack| |lbrack| |rbrack| |rbrack| & |exp| & |[[]]| \cr
+\+& |attr| |function| & |function| \hfill $A\.\ F$
+ & attribute and function \cr
+\+& |default_like| |colon| & |case_like| |colon| & |default:| \cr
+\+& |default_like| & |exp| & $f(\,)=\&{default};$ \cr
+\+& |struct_like| |struct_like| & |struct_like| \hfill $S_1\.\ S_2$
+ & |enum class| \cr
+\+& |exp| |colcol| |int_like| & |int_like| & $\\{std}\DC\&{atomic}$ \cr
+\advance\midcol-30pt
+\+\dagit& |langle| |struct_like| \alt |exp| |int_like| |comma| &
+ |langle| \hfill $LS$\alt $E^{**}$ $I^{**}$ \unskip $C$
+ & $\langle$\&{typename} $t,$\cr
+\+\dagit& |langle| |struct_like| \alt |exp| |int_like| |prerangle| &
+ |cast| \hfill $LS$\alt $E^{**}$ $I^{**}$ \unskip $P$
+ & $\langle$\&{typename} $t\rangle$ \cr
+\advance\midcol30pt
+\+& |template_like| |cast| |struct_like| & |struct_like| \hfill $T\.\ CS$ &
+ |template<@t\dots@>> class| \cr
+\+& |tag| |rbrace| & |decl| |rbrace| & @q{@>|public: }| \cr
+\+& |fn_decl| |attr| & |fn_decl| \hfill $F\.\ A$
+ & \&{void} $f$(\,) \&{noexcept} \cr
+\+& |alignas_like| |cast| & |attr| & |alignas(int)| \cr
+\vfill\break
\parindent=0pt
\dag{\bf Notes}
\yskip
-Rule 35: The |exp| must not be immediately followed by |lpar|, |exp|,
- or~|cast|.
+Rule 35: The |exp| must not be immediately followed by |lpar|, |lbrack|,
+|exp|, or~|cast|.
Rule 48: The |exp| or |int_like| must not be immediately followed by |base|.
@@ -304,4 +357,7 @@ or |cast|.
Rule 123: The mathness of the |colon| or |base| changes to `yes'.
+Rules 153, 154: |make_reserved| is called only if \.{CWEAVE} has been invoked
+with the \.{+t} option.
+
\endgroup