/* l2xixref.c Interpeter X-referencing */ /* BASED ON: xref.c (unaltered except for common names) */ #include #include "l2xicmon.h" #include "l2xiscan.h" #include "l2xisymt.h" #define DEBUG 0 #define MAX_LINENUMS_PER_LINE 10 /* line number item and list header */ typedef struct linenum_item { struct linenum_item *next; int line_number; } LINENUM_ITEM, *LINENUM_ITEM_PTR; typedef struct { LINENUM_ITEM_PTR first_linenum; LINENUM_ITEM_PTR last_linenum; } LINENUM_HEADER, *LINENUM_HEADER_PTR; /* EXTERNALS */ extern int line_number; extern TOKEN_CODE token; extern char word_string[]; extern SYMTAB_NODE_PTR symtab_root; /***************************************************************************/ /* main(argc, argv() loop to process identifiers, then print xref */ /* call as: xref infile */ main(argc, argv) int argc; char *argv[]; { SYMTAB_NODE_PTR np; /* ptr to symtab entry */ LINENUM_HEADER_PTR hp; /* ptr to line item list header */ if (DEBUG) { fprintf(stderr, "\n ****Starting program xref\nCalling init_scanner\n"); fflush(stderr); } init_scanner(argv[1]); if (DEBUG) { fprintf(stderr, "Returned from init_scanner\nProcessing tokens\n"); fflush(stderr); } /* process tokens until end of file */ do { get_token(); if (token == END_OF_FILE) break; if (token == IDENTIFIER) { /* put identifier into symtab if not there, and record the */ /* line number in the symtab entry */ np = search_symtab(word_string, symtab_root); if (np == NULL) { np = enter_symtab(word_string, &symtab_root); hp = alloc_struct(LINENUM_HEADER); hp->first_linenum = hp->last_linenum = NULL; np->info = (char *) hp; } record_line_number(np, line_number); } } while (token != PERIOD); /* end do */ if (DEBUG) { fprintf(stderr, "Finished token processing\nCalling print_xref\n\n"); fflush(stderr); } /* print the xref listing */ printf("\n\nCross-Reference"); printf( "\n---------------\n"); print_xref(symtab_root); if (DEBUG) { fprintf(stderr, "\n\nReturned from print_xref\nCalling quit_scanner\n"); fflush(stderr); } quit_scanner(); if (DEBUG) { fprintf(stderr, "Returned from quit_scanner\n***That's all\n\n"); fflush(stderr); } } /* end main */ /***************************************************************************/ /***************************************************************************/ /* record_line_number(np, number) Record a line number into the */ /* symtab entry */ record_line_number(np, number) SYMTAB_NODE_PTR np; /* ptr to symtab entry */ int number; /* line number */ { LINENUM_ITEM_PTR ip; /* ptr to line item */ LINENUM_HEADER_PTR hp; /* ptr to line item list header */ /* create a new line number item */ ip = alloc_struct(LINENUM_ITEM); ip->line_number = number; ip->next = NULL; /* link it to the list */ hp = (LINENUM_HEADER_PTR) np->info; if (hp->first_linenum == NULL) hp->first_linenum = hp->last_linenum = ip; else { (hp->last_linenum)->next = ip; hp->last_linenum = ip; } } /* end record_line_number */ /***************************************************************************/ /***************************************************************************/ /* print_xref(np) Print x-refed names and line numbers in alpha order */ print_xref(np) SYMTAB_NODE_PTR np; /* pointer to subtree */ { int n; LINENUM_ITEM_PTR ip; /* ptr to line item */ LINENUM_HEADER_PTR hp; /* ptr to line item list header */ if (np == NULL) return; /* print the left subtree */ print_xref(np->left); /* then print the root of the subtree with at most MAX_LINENUMS_PER_LINE */ printf("\n%-16s ", np->name); n = strlen(np->name) > 16 ? 0 : MAX_LINENUMS_PER_LINE; hp = (LINENUM_HEADER_PTR) np->info; for (ip = hp->first_linenum; ip != NULL; ip = ip->next) { if (n == 0) { printf("\n%-16s ", " "); n = MAX_LINENUMS_PER_LINE; } printf(" %4d", ip->line_number); --n; } printf("\n"); /* now print the right subtree */ print_xref(np->right); } /* end print_xref */ /***************************************************************************/ /***************************************************************************/ /* () */ /* () { } /* end */ /***************************************************************************/ /***************************************************************************/ /* () */ /* () { } /* end */ /***************************************************************************/ /***************************************************************************/ /* () */ /* () { } /* end */ /***************************************************************************/