summaryrefslogtreecommitdiff
path: root/Build/source/texk/web2c/cwebdir/cweave.w
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/texk/web2c/cwebdir/cweave.w')
-rw-r--r--Build/source/texk/web2c/cwebdir/cweave.w736
1 files changed, 472 insertions, 264 deletions
diff --git a/Build/source/texk/web2c/cwebdir/cweave.w b/Build/source/texk/web2c/cwebdir/cweave.w
index a8e31055b23..58b2934fc01 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 --- April 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 */
}
@@ -143,7 +144,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 +177,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 +234,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,7 +244,7 @@ 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;
@@ -289,9 +294,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 +314,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 +354,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 +389,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 +412,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 +446,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 +465,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 +481,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 +490,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 +518,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 +542,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 `\.{@@.}' */
@@ -549,7 +578,7 @@ representation by means of the table |ccode|.
static eight_bits ccode[256]; /* meaning of a char following \.{@@} */
@ @<Set ini...@>=
-{int c; for (c=0; c<256; c++) ccode[c]=0;}
+{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['@@']='@@'; /* `quoted' at sign */
@@ -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,8 +2238,8 @@ 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 */
@@ -2150,7 +2251,7 @@ text_pointer p@t\2\2@>)
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(">");
+ case 3: putchar('<'); print_section_name((name_dir+r)); putchar('>');
break; /* |section_flag| */
case 4: printf("[[%d]]",r); break; /* |tok_flag| */
case 5: printf("|[[%d]]|",r); break; /* |inner_tok_flag| */
@@ -2169,6 +2270,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 +2280,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 +2355,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 +2381,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 +2423,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 +2440,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 +2494,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 +2567,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 +2598,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 +2645,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 +2658,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 +2672,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 +2708,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 +2728,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,15 +2756,15 @@ 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) {
make_underlined(pp+1); squash(pp,2,decl_head,-1,35);
@@ -2662,18 +2774,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 +2796,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 +2816,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 +2840,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 +2862,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 +2873,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 +2900,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 +2933,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 +2961,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 +2970,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 +2980,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 +3004,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 +3019,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 +3069,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 +3087,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 +3105,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 +3126,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 +3135,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,26 +3286,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) {
+ if (tracing==fully) {
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==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) fputs("...",stdout); /* indicate that more is coming */
+ if (hi_ptr<=scrap_ptr) printf("..."); /* indicate that more is coming */
}
}
@@ -3143,8 +3330,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 +3358,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,8 +3395,8 @@ 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) {
@@ -3236,7 +3423,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 +3458,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 +3509,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;
@@ -3447,8 +3636,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 +3664,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 +3682,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 +3803,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 +3889,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 +3911,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 +3922,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 +3939,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 +3973,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 +3985,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 +4017,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 +4027,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 +4108,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 +4122,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 +4256,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 +4305,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 +4314,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 +4322,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 +4344,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 +4381,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 +4426,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,8 +4483,8 @@ 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;
@@ -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 */
@@ -4576,14 +4782,15 @@ 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;
+ case normal: case func_template:
+ if (is_tiny(cur_name)) out_str("\\|");
+ else {@+char *j;
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;
@.\\|@>
@.\\.@>
@.\\\\@>
@@ -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");