Path: utzoo!utgpu!cs.utexas.edu!sdd.hp.com!wuarchive!rex!uflorida!travis!tom From: tom@ssd.csd.harris.com (Tom Horsley) Newsgroups: alt.sources Subject: mkid 06/11 (identifier cross reference tool) Message-ID: Date: 12 Dec 90 14:44:12 GMT Sender: news@travis.csd.harris.com Organization: Harris Computer Systems Division Lines: 731 #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh 'getscan.c' <<'END_OF_FILE' X/* Copyright (c) 1986, Greg McGary */ Xstatic char sccsid[] = "@(#)getscan.c 1.1 86/10/09"; X X#include X#include X#include X#include X#include X Xchar *getLanguage(); Xchar *(*getScanner())(); Xvoid setScanArgs(); X Xstatic struct sufftab *suffSlot(); Xstatic struct langtab *langSlot(); Xstatic void sorryNoScan(); X Xvoid setAdaArgs(lang) { sorryNoScan(lang); } Xchar *getAdaId() { setAdaArgs("ada"); return NULL; } X Xvoid setPascalArgs(lang) { sorryNoScan(lang); } Xchar *getPascalId() { setPascalArgs("pascal"); return NULL; } X Xvoid setLispArgs(lang) { sorryNoScan(lang); } Xchar *getLispId() { setLispArgs("lisp"); return NULL; } X Xstruct langtab { X struct langtab *lt_next; X char *lt_name; X char *(*lt_getid)(); X void (*lt_setargs)(); X char *lt_filter; X}; X Xstruct sufftab { X struct sufftab *st_next; X char *st_suffix; X struct langtab *st_lang; X}; X X Xstruct langtab langtab[] = { X#define SCAN_C (&langtab[0]) X{&langtab[1], "c", getCId, setCArgs, NULL}, X#define SCAN_ASM (&langtab[1]) X{&langtab[2], "asm", getAsmId, setAsmArgs, NULL}, X#define SCAN_ADA (&langtab[2]) X{&langtab[3], "ada", getAdaId, setAdaArgs, NULL}, X#define SCAN_PASCAL (&langtab[3]) X{&langtab[4], "pascal", getPascalId, setPascalArgs, NULL}, X#define SCAN_LISP (&langtab[4]) X{&langtab[5], "lisp", getLispId, setLispArgs, NULL}, X#define SCAN_TEXT (&langtab[5]) X{&langtab[6], "text", getTextId, setTextArgs, NULL}, X#define SCAN_VHIL (&langtab[6]) X{&langtab[7], "vhil", getVhilId, setCArgs, NULL}, X#define SCAN_TEX (&langtab[7]) X{&langtab[8], "tex", getTextId, setTextArgs, "detex -i %s"}, X#define SCAN_ROFF (&langtab[8]) X{&langtab[9], "roff", getTextId, setTextArgs, "sed '/^\\.so/d' < %s | deroff"}, X#define SCAN_CATMAN (&langtab[9]) X{&langtab[10], "catman", getTextId, setTextArgs, "pcat %s | col -b"}, X{ NULL, NULL, NULL, NULL, NULL} X}; X X/* X This is a rather incomplete list of default associations X between suffixes and languages. You may add more to the X default list, or you may define them dynamically with the X `-S=' argument to mkid(1) and idx(1). e.g. to X associate a `.ada' suffix with the Ada language, use X `-S.ada=ada' X*/ Xstruct sufftab sufftab[] = { X{&sufftab[1], ".c", SCAN_C }, X{&sufftab[2], ".h", SCAN_C }, X{&sufftab[3], ".y", SCAN_C }, X{&sufftab[4], ".s", SCAN_ASM }, X{&sufftab[5], ".p", SCAN_PASCAL }, X{&sufftab[6], ".pas", SCAN_PASCAL }, X{&sufftab[7], ".x", SCAN_VHIL }, X{&sufftab[8], ".l", SCAN_C }, /* lex */ X{&sufftab[9], ".doc", SCAN_TEXT }, X{&sufftab[10], ".1", SCAN_ROFF }, X{&sufftab[11], ".tex", SCAN_TEX }, X{&sufftab[12], ".z", SCAN_CATMAN }, X{&sufftab[13], "", SCAN_TEXT }, /* default to text */ X{ NULL, NULL, NULL }, X}; X X/* X Return an index into the langtab array for the given suffix. X*/ Xstatic struct sufftab * XsuffSlot(suffix) X register char *suffix; X{ X register struct sufftab *stp; X X if (suffix == NULL) X suffix = ""; X X for (stp = sufftab; stp->st_next; stp = stp->st_next) X if (strequ(stp->st_suffix, suffix)) X return stp; X return stp; X} X Xstatic struct langtab * XlangSlot(lang) X char *lang; X{ X register struct langtab *ltp; X X if (lang == NULL) X lang = ""; X X for (ltp = langtab; ltp->lt_next; ltp = ltp->lt_next) X if (strequ(ltp->lt_name, lang)) X return ltp; X return ltp; X} X Xchar * XgetLanguage(suffix) X char *suffix; X{ X struct sufftab *stp; X X if ((stp = suffSlot(suffix))->st_next == NULL) X return NULL; X return (stp->st_lang->lt_name); X} X Xchar * XgetFilter(suffix) X char *suffix; X{ X struct sufftab *stp; X X if ((stp = suffSlot(suffix))->st_next == NULL) X return NULL; X return (stp->st_lang->lt_filter); X} X Xchar *(* XgetScanner(lang))() X char *lang; X{ X struct langtab *ltp; X X if ((ltp = langSlot(lang))->lt_next == NULL) X return NULL; X return (ltp->lt_getid); X} X Xstatic void Xusage() X{ X fprintf(stderr, "Usage: %s [-S=] [+S(+|-)] [-S(+|-)] [-S//]\n", MyName); X exit(1); X} Xvoid XsetScanArgs(op, arg) X int op; X char *arg; X{ X struct langtab *ltp, *ltp2; X struct sufftab *stp; X char *lhs, *lhs2; X int count = 0; X X lhs = arg; X while (isalnum(*arg) || *arg == '.') X arg++; X X if (strequ(lhs, "?=?")) { X for (stp = sufftab; stp->st_next; stp = stp->st_next) { X printf("%s%s=%s", (count++>0)?", ":"", stp->st_suffix, stp->st_lang->lt_name); X if (stp->st_lang->lt_filter) X printf(" (%s)", stp->st_lang->lt_filter); X } X if (count) X putchar('\n'); X return; X } X X if (strnequ(lhs, "?=", 2)) { X lhs += 2; X if ((ltp = langSlot(lhs))->lt_next == NULL) { X printf("No scanner for language `%s'\n", lhs); X return; X } X for (stp = sufftab; stp->st_next; stp = stp->st_next) X if (stp->st_lang == ltp) { X printf("%s%s=%s", (count++>0)?", ":"", stp->st_suffix, ltp->lt_name); X if (stp->st_lang->lt_filter) X printf(" (%s)", stp->st_lang->lt_filter); X } X if (count) X putchar('\n'); X return; X } X X if (strequ(arg, "=?")) { X lhs[strlen(lhs)-2] = '\0'; X if ((stp = suffSlot(lhs))->st_next == NULL) { X printf("No scanner assigned to suffix `%s'\n", lhs); X return; X } X printf("%s=%s", stp->st_suffix, stp->st_lang->lt_name); X if (stp->st_lang->lt_filter) X printf(" (%s)",stp->st_lang->lt_filter); X printf("\n"); X return; X } X X if (*arg == '=') { X *arg++ = '\0'; X X if ((ltp = langSlot(arg))->lt_next == NULL) { X fprintf(stderr, "%s: Language undefined: %s\n", MyName, arg); X return; X } X if ((stp = suffSlot(lhs))->st_next == NULL) { X stp->st_suffix = lhs; X stp->st_lang = ltp; X stp->st_next = NEW(struct sufftab); X } else if (!strequ(arg, stp->st_lang->lt_name)) { X fprintf(stderr, "%s: Note: `%s=%s' overrides `%s=%s'\n", MyName, lhs, arg, lhs, stp->st_lang->lt_name); X stp->st_lang = ltp; X } X return; X } else if (*arg == '/') { X *arg++ = '\0'; X if ((ltp = langSlot(lhs))->lt_next == NULL) { X ltp->lt_name = lhs; X ltp->lt_getid = getTextId; X ltp->lt_setargs = setTextArgs; X ltp->lt_filter = NULL; X ltp->lt_next = NEW(struct langtab); X } X lhs2 = arg; X arg = strchr(arg, '/'); X if (arg == NULL) { X ltp2 = ltp; X } else { X *arg++ = '\0'; X if ((ltp2 = langSlot(lhs2))->lt_next == NULL) { X fprintf(stderr,"%s: language %s not defined.\n", MyName, lhs2); X ltp2 = ltp; X } X } X ltp->lt_getid = ltp2->lt_getid; X ltp->lt_setargs = ltp2->lt_setargs; X if ((ltp->lt_filter != NULL) && (!strequ(arg, ltp->lt_filter))){ X fprintf(stderr, "%s: Note: `%s/%s' overrides `%s/%s'\n", MyName, lhs, arg, lhs, ltp->lt_filter); X } X ltp->lt_filter = arg; X return; X } X X if (op == '+') { X switch (op = *arg++) X { X case '+': X case '-': X case '?': X break; X default: X usage(); X } X for (ltp = langtab; ltp->lt_next; ltp = ltp->lt_next) X (*ltp->lt_setargs)(NULL, op, arg); X return; X } X X if (*arg == '-' || *arg == '+' || *arg == '?') { X op = *arg; X *arg++ = '\0'; X X if ((ltp = langSlot(lhs))->lt_next == NULL) { X fprintf(stderr, "%s: Language undefined: %s\n", MyName, lhs); X return; X } X (*ltp->lt_setargs)(lhs, op, arg); X return; X } X X usage(); X} X X/* X Notify user of unimplemented scanners. X*/ Xstatic void XsorryNoScan(lang) X char *lang; X{ X if (lang == NULL) X return; X fprintf(stderr, "Sorry, no scanner is implemented for %s...\n", lang); X} END_OF_FILE if test 7141 -ne `wc -c <'getscan.c'`; then echo shar: \"'getscan.c'\" unpacked with wrong size! fi # end of 'getscan.c' fi if test -f 'scan-c.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'scan-c.c'\" else echo shar: Extracting \"'scan-c.c'\" \(8401 characters\) sed "s/^X//" >'scan-c.c' <<'END_OF_FILE' X/* Copyright (c) 1986, Greg McGary */ X/* Vhil scanning mods added Jan 7th, 1988 by Tom Horsley */ Xstatic char sccsid[] = "@(#)scan-c.c 1.1 86/10/09"; X X#include X#include X#include X#include X Xchar *getCId(); Xchar *getVhilId(); Xvoid setCArgs(); X Xstatic void clrCtype(); Xstatic void setCtype(); X X#define I1 0x0001 /* 1st char of an identifier [a-zA-Z_] */ X#define DG 0x0002 /* decimal digit [0-9] */ X#define NM 0x0004 /* extra chars in a hex or long number [a-fA-FxXlL] */ X#define C1 0x0008 /* C comment introduction char: / */ X#define C2 0x0010 /* C comment termination char: * */ X#define Q1 0x0020 /* single quote: ' */ X#define Q2 0x0040 /* double quote: " */ X#define ES 0x0080 /* escape char: \ */ X#define NL 0x0100 /* newline: \n */ X#define EF 0x0200 /* EOF */ X#define SK 0x0400 /* Make these chars valid for names within strings */ X#define VH 0x0800 /* VHIL comment introduction char: # */ X#define WS 0x1000 /* White space characters */ X X/* X character class membership macros: X*/ X#define ISDIGIT(c) ((rct)[c]&(DG)) /* digit */ X#define ISNUMBER(c) ((rct)[c]&(DG|NM)) /* legal in a number */ X#define ISEOF(c) ((rct)[c]&(EF)) /* EOF */ X#define ISID1ST(c) ((rct)[c]&(I1)) /* 1st char of an identifier */ X#define ISIDREST(c) ((rct)[c]&(I1|DG)) /* rest of an identifier */ X#define ISSTRKEEP(c) ((rct)[c]&(I1|DG|SK)) /* keep contents of string */ X#define ISSPACE(c) ((rct)[c]&(WS)) /* white space character */ X/* X The `BORING' classes should be skipped over X until something interesting comes along... X*/ X#define ISBORING(c) (!((rct)[c]&(EF|NL|I1|DG|Q1|Q2|C1|VH))) /* fluff */ X#define ISCBORING(c) (!((rct)[c]&(EF|C2))) /* comment fluff */ X#define ISVBORING(c) (!((rct)[c]&(EF|NL))) /* vhil comment fluff */ X#define ISQ1BORING(c) (!((rct)[c]&(EF|NL|Q1|ES))) /* char const fluff */ X#define ISQ2BORING(c) (!((rct)[c]&(EF|NL|Q2|ES))) /* quoted str fluff */ X Xstatic short idctype[] = { X X EF, X X /* 0 1 2 3 4 5 6 7 */ X /* ----- ----- ----- ----- ----- ----- ----- ----- */ X X /*000*/ 0, 0, 0, 0, 0, 0, 0, 0, X /*010*/ 0, 0, NL, 0, 0, 0, 0, 0, X /*020*/ 0, 0, 0, 0, 0, 0, 0, 0, X /*030*/ 0, 0, 0, 0, 0, 0, 0, 0, X /*040*/ 0, 0, Q2, 0, 0, 0, 0, Q1, X /*050*/ 0, 0, C2, 0, 0, 0, 0, C1, X /*060*/ DG, DG, DG, DG, DG, DG, DG, DG, X /*070*/ DG, DG, 0, 0, 0, 0, 0, 0, X /*100*/ 0, I1|NM, I1|NM, I1|NM, I1|NM, I1|NM, I1|NM, I1, X /*110*/ I1, I1, I1, I1, I1|NM, I1, I1, I1, X /*120*/ I1, I1, I1, I1, I1, I1, I1, I1, X /*130*/ I1|NM, I1, I1, 0, ES, 0, 0, I1, X /*140*/ 0, I1|NM, I1|NM, I1|NM, I1|NM, I1|NM, I1|NM, I1, X /*150*/ I1, I1, I1, I1, I1|NM, I1, I1, I1, X /*160*/ I1, I1, I1, I1, I1, I1, I1, I1, X /*170*/ I1|NM, I1, I1, 0, 0, 0, 0, 0, X X /*200*/ 0, 0, 0, 0, 0, 0, 0, 0, X /*210*/ 0, 0, 0, 0, 0, 0, 0, 0, X /*220*/ 0, 0, 0, 0, 0, 0, 0, 0, X /*230*/ 0, 0, 0, 0, 0, 0, 0, 0, X /*240*/ 0, 0, 0, 0, 0, 0, 0, 0, X /*250*/ 0, 0, 0, 0, 0, 0, 0, 0, X /*260*/ 0, 0, 0, 0, 0, 0, 0, 0, X /*270*/ 0, 0, 0, 0, 0, 0, 0, 0, X /*300*/ 0, 0, 0, 0, 0, 0, 0, 0, X /*310*/ 0, 0, 0, 0, 0, 0, 0, 0, X /*320*/ 0, 0, 0, 0, 0, 0, 0, 0, X /*330*/ 0, 0, 0, 0, 0, 0, 0, 0, X /*340*/ 0, 0, 0, 0, 0, 0, 0, 0, X /*350*/ 0, 0, 0, 0, 0, 0, 0, 0, X /*360*/ 0, 0, 0, 0, 0, 0, 0, 0, X /*370*/ 0, 0, 0, 0, 0, 0, 0, 0, X X}; X Xstatic bool eatUnder = TRUE; Xstatic bool scanVhil = FALSE; X X/* X*/ Xchar * XgetVhilId(inFILE, flagP) X{ X if (! scanVhil) { X setCArgs("vhil",'+',"v"); X } X return(getCId(inFILE, flagP)); X} X X/* X Grab the next identifier the C source X file opened with the handle `inFILE'. X This state machine is built for speed, not elegance. X*/ Xchar * XgetCId(inFILE, flagP) X FILE *inFILE; X int *flagP; X{ X static char idBuf[BUFSIZ]; X static bool newLine = TRUE; X register short *rct = &idctype[1]; X register int c; X register char *id = idBuf; X Xtop: X c = getc(inFILE); X if (newLine) { X newLine = FALSE; X if (c == '.') { X /* Auto-recognize vhil code when you see a . in column 1. X * also ignore lines that start with a . X */ X if (! scanVhil) { X setCArgs("vhil",'+',"v"); X } X while (ISVBORING(c)) X c = getc(inFILE); X newLine = TRUE; X goto top; X } X if (c != '#') X goto next; X c = getc(inFILE); X if (scanVhil && ISSPACE(c)) { X while (ISVBORING(c)) X c = getc(inFILE); X newLine = TRUE; X goto top; X } X while (ISBORING(c)) X c = getc(inFILE); X if (!ISID1ST(c)) X goto next; X id = idBuf; X *id++ = c; X while (ISIDREST(c = getc(inFILE))) X *id++ = c; X *id = '\0'; X if (strequ(idBuf, "include")) { X while (c == ' ' || c == '\t') c = getc(inFILE) ; X if (c == '\n') {newLine = TRUE; goto top;} X id = idBuf; X if (c == '"') { X c = getc(inFILE); X while (c != '\n' && c != EOF && c != '"') { X *id++ = c; X c = getc(inFILE); X } X *flagP = IDN_STRING; X } else if (c == '<') { X c = getc(inFILE); X while (c != '\n' && c != EOF && c != '>') { X *id++ = c; X c = getc(inFILE); X } X *flagP = IDN_STRING; X } else if (ISID1ST(c)) { X *id++ = c ; X while (ISIDREST(c = getc(inFILE))) *id++ = c; X *flagP = IDN_NAME; X } else { X while (c != '\n' && c != EOF) c = getc(inFILE); X newLine = TRUE; X goto top; X } X while (c != '\n' && c != EOF) c = getc(inFILE) ; X newLine = TRUE; X *id = '\0'; X return idBuf; X } X if (strnequ(idBuf, "if", 2) X || strequ(idBuf, "define") X || strequ(idBuf, "elif") /* ansi C */ X || (scanVhil && strequ(idBuf, "elsif")) X || strequ(idBuf, "undef")) X goto next; X while ((c != '\n') && (c != EOF)) X c = getc(inFILE); X newLine = TRUE; X goto top; X } X Xnext: X while (ISBORING(c)) X c = getc(inFILE); X X switch (c) X { X case '"': X id = idBuf; X *id++ = c = getc(inFILE); X for (;;) { X while (ISQ2BORING(c)) X *id++ = c = getc(inFILE); X if (c == '\\') { X *id++ = c = getc(inFILE); X continue; X } else if (c != '"') X goto next; X break; X } X *--id = '\0'; X id = idBuf; X while (ISSTRKEEP(*id)) X id++; X if (*id || id == idBuf) { X c = getc(inFILE); X goto next; X } X *flagP = IDN_STRING; X if (eatUnder && idBuf[0] == '_' && idBuf[1]) X return &idBuf[1]; X else X return idBuf; X X case '\'': X c = getc(inFILE); X for (;;) { X while (ISQ1BORING(c)) X c = getc(inFILE); X if (c == '\\') { X c = getc(inFILE); X continue; X } else if (c == '\'') X c = getc(inFILE); X goto next; X } X X case '/': X if ((c = getc(inFILE)) != '*') X goto next; X c = getc(inFILE); X for (;;) { X while (ISCBORING(c)) X c = getc(inFILE); X if ((c = getc(inFILE)) == '/') { X c = getc(inFILE); X goto next; X } else if (ISEOF(c)) { X newLine = TRUE; X return NULL; X } X } X X case '\n': X newLine = TRUE; X goto top; X X case '#': X if (! scanVhil) { X /* Auto-recognize vhil when find a # in the middle of a line. X */ X setCArgs("vhil",'+',"v"); X } X c = getc(inFILE); X while (ISVBORING(c)) X c = getc(inFILE); X newLine = TRUE; X goto top; X default: X if (ISEOF(c)) { X newLine = TRUE; X return NULL; X } X name: X id = idBuf; X *id++ = c; X if (ISID1ST(c)) { X *flagP = IDN_NAME; X while (ISIDREST(c = getc(inFILE))) X *id++ = c; X } else if (ISDIGIT(c)) { X *flagP = IDN_NUMBER; X while (ISNUMBER(c = getc(inFILE))) X *id++ = c; X } else X fprintf(stderr, "junk: `\\%3o'", c); X ungetc(c, inFILE); X *id = '\0'; X *flagP |= IDN_LITERAL; X return idBuf; X } X} X Xstatic void XsetCtype(chars, type) X char *chars; X int type; X{ X short *rct = &idctype[1]; X X while (*chars) X rct[*chars++] |= type; X} Xstatic void XclrCtype(chars, type) X char *chars; X int type; X{ X short *rct = &idctype[1]; X X while (*chars) X rct[*chars++] &= ~type; X} X Xextern char *MyName; Xstatic void Xusage(lang) X char *lang; X{ X fprintf(stderr, "Usage: %s does not accept %s scanner arguments\n", MyName, lang); X exit(1); X} Xstatic char *cDocument[] = X{ X"The C scanner arguments take the form -Sc, where ", X"is one of the following: ( denotes one or more characters)", X" (+|-)u . . . . (Do|Don't) strip a leading `_' from ids in strings.", X" -s . . . . Allow in string ids.", X" -v . . . . . . Skip vhil comments.", XNULL X}; Xvoid XsetCArgs(lang, op, arg) X char *lang; X int op; X char *arg; X{ X if (op == '?') { X document(cDocument); X return; X } X switch (*arg++) X { X case 'u': X eatUnder = (op == '+'); X break; X case 's': X setCtype(arg, SK); X break; X case 'v': X setCtype("$", I1); X setCtype("#", VH); X setCtype(" \t", WS); X scanVhil = TRUE; X break; X default: X if (lang) X usage(lang); X break; X } X} END_OF_FILE if test 8401 -ne `wc -c <'scan-c.c'`; then echo shar: \"'scan-c.c'\" unpacked with wrong size! fi # end of 'scan-c.c' fi echo shar: End of archive 6 \(of 11\). cp /dev/null ark6isdone MISSING="" for I in 1 2 3 4 5 6 7 8 9 10 11 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 11 archives. rm -f ark[1-9]isdone ark[1-9][0-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0 -- ====================================================================== domain: tahorsley@csd.harris.com USMail: Tom Horsley uucp: ...!uunet!hcx1!tahorsley 511 Kingbird Circle Delray Beach, FL 33444 +==== Censorship is the only form of Obscenity ======================+ | (Wait, I forgot government tobacco subsidies...) | +====================================================================+