Path: utzoo!utgpu!cs.utexas.edu!usc!wuarchive!rex!uflorida!travis!tom From: tom@ssd.csd.harris.com (Tom Horsley) Newsgroups: alt.sources Subject: mkid 07/11 (identifier cross reference tool) Message-ID: Date: 12 Dec 90 14:45:16 GMT Sender: news@travis.csd.harris.com Organization: Harris Computer Systems Division Lines: 549 #! /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 'iid.y' <<'END_OF_FILE' X%{ X/* This is the yacc definition for the iid command language. X * The main program, scanner, and parser are defined here. X * The utility functions invoked from here are in iidfun.c X */ X X#include "iiddef.h" X X%} X X%union { X set_type * setdef ; X id_type * strdef ; X id_list_type * listdef ; X} X X%token < setdef > SET X X%token < strdef > ID SHELL_QUERY SHELL_COMMAND X X%type < setdef > Query Primitive X X%type < listdef > Lid_group Aid_group Id_list Command_list X X%token LID AID BEGIN SETS SS FILES SHOW HELP OFF MATCH X X%left OR X X%left AND X X%left NOT X X%start Command X X%% X XCommand : X BEGIN ID X { X /* cd to the directory specified as argument, flush sets */ X X SetDirectory($2) ; X FlushSets() ; X } X| Set_query Query X| File_query Query X { X /* print the list of files resulting from Query */ X X PrintSet($2) ; X } X| SHOW SET X { X /* run PAGER on the list of files in SET */ X X RunPager(Pager, $2) ; X } X| SETS X { X /* describe sets created so far */ X X DescribeSets() ; X } X| HELP X { X /* run PAGER on the help file */ X X RunPager(Pager, HelpSet) ; X } X| OFF X { X exit(0) ; X } X| SHELL_QUERY Command_list X { X /* run the shell command and eat the results as a file set */ X X OneDescription(RunProg($1->id, $2)) ; X free($1) ; X } X| SHELL_COMMAND Command_list X { X /* run the shell command */ X X RunShell($1->id, $2) ; X free($1) ; X } X; X XSet_query : X SS X { X /* Turn on verbose query flag */ X X VerboseQuery = TRUE ; X } X; X XFile_query : X FILES X { X /* Turn off verbose query flag */ X X VerboseQuery = FALSE ; X } X; X XQuery : X Primitive X { X /* value of query is set associated with primitive */ X X $$ = $1 ; X } X| Query AND Query X { X /* value of query is intersection of the two query sets */ X X $$ = SetIntersect($1, $3) ; X if (VerboseQuery) { X OneDescription($$) ; X } X } X| Query OR Query X { X /* value of query is union of the two query sets */ X X $$ = SetUnion($1, $3) ; X if (VerboseQuery) { X OneDescription($$) ; X } X } X| NOT Query X { X /* value of query is inverse of other query */ X X $$ = SetInverse($2) ; X if (VerboseQuery) { X OneDescription($$) ; X } X } X; X XPrimitive : X SET X { X /* Value of primitive is value of recorded set */ X X $$ = $1 ; X } X| Lid_group X { X /* Value of primitive is obtained by running an lid query */ X X $$ = RunProg(LidCommand, $1) ; X if (VerboseQuery) { X OneDescription($$) ; X } X } X| Aid_group X { X /* Value of primitive is obtained by running an aid query */ X X $$ = RunProg("aid -kmn", $1) ; X if (VerboseQuery) { X OneDescription($$) ; X } X } X| MATCH Id_list X { X /* Match names from database against pattern */ X $$ = RunProg("pid -kmn", $2) ; X if (VerboseQuery) { X OneDescription($$) ; X } X } X| '(' Query ')' X { X /* value of primitive is value of query */ X X $$ = $2 ; X } X; X XLid_group : X ID X { X /* make arg list holding single ID */ X X $$ = InitList() ; X $$ = ExtendList($$, $1) ; X LidCommand = DefaultCommand ; X } X| LID Id_list X { X /* arg list is Id_list */ X X $$ = $2 ; X LidCommand = "lid -kmn" ; X } X; X XAid_group : X AID Id_list X { X /* arg list is Id_list */ X X $$ = $2 ; X } X; X XCommand_list : X ID X { X /* make arg list holding single ID */ X X $$ = InitList() ; X $$ = ExtendList($$, $1) ; X } X| SET X { X /* make arg list holding names from set */ X X $$ = InitList() ; X $$ = SetList($$, $1) ; X } X| Command_list ID X { X /* extend arg list with additional ID */ X X $$ = ExtendList($1, $2) ; X } X| Command_list SET X { X /* extend arg list with additional file names */ X X $$ = SetList($1, $2) ; X } X; X XId_list : X ID X { X /* make arg list holding single ID */ X X $$ = InitList() ; X $$ = ExtendList($$, $1) ; X } X| Id_list ID X { X /* extend arg list with additional ID */ X X $$ = ExtendList($1, $2) ; X } X; X X%% X X/* ScanLine - a global variable holding a pointer to the current X * command being scanned. X */ Xchar * ScanLine ; X X/* ScanPtr - a global pointer to the current scan position in ScanLine. X */ Xchar * ScanPtr ; X X/* yytext - buffer holding the token. X */ Xchar yytext [ MAXCMD ] ; X X/* yyerror - process syntax errors. X */ Xint Xyyerror(s) X char * s ; X{ X if (*ScanPtr == '\0') { X fprintf(stderr,"Syntax error near end of command.\n") ; X } else { X fprintf(stderr,"Syntax error on or before %s\n",ScanPtr) ; X } X return(0) ; X} X X/* ScanInit - initialize the yylex routine for the new line of input. X * Basically just initializes the global variables that hold the char X * ptrs the scanner uses. X */ Xvoid XScanInit(line) X char * line ; X{ X /* skip the leading white space - the yylex routine is sensitive X * to keywords in the first position on the command line. X */ X X while (isspace(*line)) ++line ; X ScanLine = line ; X ScanPtr = line ; X} X X/* NameEq - compare two names for equality in a case insensitive manner. X * return TRUE for equal, FALSE otherwise. X */ Xint XNameEq(n1,n2) X char * n1 ; X char * n2 ; X{ X char c1 ; X char c2 ; X X for ( ; ; ) { X c1 = *n1++ ; X c2 = *n2++ ; X if (isalpha(c1)) c1 = tolower(c1) ; X if (isalpha(c2)) c2 = tolower(c2) ; X if (c1 != c2) return FALSE ; X if (c1 == '\0') return TRUE ; X } X} X X/* yylex - the scanner for iid. Basically a kludge ad-hoc piece of junk, X * but what the heck, if it works... X * X * Mostly just scans for non white space strings and returns ID for them. X * Does check especially for '(' and ')'. Just before returning ID it X * checks for command names if it is the first token on line or X * AND, OR, LID, AID if it is in the middle of a line. X */ Xint Xyylex() X{ X char * bp ; X char c ; X int code = ID ; X char * dp ; X char * sp ; X int val ; X X bp = ScanPtr ; X while (isspace(*bp)) ++bp ; X sp = bp ; X c = *sp++ ; X if ((c == '(') || (c == ')') || (c == '\0')) { X ScanPtr = sp ; X if (c == '\0') { X --ScanPtr ; X } X return(c) ; X } else { X dp = yytext ; X while (! ((c == '(') || (c == ')') || (c == '\0') || isspace(c))) { X *dp++ = c ; X c = *sp++ ; X } X *dp++ = '\0' ; X ScanPtr = sp - 1 ; X if (bp == ScanLine) { X X /* first token on line, check for command names */ X X if (NameEq(yytext, "SS")) return(SS) ; X if (NameEq(yytext, "FILES")) return(FILES) ; X if (NameEq(yytext, "F")) return(FILES) ; X if (NameEq(yytext, "HELP")) return(HELP) ; X if (NameEq(yytext, "H")) return(HELP) ; X if (NameEq(yytext, "?")) return(HELP) ; X if (NameEq(yytext, "BEGIN")) return(BEGIN) ; X if (NameEq(yytext, "B")) return(BEGIN) ; X if (NameEq(yytext, "SETS")) return(SETS) ; X if (NameEq(yytext, "SHOW")) return(SHOW) ; X if (NameEq(yytext, "P")) return(SHOW) ; X if (NameEq(yytext, "OFF")) return(OFF) ; X if (NameEq(yytext, "Q")) return(OFF) ; X if (NameEq(yytext, "QUIT")) return(OFF) ; X if (yytext[0] == '!') { X code = SHELL_COMMAND ; X } else { X code = SHELL_QUERY ; X } X } else { X X /* not first token, check for operator names */ X X if (NameEq(yytext, "LID")) return(LID) ; X if (NameEq(yytext, "AID")) return(AID) ; X if (NameEq(yytext, "AND")) return(AND) ; X if (NameEq(yytext, "OR")) return(OR) ; X if (NameEq(yytext, "NOT")) return(NOT) ; X if (NameEq(yytext, "MATCH")) return(MATCH) ; X if ((yytext[0] == 's' || yytext[0] == 'S') && isdigit(yytext[1])) { X X /* this might be a set specification */ X X sp = &yytext[1] ; X val = 0 ; X for ( ; ; ) { X c = *sp++ ; X if (c == '\0') { X if (val < NextSetNum) { X yylval.setdef = TheSets[val] ; X return(SET) ; X } X } X if (isdigit(c)) { X val = (val * 10) + (c - '0') ; X } else { X break ; X } X } X } X } X yylval.strdef = (id_type *)malloc(sizeof(id_type) + strlen(yytext)) ; X if (yylval.strdef == NULL) { X fatal("Out of memory in yylex") ; X } X yylval.strdef->next_id = NULL ; X if (code == SHELL_COMMAND) { X strcpy(yylval.strdef->id, &yytext[1]) ; X } else { X strcpy(yylval.strdef->id, yytext) ; X } X return(code) ; X } X} X X/* The main program for iid - parse the command line, initialize processing, X * loop processing one command at a time. X */ Xmain(argc, argv) X int argc ; X char * argv [ ] ; X{ X int c ; /* current option */ X char * CmdPtr ; /* Points to the command string */ X char Command [ MAXCMD ] ; /* Buffer for reading commands */ X int Do1 = FALSE ; /* TRUE if should only do 1 command */ X int DoPrompt ; /* TRUE if should write a prompt */ X int errors = 0 ; /* error count */ X X DoPrompt = isatty(fileno(stdin)) ; X while ((c = getopt(argc, argv, "Hac:")) != EOF) { X switch(c) { X case 'a': X DefaultCommand = "aid -kmn" ; X break ; X case 'c': X CmdPtr = optarg ; X Do1 = TRUE ; X break ; X case 'H': X fputs("\ Xiid: interactive ID database query tool. Call with:\n\ X iid [-a] [-c] [-H]\n\ X\n\ X-a\tUse the aid as the default query command (not lid).\n\ X-c cmd\tExecute the single query cmd and exit.\n\ X-H\tPrint this message and exit.\n\ X\n\ XTo get help after starting program type 'help'.\n\ X",stderr) ; X exit(0) ; X default: X ++errors ; X break ; X } X } X if (argc != optind) { X fputs("iid: Excess arguments ignored.\n",stderr) ; X ++errors ; X } X if (errors) { X fputs("run iid -H for help.\n",stderr) ; X exit(1) ; X } X X /* initialize global data */ X X InitIid() ; X X /* run the parser */ X X if (Do1) { X ScanInit(CmdPtr) ; X exit(yyparse()) ; X } else { X for ( ; ; ) { X if (DoPrompt) { X fputs(Prompt, stdout) ; X fflush(stdout) ; X } X gets(Command) ; X if (feof(stdin)) { X if (DoPrompt) fputs("\n", stdout) ; X strcpy(Command, "off") ; X } X ScanInit(Command) ; X errors += yyparse() ; X } X } X} END_OF_FILE if test 11278 -ne `wc -c <'iid.y'`; then echo shar: \"'iid.y'\" unpacked with wrong size! fi # end of 'iid.y' fi echo shar: End of archive 7 \(of 11\). cp /dev/null ark7isdone 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...) | +====================================================================+