								-*-Web-*-
This file, CWEAVE-P.CH, is part of CWEB-p. It is a changefile written by
Hans-Hermann Bode (HHBODE@@DOSUNI1.BITNET or
hhbode@@dosuni1.rz.uni-osnabrueck.de) for CWEAVE.W that provides changes
appropriate for ANSI-C compilers and for the Turbo-C++ compiler. The latter
will become effective only if the symbol __TURBOC__ is defined, which
automatically is the case when compiled with Turbo C++. Also there are
changes for the SAS/C 6.0 compiler made by Andreas Scherer which are based
on ideas of Carsten Steger. These will become effective only if the
symbol __SASC is defined, which automatically is the case when compiled
with SAS/C 6.0 or higher.

This program is distributed WITHOUT ANY WARRANTY, express or implied.

The following copyright notice extends to this changefile only, not to the
masterfile.

Copyright (C) 1991, 1992 Hans-Hermann Bode

The following copyright notice extends to the SAS/C specific changes in
this changefile only, not to the masterfile.

Copyright (C) 1991 Carsten Steger
Copyright (C) 1993 Andreas Scherer

Permission is granted to make and distribute verbatim copies of this
document provided that the copyright notice and this permission notice
are preserved on all copies.

Permission is granted to copy and distribute modified versions of this
document under the conditions for verbatim copying, provided that the
entire resulting derived work is distributed under the terms of a
permission notice identical to this one.

Version history:

Version	Date		Author	Comment
a1/t1	10 Oct 1991	H2B	First attempt for CWEAVE.W 2.1.
p2	13 Feb 1992	H2B	Updated for CWEAVE.W 2.4, ANSI and Turbo
				changefiles merged together, typesetting of
				certain ANSI and special constructions fixed.
p3	16 Apr 1992	H2B	Updated for CWEAVE.W 2.5.
p4	22 Jun 1992	H2B	Updated for CWEAVE.W 2.6, retaining hack for
				underlining of customized iddentifiers.
p5	21 Jul 1992	H2B	Extensions for C++ implemented.
p5a	24 Jul 1992	KG	adaptions for other ANSI C compiler
p5b	28 Jul 1992	H2B	Remaining headers converted to ANSI style.
p5c	30 Jul 1992	KG	removed comments used after #endif
p6	06 Sep 1992	H2B	Updated for CWEAVE.W 2.7, |dot_dot_dot| added,
				proper typesetting of formatted macro
				identifiers provided, bug in processing
				short comments fixed.
p6a     15 Mar 1993     AS      adaptions for SAS/C 6.0 and use of German
                                macro file ccwebmacg.tex

Extensions for use with other C compiler by Klaus Guntermann (KG),
TH Darmstadt (guntermann@@iti.informatik.th-darmstadt.de).
Mainly just modified all headers of prototyped functions.

------------------------------------------------------------------------------
@x l.2
% This program by Silvio Levy is based on a program by D. E. Knuth.
% It is distributed WITHOUT ANY WARRANTY, express or implied.
% Version 2.7 --- Don Knuth, July 1992

% Copyright (C) 1987,1990,1992 Silvio Levy and Donald E. Knuth
@y
% This program by Silvio Levy is based on a program by D. E. Knuth.
% ANSI-C conforming changes and Turbo-C++ implementation are made by
% Hans-Hermann Bode.
% The program is distributed WITHOUT ANY WARRANTY, express or implied.
% Version 2.6 --- Don Knuth, June 1992
% Version 2.6 [p5] --- Hans-Hermann Bode, July 1992
% Version 2.6 [p5a] --- Klaus Guntermann, July 1992
% Version 2.6 [p5b] --- Hans-Hermann Bode, July 1992
% Version 2.6 [p5c] --- Klaus Guntermann, July 1992
% Version 2.7 --- Don Knuth, July 1992
% Version 2.7 [p6] --- Hans-Hermann Bode, September 1992
% Version 2.7 [p6a] --- Andreas Scherer, March 1993

% Copyright (C) 1987,1990,1992 Silvio Levy and Donald E. Knuth

% Changes conforming to ANSI C and Turbo C++ are
% Copyright (C) 1991, 1992 Hans-Hermann Bode
% Changes conforming to the SAS/C 6.0 compiler are
% Copyright (C) 1991 Carsten Steger
% Copyright (C) 1993 Andreas Scherer
% See the changefile CWEAVE-P.CH for more information.
@z
------------------------------------------------------------------------------
@x l.31
\def\title{CWEAVE (Version 2.6)}
@y
\def\title{CWEAVE (Version 2.7 [p6a])}
@z
------------------------------------------------------------------------------
@x l.35
  \centerline{(Version 2.6)}
@y
  \centerline{(Version 2.7 [p6a])}
@z
------------------------------------------------------------------------------
@x l.39
Copyright \copyright\ 1987,\thinspace1990 Silvio Levy and Donald E. Knuth
@y
Copyright \copyright\ 1987,\thinspace1990 Silvio Levy and Donald E. Knuth
\smallskip\noindent
Copyright \copyright\ 1991,\thinspace1992 Hans-Hermann Bode
\smallskip\noindent
Copyright \copyright\ 1991 Carsten Steger
Copyright \copyright\ 1993 Andreas Scherer
@z
------------------------------------------------------------------------------
Activate this, if only the changed modules should be printed.
x l.52
\let\maybe=\iftrue
y
\let\maybe=\iffalse
z
------------------------------------------------------------------------------
@x l.55
This is the \.{CWEAVE} program by Silvio Levy, based on \.{WEAVE} by
D.~E. Knuth.
@y
This is the \.{CWEAVE} program by Silvio Levy, based on \.{WEAVE} by
D.~E. Knuth, with {\mc ANSI-C} conforming changes and {\mc Turbo-C++}
implementation made by Hans-Hermann Bode. Use of German macros and {\mc
SAS/C~6.0} implementation made by Andreas Scherer based on ideas by Carsten
Steger.
@z
------------------------------------------------------------------------------
@x l.61
@d banner "This is CWEAVE (Version 2.6)\n"
@y
@d banner "This is CWEAVE (Version 2.7 [p6a])\n"
@z
------------------------------------------------------------------------------
@x l.78
main (ac, av)
int ac; /* argument count */
char **av; /* argument values */
@y
@<Prototypes@>@;

int main (int ac, char *av[])
/* argument count and argument values */
@z
------------------------------------------------------------------------------
the int function main needs a return value (although it will never return here)
@x l.89
  wrap_up(); /* and exit gracefully */
@y
  wrap_up(); /* and exit gracefully */
  return(0); /* not reached, but conforming to standards */
@z
------------------------------------------------------------------------------
@x l.123
@i common.h
@y
@i common-p.h
@z
------------------------------------------------------------------------------
@x l.197
typedef struct xref_info {
  sixteen_bits num; /* module number plus zero or |def_flag| */
  struct xref_info *xlink; /* pointer to the previous cross-reference */
} xref_info;
typedef xref_info *xref_pointer;
@y
typedef struct xref_info {
  sixteen_bits num; /* module number plus zero or |def_flag| */
  struct xref_info HUGE *xlink; /* pointer to the previous cross-reference */
} xref_info;
typedef xref_info HUGE *xref_pointer;
@z
------------------------------------------------------------------------------
@x l.204
xref_info xmem[max_refs]; /* contains cross-reference information */
xref_pointer xmem_end = xmem+max_refs-1;
@y
#ifdef __TURBOC__
xref_info HUGE *xmem; /* contains cross-reference information */
xref_pointer xmem_end;
#else
xref_info xmem[max_refs]; /* contains cross-reference information */
xref_pointer xmem_end = xmem+max_refs-1;
#endif
@z
------------------------------------------------------------------------------
@x l.217
xref_ptr=xmem; name_dir->xref=(char*)xmem; xref_switch=0; mod_xref_switch=0;
@y
#ifdef __TURBOC__
xmem=allocsafe(max_refs,sizeof(*xmem));
xmem_end=xmem+max_refs-1;
#endif
xref_ptr=xmem; name_dir->xref=(char HUGE*)xmem; xref_switch=0; mod_xref_switch=0;
@z
------------------------------------------------------------------------------
@x l.235
@c new_xref(p)
name_pointer p;
@y
@c static void new_xref(name_pointer p)
@z
------------------------------------------------------------------------------
@x l.250
  append_xref(m); xref_ptr->xlink=q; p->xref=(char*)xref_ptr;
@y
  append_xref(m); xref_ptr->xlink=q; p->xref=(char HUGE*)xref_ptr;
@z
------------------------------------------------------------------------------
@x l.260
@c new_mod_xref(p)
name_pointer p;
@y
@c static void new_mod_xref(name_pointer p)
@z
------------------------------------------------------------------------------
@x l.280
  if (r==xmem) p->xref=(char*)xref_ptr;
@y
  if (r==xmem) p->xref=(char HUGE*)xref_ptr;
@z
------------------------------------------------------------------------------
@x l.287
@c set_file_flag(p)
name_pointer p;
@y
@c static void set_file_flag(name_pointer p)
@z
------------------------------------------------------------------------------
@x l.294
p->xref = (char *)xref_ptr;
@y
p->xref = (char HUGE*)xref_ptr;
@z
------------------------------------------------------------------------------
@x l.305
typedef token *token_pointer;
typedef token_pointer *text_pointer;
@y
typedef token HUGE *token_pointer;
typedef token_pointer HUGE *text_pointer;
@z
------------------------------------------------------------------------------
@x l.314
token tok_mem[max_toks]; /* tokens */
token_pointer tok_mem_end = tok_mem+max_toks-1; /* end of |tok_mem| */
@y
#ifdef __TURBOC__
token HUGE *tok_mem; /* tokens */
token_pointer tok_mem_end; /* end of |tok_mem| */
#else
token tok_mem[max_toks]; /* tokens */
token_pointer tok_mem_end = tok_mem+max_toks-1; /* end of |tok_mem| */
#endif
@z
------------------------------------------------------------------------------
ANSI C compilers warn about text behind an #endif
This happens several times in cweave.w
Just comment it out
@x l.323
#endif STAT
@y
#endif /* STAT */
@z
------------------------------------------------------------------------------
@x l.326
tok_ptr=tok_mem+1; text_ptr=tok_start+1; tok_start[0]=tok_mem+1;
@y
#ifdef __TURBOC__
tok_mem=allocsafe(max_toks,sizeof(*tok_mem));
tok_mem_end=tok_mem+max_toks-1;
#endif
tok_ptr=tok_mem+1; text_ptr=tok_start+1; tok_start[0]=tok_mem+1;
@z
------------------------------------------------------------------------------
@x l.330
#endif STAT
@y
#endif /* STAT */
@z
------------------------------------------------------------------------------
@x l.333
@c names_match(p,first,l,t)
name_pointer p; /* points to the proposed match */
char *first; /* position of first character of string */
int l; /* length of identifier */
eight_bits t; /* desired ilk */
@y
@c boolean names_match(name_pointer p,char *first,int l,eight_bits t)
/* |p|: points to the proposed match */
/* |first|:  position of first character of string */
/* |l|: length of identifier */
/* |t|: desired |ilk| */
@z
------------------------------------------------------------------------------
@x l.341
  return !strncmp(first,p->byte_start,l);
@y
  return( (boolean) !strncmp(first,p->byte_start,l) );
@z
------------------------------------------------------------------------------
@x l.344
init_p(p,t)
name_pointer p;
eight_bits t;
@y
void init_p(name_pointer p,eight_bits t)
@z
------------------------------------------------------------------------------
@x l.348
  p->ilk=t; p->xref=(char*)xmem;
@y
  p->ilk=t; p->xref=(char HUGE*)xmem;
@z
------------------------------------------------------------------------------
@x l.351
init_node(p)
name_pointer p;
@y
void init_node(name_pointer p)
@z
------------------------------------------------------------------------------
@x l.354
  p->xref=(char*)xmem;
@y
  p->xref=(char HUGE*)xmem;
@z
------------------------------------------------------------------------------
We append missing ANSI and C++ keywords to the list of reserved words.
Additionally there are AMIGA specific types from Commodore and SAS
Institute.
@x l.416
id_lookup("TeX",NULL,custom);
@y
id_lookup("TeX",NULL,custom);
id_lookup("signed",NULL,int_like);
id_lookup("volatile",NULL,int_like);
id_lookup("elif",NULL,if_like);
id_lookup("error",NULL,if_like);
id_lookup("pragma",NULL,if_like);
id_lookup("defined",NULL,sizeof_like);
id_lookup("asm",NULL,sizeof_like);
id_lookup("catch",NULL,struct_like);
id_lookup("class",NULL,struct_like);
id_lookup("delete",NULL,sizeof_like);
id_lookup("friend",NULL,int_like);
id_lookup("inline",NULL,int_like);
id_lookup("new",NULL,sizeof_like);
id_lookup("operator",NULL,sizeof_like);
id_lookup("private",NULL,case_like);
id_lookup("protected",NULL,case_like);
id_lookup("public",NULL,case_like);
id_lookup("template",NULL,case_like);
id_lookup("this",NULL,quoted);
id_lookup("throw",NULL,sizeof_like);
id_lookup("try",NULL,struct_like);
id_lookup("virtual",NULL,int_like);

#ifdef __SASC
if(use_amiga_keywords) {
   @<Keywords specific to {\mc SAS/C 6.0}@>@;
   @<Registers of the Amiga@>@;
   @<Keywords by Commodore@>@;
   }
#endif

@ @<Keywords specific to {\mc SAS/C 6.0}@>=
   id_lookup("__aligned",NULL,int_like);
   id_lookup("__asm",NULL,int_like);
   id_lookup("__chip",NULL,int_like);
   id_lookup("__far",NULL,int_like);
   id_lookup("__inline",NULL,int_like);
   id_lookup("__interrupt",NULL,int_like);
   id_lookup("__near",NULL,int_like);
   id_lookup("__regargs",NULL,int_like);
   id_lookup("__saveds",NULL,int_like);
   id_lookup("__stackext",NULL,int_like);
   id_lookup("__stdargs",NULL,int_like);

@ @<Registers of the Amiga@>=
   id_lookup("__d0",NULL,int_like);
   id_lookup("__d1",NULL,int_like);
   id_lookup("__d2",NULL,int_like);
   id_lookup("__d3",NULL,int_like);
   id_lookup("__d4",NULL,int_like);
   id_lookup("__d5",NULL,int_like);
   id_lookup("__d6",NULL,int_like);
   id_lookup("__d7",NULL,int_like);
   id_lookup("__a0",NULL,int_like);
   id_lookup("__a1",NULL,int_like);
   id_lookup("__a2",NULL,int_like);
   id_lookup("__a3",NULL,int_like);
   id_lookup("__a4",NULL,int_like);
   id_lookup("__a5",NULL,int_like);
   id_lookup("__a6",NULL,int_like);
   id_lookup("__a7",NULL,int_like);
   id_lookup("__fp0",NULL,int_like);
   id_lookup("__fp1",NULL,int_like);
   id_lookup("__fp2",NULL,int_like);
   id_lookup("__fp3",NULL,int_like);
   id_lookup("__fp4",NULL,int_like);
   id_lookup("__fp5",NULL,int_like);
   id_lookup("__fp6",NULL,int_like);
   id_lookup("__fp7",NULL,int_like);

@ @<Keywords by Commodore@>=
   id_lookup("GLOBAL",NULL,int_like);
   id_lookup("IMPORT",NULL,int_like);
   id_lookup("STATIC",NULL,int_like);
   id_lookup("REGISTER",NULL,int_like);
   id_lookup("VOID",NULL,int_like);
   id_lookup("APTR",NULL,int_like);
   id_lookup("LONG",NULL,int_like);
   id_lookup("ULONG",NULL,int_like);
   id_lookup("LONGBITS",NULL,int_like);
   id_lookup("WORD",NULL,int_like);
   id_lookup("UWORD",NULL,int_like);
   id_lookup("WORDBITS",NULL,int_like);
   id_lookup("BYTE",NULL,int_like);
   id_lookup("UBYTE",NULL,int_like);
   id_lookup("BYTEBITS",NULL,int_like);
   id_lookup("RPTR",NULL,int_like);
   id_lookup("STRPTR",NULL,int_like);
   id_lookup("SHORT",NULL,int_like);
   id_lookup("USHORT",NULL,int_like);
   id_lookup("COUNT",NULL,int_like);
   id_lookup("UCOUNT",NULL,int_like);
   id_lookup("CPTR",NULL,int_like);
   id_lookup("FLOAT",NULL,int_like);
   id_lookup("DOUBLE",NULL,int_like);
   id_lookup("BOOL",NULL,int_like);
   id_lookup("TEXT",NULL,int_like);
   id_lookup("BPTR",NULL,int_like);
   id_lookup("BSTR",NULL,int_like);

@ @<Keywords by Commodore@>=
   id_lookup("byte",NULL,int_like);
   id_lookup("Class",NULL,int_like);
   id_lookup("ClassID",NULL,int_like);
   id_lookup("CxMsg",NULL,int_like);
   id_lookup("CxObj",NULL,int_like);
   id_lookup("dev_t",NULL,int_like);
   id_lookup("DIR",NULL,int_like);
   id_lookup("DisplayInfoHandle",NULL,int_like);
   id_lookup("ino_t",NULL,int_like);
   id_lookup("IX",NULL,int_like);
   id_lookup("Msg",NULL,int_like);
   id_lookup("Object",NULL,int_like);
   id_lookup("off_t",NULL,int_like);
   id_lookup("PFL",NULL,int_like);
   id_lookup("PLANEPTR",NULL,int_like);
   id_lookup("Tag",NULL,int_like);
   id_lookup("tPoint",NULL,int_like);
   id_lookup("ushort",NULL,int_like);
   id_lookup("u_char",NULL,int_like);
   id_lookup("u_int",NULL,int_like);
   id_lookup("u_long",NULL,int_like);
   id_lookup("u_short",NULL,int_like);
   id_lookup("WINDOW",NULL,int_like);
@z
------------------------------------------------------------------------------
@x l.439
@d begin_comment '\t' /* tab marks will not appear */
@y
@d begin_short_comment 03 /* \Cpp\ short comment */
@d begin_comment '\t' /* tab marks will not appear */
@z
------------------------------------------------------------------------------
@x l.497
#endif DEBUG
@y
#endif /* DEBUG */
@z
------------------------------------------------------------------------------
@x l.504
@c skip_limbo() {
@y
@c static void skip_limbo(void) {
@z
------------------------------------------------------------------------------
@x l.520
@c unsigned skip_TeX() /* skip past pure \TeX\ code */
@y
@c static unsigned skip_TeX(void) /* skip past pure \TeX\ code */
@z
------------------------------------------------------------------------------
@x l.583
@c eight_bits get_next() /* produces the next input token */
@y
@c static eight_bits get_next(void) /* produces the next input token */
@z
------------------------------------------------------------------------------
This bug in the original CWEAVE should cause no error, we correct it anyway.
@x l.626
while (loc<=buffer_end-7 & isspace(*loc)) loc++;
@y
while (loc<=buffer_end-7 && isspace(*loc)) loc++;
@z
------------------------------------------------------------------------------
@x l.642
\.{--}, \.{->}, \.{>=}, \.{<=}, \.{==}, \.{<<}, \.{>>}, \.{!=}, \.{\v\v}, and
\.{\&\&}.  The compound assignment operators (e.g., \.{+=}) are 
@y
\.{--}, \.{->}, \.{>=}, \.{<=}, \.{==}, \.{<<}, \.{>>}, \.{!=}, \.{\v\v},
\.{\&\&}, \.{::}, \.{.*}, \.{->*}, and \.{...}.  The compound assignment
operators (e.g., \.{+=}) are
@z
------------------------------------------------------------------------------
@x l.651
  case '/': if (*loc=='*') compress(begin_comment); break;
@y
  case '/': if (*loc=='*') {compress(begin_comment);}
    else if (*loc=='/') compress(begin_short_comment); break;
@z
------------------------------------------------------------------------------
@x l.654
    else if (*loc=='>') compress(minus_gt); break;
@y
    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;
  case ':': if (*loc==':') compress(colon_colon); break;
@z
------------------------------------------------------------------------------
@x l.759
#endif DEBUG
@y
#endif /* DEBUG */
@z
------------------------------------------------------------------------------
@x l.870
@c phase_one() {
@y
@c static void phase_one(void) {
@z
------------------------------------------------------------------------------
@x l.908
@c C_xref() /* makes cross-references for \Cee\ identifiers */
@y
@c static void C_xref(void) /* makes cross-references for \Cee\ identifiers */
@z
------------------------------------------------------------------------------
@x l.916
    if (next_control=='|' || next_control==begin_comment) return;
@y
    if (next_control=='|' || next_control==begin_comment ||
        next_control==begin_short_comment) return;
@z
------------------------------------------------------------------------------
@x l.924
@c outer_xref() /* extension of |C_xref| */
@y
@c static void outer_xref(void) /* extension of |C_xref| */
@z
------------------------------------------------------------------------------
@x l.928
    if (next_control!=begin_comment) C_xref();
    else {
      bal=copy_comment(1); next_control='|';
      while (bal>0) {
        C_xref();
        if (next_control=='|') bal=copy_comment(bal);
@y
    if (next_control!=begin_comment && next_control!=begin_short_comment)
      C_xref();
    else {
      boolean const long_style=next_control==begin_comment;
      bal=copy_comment(long_style,1); next_control='|';
      while (bal>0) {
        C_xref();
        if (next_control=='|') bal=copy_comment(long_style,bal);
@z
------------------------------------------------------------------------------
@x l.950
#endif DEBUG
@y
#endif /* DEBUG */
@z
------------------------------------------------------------------------------
Without this re-change, customized identifiers are never underlined except for
explicit |@@!|. This hack---generating an underlined index entry ONLY for
the format definition---may be revised in future versions.
@x l.981
  if (next_control==definition) {
    xref_switch=def_flag; /* implied \.{@@!} */
    next_control=get_next();
  } else @<Process a format definition@>;
@y
  xref_switch=def_flag; /* implied \.{@@!} */
  if (next_control==definition) {
    next_control=get_next();
  } else @<Process a format definition@>;
@z
------------------------------------------------------------------------------
@x l.1007
            else lhs->xref=(char*)q->xlink;
@y
            else lhs->xref=(char HUGE*)q->xlink;
@z
------------------------------------------------------------------------------
@x l.1043
@c mod_check(p) name_pointer p; /* print anomalies in subtree |p| */
@y
@c static void mod_check(name_pointer p) /* print anomalies in subtree |p| */
@z
------------------------------------------------------------------------------
@x l.1095
@c flush_buffer(b,per_cent,carryover)
char *b;  /* outputs from |out_buf+1| to |b|,where |b<=out_ptr| */
boolean per_cent,carryover;
@y
@c static void flush_buffer(char *b,boolean per_cent,boolean carryover)
/* outputs from |out_buf+1| to |b|,where |b<=out_ptr| */
@z
------------------------------------------------------------------------------
@x l.1122
@c finish_line() /* do this at the end of a line */
@y
@c static void finish_line(void) /* do this at the end of a line */
@z
------------------------------------------------------------------------------
% Additionally to the AMIGA keywords there is also a German version of
% the TeX macros called ccwebmacg.tex. You may include these macros by
% setting the `+g' command line switch.
@x l.1136
`\.{\\input cwebmac}'.

@<Set init...@>=
out_ptr=out_buf+1; out_line=1; *out_ptr='c'; tex_printf("\\input cwebma");
@y
`\.{\\input ccwebmac}'.

@<Set init...@>=
if(use_german_macros) {
   out_ptr=out_buf+1; out_line=1; *out_ptr='g'; tex_printf("\\input ccwebmac");
   }
else {
   out_ptr=out_buf+1; out_line=1; *out_ptr='c'; tex_printf("\\input ccwebma");
   }
@z
------------------------------------------------------------------------------
The function |out_str_del| actually is never called.
@x l.1153
@c out_str_del(s,t) /* output characters from |s| to |t-1| */
char *s, *t;
{
  while (s<t) out(*s++);
}
@y
@c
#ifdef DEAD_CODE
static void out_str_del(char*s,char*t) /* output characters from |s| to |t-1| */
{
  while (s<t) out(*s++);
}
#endif
@z
------------------------------------------------------------------------------
@x l.1159
out_str(s) /* output characters from |s| to end of string */
char *s;
@y
static void out_str(char*s) /* output characters from |s| to end of string */
@z
------------------------------------------------------------------------------
@x l.1176
@c break_out() /* finds a way to break the output line */
@y
@c static void break_out(void) /* finds a way to break the output line */
@z
------------------------------------------------------------------------------
@x l.1209
@c out_mod(n) sixteen_bits n;
@y
@c static void out_mod(sixteen_bits n)
@z
------------------------------------------------------------------------------
@x l.1220
@c out_name(p) name_pointer p; {
  char *k, *k_end=(p+1)->byte_start; /* pointers into |byte_mem| */
@y
@c static void out_name(name_pointer p) {
  char HUGE *k, HUGE *k_end=(p+1)->byte_start; /* pointers into |byte_mem| */
@z
------------------------------------------------------------------------------
@x l.1243
@c copy_limbo()
@y
@c static void copy_limbo(void)
@z
------------------------------------------------------------------------------
@x l.1270
@c eight_bits copy_TeX()
@y
@c static eight_bits copy_TeX(void)
@z
------------------------------------------------------------------------------
@x l.1297
@c copy_comment(bal) /* copies \TeX\ code in comments */
int bal; /* brace balance */
@y
@c static copy_comment(boolean long_style,int bal) /* copies \TeX\ code in comments */
/* |long_style|: is this a traditional \Cee\ comment? */
/* |bal|: brace balance */
@z
------------------------------------------------------------------------------
In the following, |get_line| must not be called at the end of a short
comment, since this would cause errors with preprocessor commands.
@x l.1302
    if (loc>limit) if (get_line()==0) {
        err_print("! Input ended in mid-comment");
@.Input ended in mid-comment@>
        loc=buffer+1; goto done;
      }
    c=*(loc++);
    if (c=='|') return(bal);
    @<Check for end of comment@>;
@y
    if (loc>limit) {
      if (long_style) {
        if (get_line()==0) {
          err_print("! Input ended in mid-comment");
@.Input ended in mid-comment@>
          loc=buffer+1; goto done;
        }
      }
      else {
        if (bal>1) err_print("! Missing } in comment");
@.Missing \} in comment@>
        goto done;
      }
    }
    c=*(loc++);
    if (c=='|') return(bal);
    if (long_style) @<Check for end of comment@>;
@z
------------------------------------------------------------------------------
@x l.1437
#endif DEBUG
@y
#endif /* DEBUG */
@z
------------------------------------------------------------------------------
@x l.1481
#endif DEBUG
@y
#endif /* DEBUG */
@z
------------------------------------------------------------------------------
@x l.1488
print_cat(c) /* symbolic printout of a category */
eight_bits c;
@y
static void print_cat(eight_bits c) /* symbolic printout of a category */
@z
------------------------------------------------------------------------------
@x l.1493
#endif DEBUG
@y
#endif /* DEBUG */
@z
------------------------------------------------------------------------------
We add missing C++ operators and |...|.
@x l.1584
\.{<<}&|binop|: \.{\\LL}&yes\cr
@y
\.{<<}&|binop|: \.{\\LL}&yes\cr
\.{::}&|unorbinop|: \.{\\DC}&yes\cr
\.{.*}&|binop|: \.{\\PA}&yes\cr
\.{->*}&|binop|: \.{\\MGA}&yes\cr
\.{...}&|exp|: \.{\\dots}&maybe\cr
@z
------------------------------------------------------------------------------
Here we add missing ANSI and C++ keywords also.
@x l.1662
\.{void}&|int_like|: \stars&maybe\cr
@y
\.{void}&|int_like|: \stars&maybe\cr
\.{const}&|int_like|: \stars&maybe\cr
\.{signed}&|int_like|: \stars&maybe\cr
\.{volatile}&|int_like|: \stars&maybe\cr
\.{elif}&|if_like|: \stars&maybe\cr
\.{error}&|if_like|: \stars&maybe\cr
\.{pragma}&|if_like|: \stars&maybe\cr
\.{defined}&|sizeof_like|: \stars&maybe\cr
\.{asm}&|sizeof_like|: \stars&maybe\cr
\.{catch}&|struct_like|: \stars&maybe\cr
\.{class}&|struct_like|: \stars&maybe\cr
\.{delete}&|sizeof_like|: \stars&maybe\cr
\.{friend}&|int_like|: \stars&maybe\cr
\.{inline}&|int_like|: \stars&maybe\cr
\.{new}&|sizeof_like|: \stars&maybe\cr
\.{operator}&|sizeof_like|: \stars&maybe\cr
\.{private}&|case_like|: \stars&maybe\cr
\.{protected}&|case_like|: \stars&maybe\cr
\.{public}&|case_like|: \stars&maybe\cr
\.{template}&|case_like|: \stars&maybe\cr
\.{this}&|exp|: \.{\\this}&yes\cr
\.{throw}&|sizeof_like|: \stars&maybe\cr
\.{try}&|struct_like|: \stars&maybe\cr
\.{virtual}&|int_like|: \stars&maybe\cr
@z
------------------------------------------------------------------------------
@x l.1680
\.{/*}comment\.{*/}&|insert|: \.{\\C\{}translated comment\.\} |force|&no\cr
@y
\.{/*}comment\.{*/}&|insert|: \.{\\C\{}translated comment\.\} |force|&no\cr
\.{//}comment&|insert|: \.{\\SHC\{}translated comment\.\} |force|&no\cr
@z
------------------------------------------------------------------------------
@x l.1683
@i prod.w
@y
@i prod-p.w
@z
------------------------------------------------------------------------------
@x l.1740
#endif STAT
@y
#endif /* STAT */
@z
------------------------------------------------------------------------------
@x l.1746
#endif STAT
@y
#endif /* STAT */
@z
------------------------------------------------------------------------------
The function |print_text| is never called in CWEAVE.
@x l.1770
@d inner_tok_flag 5*id_flag /* signifies a token list in `\pb' */

@c
#ifdef DEBUG
print_text(p) /* prints a token list for online debugging */
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("\\\\{"); print_id((name_dir+r)); printf("}"); break;
        /* |id_flag| */
      case 2: printf("\\&{"); print_id((name_dir+r)); printf("}"); break;
        /* |res_flag| */
      case 3: printf("<"); print_id((name_dir+r)); printf(">"); break;
        /* |mod_flag| */
      case 4: printf("[[%d]]",r); break; /* |tok_flag| */
      case 5: printf("|[[%d]]|",r); break; /* |inner_tok_flag| */
      default: @<Print token |r| in symbolic form@>;
    }
  }
  fflush(stdout);
}
#endif DEBUG
@y
@d inner_tok_flag 5*id_flag /* signifies a token list in `\pb' */

@c
#ifdef DEBUG
#ifdef DEAD_CODE
void print_text(text_pointer p) /* prints a token list for online debugging */
{
  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("\\\\{"); print_id((name_dir+r)); printf("}"); break;
        /* |id_flag| */
      case 2: printf("\\&{"); print_id((name_dir+r)); printf("}"); break;
        /* |res_flag| */
      case 3: printf("<"); print_id((name_dir+r)); printf(">"); break;
        /* |mod_flag| */
      case 4: printf("[[%d]]",r); break; /* |tok_flag| */
      case 5: printf("|[[%d]]|",r); break; /* |inner_tok_flag| */
      default: @<Print token |r| in symbolic form@>;
    }
  }
  fflush(stdout);
}
#endif
#endif
@z
------------------------------------------------------------------------------
@x l.1895
@ @c app_str(s)
char *s;
@y
@ @c static void app_str(char*s)
@z
------------------------------------------------------------------------------
@x l.1900
big_app(a)
token a;
@y
static void big_app(token a)
@z
------------------------------------------------------------------------------
@x l.1915
big_app1(a)
scrap_pointer a;
@y
static void big_app1(scrap_pointer a)
@z
------------------------------------------------------------------------------
@x l.1997
find_first_ident(p)
text_pointer p;
@y
static find_first_ident(text_pointer p)
@z
------------------------------------------------------------------------------
@x l.2021
@c make_reserved(p) /* make the first identifier in |p->trans| like |int| */
scrap_pointer p;
@y
@c static void make_reserved(scrap_pointer p)
/* make the first identifier in |p->trans| like |int| */
@z
------------------------------------------------------------------------------
@x l.2050
@c make_underlined(p)
/* underline the entry for the first identifier in |p->trans| */
scrap_pointer p;
@y
@c static void make_underlined(scrap_pointer p)
/* underline the entry for the first identifier in |p->trans| */
@z
------------------------------------------------------------------------------
@x l.2065
@c underline_xref(p)
name_pointer p;
@y
@c static void underline_xref(name_pointer p)
@z
------------------------------------------------------------------------------
@x l.2097
  p->xref=(char*)xref_ptr;
@y
  p->xref=(char HUGE*)xref_ptr;
@z
------------------------------------------------------------------------------
CWeave indents declarations after function definitions.
That's just awful!  Make this better looking!
@x l.2106
@<Cases for |exp|@>=
if (cat1==lbrace || cat1==int_like || cat1==decl) {
  make_underlined(pp); big_app1(pp); big_app(indent); app(indent);
  reduce(pp,1,fn_decl,0,1);
}
@y
@<Cases for |exp|@>=
if(cat1==lbrace || cat1==int_like || cat1==decl) {
  make_underlined(pp); big_app1(pp);
  reduce(pp,1,fn_decl,0,1);
  }
@z
------------------------------------------------------------------------------
The next change is necessary for function prototypes with multiple
|int_like|s in the second or further argument (for simpler prototypes the
original rule would suffice).
@x l.2130
else if ((cat1==decl_head || cat1==int_like) && cat2==rpar)
  squash(pp,3,cast,-1,10);
@y
else if (cat1==decl_head || cat1==int_like) {
  if (cat2==rpar) squash(pp,3,cast,-1,10);
  else if (cat2==comma) squash(pp,3,lpar,0,115);
}
@z
------------------------------------------------------------------------------
This is for C++ destructors.
@x l.2140
if (cat1==exp) squash(pp,2,exp,-2,13);
@y
if (cat1==exp || cat1==int_like) squash(pp,2,cat1,-2,13);
@z
------------------------------------------------------------------------------
This is for |new| and |operator| constructions in C++.
@x l.2165
if (cat1==cast) squash(pp,2,exp,-2,18);
else if (cat1==exp) {
  big_app1(pp); big_app(' '); big_app1(pp+1); reduce(pp,2,exp,-2,19);
@y
if (cat1==cast) squash(pp,2,exp,-2,18);
else if (cat1==exp&&cat2==int_like) {
  big_app2(pp); big_app(' '); big_app1(pp+2); reduce(pp,3,exp,-2,100);
}
else if ((cat1==unorbinop||cat1==binop)&&cat2==binop) {
  big_app('{'); big_app1(pp+1); big_app('}');
  big_app('{'); big_app1(pp+2); big_app('}');
  reduce(pp+1,2,binop,0,112);
}
else if (cat1==exp||cat1==int_like||cat1==unorbinop||cat1==binop||cat1==unop||
    cat1==sizeof_like||cat1==comma) {
  big_app1(pp); big_app(' '); big_app1(pp+1); reduce(pp,2,exp,-2,19);
@z
------------------------------------------------------------------------------
The first change is required by the next for function prototypes, the second
allows for C++ function-style explicit type conversions, the third for
constructor declarations.
@x l.2174
else if (cat1==exp || cat1==unorbinop || cat1==semi) {
  big_app1(pp);
  if (cat1!=semi) big_app(' ');
  reduce(pp,1,decl_head,-1,21);
}
@y
else if (cat1==exp || cat1==unorbinop || cat1==semi) {
  big_app1(pp);
  if (cat1!=semi) big_app(' ');
  reduce(pp,1,decl_head,-2,21);
}
else if (cat1==comma&&cat2==int_like) {
  big_app2(pp); app(opt); app('9'); big_app1(pp+2);
  reduce(pp,3,int_like,-1,101);
}
else if (cat1==lpar&&cat2==exp&&cat3==rpar) squash(pp,4,exp,-2,102);
else if (cat1==cast) squash(pp,2,decl_head,-2,111);
@z
------------------------------------------------------------------------------
Here additional production rules for function prototypes, ANSI constructions
like |int *const|, and special constructions like |, huge*|  are implemented.
Also there is a change on indentation.
@x l.2181
@ @<Cases for |decl_head|@>=
if (cat1==comma) {
  big_app2(pp); big_app(' '); reduce(pp,2,decl_head,-1,22);
}
else if (cat1==unorbinop) {
  big_app1(pp); big_app('{'); big_app1(pp+1); big_app('}');
  reduce(pp,2,decl_head,-1,23);
}
else if (cat1==exp && cat2!=lpar && cat2!=exp) {
  make_underlined(pp+1); squash(pp,2,decl_head,-1,24);
}
else if ((cat1==binop||cat1==colon) && cat2==exp && (cat3==comma || cat3==semi))
  squash(pp,3,decl_head,-1,25);
else if (cat1==lbrace || cat1==int_like || cat1==decl) {
  big_app1(pp); big_app(indent); app(indent); reduce(pp,1,fn_decl,0,26);
}
else if (cat1==semi) squash(pp,2,decl,-1,27);
@y
@ @<Cases for |decl_head|@>=
if (cat1==comma) {
  big_app2(pp); big_app(' ');
  if (cat2==int_like) {
    big_app1(pp+2); if (cat3!=rpar) big_app(' ');
    reduce(pp,3,decl_head,-2,103);
  } else reduce(pp,2,decl_head,-2,22);
}
else if (cat1==unorbinop) {
  big_app1(pp); big_app('{'); big_app1(pp+1); big_app('}');
  if (cat2==int_like) {
    big_app1(pp+2); if (cat3!=rpar) big_app(' ');
    reduce(pp,3,decl_head,-2,104);
  } else reduce(pp,2,decl_head,-2,23);
}
else if (cat1==exp) {
  make_underlined(pp+1); squash(pp,2,decl_head,-2,24);
}
else if ((cat1==binop||cat1==colon) && cat2==exp &&
    (cat3==comma || cat3==semi || cat3==rpar))
  squash(pp,3,decl_head,-1,25);
else if (cat1==cast) squash(pp,2,decl_head,-2,105);
else if (cat1==lbrace || cat1==int_like || cat1==decl) {
  big_app1(pp); reduce(pp,1,fn_decl,0,26);
}
else if (cat1==semi) squash(pp,2,decl,-1,27);
@z
------------------------------------------------------------------------------
There should be no extra space between a declaration and a statement anymore.
@x l.2205
  big_app1(pp); big_app(big_force); big_app1(pp+1); reduce(pp,2,cat1,-1,29);
@y
  big_app1(pp); big_app(cat1==stmt? force: big_force); big_app1(pp+1);
  reduce(pp,2,cat1,-1,29);
@z
------------------------------------------------------------------------------
The following---like the similar construction above---is re-changed for
function prototypes and C++ declarations.
@x l.2210
  if ((cat2==exp&&cat3!=lpar&&cat3!=exp)||cat2==int_like) {
@y
  if (cat2==exp||cat2==int_like) {
@z
------------------------------------------------------------------------------
Names of structure types should be made reserved. Furthermore, we take care
of C++ derived classes.
@x l.2220
  big_app1(pp); big_app(' '); big_app1(pp+1); reduce(pp,2,struct_head,0,32);
}
else if (cat1==exp||cat1==int_like) {
  if (cat2==lbrace) {
    make_underlined(pp+1);
    big_app1(pp); big_app(' '); big_app1(pp+1);
    big_app(' '); big_app1(pp+2);reduce(pp,3,struct_head,0,33);
  }
@y
  big_app1(pp); big_app(' '); big_app1(pp+1); reduce(pp,2,struct_head,0,32);
}
else if (cat1==colon) {
  if (cat2==exp||cat2==int_like||cat2==case_like) {
    big_app1(pp+1); big_app(' '); big_app1(pp+2); reduce(pp+1,2,colon,0,106);
  }
  else if (cat2==comma) {
    big_app2(pp+1); big_app(' '); reduce(pp+1,2,colon,0,113);
  }
  else {
    big_app1(pp); big_app(' '); big_app1(pp+1); reduce(pp,2,struct_like,0,107);
  }
}
else if (cat1==exp||cat1==int_like) {
  if (cat2==lbrace) {
    make_underlined(pp+1); make_reserved(pp+1);
    big_app1(pp); big_app(' '); big_app1(pp+1);
    big_app(' '); big_app1(pp+2);reduce(pp,3,struct_head,0,33);
  }
  else if (cat2==colon) {
    if (cat3==exp||cat3==int_like||cat3==case_like) {
      big_app1(pp+2); big_app(' '); big_app1(pp+3); reduce(pp+2,2,colon,0,108);
    }
    else if (cat3==comma) {
      big_app2(pp+2); big_app(' '); reduce(pp+2,2,colon,0,114);
    }
    else {
      big_app1(pp+1); big_app(' '); big_app1(pp+2); reduce(pp+1,2,cat1,0,109);
    }
  }
@z
------------------------------------------------------------------------------
C++ classes can contain function definitions.
@x l.2234
if ((cat1==decl || cat1==stmt) && cat2==rbrace) {
@y
if ((cat1==decl || cat1==stmt || cat1==function) && cat2==rbrace) {
@z
------------------------------------------------------------------------------
Another change on indentation.
@x l.2240
@ @<Cases for |fn_decl|@>=
if (cat1==decl) {
  big_app1(pp); big_app(force); big_app1(pp+1); reduce(pp,2,fn_decl,0,36);
}
else if (cat1==stmt) {
  big_app1(pp); app(outdent); app(outdent); big_app(force);
  big_app1(pp+1); reduce(pp,2,function,-1,37);
}
@y
@ @<Cases for |fn_decl|@>=
if (cat1==decl) {
  big_app1(pp); big_app(force); big_app1(pp+1); reduce(pp,2,fn_decl,0,36);
}
else if (cat1==stmt) {
  big_app1(pp); big_app(force);
  big_app1(pp+1); reduce(pp,2,function,-1,37);
}
@z
----------------------------------------------------------------------
No extra indentation for |else if|, please.
@x l.2282
  else reduce(pp,2,stmt,-1,45);
@y
  else reduce(pp,2,stmt,-1,45);
}
else if (cat1==else_like) {
  big_app1(pp); big_app(' '); big_app1(pp+1); reduce(pp,2,else_like,0,110);
@z
------------------------------------------------------------------------------
In C++, declarations can have a tag, also.
@x l.2323
else if (cat1==stmt) {
  big_app(force); big_app(backup); big_app1(pp); big_app(break_space);
  big_app1(pp+1); reduce(pp,2,stmt,-1,54);
@y
else if (cat1==stmt||cat1==decl) {
  big_app(force); big_app(backup); big_app1(pp); big_app(break_space);
  big_app1(pp+1); reduce(pp,2,cat1,-1,54);
@z
------------------------------------------------------------------------------
In C++, a statement may be followed by a declaration.
@x l.2329
if (cat1==stmt) {
@y
if (cat1==stmt||cat1==decl) {
@z
------------------------------------------------------------------------------
@x l.2381
@c reduce(j,k,c,d,n)
scrap_pointer j;
eight_bits c;
short k, d, n;
@y
@c static void reduce(scrap_pointer j, short k, eight_bits c, short d, short n)
@z
------------------------------------------------------------------------------
@x l.2409
@c squash(j,k,c,d,n)
scrap_pointer j;
eight_bits c;
short k, d, n;
@y
@c static void squash(scrap_pointer j, short k, eight_bits c, short d, short n)
@z
------------------------------------------------------------------------------
@x l.2444
#endif STAT
@y
#endif /* STAT */
@z
------------------------------------------------------------------------------
@x l.2450
#endif STAT
@y
#endif /* STAT */
@z
------------------------------------------------------------------------------
@x l.2478
#endif DEBUG
@y
#endif /* DEBUG */
@z
------------------------------------------------------------------------------
@x l.2496
#endif DEBUG
@y
#endif /* DEBUG */
@z
------------------------------------------------------------------------------
@x l.2511
@c text_pointer translate() /* converts a sequence of scraps */
@y
@c static text_pointer translate(void) /* converts a sequence of scraps */
@z
------------------------------------------------------------------------------
@x l.2548
#endif DEBUG
@y
#endif /* DEBUG */
@z
------------------------------------------------------------------------------
@x l.2561
#endif DEBUG
@y
#endif /* DEBUG */
@z
------------------------------------------------------------------------------
@x l.2578
@c C_parse() /* creates scraps from \Cee\ tokens */
@y
@c static void C_parse(void) /* creates scraps from \Cee\ tokens */
@z
------------------------------------------------------------------------------
@x l.2585
    if (next_control=='|' || next_control==begin_comment) return;
@y
    if (next_control=='|' || next_control==begin_comment ||
        next_control==begin_short_comment) return;
@z
------------------------------------------------------------------------------
@x l.2662
#endif STAT
@y
#endif /* STAT */
@z
------------------------------------------------------------------------------
@x l.2692
@.\\LL@>
@y
@.\\LL@>
case colon_colon: app_str("\\DC");@+app_scrap(unorbinop,yes_math);@+break;
@.\\DC@>
case period_ast: app_str("\\PA");@+app_scrap(binop,yes_math);@+break;
@.\\PA@>
case minus_gt_ast: app_str("\\MGA");@+app_scrap(binop,yes_math);@+break;
@.\\MGA@>
case dot_dot_dot: app_str("\\dots");@+app_scrap(exp,maybe_math);@+break;
@.\\dots@>
@z
------------------------------------------------------------------------------
|app_curr_id|---to be used later---is located here to be near the code it is
derived from. It's defined as a macro to leave the section numbering intact.
@x l.2733
@ @<Append an identifier scrap@>=
@y
@ The macro |app_curr_id| is a raw version of the following \Cee\ code that
only appends the current identifier to the token list without building a new
scrap.

@d app_curr_id {
  name_pointer p=id_lookup(id_first,id_loc,normal);
  if (!(reserved(p))) app(id_flag+p-name_dir); /* not a reserved word */
  else if (p->ilk<=quoted) { /* |custom| or |quoted| */
    app('\\');
    while (id_first++<id_loc) {
      if (isxalpha(*(id_first-1))) app_tok('x')
      else app_tok(*(id_first-1));
    }
@.\\NULL@>
  }
  else app(res_flag+p-name_dir);
}

@<Append an identifier scrap@>=
@z
------------------------------------------------------------------------------
@x l.2757
@c text_pointer C_translate()
@y
@c static text_pointer C_translate(void)
@z
------------------------------------------------------------------------------
@x l.2770
#endif STAT
@y
#endif /* STAT */
@z
------------------------------------------------------------------------------
@x l.2779
@c outer_parse() /* makes scraps from \Cee\ tokens and comments */
@y
@c static void outer_parse(void) /* makes scraps from \Cee\ tokens and comments */
@z
------------------------------------------------------------------------------
@x l.2784
    if (next_control!=begin_comment) C_parse();
    else {
      @<Make sure that there is room for the new...@>;
      app(cancel); app_str("\\C{");
@.\\C@>
      bal=copy_comment(1); next_control=ignore;
      while (bal>0) {
        p=text_ptr; freeze_text; q=C_translate();
         /* at this point we have |tok_ptr+6<=max_toks| */
        app(tok_flag+p-tok_start); app(inner_tok_flag+q-tok_start);
        if (next_control=='|') {
          bal=copy_comment(bal);
@y
    if (next_control!=begin_comment && next_control!=begin_short_comment)
      C_parse();
    else {
      boolean const long_style=next_control==begin_comment;
      @<Make sure that there is room for the new...@>;
      app(cancel);
      if (long_style) app_str("\\C{");
      else app_str("\\SHC{");
@.\\C@>
      bal=copy_comment(long_style,1); next_control=ignore;
      while (bal>0) {
        p=text_ptr; freeze_text; q=C_translate();
         /* at this point we have |tok_ptr+6<=max_toks| */
        app(tok_flag+p-tok_start); app(inner_tok_flag+q-tok_start);
        if (next_control=='|') {
          bal=copy_comment(long_style,bal);
@z
------------------------------------------------------------------------------
@x l.2867
#endif STAT
@y
#endif /* STAT */
@z
------------------------------------------------------------------------------
@x l.2872
#endif STAT
@y
#endif /* STAT */
@z
------------------------------------------------------------------------------
@x l.2878
@c push_level(p) /* suspends the current level */
text_pointer p;
@y
@c static void push_level(text_pointer p) /* suspends the current level */
@z
------------------------------------------------------------------------------
@x l.2890
#endif STAT
@y
#endif /* STAT */
@z
------------------------------------------------------------------------------
@x l.2898
@c pop_level()
@y
@c static void pop_level(void)
@z
------------------------------------------------------------------------------
@x l.2918
@c eight_bits get_output() /* returns the next token of output */
@y
@c static eight_bits get_output(void) /* returns the next token of output */
@z
------------------------------------------------------------------------------
@x l.2925
    switch (a / id_flag) {
      case 2: return(res_word); /* |a==res_flag+cur_name| */
      case 3: return(mod_name); /* |a==mod_flag+cur_name| */
      case 4: push_level(a % id_flag + tok_start); goto restart;
        /* |a==tok_flag+cur_name| */
      case 5: push_level(a % id_flag + tok_start); cur_mode=inner; goto restart;
        /* |a==inner_tok_flag+cur_name| */
      default: return(identifier); /* |a==id_flag+cur_name| */
    }
  }
  return(a);
@y
    switch (a / id_flag) {
      case 2: return((eight_bits)res_word); /* |a==res_flag+cur_name| */
      case 3: return((eight_bits)mod_name); /* |a==mod_flag+cur_name| */
      case 4: push_level(a % id_flag + tok_start); goto restart;
        /* |a==tok_flag+cur_name| */
      case 5: push_level(a % id_flag + tok_start); cur_mode=inner; goto restart;
        /* |a==inner_tok_flag+cur_name| */
      default: return((eight_bits)identifier); /* |a==id_flag+cur_name| */
    }
  }
  return((eight_bits)a);
@z
------------------------------------------------------------------------------
@x l.2954
output_C() /* outputs the current token list */
@y
static void output_C(void) /* outputs the current token list */
@z
------------------------------------------------------------------------------
@x l.2967
#endif STAT
@y
#endif /* STAT */
@z
------------------------------------------------------------------------------
@x l.2974
@c make_output() /* outputs the equivalents of tokens */
@y
@c static void make_output(void) /* outputs the equivalents of tokens */
@z
------------------------------------------------------------------------------
@x l.2979
  char *k, *k_limit; /* indices into |byte_mem| */
@y
  char HUGE *k, HUGE *k_limit; /* indices into |byte_mem| */
@z
------------------------------------------------------------------------------
We need a huge pointer here instead of j; k seems a good choice, since it is
declared as index into byte_mem anyhow.
@x l.3022
    for (j=cur_name->byte_start;j<(cur_name+1)->byte_start;j++)
      if (islower(*j)) { /* not entirely uppercase */
@y
    for (k=cur_name->byte_start;k<(cur_name+1)->byte_start;k++)
      if (islower(*k)) { /* not entirely uppercase */
@z
------------------------------------------------------------------------------
@x l.3201
@c phase_two() {
@y
@c static void phase_two(void) {
@z
------------------------------------------------------------------------------
@x l.3300
@c finish_C(visible) /* finishes a definition or a \Cee\ part */
  boolean visible; /* nonzero if we should produce \TeX\ output */
@y
@c static void finish_C(boolean visible) /* finishes a definition or a \Cee\ part */
  /* |visible|: nonzero if we should produce \TeX\ output */
@z
------------------------------------------------------------------------------
@x l.3322
#endif STAT
@y
#endif /* STAT */
@z
------------------------------------------------------------------------------
This change and the next provide proper typesetting of the identifiers
involved (especially when they are customized).
@x l.3344
    app('$'); app(id_flag+id_lookup(id_first, id_loc,normal)-name_dir);
@y
    app('$'); app_curr_id;
@z
------------------------------------------------------------------------------
@x l.3348
      case identifier: app(id_flag+id_lookup(id_first, id_loc,normal)-name_dir); goto reswitch;
@y
      case identifier: app_curr_id; goto reswitch;
@z
------------------------------------------------------------------------------
@x l.3490
@c footnote(flag) /* outputs module cross-references */
sixteen_bits flag;
@y
@c static void footnote(sixteen_bits flag) /* outputs module cross-references */
@z
------------------------------------------------------------------------------
@x l.3532
@c phase_three() {
@y
@c static void phase_three(void) {
@z
------------------------------------------------------------------------------
The hash_pointer h is already defined external in COMMON.
@x l.3590
hash_pointer h; /* index into |hash| */
@y
@z
------------------------------------------------------------------------------
@x l.3603
    if (cur_name->xref!=(char*)xmem) {
@y
    if (cur_name->xref!=(char HUGE*)xmem) {
@z
------------------------------------------------------------------------------
@x l.3634
char *cur_byte; /* index into |byte_mem| */
@y
char HUGE *cur_byte; /* index into |byte_mem| */
@z
------------------------------------------------------------------------------
@x l.3638
#endif STAT
@y
#endif /* STAT */
@z
------------------------------------------------------------------------------
@x l.3643
#endif STAT
@y
#endif /* STAT */
@z
------------------------------------------------------------------------------
@x l.3671
@c unbucket(d) /* empties buckets having depth |d| */
eight_bits d;
@y
@c static void unbucket(eight_bits d) /* empties buckets having depth |d| */
@z
------------------------------------------------------------------------------
@x l.3681
#endif STAT
@y
#endif /* STAT */
@z
------------------------------------------------------------------------------
@x l.3728
    else {char *j;
@y
    else {char HUGE *j;
@z
------------------------------------------------------------------------------
@x l.3743
  case custom: case quoted: {char *j; out_str("$\\");
@y
  case custom: case quoted: {char HUGE *j; out_str("$\\");
@z
------------------------------------------------------------------------------
@x l.3784
@c mod_print(p) /* print all module names in subtree |p| */
name_pointer p;
@y
@c static void mod_print(name_pointer p) /* print all module names in subtree |p| */
@z
------------------------------------------------------------------------------
@x l.3802
print_stats() {
@y
void print_stats(void) {
@z
------------------------------------------------------------------------------
@x l.3805
  printf("%d names (out of %d)\n",name_ptr-name_dir,max_names);
  printf("%d cross-references (out of %d)\n",xref_ptr-xmem,max_refs);
  printf("%d bytes (out of %d)\n",byte_ptr-byte_mem,max_bytes);
  printf("Parsing:\n");
  printf("%d scraps (out of %d)\n",max_scr_ptr-scrap_info,max_scraps);
  printf("%d texts (out of %d)\n",max_text_ptr-tok_start,max_texts);
  printf("%d tokens (out of %d)\n",max_tok_ptr-tok_mem,max_toks);
  printf("%d levels (out of %d)\n",max_stack_ptr-stack,stack_size);
  printf("Sorting:\n");
  printf("%d levels (out of %d)\n",max_sort_ptr-scrap_info,max_scraps);
@y
#ifdef __TURBOC__
  printf("%ld names (out of %ld)\n",name_ptr-name_dir,(long)max_names);
  printf("%ld cross-references (out of %ld)\n",xref_ptr-xmem,(long)max_refs);
  printf("%ld bytes (out of %ld)\n",byte_ptr-byte_mem,(long)max_bytes);
  printf("Parsing:\n");
  printf("%ld scraps (out of %ld)\n",max_scr_ptr-scrap_info,(long)max_scraps);
  printf("%ld texts (out of %ld)\n",max_text_ptr-tok_start,(long)max_texts);
  printf("%ld tokens (out of %ld)\n",max_tok_ptr-tok_mem,(long)max_toks);
  printf("%ld levels (out of %ld)\n",max_stack_ptr-stack,(long)stack_size);
  printf("Sorting:\n");
  printf("%ld levels (out of %ld)\n",max_sort_ptr-scrap_info,(long)max_scraps);
#else
  printf("%d names (out of %d)\n",name_ptr-name_dir,max_names);
  printf("%d cross-references (out of %d)\n",xref_ptr-xmem,max_refs);
  printf("%d bytes (out of %d)\n",byte_ptr-byte_mem,max_bytes);
  printf("Parsing:\n");
  printf("%d scraps (out of %d)\n",max_scr_ptr-scrap_info,max_scraps);
  printf("%d texts (out of %d)\n",max_text_ptr-tok_start,max_texts);
  printf("%d tokens (out of %d)\n",max_tok_ptr-tok_mem,max_toks);
  printf("%d levels (out of %d)\n",max_stack_ptr-stack,stack_size);
  printf("Sorting:\n");
  printf("%d levels (out of %d)\n",max_sort_ptr-scrap_info,max_scraps);
#endif
@z
------------------------------------------------------------------------------
@x l.3818
@* Index.
@y
@*Function declarations. Here are declarations---conforming to {\mc ANSI~C}---of
all functions in this code, as far as they are not already in |"common.h"|.

@<Proto...@>=
static void new_xref(name_pointer p);
static void new_mod_xref(name_pointer p);
static void set_file_flag(name_pointer p);
static void skip_limbo(void);
static unsigned skip_TeX(void);
static eight_bits get_next(void);
static void phase_one(void);
static void C_xref(void);
static void outer_xref(void);
static void mod_check(name_pointer p);
static void flush_buffer(char*b,boolean per_cent,boolean carryover);
static void finish_line(void);
#ifdef DEAD_CODE
static void out_str_del(char*s,char*t);
#endif
static void out_str(char*s);
static void break_out(void);
static void out_mod(sixteen_bits n);
static void out_name(name_pointer p);
static void copy_limbo(void);
static eight_bits copy_TeX(void);
static int copy_comment(boolean long_style,int bal);
static void app_str(char*s);
static void big_app(token a);
static void big_app1(scrap_pointer a);
static token_pointer find_first_ident(text_pointer p);
static void make_reserved(scrap_pointer p);
static void make_underlined(scrap_pointer p);
static void underline_xref(name_pointer p);
static void reduce(scrap_pointer j,short k,eight_bits c,short d,short n);
static void squash(scrap_pointer j,short k,eight_bits c,short d,short n);
static text_pointer translate(void);
static void C_parse(void);
static text_pointer C_translate(void);
static void outer_parse(void);
static void push_level(text_pointer p);
static void pop_level(void);
static eight_bits get_output(void);
static void output_C(void);
static void make_output(void);
static void phase_two(void);
static void finish_C(boolean visible);
static void footnote(sixteen_bits flag);
static void phase_three(void);
static void unbucket(eight_bits d);
static void mod_print(name_pointer p);

#ifdef DEBUG
static void print_cat(eight_bits c);
#ifdef DEAD_CODE
static void print_text(text_pointer p);
#endif
#endif

@ Finally, we include \.{string.h} for |strcpy|, |strncpy|, and |strncmp|.
We include \.{fcntl.h} for |write|.

@<Include...@>=
#include <string.h>
#include <fcntl.h>

@* Index.
@z
------------------------------------------------------------------------------
