From 1dcf5ae370901d240e8f660100c4212face881f6 Mon Sep 17 00:00:00 2001 From: Matthew Gretton-Dann Date: Fri, 15 Mar 2024 08:31:10 +0000 Subject: [PATCH] Output #line directives as part of nuweb tangling. This makes error location easier. --- nuweb.w | 172 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 86 insertions(+), 86 deletions(-) diff --git a/nuweb.w b/nuweb.w index db1841e..aefdb83 100644 --- a/nuweb.w +++ b/nuweb.w @@ -822,7 +822,7 @@ Processing a web requires three major steps: I have divided the program into several files for quicker recompilation during development. -@o global.h -cc +@o global.h -cc -d @{@ @ @ @@ -874,14 +874,14 @@ The code is divided into four main files (introduced here) and five support files (introduced in the next section). The file \verb|main.c| will contain the driver for the whole program (see Section~\ref{main-routine}). -@o main.c -cc +@o main.c -cc -d @{#include "global.h" @} The first pass over the source file is contained in \verb|pass1.c|. It handles collection of all the file names, fragments names, and scraps (see Section~\ref{pass-one}). -@o pass1.c -cc +@o pass1.c -cc -d @{#include "global.h" @} @@ -889,7 +889,7 @@ The \verb|.tex| file is created during a second pass over the source file. The file \verb|latex.c| contains the code controlling the construction of the \verb|.tex| file (see Section~\ref{latex-file}). -@o latex.c -cc +@o latex.c -cc -d @{#include "global.h" static int scraps = 1; @} @@ -904,7 +904,7 @@ static int scraps = 1; The code controlling the creation of the output files is in \verb|output.c| (see Section~\ref{output-files}). -@o output.c -cc +@o output.c -cc -d @{#include "global.h" @} @@ -915,32 +915,32 @@ The support files contain a variety of support routines used to define and manipulate the major data abstractions. The file \verb|input.c| holds all the routines used for referring to source files (see Section~\ref{source-files}). -@o input.c -cc +@o input.c -cc -d @{#include "global.h" @} Creation and lookup of scraps is handled by routines in \verb|scraps.c| (see Section~\ref{scraps}). -@o scraps.c -cc +@o scraps.c -cc -d @{#include "global.h" @} The handling of file names and fragment names is detailed in \verb|names.c| (see Section~\ref{names}). -@o names.c -cc +@o names.c -cc -d @{#include "global.h" @} Memory allocation and deallocation is handled by routines in \verb|arena.c| (see Section~\ref{memory-management}). -@o arena.c -cc +@o arena.c -cc -d @{#include "global.h" @} Finally, for best portability, I seem to need a file containing (useless!) definitions of all the global variables. -@o global.c -cc +@o global.c -cc -d @{#include "global.h" @ @ @@ -951,7 +951,7 @@ Finally, for best portability, I seem to need a file containing The main routine is quite simple in structure. It wades through the optional command-line arguments, then handles any files listed on the command line. -@o main.c -cc +@o main.c -cc -d @{ #include int main(argc, argv) @@ -1412,7 +1412,7 @@ necessary preparation, we make a pass over the file, filling in all our data structures. Next, we seach all the scraps for references to the user-specified index entries. Finally, we must reverse all the cross-reference lists accumulated while scanning the scraps. -@o pass1.c -cc +@o pass1.c -cc -d @{void pass1(file_name) char *file_name; { @@ -1814,7 +1814,7 @@ Fragment parameters were added on later in nuweb's development. There still is not, for example, an index of fragment parameters. We need a data type to keep track of fragment parameters. -@o global.h -cc +@o global.h -cc -d @{typedef int *Parameters; @| Parameters @} @@ -2040,7 +2040,7 @@ be the place to look. We need a few local function declarations before we get into the body of \verb|write_tex|. -@o latex.c -cc +@o latex.c -cc -d @{static void copy_scrap(); /* formats the body of a scrap */ static void print_scrap_numbers(); /* formats a list of scrap numbers */ static void format_entry(); /* formats an index entry */ @@ -2054,7 +2054,7 @@ static void write_ArglistElement(); The routine \verb|write_tex| takes two file names as parameters: the name of the web source file and the name of the \verb|.tex| output file. -@o latex.c -cc +@o latex.c -cc -d @{void write_tex(file_name, tex_name, sector) char *file_name; char *tex_name; @@ -2318,7 +2318,7 @@ might want to use italics or bold face in the midst of the name. } }@} -@o latex.c -cc +@o latex.c -cc -d @{static void write_arg(FILE * tex_file, char * p) { fputs("\\hbox{\\slshape\\sffamily ", tex_file); @@ -2495,7 +2495,7 @@ list. } }@} -@o latex.c -cc +@o latex.c -cc -d @{static void print_scrap_numbers(tex_file, scraps) FILE *tex_file; Scrap_Node *scraps; @@ -2589,7 +2589,7 @@ command. @{int scrap_type = 0; @| scrap_type @} -@o latex.c -cc +@o latex.c -cc -d @{static void write_literal(FILE * tex_file, char * p, int mode) { fputs(delimit_scrap[mode][0], tex_file); @@ -2604,7 +2604,7 @@ command. } @| write_literal @} -@o latex.c -cc +@o latex.c -cc -d @{static void copy_scrap(file, prefix, name) FILE *file; int prefix; @@ -2859,7 +2859,7 @@ This scrap helps deal with bold keywords: fputs(", \\ldots\\ ", file); }@} -@o latex.c -cc +@o latex.c -cc -d @{static void write_ArglistElement(FILE * file, Arglist * args, char ** params) { @@ -2929,7 +2929,7 @@ write_ArglistElement(FILE * file, Arglist * args, char ** params) c = source_get(); }@} -@o latex.c -cc +@o latex.c -cc -d @{static void format_file_entry(name, tex_file) Name *name; FILE *tex_file; @@ -2990,7 +2990,7 @@ putc('\n', tex_file);@} c = source_get(); @} -@o latex.c -cc +@o latex.c -cc -d @{static int load_entry(Name * name, Name ** nms, int n) { while (name) { @@ -3002,7 +3002,7 @@ c = source_get(); } @| load_entry @} -@o latex.c -cc +@o latex.c -cc -d @{static void format_entry(name, tex_file, sector) Name *name; FILE *tex_file; @@ -3111,7 +3111,7 @@ for (j = 1; j < @2; j++) @{extern int has_sector(Name *, unsigned char); @} -@o latex.c -cc +@o latex.c -cc -d @{int has_sector(Name * name, unsigned char sector) { while(name) { @@ -3143,7 +3143,7 @@ for (j = 1; j < @2; j++) }@} -@o latex.c -cc +@o latex.c -cc -d @{static void format_user_entry(name, tex_file, sector) Name *name; FILE *tex_file; @@ -3789,7 +3789,7 @@ pointed out any during the first pass. @{extern void write_files(); @} -@o output.c -cc +@o output.c -cc -d @{void write_files(files) Name *files; { @@ -3934,14 +3934,14 @@ int source_line = 0; \subsection{Local Declarations} -@o input.c -cc +@o input.c -cc -d @{static FILE *source_file; /* the current input file */ static int double_at; static int include_depth; @| source_file double_at include_depth @} -@o input.c -cc +@o input.c -cc -d @{static struct { FILE *file; char *name; @@ -3958,7 +3958,7 @@ current source file. It notices newlines and keeps the line counter for \verb|@@|~characters. All other characters are immediately returned. We define \verb|source_last| to let us tell which type of scrap we are defining. -@o input.c -cc +@o input.c -cc -d @{ int source_peek; int source_last; @@ -3989,7 +3989,7 @@ int source_get() @} -@o input.c -cc +@o input.c -cc -d @{void source_ungetc(int *c) { ungetc(source_peek, source_file); @@ -4127,7 +4127,7 @@ on the stack, the \verb|EOF| is returned. The routine \verb|source_open| takes a file name and tries to open the file. If unsuccessful, it complains and halts. Otherwise, it sets \verb|source_name|, \verb|source_line|, and \verb|double_at|. -@o input.c -cc +@o input.c -cc -d @{void source_open(name) char *name; { @@ -4151,7 +4151,7 @@ file. If unsuccessful, it complains and halts. Otherwise, it sets \section{Scraps} \label{scraps} -@o scraps.c -cc +@o scraps.c -cc -d @{#define SLAB_SIZE 1024 typedef struct slab { @@ -4160,7 +4160,7 @@ typedef struct slab { } Slab; @| Slab next SLAB_SIZE @} -@o scraps.c -cc +@o scraps.c -cc -d @{typedef struct { char *file_name; Slab *slab; @@ -4175,7 +4175,7 @@ typedef struct slab { There's some issue with reading the auxiliary file if it has more than 255 lines, so (as a workround only) increase the size of the array of \verb|ScrapEntry|s held in \verb|SCRAP[n]|. -@o scraps.c -cc +@o scraps.c -cc -d @{ #define SCRAP_BITS 10 #define SCRAP_SIZE (1<defs || name->defs->scrap != current_scrap) { pushs(buff, &writer); }@} -@o scraps.c -cc +@o scraps.c -cc -d @{void add_to_use(Name * name, int current_scrap) { @@ -4530,7 +4530,7 @@ add_to_use(Name * name, int current_scrap) @d Function... @{extern void add_to_use(Name * name, int current_scrap); @} -@o scraps.c -cc +@o scraps.c -cc -d @{static char pop(manager) Manager *manager; { @@ -4547,7 +4547,7 @@ add_to_use(Name * name, int current_scrap) } @| pop @} -@o scraps.c -cc +@o scraps.c -cc -d @{static void backup(n, manager) int n; Manager *manager; @@ -4564,7 +4564,7 @@ add_to_use(Name * name, int current_scrap) } @| backup @} -@o scraps.c -cc +@o scraps.c -cc -d @{void lookup(int n, Arglist * par, char * arg[9], Name **name, Arglist ** args) { @@ -4586,7 +4586,7 @@ lookup(int n, Arglist * par, char * arg[9], Name **name, Arglist ** args) } @| lookup @} -@o scraps.c -cc +@o scraps.c -cc -d @{Arglist * instance(Arglist * a, Arglist * par, char * arg[9], int * ch) { if (a != NULL) { @@ -4636,7 +4636,7 @@ a->name = name; a->args = args; a->next = next;@} -@o scraps.c -cc +@o scraps.c -cc -d @{static Arglist *pop_scrap_name(manager, parameters) Manager *manager; Parameters *parameters; @@ -4671,7 +4671,7 @@ a->next = next;@} @ }@} -@o scraps.c -cc +@o scraps.c -cc -d @{int write_scraps(file, spelling, defs, global_indent, indent_chars, debug_flag, tab_flag, indent_flag, comment_flag, inArgs, inParams, parameters, title) @@ -5029,7 +5029,7 @@ fputc('>', file);@} @{extern void collect_numbers(); @} -@o scraps.c -cc +@o scraps.c -cc -d @{void collect_numbers(aux_name) char *aux_name; { @@ -5168,7 +5168,7 @@ extern char *save_string(); extern void reverse_lists(); @} -@o names.c -cc +@o names.c -cc -d @{enum { LESS, GREATER, EQUAL, PREFIX, EXTENSION }; static int compare(x, y) @@ -5199,7 +5199,7 @@ static int compare(x, y) @| compare LESS GREATER EQUAL PREFIX EXTENSION @} -@o names.c -cc +@o names.c -cc -d @{char *save_string(s) char *s; { @@ -5209,7 +5209,7 @@ static int compare(x, y) } @| save_string @} -@o names.c -cc +@o names.c -cc -d @{static int ambiguous_prefix(); static char * found_name = NULL; @@ -5263,7 +5263,7 @@ continue the search down {\em both\/} branches of the tree. command_name, nw_char, spelling, nw_char, source_name, source_line); }@} -@o names.c -cc +@o names.c -cc -d @{static int ambiguous_prefix(node, spelling, sector) Name *node; char *spelling; @@ -5314,7 +5314,7 @@ and 2 for alphabetically greater-than. @{extern int robs_strcmp(char*, char*); @} -@o names.c -cc +@o names.c -cc -d @{int robs_strcmp(char* x, char* y) { int cmp = 0; @@ -5353,7 +5353,7 @@ them to be considered for the alphabetical ordering. @1++; @} -@o names.c -cc +@o names.c -cc -d @{Name *name_add(rt, spelling, sector) Name **rt; char *spelling; @@ -5416,7 +5416,7 @@ them to be considered for the alphabetical ordering. Name terminated by whitespace. Also check for ``per-file'' flags. Keep skipping white space until we reach scrap. -@o names.c -cc +@o names.c -cc -d @{Name *collect_file_name() { Name *new_name; @@ -5499,7 +5499,7 @@ char * comment_end[4] = { "", " */", "", ""}; @| comment_begin comment_end comment_mid @} Name terminated by \verb+\n+ or \verb+@@{+; but keep skipping until \verb+@@{+ -@o names.c -cc +@o names.c -cc -d @{Name *collect_macro_name() { char name[MAX_NAME_LEN]; @@ -5636,7 +5636,7 @@ while ((c = source_get()) != EOF) { @{extern Name *install_args(); @} -@o names.c -cc +@o names.c -cc -d @{Name *install_args(Name * name, int argc, char *arg[9]) { int i; @@ -5657,7 +5657,7 @@ struct arglist * next; } Arglist; @| Arglist @} -@o names.c -cc +@o names.c -cc -d @{Arglist * buildArglist(Name * name, Arglist * a) { Arglist * args = (Arglist *)arena_getmem(sizeof(Arglist)); @@ -5670,7 +5670,7 @@ struct arglist * next; @| buildArglist @} Terminated by \verb+@@>+ -@o names.c -cc +@o names.c -cc -d @{Arglist * collect_scrap_name(int current_scrap) { char name[MAX_NAME_LEN]; @@ -5832,7 +5832,7 @@ tail = &(*tail)->next; tail = &(*tail)->next; @} -@o names.c -cc +@o names.c -cc -d @{static Scrap_Node *reverse(); /* a forward declaration */ void reverse_lists(names) @@ -5850,7 +5850,7 @@ void reverse_lists(names) Just for fun, here's a non-recursive version of the traditional list reversal code. Note that it reverses the list in place; that is, it does no new allocations. -@o names.c -cc +@o names.c -cc -d @{static Scrap_Node *reverse(a) Scrap_Node *a; { @@ -5878,14 +5878,14 @@ however, there is an interesting paper describing an efficient solution~\cite{aho:75}. -@o scraps.c -cc +@o scraps.c -cc -d @{typedef struct name_node { struct name_node *next; Name *name; } Name_Node; @| Name_Node @} -@o scraps.c -cc +@o scraps.c -cc -d @{typedef struct goto_node { Name_Node *output; /* list of words ending in this state */ struct move_node *moves; /* list of possible moves */ @@ -5894,7 +5894,7 @@ solution~\cite{aho:75}. } Goto_Node; @| Goto_Node @} -@o scraps.c -cc +@o scraps.c -cc -d @{typedef struct move_node { struct move_node *next; Goto_Node *state; @@ -5902,14 +5902,14 @@ solution~\cite{aho:75}. } Move_Node; @| Move_Node @} -@o scraps.c -cc +@o scraps.c -cc -d @{static Goto_Node *root[256]; static int max_depth; static Goto_Node **depths; @| root max_depth depths @} -@o scraps.c -cc +@o scraps.c -cc -d @{static Goto_Node *goto_lookup(c, g) char c; Goto_Node *g; @@ -5926,7 +5926,7 @@ static Goto_Node **depths; \subsection{Retrieving scrap uses} -@o scraps.c -cc +@o scraps.c -cc -d @{typedef struct ArgMgr_s { char * pv; @@ -5936,7 +5936,7 @@ static Goto_Node **depths; } ArgMgr; @| ArgMgr @} -@o scraps.c -cc +@o scraps.c -cc -d @{typedef struct ArgManager_s { Manager * m; @@ -5944,7 +5944,7 @@ static Goto_Node **depths; } ArgManager; @| ArgManager @} -@o scraps.c -cc +@o scraps.c -cc -d @{static void pushArglist(ArgManager * mgr, Arglist * a) { @@ -5962,7 +5962,7 @@ pushArglist(ArgManager * mgr, Arglist * a) } @| pushArglist @} -@o scraps.c -cc +@o scraps.c -cc -d @{static char argpop(ArgManager * mgr) { while (mgr->a != NULL) @@ -6015,7 +6015,7 @@ the others can occur in this context, which makes the whole free(a); }@} -@o scraps.c -cc +@o scraps.c -cc -d @{static char prev_char(ArgManager * mgr, int n) { @@ -6061,7 +6061,7 @@ else if (m->prev) @{extern void search(); @} -@o scraps.c -cc +@o scraps.c -cc -d @{static void build_gotos(); static int reject_match(); @@ -6082,7 +6082,7 @@ void search() -@o scraps.c -cc +@o scraps.c -cc -d @{static void build_gotos(tree) Name *tree; { @@ -6265,7 +6265,7 @@ static void add_uses(); static int scrap_is_in(); @} -@o scraps.c -cc +@o scraps.c -cc -d @{ static int scrap_is_in(Scrap_Node * list, int i) { @@ -6278,7 +6278,7 @@ static int scrap_is_in(Scrap_Node * list, int i) } @| scrap_is_in@} -@o scraps.c -cc +@o scraps.c -cc -d @{ static void add_uses(Uses * * root, Name *name) { @@ -6309,7 +6309,7 @@ static void add_uses(Uses * * root, Name *name) @{extern void format_uses_refs(FILE *, int); @} -@o scraps.c -cc +@o scraps.c -cc -d @{ void format_uses_refs(FILE * tex_file, int scrap) @@ -6364,7 +6364,7 @@ fputs("}", tex_file);@} @{extern void format_defs_refs(FILE *, int); @} -@o scraps.c -cc +@o scraps.c -cc -d @{ void format_defs_refs(FILE * tex_file, int scrap) @@ -6419,7 +6419,7 @@ longer token. Of course, the concept of {\sl token\/} is language-dependent, so we may be occasionally mistaken. For the present, we'll consider the mechanism an experiment. -@o scraps.c -cc +@o scraps.c -cc -d @{#define sym_char(c) (isalnum(c) || (c) == '_') static int op_char(c) @@ -6436,7 +6436,7 @@ static int op_char(c) } @| sym_char op_char @} -@o scraps.c -cc +@o scraps.c -cc -d @{static int reject_match(name, post, reader) Name *name; char post; @@ -6469,7 +6469,7 @@ while (c = @1, c != nw_char) /* Here is @xlabel@x */ c = @1; @} -@o scraps.c -cc +@o scraps.c -cc -d @{void write_label(char label_name[], FILE * file) @,@)@> @@ -6540,7 +6540,7 @@ lbl->seq = ++lblseq; } @} -@o global.c -cc +@o global.c -cc -d @{label_node * label_tab = NULL; @| label_tab@} @@ -6574,7 +6574,7 @@ extern void arena_free(); @} -@o arena.c -cc +@o arena.c -cc -d @{typedef struct chunk { struct chunk *next; char *limit; @@ -6588,7 +6588,7 @@ at the current chunk of memory; it's initially pointed at \verb|first|. As soon as some storage is required, a ``real'' chunk of memory will be allocated and attached to \verb|first->next|; storage will be allocated from the new chunk (and later chunks if necessary). -@o arena.c -cc +@o arena.c -cc -d @{static Chunk first = { NULL, NULL, NULL }; static Chunk *arena = &first; @| first arena @} @@ -6602,7 +6602,7 @@ that returned pointers are always aligned. We align to the nearest 8-byte segment, since that'll satisfy the more common 2-byte and 4-byte alignment restrictions too. -@o arena.c -cc +@o arena.c -cc -d @{void *arena_getmem(n) size_t n; { @@ -6661,7 +6661,7 @@ need to allocate a new one. To free all the memory in the arena, we need only point \verb|arena| back to the first empty chunk. -@o arena.c -cc +@o arena.c -cc -d @{void arena_free() { arena = &first;