summaryrefslogtreecommitdiff
path: root/Build/source/texk/web2c/cwebdir/cweave.w
diff options
context:
space:
mode:
authorAndreas Scherer <andreas_tex@freenet.de>2021-05-03 13:03:46 +0000
committerAndreas Scherer <andreas_tex@freenet.de>2021-05-03 13:03:46 +0000
commit60712e2174bfaa66828692206c37af9b20d9fc9a (patch)
tree3e9284ecd37b56a42a67118bb5aa94482e07112b /Build/source/texk/web2c/cwebdir/cweave.w
parentd3de05fb9dda5d710a51f3ad2097d67d8452a166 (diff)
[CWEB] New release 4.3.1.
This release is almost the same as CWEB 4.3 of 2021-04-16, but * it fixes the indexing bug in CWEAVE/CTWILL that got retracted * it extracts and collects all additions made in CTWILL, so that the section numbers of CWEAVE are retained up to ยง272 and new material is described in the (first) appendix, including the CTWILL user manual * it provides fully revised and (hopefully) corrected mini-indexes for CTWILL, if it is processed by itself (to be published in package 'knuth-pdf' on CTAN) git-svn-id: svn://tug.org/texlive/trunk@59061 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk/web2c/cwebdir/cweave.w')
-rw-r--r--Build/source/texk/web2c/cwebdir/cweave.w802
1 files changed, 505 insertions, 297 deletions
diff --git a/Build/source/texk/web2c/cwebdir/cweave.w b/Build/source/texk/web2c/cwebdir/cweave.w
index a8e31055b23..30bcedb7037 100644
--- a/Build/source/texk/web2c/cwebdir/cweave.w
+++ b/Build/source/texk/web2c/cwebdir/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.3 --- May 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.3)}
\def\topofcontents{\null\vfill
\centerline{\titlefont The {\ttitlefont CWEAVE} processor}
\vskip 15pt
- \centerline{(Version 4.2)}
+ \centerline{(Version 4.3)}
\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.3)"
-@c @<Include files@>@/
+@c
+@<Include files@>@/
@h
@<Common code for \.{CWEAVE} and \.{CTANGLE}@>@/
@<Typedef declarations@>@/
@@ -85,9 +86,9 @@ 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 */
}
@@ -116,8 +117,6 @@ 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 */
@* Data structures exclusive to {\tt CWEAVE}.
@@ -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.
@@ -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,12 +242,12 @@ 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 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 */
@@ -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;
@@ -350,11 +352,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;
@@ -385,14 +387,18 @@ name_pointer p)
@ @<Predecl...@>=@+static void update_node(name_pointer p);
-@ 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;
@@ -671,13 +700,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
@@ -694,7 +716,7 @@ get_next(void) /* produces the next input token */
|| ((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(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 +755,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++;
@@ -758,26 +781,25 @@ 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,7 +808,9 @@ switch(c) {
@ @<Get an identifier@>= {
id_first=--loc;
- while (isalpha((eight_bits)*++loc) || isdigit((eight_bits)*loc) @|
+ do
+ ++loc;
+ while (isalpha((eight_bits)*loc) || isdigit((eight_bits)*loc) @|
|| isxalpha((eight_bits)*loc) || ishigh((eight_bits)*loc));
id_loc=loc; return identifier;
}
@@ -798,28 +822,38 @@ 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 bit of 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++;
@@ -827,22 +861,37 @@ are pointers into the array |section_text|, not into |buffer|.
return constant;
}
+@ @<Get a hex...@>={
+ *id_loc++='^'; loc++;
+ gather_digits_while(xisxdigit(*loc) || *loc=='.');
+ *id_loc++='/'; goto get_exponent;
+}
+
+@ @<Get a bin...@>={
+ *id_loc++='\\'; loc++;
+ gather_digits_while(*loc=='0' || *loc=='1');
+ *id_loc++='/'; goto digit_suffix;
+}
+
+@ @<Get an oct...@>={
+ *id_loc++='~'; gather_digits_while(xisdigit(*loc));
+ *id_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 +907,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,6 +927,11 @@ 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.
@@ -885,7 +943,7 @@ whether there is more work to do.
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 TeX_string: skip_restricted(); return ccode[(eight_bits)c];
case section_name:
@<Scan the section name and make |cur_section| point to it@>@;
case verbatim: @<Scan a verbatim string@>@;
@@ -902,8 +960,9 @@ because the section name might (for example) follow \&{int}.
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;
}
@@ -969,8 +1028,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");
@@ -1067,8 +1125,8 @@ 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) {
@@ -1297,7 +1355,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 +1371,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);
@@ -1378,8 +1436,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++);
}
@@ -1546,9 +1604,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 +1617,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 +1640,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 +1658,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++))@; 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 +1742,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,10 +1765,13 @@ 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];
@@ -1774,14 +1836,21 @@ 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@>)
+print_cat( /* symbolic printout of a category */
+eight_bits c)
{
fputs(cat_name[c],stdout);
}
@@ -1813,7 +1882,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 +1898,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 +1929,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.
@@ -1892,11 +1968,14 @@ with discretionary breaks in between.
\.{@@=}string\.{@@>}&|exp|: \.{\\vb\{}string with special characters
quoted\.\}&maybe\cr
\.{@@'7'}&|exp|: \.{\\.\{@@'7'\}}&maybe\cr
-\.{077} or \.{\\77}&|exp|: \.{\\T\{\\\~77\}}&maybe\cr
-\.{0x7f}&|exp|: \.{\\T\{\\\^7f\}}&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/\\\%3\}}&maybe\cr
+\.{1'000'000}&|exp|: \.{\\T\{1\\\ 000\\\ 000\}}&maybe\cr
\.+&|ubinop|: \.+&yes\cr
\.-&|ubinop|: \.-&yes\cr
\.*&|raw_ubin|: \.*&yes\cr
@@ -1913,9 +1992,9 @@ 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
@@ -1926,6 +2005,8 @@ with discretionary breaks in between.
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 +2018,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 +2053,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 +2062,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 +2074,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 +2090,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 +2099,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
@@ -2137,23 +2238,26 @@ translated without line-break controls.
@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]]",r); break;
+ case inner_tok_flag: printf("|[[%d]]|",r); break;
default: @<Print token |r| in symbolic form@>@;
}
}
@@ -2169,6 +2273,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 +2283,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(r);
}
@ The production rules listed above are embedded directly into \.{CWEAVE},
@@ -2253,8 +2358,9 @@ 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 big_app2(a) big_app1(a);@+big_app1(a+1)
+@d big_app3(a) big_app2(a);@+big_app1(a+2)
+@d big_app1_insert(p,c) big_app1(p);@+big_app(c);@+big_app1(p+1)
@d app(a) *(tok_ptr++)=(token)(a)
@d app1(a) *(tok_ptr++)=(token)(tok_flag+(int)((a)->trans-tok_start))
@@ -2278,12 +2384,12 @@ 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 +2426,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
@@ -2337,6 +2443,8 @@ code needs to be provided with a proper environment.
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) squash(pp,1,rpar,-3,130);
+ else if (pp->cat==using_like) squash(pp,1,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);
@@ -2389,6 +2497,11 @@ 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 */
}
@@ -2457,8 +2570,8 @@ 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| */
@@ -2488,9 +2601,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,11 +2648,11 @@ 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,
@@ -2548,7 +2661,7 @@ to be performed, followed by |goto found|.
@<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_app(dindent); big_app1(pp);
reduce(pp,1,fn_decl,0,1);
}
else if (cat1==unop) squash(pp,2,exp,-2,2);
@@ -2562,16 +2675,20 @@ 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==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==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);
@@ -2594,15 +2711,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,19 +2731,19 @@ 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);
@ @<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);
@@ -2644,17 +2759,17 @@ else squash(pp,1,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 +2777,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); big_app1(pp); reduce(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,19 +2799,19 @@ 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);
@@ -2703,14 +2819,20 @@ else if (cat1==exp||cat1==int_like) {
}
else if (cat2==colon) squash(pp+2,1,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,16 +2843,19 @@ 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|@>=
@@ -2740,8 +2865,8 @@ if (cat1==rbrace) {
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,7 +2876,7 @@ 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|@>=
@@ -2778,19 +2903,24 @@ else if (cat1==stmt) {
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 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);
}
@@ -2806,22 +2936,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) squash(pp,1,decl,-1,156);
@ The user can decide at run-time whether short statements should be
grouped together on the same line.
@@ -2833,12 +2964,8 @@ 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|@>=
@@ -2846,7 +2973,7 @@ big_app(' '); big_app1(pp); reduce(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);
@@ -2856,7 +2983,7 @@ else if (cat1==rproc) {
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");
+ app(inserted); big_app1_insert(pp,' '); app_str("\\5");
@.\\5@>
big_app2(pp+2); reduce(pp,4,insert,-1,80);
}
@@ -2880,7 +3007,10 @@ 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);
@.\\,@>
@@ -2892,31 +3022,42 @@ 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) {
+ if ((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);
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 squash(pp,1,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);
@ @<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==exp) {
@@ -2931,14 +3072,15 @@ else squash(pp,1,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 squash(pp,1,ubinop,-2,104);
@ @<Cases for |const_like|@>=
squash(pp,1,int_like,-2,105);
@@ -2948,16 +3090,16 @@ if (cat1==prelangle) squash(pp+1,1,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==lbrack) squash(pp,1,exp,-2,144);
else if (cat1!=langle) squash(pp,1,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);
@@ -2966,19 +3108,18 @@ else if (cat1!=raw_ubin) squash(pp,1,new_exp,0,114);
if ((cat1==int_like || cat1==cast) && (cat2==comma || cat2==semi))
squash(pp+1,1,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|@>=
@@ -2988,7 +3129,7 @@ if (cat1==lpar && cat2==rpar) {
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,6 +3138,51 @@ if (cat1==exp && (cat2==colon || cat2==base)) {
squash(pp,3,binop,-2,123);
}
+@ @<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 squash(pp,1,lpar,-1,129);
+
+@ @<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) squash(pp,1,case_like,-3,149);
+else squash(pp,1,exp,-2,150);
+
@ Now here's the |reduce| procedure used in our code for productions.
The `|freeze_text|' macro is used to give official status to a token list.
@@ -3103,27 +3289,30 @@ if (lo_ptr<pp+3) {
}
@ 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_l; /* pointer into |scrap_info| */
+ printf("\n%d:",n);
+ for (k_l=scrap_base; k_l<=lo_ptr; k_l++) {
+ if (k_l==pp) putchar('*'); else putchar(' ');
+ if (k_l->mathness %4 == yes_math) putchar('+');
+ else if (k_l->mathness %4 == no_math) putchar('-');
+ print_cat(k_l->cat);
+ if (k_l->mathness /4 == yes_math) putchar('+');
+ else if (k_l->mathness /4 == no_math) putchar('-');
}
+ if (hi_ptr<=scrap_ptr) printf("..."); /* indicate that more is coming */
}
@ The |translate| function assumes that scraps have been stored in
@@ -3143,8 +3332,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...@>@;
@@ -3171,17 +3360,17 @@ where appropriate.
}
@ @<If semi-tracing, show the irreducible scraps@>=
-if (lo_ptr>scrap_base && tracing==1) {
+if (lo_ptr>scrap_base && tracing==partly) {
printf("\nIrreducible scrap sequence in section %d:",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 +3397,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 +3424,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 +3459,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;
@@ -3320,7 +3510,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,8 +3552,7 @@ 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;
+@<Append a string or...@>={@+ int count=-1; /* characters remaining before string break */
if (next_control==constant) app_str("\\T{"@q}@>);
@.\\T@>
else if (next_control==string) {
@@ -3407,6 +3596,7 @@ while (id_first<id_loc) {
}
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
@@ -3447,8 +3637,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 */
@@ -3475,8 +3665,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 +3683,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.
@@ -3615,8 +3804,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 +3890,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 +3912,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 +3923,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) {
@@ -3751,11 +3940,17 @@ make_output(void) /* outputs the equivalents of tokens */
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) c++;
+ else if (a==outdent) c--;
+ else if (a==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;
@@ -3779,7 +3974,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('|')@;
@.\\|@>
else { delim='.';
for (p=cur_name->byte_start;p<(cur_name+1)->byte_start;p++)
@@ -3790,10 +3986,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]))
@@ -3820,7 +4018,7 @@ if (a<break_space || a==preproc_line) {
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 +4028,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;
@@ -3908,9 +4109,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 +4123,16 @@ while (k<k_limit) {
@.\\\~@>
@.\\\&@>
@.\\\_@>
- default: out(b);
+ default: out(b);
+ }
+ 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;
}
- 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...@>=
@@ -4055,14 +4257,13 @@ else {
if (show_progress)
printf("*%d",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) {
+ switch (next_control=copy_TeX()) {
case '|': init_stack; output_C(); break;
case '@@': out('@@'); break;
case TeX_string: case noop:
@@ -4105,8 +4306,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 +4315,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 +4323,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 +4345,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 +4382,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) {
@@ -4220,7 +4427,7 @@ do next_control=get_next();
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@>
@@ -4277,11 +4484,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 +4505,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 */
@@ -4443,7 +4650,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 +4725,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 */
@@ -4575,15 +4781,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;
+ 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 +4799,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 +4828,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,8 +4846,8 @@ 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");