Annotation of researchv10no/cmd/prefer/pref/prefer.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * prefer - bibligraphy formatter
                      3:  *
                      4:  *     Marcia Derr
                      5:  *     February 26, 1988
                      6:  *
                      7:  *     input:  (stdin) text containing prefer commands;
                      8:  *     output: (stdout) text with formatted citations and reference list
                      9:  */
                     10: 
                     11: 
                     12: 
                     13: #include       <stdio.h>
                     14: #include       <ctype.h>
                     15: #include       <signal.h>
                     16: #include       <sys/types.h>
                     17: #include       <sys/stat.h>
                     18: 
                     19: #ifdef SVR2                    /* for UNIX System V */ 
                     20: #include       <fcntl.h>
                     21: #define        dup2(fildes, fildes2) close(fildes2);fcntl(fildes, F_DUPFD, fildes2)
                     22: #endif
                     23: 
                     24: #include       "streams.h"
                     25: #include       "bib.h"
                     26: 
                     27: 
                     28: /* prefer commands */
                     29: #define                REF_CITE        "reference"
                     30: #define                REF_STYLE       "reference_style"
                     31: #define                REF_PLACE       "reference_placement"
                     32: #define                REF_LIST        "reference_list"
                     33: #define                REF_DB          "reference_database"
                     34: #define                REF_INCLUDE     "reference_include"
                     35: 
                     36: /* control words to awk */
                     37: #define                LETS_GO         "%LETS_GO"
                     38: #define                BEGIN_CITE      "%BEGIN_CITE"
                     39: #define                END_CITE        "%END_CITE"
                     40: #define                END_LIST        "%END_LIST"
                     41: #define                BIBLIO          "%BIBLIO"
                     42: #define                WHOLEBIB        "%WHOLEBIB"
                     43: #define                DBINCLUDE       "%DBINCLUDE"
                     44: #define                TYPE            "%type"
                     45: #define                TWOPASS         "%TWOPASS\n"
                     46: #define                ALSO            "%also"
                     47: #define                ALSOBEGIN       "%also_begin"
                     48: #define                ALSOEND         "%also_end"
                     49: 
                     50: #define                DSTYLE          "att"           /* default style */
                     51: #define                STYLEDIR        "/styles/"      /* style directory */
                     52: #define                AWK             "prefawk"       /* special awk version */
                     53: 
                     54: #define                PREFERTMP       "/tmp/preferXXXXXX"
                     55: #define                MAXTOK          2500
                     56: #define                BAR             '|'
                     57: #define                SLASH           "/"
                     58: 
                     59: 
                     60: char   stylename[maxstr] = "",         /* set by style(), options */
                     61:        awkline[MAXTOK];                /* for passing to/from awk */
                     62: 
                     63: FILE   *readtext,              /* input text */
                     64:        *writetext,             /* output text */
                     65:        *readbib,               /* from awk */
                     66:        *writebib,              /* to awk */
                     67:        *savefile;              /* save original file when diverting to temp */
                     68: 
                     69: int    nroff = 0;              /* nroff/troff flag */
                     70: int    prmult = 0;             /* print multiple references */
                     71: int    rp = 0;                 /* released_paper/tm flag */
                     72: int    sort = 0;               /* order flag for reference_list */
                     73: char   sortkey[maxstr] = "";   /* sort keys (eg adt) */
                     74: int    haveeof = 0;            /* flag eof in input file */
                     75: 
                     76: char    INDEX[maxstr];         /* name of index file */
                     77: char   *DINPUT = BIBFILE;      /* default input file */
                     78: char   *divertname;            /* two pass output is diverted here */
                     79: int    pass = 0;               /* indicates how many text passes are required */
                     80: 
                     81: int     argc;
                     82: char    **argv;
                     83: 
                     84: typedef enum {T_OPEN, T_CLOSE, T_COMMAND, T_REFER, T_WORD, T_EOF} TOKEN;
                     85: typedef enum {NORMAL, END, BIBLIST} bibflag;
                     86:        enum {OK, NONE} awkstate = NONE;
                     87: 
                     88: 
                     89: char   tok[MAXTOK];                    /* for get_token */
                     90: TOKEN  type;                           /* type returned by get_token */
                     91: char   right;                          /* expected right delimeter */
                     92: 
                     93: int    cleanup();
                     94: char   *strchr();
                     95: char   *libpath();
                     96: TOKEN  get_token();
                     97: char   *mktemp(),
                     98:        *locate(),
                     99:        *gulpnl(),
                    100:        *realloc(),
                    101:        *strtok();
                    102: 
                    103: #define        leftdelim {                                                             \
                    104:        if((type = get_token(tok,0)) != T_OPEN) {                               \
                    105:                token_err(type,"Expecting left delimiter, got %s\n",tok);       \
                    106:        }                                                                       \
                    107:        right = getright(*tok);                                                 \
                    108: }
                    109: 
                    110: #define        rightdelim {                                                            \
                    111:        if (type != T_CLOSE)                                                    \
                    112:                token_err(type,"Expecting right delimeter, got %s\n",tok);      \
                    113:        post_command();                                                 \
                    114: }
                    115: 
                    116: 
                    117: #define USAGE  "prefer [-p database -s style -n -o key -r] [filename]\n"
                    118: 
                    119: #ifdef _NFILE
                    120: #define        FILENUM _NFILE
                    121: #else
                    122: #define        FILENUM 20
                    123: #endif
                    124: 
                    125: 
                    126: 
                    127: /*
                    128:  * main - process prefer command line 
                    129:  */
                    130: 
                    131: main(argcount,arglist)
                    132: int argcount;
                    133: char **arglist;
                    134: {
                    135: 
                    136: /*
                    137:  * set up signals, get options flags, and process command line arguments;
                    138:  * make path names;  setup I/O
                    139:  */    
                    140:        if(signal(SIGINT, SIG_IGN) != SIG_IGN)
                    141:                signal(SIGINT, cleanup);
                    142:        signal(SIGQUIT, cleanup);
                    143:        argc= argcount-1;
                    144:        argv= arglist+1;
                    145: 
                    146:        strcpy(stylename,DSTYLE);
                    147:        strcpy(INDEX,DINPUT);
                    148: 
                    149:        flags();
                    150:        strcat(INDEX,".i");
                    151: 
                    152:        switch(argc) {
                    153:        case 0:
                    154:                readtext = stdin;
                    155:                break;
                    156:        case 1:
                    157:                if((readtext = fopen(*argv,"r")) == NULL)
                    158:                        errexit(1,"error opening textfile %s\n",*argv);
                    159:                break;
                    160:        default:
                    161:                errexit(1,USAGE);
                    162:        }
                    163:        writetext = stdout;
                    164: 
                    165: /*
                    166:  * now filter text for prefer commands
                    167:  */
                    168:        scan_text();
                    169:        exit(0);
                    170: 
                    171: }
                    172: 
                    173: 
                    174: /*
                    175:  * get option flags
                    176:  *
                    177:  * -n  set nroff flag (default troff)
                    178:  * -o  set sort flag for listing entire bibliographies (default sequence)
                    179:  * -p  pathname of database file (default BIBFILE)
                    180:  * -r  set rp (released paper) flag (default tm)
                    181:  * -s  set style (default att)
                    182:  */
                    183: 
                    184: # define    operand     (strlen(*argv+2)==0 ? (argv++,argc--,*argv) : *argv+2)
                    185: 
                    186: flags()
                    187: {   
                    188:     for (; argc>0 && *argv[0]=='-';  argc--,argv++) {
                    189:        switch ((*argv)[1]) {   
                    190:            case 'c':
                    191:            case 'l':   fprintf(stderr,USAGE);
                    192:                        break;
                    193:        case 'm':       prmult = 1;
                    194:                        break;
                    195:            case 'n':   nroff = 1;
                    196:                        break;
                    197:            case 'o':   sort = 1;
                    198:                        strcpy(sortkey,operand);
                    199:                        break;
                    200:             case 'p':   strcpy(INDEX,operand);
                    201:                         break;
                    202:            case 'r':   rp = 1;
                    203:                        break;
                    204:            case 's':   strcpy(stylename,operand);
                    205:                        break;
                    206:             default:    errexit(1, USAGE);
                    207:         }
                    208:     }
                    209: }
                    210: 
                    211: 
                    212: /*
                    213:  * scan_text
                    214:  *
                    215:  * filter text for prefer commands (beginning with '|') and pass
                    216:  * these off to do_command
                    217:  */
                    218: 
                    219: scan_text()
                    220: {
                    221:        register int c, lastc;
                    222:        char space[maxstr];
                    223: 
                    224:        lastc = 0;
                    225:        for(;;) {
                    226: 
                    227:        /*
                    228:         * if EOF, put out last saved character and space;
                    229:         * finish processing references; close awk
                    230:         */
                    231:                if((c = gobble(space)) == EOF) {
                    232:                        if(lastc) putc(lastc,writetext);
                    233:                        lastc = 0;
                    234:                        if(*space) fputs(space, writetext);
                    235:                        if(awkstate == OK) {
                    236:                                biblio(END);
                    237:                                continue;
                    238:                        }
                    239:                        break;
                    240:                }
                    241: 
                    242:        /*
                    243:         * if a '|' then call do_command to process it
                    244:         */
                    245:                if(c == BAR) {
                    246: 
                    247:                        /* checkfor preceding punctuation */
                    248: 
                    249:                        if(lastc == 0134 && !*space) {  /* backslash */
                    250:                                putc(lastc,writetext);
                    251:                                lastc = c;
                    252:                                continue;
                    253:                        }
                    254:                        if(!ismypunct(lastc)) {
                    255:                                if(lastc) {
                    256:                                        putc(lastc,writetext);
                    257:                                        lastc = 0;
                    258:                                }
                    259:                        }
                    260:                        do_command(lastc,space);
                    261:                        lastc = 0;
                    262:                        continue;
                    263:                }
                    264: 
                    265:                if(lastc) putc(lastc,writetext);
                    266:                if(*space) fputs(space,writetext);
                    267:                lastc = c;
                    268:        }
                    269:        if(awkstate != NONE)
                    270:                awkclose(readbib,writebib);
                    271: }
                    272: 
                    273: 
                    274: /*
                    275:  * parse and execute prefer commands:
                    276:  *     |reference(...)
                    277:  *     |reference_style(..)
                    278:  *     |reference_database(...)
                    279:  *     |reference_list(...)
                    280:  *     |reference_placement
                    281:  */
                    282: 
                    283: do_command(ppunc,white)
                    284: int ppunc;     /* punctuation preceding command */
                    285: char *white;   /* white space preceding command */
                    286: {
                    287:        register  int   cite_list,      /* flag "in a citation list" */
                    288:                        c;              /* for reading characters */
                    289:        char            space[maxstr];  /* gobbled space goes here */
                    290: 
                    291: /*
                    292:  * '|' has already been read; now read command and dispatch
                    293:  */
                    294:        cite_list = 0;
                    295:        for(;;) {
                    296: 
                    297:        /*
                    298:         * if space after BAR; finish citation list put out white space and punc
                    299:         */
                    300:                c=gobble(space);
                    301:                if(*space) {
                    302:                        if(cite_list) {
                    303:                                end_citations(ppunc);
                    304:                        }
                    305:                        else {
                    306:                                if(ppunc) putc(ppunc,writetext);
                    307:                                if(*white) fputs(white,writetext);
                    308:                        }
                    309:                        putc(BAR,writetext);
                    310:                        fputs(space,writetext);
                    311:                        if(c != EOF) ungetc(c,readtext);
                    312:                        return;
                    313:                }
                    314:        /*
                    315:         * at EOF, put out any citation list
                    316:         */
                    317:                if(c == EOF) {
                    318:                        if(cite_list) { 
                    319:                                end_citations(ppunc);
                    320:                                cite_list == 0;
                    321:                        }
                    322:                        putc(BAR,writetext);
                    323:                        return;
                    324:                }
                    325:                else
                    326:                        ungetc(c,readtext);
                    327:                        
                    328: 
                    329:        /*
                    330:         * process one or more citations
                    331:         */
                    332:                get_token(tok,0);
                    333:                if(strcmp(tok,REF_CITE) == 0) {
                    334:                        *white = NULL;
                    335:                        citation();
                    336:                        cite_list = 1;
                    337:                        if((c = gobble(white)) == BAR)
                    338:                                continue;
                    339:                        else if (*white || !ismypunct(c)) {
                    340:                                end_citations(ppunc);
                    341:                                if(*white) fputs(white,writetext);
                    342:                                if(c != EOF) ungetc(c,readtext);
                    343:                        }
                    344:                        else {
                    345:                                if(ppunc) putc(ppunc,writetext);
                    346:                                end_citations(c);
                    347:                        }
                    348:                        return;
                    349:                }
                    350:        
                    351:        /*
                    352:         * end a list of citations or if no citation, put out punctuation
                    353:         * and white space
                    354:         */
                    355:                if(cite_list)  end_citations(ppunc);
                    356:                else if (ppunc) putc(ppunc,writetext);
                    357:                if (*white) {
                    358:                        fputs(white,writetext);
                    359:                }
                    360:                        
                    361: 
                    362:        /*
                    363:         * process style, placement, list, or db commands
                    364:         */
                    365:                if(strcmp(tok,REF_STYLE) == 0) {
                    366:                        style();
                    367:                        return;
                    368:                }
                    369: 
                    370:                else if(strcmp(tok,REF_PLACE) == 0) {
                    371:                        if(awkstate == OK) biblio(NORMAL);
                    372:                        if(pass != 2) post_command();
                    373:                        return;
                    374:                }
                    375: 
                    376:                else if(strcmp(tok,REF_LIST) == 0) {
                    377:                        bib_list();
                    378:                        return;
                    379:                }
                    380: 
                    381:                else if(strcmp(tok,REF_INCLUDE) == 0) {
                    382:                        dbinclude();
                    383:                        return;
                    384:                }
                    385: 
                    386:                else if(strcmp(tok,REF_DB) == 0) {
                    387:                        database();
                    388:                        return;
                    389:                }
                    390: 
                    391:        /*
                    392:         * no command so, put out bar and token
                    393:         */
                    394:                else {
                    395:                        putc(BAR,writetext);
                    396:                        fputs(tok,writetext);
                    397:                        return;
                    398:                }
                    399:        }
                    400: 
                    401: }
                    402: 
                    403: 
                    404: /*
                    405:  * ismypunct - test for puctuation
                    406:  */
                    407: 
                    408: ismypunct(c)
                    409: int c;
                    410: {
                    411:        switch(c) {
                    412:        case '.':
                    413:        case ',':
                    414:        case ';':
                    415:        case ':':
                    416:        case '?':
                    417:        case '!':
                    418:        case '"':
                    419:        case '\'':
                    420:        case '(':
                    421:                return(1);
                    422:        default:
                    423:                return(0);
                    424:        }
                    425: }
                    426: 
                    427: 
                    428: /*
                    429:  * getright - given right delimeter, return left
                    430:  */
                    431: 
                    432: getright(left)
                    433: char left;
                    434: {
                    435:        switch(left) {
                    436:        case '(':
                    437:                return(')');
                    438:        case '{':
                    439:                return('}');
                    440:        case '[':
                    441:                return(']');
                    442:        case '<':
                    443:                return('>');
                    444:        }
                    445:        return(0);
                    446: }
                    447: 
                    448: 
                    449: /*
                    450:  * gobble - gobble up space to the the next non-space character
                    451:  *     return space and char
                    452:  */
                    453: 
                    454: gobble(space)
                    455: char *space;                   /* gobbled space returned here */
                    456: {
                    457:        register int c;         /* non-space character returned here */
                    458:        register char *t;
                    459: 
                    460:        t = space;
                    461:        while(isspace(c = mygetc(readtext))) {
                    462:                *t++ = c;
                    463:        }
                    464:        *t = '\0';
                    465:        return(c);
                    466: }
                    467: 
                    468: /*
                    469:  * gulp string up thru newline 
                    470:  */
                    471: 
                    472: char *
                    473: gulpnl(space)
                    474: char *space;
                    475: {
                    476:        register char *w;
                    477:        for(w=space; *w;) {
                    478:                if(*w++ == '\n')
                    479:                        break;
                    480:        }
                    481:        return(w);
                    482: }              
                    483: 
                    484: 
                    485: post_command()
                    486: {
                    487:        register int c;         /* non-space character returned here */
                    488:        while((c = mygetc(readtext)) != EOF) {
                    489:                if (c == '\n')
                    490:                        break;
                    491:                else if(!isspace(c)) {
                    492:                        errexit(1,"prefer command must end with newline\n");
                    493:                }
                    494:        }
                    495: }
                    496:        
                    497: /*
                    498:  * token
                    499:  *
                    500:  * tokenizer - returns:
                    501:  *     T_COMMAND       anything after a |
                    502:  *     T_REFER         a line starting with % to next % or right delim
                    503:  *     T_WORDS         anthing
                    504:  *     T_OPEN          left delimeter
                    505:  *     T_CLOSE         right delimeter
                    506:  *     T_WORD          anything else (non-space)
                    507:  */
                    508: 
                    509: TOKEN
                    510: get_token(value,right)
                    511: char *value;                   /* token value */
                    512: char right;                    /* expected right delimeter */
                    513: {
                    514:        register int c;         /* current character */
                    515:        register char *v;       /* current position in *value */
                    516:                                /* state of tokenizer */
                    517: 
                    518:        enum {BEGIN, ANYTHING, REFER, COMMAND, WORD, ENDREFER, CONTINUE} state;
                    519: 
                    520: 
                    521:        if(right == 0) state = BEGIN;
                    522:        else state = ANYTHING;
                    523:        v = value;
                    524: 
                    525:        while((c = mygetc(readtext)) != EOF) {
                    526:                switch(state) {
                    527: 
                    528:                case BEGIN:
                    529:                        switch(c) {
                    530:                        case '|':
                    531:                                *v = '\0';
                    532:                                ungetc(c,readtext);
                    533:                                return(T_COMMAND);
                    534:                        case '(':
                    535:                        case '[':
                    536:                        case '{':
                    537:                        case '<':
                    538:                                *v++ = c;
                    539:                                *v = '\0';
                    540:                                return(T_OPEN);
                    541:                        case ' ':
                    542:                        case '\n':
                    543:                        case '\t':
                    544:                                continue;
                    545:                        default:
                    546:                                *v++ = c;
                    547:                                state = COMMAND;
                    548:                                continue;
                    549:                        }
                    550: 
                    551:                case ANYTHING:
                    552:                        switch(c) {
                    553:                        case ' ':
                    554:                        case '\n':
                    555:                        case '\t':
                    556:                                continue;
                    557:                        case '%':
                    558:                                *v++ = c;
                    559:                                state = REFER;
                    560:                                continue;
                    561:                        case ')':
                    562:                        case ']':
                    563:                        case '}':
                    564:                        case '>':
                    565:                                if(c == right) {
                    566:                                        *v++ = c;
                    567:                                        *v = '\0';
                    568:                                        return(T_CLOSE);
                    569:                                }
                    570:                        default:
                    571:                                *v++ = c;
                    572:                                state = WORD;
                    573:                                continue;
                    574:                        }
                    575:                
                    576:                                        
                    577:                case COMMAND:
                    578:                        switch(c) {
                    579:                        case '|':
                    580:                        case ' ':
                    581:                        case '\n':
                    582:                        case '\t':
                    583:                        case '(':
                    584:                        case '[':
                    585:                        case '{':
                    586:                        case '<':
                    587:                                *v = '\0';
                    588:                                ungetc(c,readtext);
                    589:                                return(T_COMMAND);
                    590:                        default:
                    591:                                *v++ = c;
                    592:                                continue;
                    593:                        }
                    594:        
                    595: 
                    596:                case WORD:
                    597:                        switch(c) {
                    598:                        case ' ':
                    599:                        case '\n':
                    600:                        case '\t':
                    601:                        case '%':
                    602:                                *v = '\0';
                    603:                                ungetc(c,readtext);
                    604:                                return(T_WORD);
                    605:                        case ')':
                    606:                        case ']':
                    607:                        case '}':
                    608:                        case '>':
                    609:                                if(c == right) {
                    610:                                        *v = '\0';
                    611:                                        ungetc(c,readtext);
                    612:                                        return(T_WORD);
                    613:                                }
                    614:                        default:
                    615:                                *v++ = c;
                    616:                                continue;
                    617:                        }
                    618:                        
                    619: 
                    620:                case REFER:
                    621:                        switch(c) {
                    622:                        case '\n':
                    623:                                state = ENDREFER;
                    624:                                continue;
                    625:                        case '\\':
                    626:                                state = CONTINUE;
                    627:                                continue;
                    628:                        case ')':
                    629:                        case ']':
                    630:                        case '}':
                    631:                        case '>':
                    632:                                if(c == right) {
                    633:                                        *v++ = '\n';
                    634:                                        *v = '\0';
                    635:                                        ungetc(c,readtext);
                    636:                                        return(T_REFER);
                    637:                                }
                    638:                        default:
                    639:                                *v++ = c;
                    640:                                continue;
                    641:                        }
                    642: 
                    643:                case CONTINUE:
                    644:                        state = REFER;
                    645:                        if(c != '\n') {
                    646:                                *v++ = '\\';
                    647:                                *v++ = c;
                    648:                        }
                    649:                        continue;
                    650:                                
                    651: 
                    652:                case ENDREFER:
                    653:                        ungetc(c,readtext);
                    654:                        if(c == '%') {
                    655:                                *v++ = '\n';
                    656:                                *v = '\0';
                    657:                                return(T_REFER);
                    658:                        }
                    659:                        if(!isspace(c)) *v++ = ' ';
                    660:                        state = REFER;
                    661:                        continue;
                    662:                }
                    663:        }
                    664:        haveeof++;
                    665:        return(T_EOF);
                    666: }
                    667: 
                    668: 
                    669: /*
                    670:  * token_err - print error message and exit
                    671:  */ 
                    672: 
                    673: token_err(type,s,tok)
                    674: TOKEN type;            /* token type in error */
                    675: char   *s,             /* error message */
                    676:        *tok;           /* error token */
                    677: {
                    678:        if(type == T_EOF)
                    679:                errexit(1, "Unexpected EOF\n");
                    680:        else
                    681:                errexit(1,s,tok);
                    682: }
                    683: 
                    684: 
                    685: /*
                    686:  * start_awk
                    687:  * open awk and handshake to determine one pass or two
                    688:  * (listing an entire bibliography is always one pass)
                    689:  */
                    690: 
                    691: start_awk(bflag)
                    692: bibflag bflag;                 /* flag complete bibliography listing (as 
                    693:                                        to normal citations and reference list */
                    694: {
                    695:        char awkcmd[maxstr];    /* line to send to awk */
                    696:        struct stat buf;        /* for stating style file */
                    697: 
                    698: /*
                    699:  * open up awk style script
                    700:  * checking to see style is one of the standards or user supplied
                    701:  */
                    702: 
                    703:        strcpy(awkcmd,stylename);
                    704:        if(stat(awkcmd,&buf)) {
                    705:                strcpy(awkcmd,libpath(PLIB));
                    706:                strcat(awkcmd,STYLEDIR);
                    707:                strcat(awkcmd,stylename);
                    708:        }
                    709:        awkopen(awkcmd,&readbib,&writebib);
                    710: 
                    711: 
                    712: /*
                    713:  * handshake, sending appropriate flags
                    714:  */
                    715:        fputs(LETS_GO,writebib);
                    716:        if(nroff)
                    717:                fputs(" nroff",writebib);
                    718:        else
                    719:                fputs(" troff",writebib);
                    720:        if(rp)
                    721:                fputs(" rp",writebib);
                    722:        else
                    723:                fputs(" tm",writebib);
                    724:        putc('\n',writebib);
                    725:        fflush(writebib);
                    726: 
                    727: /*
                    728:  * read back flag from awk that tells 1 pass or 2;
                    729:  * divert text to temp file if two pass
                    730:  */
                    731:        if(fgets(awkcmd,maxstr,readbib) == NULL)
                    732:                errexit(1,"start_awk: EOF or error from awk\n");
                    733:        if(strcmp(awkcmd,TWOPASS) == 0) {
                    734:                if(bflag != BIBLIST) {
                    735:                        pass = 1;
                    736:                        savefile = writetext;
                    737:                        divertname = mktemp(PREFERTMP);
                    738:                        writetext = fopen(divertname,"w");
                    739:                }
                    740:        }
                    741:        else pass = 0;
                    742:        awkstate = OK;
                    743: }
                    744: 
                    745: 
                    746: /*
                    747:  * citation - process |reference():
                    748:  *     use search keys to lookup a complete reference in a bibliographic
                    749:  *     database; supplement citation with additional %refer lines;
                    750:  *     send all this to an awk for formatting
                    751:  */
                    752: 
                    753: citation()
                    754: {
                    755:        char    keys[MAXTOK];           /* store keys here */
                    756:        int missing;                    /* missing flag */
                    757: 
                    758: /*
                    759:  * signal start of citation to awk
                    760:  */
                    761:        if(awkstate != OK) start_awk(NORMAL);
                    762:        missing = 0;
                    763:        if(pass != 2) {
                    764:                fputs(BEGIN_CITE,writebib);
                    765:                putc('\n',writebib);
                    766:        }
                    767: 
                    768: /*
                    769:  * after left delmeter, get keys and search for corresponding reference
                    770:  */
                    771:        leftdelim;
                    772:        *keys = '\0';
                    773:        while((type = get_token(tok,right)) == T_WORD ) {
                    774:                strcat(keys,tok);
                    775:                strcat(keys," ");
                    776:        }
                    777:        if(*keys != '\0') {
                    778:                missing = getref(keys);
                    779:        }
                    780: 
                    781: /*
                    782:  * send %lines to awk to supplement citation
                    783:  */
                    784:        if(type == T_REFER) {
                    785:                refline();
                    786:                while((type = get_token(tok,right)) == T_REFER) {
                    787:                        refline();
                    788:                }
                    789:        }
                    790: 
                    791: /*
                    792:  * get right delimeter and signal the end of citation
                    793:  */
                    794:        if (type != T_CLOSE)
                    795:                token_err(type,"Expecting right delimeter, got %s\n",tok);
                    796: 
                    797:        fputs(END_CITE,writebib);
                    798:        if (pass == 2)
                    799:                putc('2',writebib);
                    800:        putc('\n',writebib);
                    801:        fflush(writebib);
                    802: 
                    803:                /* if two pass, write marker in diverted text */
                    804: 
                    805:        if(pass == 1 && missing == 0)
                    806:                fprintf(writetext,"|%s[]",REF_CITE);
                    807: }
                    808: 
                    809: 
                    810: /*
                    811:  * pass a %refline to awk, processing %also lines appropriately
                    812:  */
                    813: 
                    814: refline()
                    815: {
                    816:        if(strncmp(ALSOBEGIN,tok,strlen(ALSOBEGIN)) == 0) {
                    817:                fputs(tok,writebib);
                    818:                while((type = get_token(tok,right)) == T_REFER) {
                    819:                        if(strncmp(ALSOEND,tok,strlen(ALSOEND)) == 0) {
                    820:                                fputs(tok,writebib);
                    821:                                fflush(writebib);
                    822:                                break;
                    823:                        }
                    824:                        else if(strncmp(ALSO,tok,strlen(ALSO)) == 0)
                    825:                                seealso(tok);
                    826:                        else fputs(tok,writebib);
                    827:                }
                    828:        }
                    829:        else if(strncmp(ALSO,tok,strlen(ALSO)) == 0) {
                    830:                fputs(ALSOBEGIN,writebib);
                    831:                putc('\n',writebib);
                    832:                seealso(tok);
                    833:                fputs(ALSOEND,writebib);
                    834:                putc('\n',writebib);
                    835:                fflush(writebib);
                    836:        }
                    837:        else
                    838:                fputs(tok,writebib);
                    839: }
                    840: 
                    841: 
                    842: /*
                    843:  * get reference corresponding to keywords and send it to awk
                    844:  */
                    845: 
                    846: int
                    847: getref(keys)
                    848: char *keys;
                    849: {
                    850:        char    *ref;                   /* points to complete reference */
                    851: 
                    852:        if((ref = locate(keys, INDEX)) == NULL) {
                    853:                fprintf(stderr,"Can't open database for %s\n",keys);
                    854:                fprintf(writebib,"%s not_found\n",TYPE);
                    855:                return(1);
                    856:        }
                    857:        if(*ref != NULL) {
                    858:                if(multiple(ref)) {
                    859:                        fprintf(stderr,"multiple references for %s\n",keys);
                    860:                }
                    861:                refwrite(ref);
                    862:                free(ref);
                    863:                return(0);
                    864:  
                    865:        }
                    866:        else {
                    867:                fprintf(stderr,"no reference found for %s\n",keys);
                    868:                fprintf(writebib,"%s not_found\n",TYPE);
                    869:                free(ref);
                    870:                return(1);
                    871:        }
                    872: }
                    873: 
                    874: 
                    875: /*
                    876:  * check for multiple new references signalled by two newlines in a row
                    877:  */
                    878: 
                    879: multiple(ref)
                    880: char *ref;
                    881: {
                    882:        register char *s;
                    883: 
                    884:        for(s = ref; *s; s++) {
                    885:                if (*s == '\n') {
                    886:                        if(strncmp(s,"\n\n%",3) == 0) {
                    887:                        if(prmult) fprintf(stderr, "multiple references>>%s<<\n", ref);
                    888:                                *(++s) = '\0';
                    889:                                return(1);
                    890:                        }
                    891:                }
                    892:        }
                    893:        return(0);
                    894: }
                    895: 
                    896: /*
                    897:  * refwrite - write out a single reference to awk
                    898:  */ 
                    899: 
                    900: 
                    901: refwrite(ref)
                    902: char *ref;
                    903: {
                    904:        register char *s, c;
                    905:        char *t, sav;
                    906:        int also;
                    907: 
                    908:        also = 0;
                    909:        for(s = ref; *s; s++) {
                    910:                if(*s == '\n') {
                    911:                        c = *(s+1);
                    912:                        if((c  != '%') && c) {
                    913:                                if(!isspace(c)) {
                    914:                                        fputc(' ',writebib);
                    915:                                        continue;
                    916:                                }
                    917:                                continue;
                    918:                        }
                    919:                }
                    920:                if(*s == '%') {
                    921:                        if(strncmp(ALSOBEGIN,s,strlen(ALSOBEGIN)) == 0)
                    922:                                also++;
                    923:                        else if(strncmp(ALSOEND,s,strlen(ALSOEND)) == 0)
                    924:                                also--;
                    925:                        else if(strncmp(ALSO,s,strlen(ALSO)) == 0) {
                    926:                                for(t = s+1; *t && *t != '%'; ) {
                    927:                                        if(*t++  == '\n')
                    928:                                                if(*t == '\n')
                    929:                                                        break;
                    930:                                }
                    931:                                sav = *t;
                    932:                                *t = '\0';
                    933:                                if(also == 0) {
                    934:                                        fputs(ALSOBEGIN,writebib);
                    935:                                        putc('\n',writebib);
                    936:                                }
                    937:                                seealso(s);
                    938:                                if(also == 0) {
                    939:                                        fputs(ALSOEND,writebib);
                    940:                                        putc('\n',writebib);
                    941:                                }
                    942:                                fflush(writebib);
                    943:                                *t = sav;
                    944:                                s = t-1;
                    945:                                continue;
                    946:                        }
                    947:                }
                    948:                putc(*s,writebib);
                    949:        }
                    950: }
                    951: 
                    952: 
                    953: 
                    954: /*
                    955:  * seealso - hunt for keywords in the "see also list"
                    956:  */
                    957: 
                    958: seealso(tok)
                    959: register char *tok;
                    960: {
                    961:        char key[MAXTOK];
                    962:        register char *k;
                    963: 
                    964:        *key = '\0';
                    965:        if(k = strtok(tok+strlen(ALSO)+1," \t\n")) {
                    966:                strcpy(key,k);
                    967:                strcat(key," ");
                    968:                while(k = strtok((char *)0," \t\n")) {
                    969:                        strcat(key,k);
                    970:                        strcat(key," ");
                    971:                }
                    972:                if(*key != '\0') {
                    973:                        getref(key);
                    974:                }
                    975:        }
                    976:        
                    977: }
                    978:                
                    979: 
                    980: 
                    981: /*
                    982:  * end_citations - end a list of citations: read back citation
                    983:  * list from awk
                    984:  */
                    985: 
                    986: end_citations(punc)
                    987: int punc;      /* punctuation following or preceeding citation list */
                    988: {
                    989:        register int l, k, j;
                    990: 
                    991:        fputs(END_LIST,writebib);
                    992:        if(pass == 1)
                    993:                putc('1',writebib);
                    994:        if(punc)
                    995:                fprintf(writebib," %c",(char)punc);
                    996:        putc('\n',writebib);
                    997:        fflush(writebib);
                    998: 
                    999:        while(fgets(awkline,MAXTOK,readbib)) {
                   1000:                l = strlen(awkline);
                   1001:                if(l >= (j=strlen(END_LIST)+1)) {
                   1002:                        k = l-j;
                   1003:                        if(strncmp(END_LIST,&awkline[k],j-1) == 0) {
                   1004:                                if(k != 0) {
                   1005:                                        awkline[k] = '\0';
                   1006:                                        fputs(awkline,writetext);
                   1007:                                }
                   1008:                                return;
                   1009:                        }
                   1010:                }
                   1011:                fputs(awkline,writetext);
                   1012:        }
                   1013:        errexit(1,"end_citations: EOF or error from awk\n");
                   1014: }
                   1015: 
                   1016: 
                   1017: /*
                   1018:  * style - process |reference_style()
                   1019:  *     select a reference formatting style and set style flags
                   1020:  */
                   1021: 
                   1022: style()
                   1023: {
                   1024: 
                   1025: /*
                   1026:  * get left delimeter, then style name and options, then right delimeter
                   1027:  */
                   1028:        leftdelim;
                   1029:        if ((type = get_token(tok,right)) == T_WORD) {
                   1030:                if(strcmp(tok,"same")) {
                   1031:                        strcpy(stylename,tok);
                   1032:                }
                   1033:                while ((type = get_token(tok,right)) == T_WORD) {
                   1034:                        if(strcmp(tok,"nroff") == 0) {
                   1035:                                nroff = 1;
                   1036:                        }
                   1037:                        else if(strcmp(tok,"troff") == 0) {
                   1038:                                nroff = 0;
                   1039:                        }
                   1040:                        else if(strcmp(tok,"rp") == 0) {
                   1041:                                rp = 1;
                   1042:                        }
                   1043:                        else if(strcmp(tok,"tm") == 0) {
                   1044:                                rp = 0;
                   1045:                        }
                   1046:                        else if(strcmp(tok,"sequence") == 0) {
                   1047:                                sort = 0;
                   1048:                        }
                   1049:                        else if(strcmp(tok,"sort") == 0) {
                   1050:                                sort = 1;
                   1051:                                strcpy(sortkey,tok);
                   1052:                        }
                   1053:                        else {
                   1054:                                sort = 1;
                   1055:                                strcpy(sortkey,tok);
                   1056:                        }
                   1057:                }
                   1058:        }
                   1059:        else {
                   1060:                token_err(type,"Expecting style name, got %s\n", tok);
                   1061:        }
                   1062: 
                   1063:        rightdelim;
                   1064: 
                   1065: /*
                   1066:  * finish previous citations before switching styles
                   1067:  */
                   1068:        if(awkstate == OK)
                   1069:                biblio(END);
                   1070: }
                   1071: 
                   1072: 
                   1073: /*
                   1074:  * database - process |reference_database
                   1075:  *     select a new bibliographic database
                   1076:  */
                   1077:  
                   1078: database()
                   1079: {
                   1080: 
                   1081: /* 
                   1082:  * after left delimeter, get name of database, then right delim
                   1083:  */
                   1084:        leftdelim;
                   1085:        if ((type = get_token(tok,right)) != T_WORD) {
                   1086:                token_err(type,"Expecting name of database file, got %s\n",tok);
                   1087:        }
                   1088:        strcpy(INDEX,tok);
                   1089:        strcat(INDEX,".i");
                   1090:        type = get_token(tok,right);
                   1091:        rightdelim;
                   1092: 
                   1093: }
                   1094: 
                   1095: 
                   1096: /*
                   1097:  * bib_list - process |reference_list()
                   1098:  *     format a bibliographic database
                   1099:  *     first finish processing for previous citations
                   1100:  */
                   1101: 
                   1102: bib_list()
                   1103: {
                   1104:        static char dbstr[MAXTOK];      /* names of one or more bibs */
                   1105:        
                   1106: /*
                   1107:  * after left delimeter get bibliography name (can skip on second pass),
                   1108:  * then right delimeter
                   1109:  */
                   1110:        leftdelim;
                   1111:        if(pass != 2) {
                   1112:                *dbstr = '\0';
                   1113:                while ((type = get_token(tok,right)) == T_WORD) {
                   1114:                        strcat(dbstr,tok);
                   1115:                        strcat(dbstr," ");
                   1116:                }
                   1117:        }
                   1118:        else type = get_token(tok,right);
                   1119:        rightdelim;
                   1120: 
                   1121: /* 
                   1122:  * format any previous citations then put out complete bibliography
                   1123:  * (unless the second pass has just begun)
                   1124:  */
                   1125:        if(awkstate == OK) {
                   1126:                biblio(BIBLIST);
                   1127:                if(pass != 2) printbib(dbstr);
                   1128:        }
                   1129:        else {
                   1130:                printbib(dbstr);
                   1131:        }
                   1132: }
                   1133: 
                   1134: 
                   1135: /*
                   1136:  * biblio - process reference_placement OR
                   1137:  *     finish processing citations before EOF, style change, or list command
                   1138:  */
                   1139: 
                   1140: biblio(bflag)
                   1141: bibflag bflag;
                   1142: {
                   1143: 
                   1144: /*
                   1145:  * signal bibliography to awk
                   1146:  */
                   1147:        fputs(BIBLIO,writebib);
                   1148:        if(pass == 1)
                   1149:                putc('1',writebib);
                   1150:        if(bflag == END || bflag == BIBLIST)
                   1151:                fputs(" no_bib",writebib);
                   1152:        putc('\n',writebib);
                   1153:        fflush(writebib);
                   1154:        
                   1155:        switch(pass) {
                   1156: 
                   1157:        /*
                   1158:         * write out bib mark to diverted text, close, and reopen
                   1159:         */
                   1160:        case 1:
                   1161:                pass = 2;
                   1162:                if(bflag != END) {
                   1163:                        putc(BAR,writetext);
                   1164:                        if(bflag == BIBLIST)
                   1165:                                fprintf(writetext,"%s<>",REF_LIST);
                   1166:                        else
                   1167:                                fputs(REF_PLACE,writetext);
                   1168:                        putc('\n',writetext);
                   1169:                }
                   1170:                fclose(writetext);
                   1171:                writetext = savefile;
                   1172:                savefile = readtext;
                   1173:                readtext = fopen(divertname,"r");
                   1174:                haveeof = 0;
                   1175:                return;
                   1176: 
                   1177:        /*
                   1178:         * close and unlink text and resume reading in original file
                   1179:         */
                   1180:        case 2:
                   1181:                fclose(readtext);
                   1182:                unlink(divertname);
                   1183:                readtext = savefile;
                   1184:                haveeof = 0;
                   1185:                pass = 0;
                   1186: 
                   1187:        /*
                   1188:         * get formatted bibliography from awk
                   1189:         */
                   1190:        case 0:
                   1191:                while(fgets(awkline,MAXTOK,readbib)) {
                   1192:                        if(strcmp("%END_BIB\n",awkline) == 0) {
                   1193:                                awkclose(readbib,writebib);
                   1194:                                return;
                   1195:                        }
                   1196:                        fputs(awkline,writetext);
                   1197:                }
                   1198:                errexit(1,"biblio: EOF or error from awk\n");
                   1199:        }
                   1200: }
                   1201: 
                   1202: 
                   1203: /*
                   1204:  * refread - read a single reference from a bibliography file
                   1205:  */
                   1206: char *
                   1207: refread(bfile)
                   1208: FILE *bfile;
                   1209: {
                   1210:        static char *buf = NULL;
                   1211:        static unsigned size;
                   1212:        register char *bp;
                   1213:        int c, nextc;
                   1214: 
                   1215:        if(buf == NULL) {
                   1216:                if((buf = malloc(MAXTOK)) == NULL)
                   1217:                        errexit(1, "malloc error in refread\n");
                   1218:                size = MAXTOK;
                   1219:        }
                   1220:        bp = buf;
                   1221:        while(isspace(c = getc(bfile))) {
                   1222:        }
                   1223:        if(c == EOF)
                   1224:                return(NULL);
                   1225:        *bp++ = c;
                   1226:        while(c = getc(bfile)) {
                   1227:                if(bp-buf == size-1) {
                   1228:                        if((buf = realloc(buf,size+MAXTOK)) == NULL)
                   1229:                                errexit(1, "malloc error in refread\n");
                   1230:                        bp = buf+size-1;
                   1231:                        size += MAXTOK;
                   1232:                }
                   1233:                if(c == EOF)
                   1234:                        break;
                   1235:                *bp++ = c;
                   1236:                if(c == '\n') {
                   1237:                        if((nextc = getc(bfile)) == '\n') {
                   1238:                                ungetc(nextc,bfile);
                   1239:                                break;
                   1240:                        }
                   1241:                        ungetc(nextc,bfile);
                   1242:                }
                   1243:        }
                   1244: 
                   1245:        if(bp == buf)
                   1246:                return(NULL);
                   1247:        if(*(bp-1) != '\n')
                   1248:                *bp++ = '\n';
                   1249:        *bp = '\0';
                   1250:        return(buf);
                   1251: }
                   1252: 
                   1253:                
                   1254: /*
                   1255:  * printbib - list one or more bibliographic databases
                   1256:  */
                   1257: printbib(bibstr)
                   1258: char *bibstr;                  /* name of database */
                   1259: {
                   1260:        register char *bp, *bn; /* ptrs to bibstr */
                   1261:        FILE *bib;              /* file ptr to database */
                   1262:        register char *ref;     /* points to a complete reference */
                   1263: 
                   1264: /*
                   1265:  * start awk, signalling that this is an entire bib (as opposed to citations)
                   1266:  */
                   1267:        start_awk(BIBLIST);
                   1268: 
                   1269: /*
                   1270:  * for each database; open the file, read each reference,
                   1271:  * sending BEGIN and END markers
                   1272:  */
                   1273:        for(bp = bibstr; *bp; bp = bn) {
                   1274:                if((bn = strchr(bp,' ')) != NULL)
                   1275:                        *bn++ = '\0';
                   1276:                else break;
                   1277:                if((bib = fopen(bp,"r")) == NULL) {
                   1278:                        fprintf(stderr,"cannot open database file %s\n",bp);
                   1279:                        continue;
                   1280:                }
                   1281: 
                   1282:                strcpy(INDEX,bp);
                   1283:                strcat(INDEX,".i");
                   1284: 
                   1285:                while(ref = refread(bib)) {
                   1286:                        fputs(BEGIN_CITE,writebib);
                   1287:                        putc('\n',writebib);
                   1288:                        refwrite(ref);
                   1289:                        fputs(END_CITE,writebib);
                   1290:                        putc('\n',writebib);
                   1291:                }
                   1292:                fflush(writebib);
                   1293:                fclose(bib);
                   1294:        }
                   1295:        fflush(writebib);
                   1296: 
                   1297: /*
                   1298:  * signal awk to format the bibliography, read it back, and print it out
                   1299:  */
                   1300:        fputs(WHOLEBIB,writebib);
                   1301:        if(sort) {
                   1302:                putc(' ',writebib);
                   1303:                fputs(sortkey,writebib);
                   1304:        }
                   1305:        putc('\n',writebib);
                   1306:        fflush(writebib);
                   1307: 
                   1308:        while(fgets(awkline,MAXTOK,readbib)) {
                   1309:                if(strcmp("%END_BIB\n",awkline) == 0) {
                   1310:                        awkclose(readbib,writebib);
                   1311:                        return;
                   1312:                }
                   1313:                fputs(awkline,writetext);
                   1314:        }
                   1315:        errexit(1,"wholebib: EOF or error from awk\n");
                   1316: }
                   1317: 
                   1318: 
                   1319: /*
                   1320:  * dbinclude - include entries from one or more bibliography databases
                   1321:  *             in the reference section without citing in the text
                   1322:  */
                   1323: dbinclude()
                   1324: {
                   1325:        static char dbstr[MAXTOK];      /* names of one or more bibs */
                   1326:        register char *bp, *bn; /* ptrs to bibstr */
                   1327:        FILE *bib;              /* file ptr to database */
                   1328:        register char *ref;     /* points to a complete reference */
                   1329:        char saveindex[maxstr]; /* for saving name of current index */
                   1330:        int includecnt;         /* count number of included biblio entries */
                   1331:        
                   1332: /*
                   1333:  * after left delimeter get bibliography name (or include count on second pass),
                   1334:  * then right delimeter
                   1335:  */
                   1336:        leftdelim;
                   1337:        *dbstr = '\0';
                   1338:        while ((type = get_token(tok,right)) == T_WORD) {
                   1339:                strcat(dbstr,tok);
                   1340:                strcat(dbstr," ");
                   1341:        }
                   1342:        rightdelim;
                   1343: 
                   1344:        if(pass != 2) {
                   1345:        
                   1346:                includecnt = 0;
                   1347:                strcpy(saveindex,INDEX);        /* save the current INDEX and start awk */
                   1348:                if(awkstate != OK) start_awk(NORMAL);
                   1349:        /*
                   1350:         * for each database; open the file, read each reference,
                   1351:         * sending BEGIN and END markers
                   1352:         */
                   1353:                for(bp = dbstr; *bp; bp = bn) {
                   1354:                        if((bn = strchr(bp,' ')) != NULL)
                   1355:                                *bn++ = '\0';
                   1356:                        else break;
                   1357:                        if((bib = fopen(bp,"r")) == NULL) {
                   1358:                                fprintf(stderr,"cannot open database file %s\n",bp);
                   1359:                                continue;
                   1360:                        }
                   1361: 
                   1362:                        strcpy(INDEX,bp);
                   1363:                        strcat(INDEX,".i");
                   1364: 
                   1365:                        while(ref = refread(bib)) {
                   1366:                                fputs(BEGIN_CITE,writebib);
                   1367:                                putc('\n',writebib);
                   1368:                                refwrite(ref);
                   1369:                                fputs("%no_cite\n",writebib);
                   1370:                                fputs(END_CITE,writebib);
                   1371:                                putc('\n',writebib);
                   1372:                                includecnt++;
                   1373:                        }
                   1374:                        fflush(writebib);
                   1375:                        fclose(bib);
                   1376:                }
                   1377:                end_citations('\0');
                   1378:                strcpy(INDEX,saveindex);
                   1379:                if(pass == 1) {
                   1380:                        fprintf(writetext,"|%s[%d]\n",REF_INCLUDE,includecnt);
                   1381:                }
                   1382:        }
                   1383:        else {
                   1384:                fputs(DBINCLUDE,writebib);
                   1385:                putc(' ',writebib);
                   1386:                fputs(dbstr,writebib);  /* number of includes */
                   1387:                putc('\n',writebib);
                   1388:                fflush(writebib);
                   1389:        }
                   1390: }
                   1391: 
                   1392: 
                   1393: mygetc(file)
                   1394: FILE *file;
                   1395: {
                   1396:        int c;
                   1397: 
                   1398:        if(haveeof)
                   1399:                return(EOF);
                   1400:        else
                   1401:                if((c = getc(file)) == EOF)
                   1402:                        haveeof++;
                   1403:                return(c);
                   1404: }
                   1405: 
                   1406: /*
                   1407:  * errexit - print error message to stderr, unlink temporary file, exit
                   1408:  */
                   1409: 
                   1410: errexit(n,s1,s2,s3)
                   1411: int n;
                   1412: char *s1;
                   1413: {
                   1414:        fprintf(stderr,s1,s2,s3);
                   1415:        unlink(divertname);
                   1416:        if(awkstate != NONE)
                   1417:                awkclose(readbib,writebib);
                   1418:        exit(n);
                   1419: }
                   1420: 
                   1421: 
                   1422: /*
                   1423:  * awkopen - open up pipes to awk process
                   1424:  */
                   1425: 
                   1426: #define        RDR     0
                   1427: #define        WTR     1
                   1428: 
                   1429: awkopen(awkfile,readawk,writeawk)
                   1430: char *awkfile;
                   1431: FILE **readawk,**writeawk;
                   1432: {
                   1433:        int
                   1434:                i,                      /* temp for closing fd's not used */
                   1435:                fromawk[2],             /* pipe file descriptors from awk */
                   1436:                toawk[2],
                   1437:                pid                     /* pipe file descriptors to awk */
                   1438:        ;
                   1439:        char    temp[maxstr];
                   1440: 
                   1441: /*
                   1442:  * *** take care of forming pipes ***
                   1443:  */
                   1444:        if (pipe(fromawk) < 0)
                   1445:                errexit(1, "can't open pipe from awk\n");
                   1446:        if (pipe(toawk) < 0)
                   1447:                errexit(1, "can't open pipe to awk\n");
                   1448: 
                   1449: /*
                   1450:  * *** make awk child ***
                   1451:  */
                   1452:        if ((pid = fork()) == 0) {
                   1453:                close(fromawk[RDR]);
                   1454:                dup2(fromawk[WTR], 1);
                   1455:                close(toawk[WTR]);
                   1456:                dup2(toawk[RDR], 0);
                   1457:                for (i=3; i<FILENUM; i++)
                   1458:                        close(i);
                   1459: 
                   1460:                strcpy(temp,libpath(PLIB));
                   1461:                strcat(temp,SLASH);
                   1462:                strcat(temp,AWK);
                   1463: /*
                   1464:                execlp(temp, AWK, "-R", awkfile, 0);
                   1465: */
                   1466:                execlp(temp, AWK, "-f", awkfile, 0);
                   1467:                errexit(1, "could not exec awk with script %s\n",awkfile);
                   1468:        }
                   1469:        if (pid == -1)
                   1470:                errexit(1, "could not fork awk\n");
                   1471: 
                   1472: /*
                   1473:  * *** make out stream pointers ***
                   1474:  */
                   1475:        close(fromawk[WTR]);
                   1476:        *readawk = fdopen(fromawk[RDR], "r");
                   1477:        close(toawk[RDR]);
                   1478:        *writeawk = fdopen(toawk[WTR], "w");
                   1479: 
                   1480: }
                   1481: 
                   1482: 
                   1483: /*
                   1484:  * awkclose - close pipes to awk
                   1485:  */
                   1486: 
                   1487: awkclose(read,write)
                   1488: FILE *read, *write;
                   1489: {
                   1490:        fclose(write);
                   1491:        fclose(read);
                   1492:        awkstate = NONE;
                   1493: }
                   1494: 
                   1495: 
                   1496: /*
                   1497:  * cleanup = after signal, get rid of temp file and close awk
                   1498:  */
                   1499: 
                   1500: cleanup()
                   1501: {
                   1502:        signal(SIGINT, SIG_IGN);
                   1503:        signal(SIGQUIT, SIG_IGN);
                   1504:        unlink(divertname);
                   1505:        if(awkstate != NONE)
                   1506:                awkclose(readbib,writebib);
                   1507:        exit(1);
                   1508: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.