Annotation of researchv10no/cmd/prefer/misc/mypubenter.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Facilitate entry of references
                      3:  */
                      4: 
                      5: #include       <stdio.h>
                      6: #include       <signal.h>
                      7: #include       <sys/types.h>
                      8: #include       <sys/stat.h>
                      9: 
                     10: #define                TEMPLATE        "/usr/frodo/lib/refer/template"
                     11: #define                REFER           "refer.out"
                     12: #define                TMPREF          "/tmp/referXXXXXX"
                     13: 
                     14: #ifdef PREFER
                     15: #define                TYPE            "%type"
                     16: #endif /* PREFER */
                     17: 
                     18: #define                TRUE            (1)
                     19: #define                FALSE           (0)
                     20: 
                     21: #define                EDITOR          "EDITOR"
                     22: #define                VISUAL          "VISUAL"
                     23: 
                     24: struct ref {
                     25:        struct ref *r_next;     /* next reference node */
                     26:        char *r_prompt;         /* prompt for reference */
                     27:        struct att *r_att;      /* attributes */
                     28: };
                     29: 
                     30: struct att {
                     31:        struct att *a_next;     /* next attribute node */
                     32:        char a_flag;            /* prompt flag */
                     33:        char *a_prompt;         /* prompt for attribute */
                     34:        char *a_def;            /* default value for attribute */
                     35:        char *a_refer;          /* refer string to output */
                     36:        char *a_mcont;          /* middle continue string to output */
                     37:        char *a_econt;          /* end continue string to output */
                     38: };
                     39: 
                     40: char
                     41:        *getenv(),
                     42:        *malloc(),
                     43:        *mktemp(),
                     44:        *strchr(),
                     45:        *strtok(),
                     46:        *tmpref
                     47: ;
                     48: 
                     49: int cleanup();
                     50: 
                     51: FILE
                     52:        *tmpopen(),
                     53:        *tmp,
                     54:        *refer
                     55: ;
                     56: 
                     57: void
                     58:        fixrefer(),
                     59:        edit()
                     60: ;
                     61: 
                     62: struct ref
                     63:        *ref,
                     64:        *sr
                     65: ;
                     66: 
                     67: main(argc, argv)
                     68: int argc;
                     69: char *argv[];
                     70: {
                     71:        register char
                     72:                *tempname,
                     73:                *refname
                     74:        ;
                     75: 
                     76:        signal(SIGINT, cleanup);
                     77:        signal(SIGQUIT, cleanup);
                     78: 
                     79:        tempname = refname = NULL;
                     80:        while (--argc) {
                     81:                if (!strcmp("-o", *++argv)) {
                     82:                        refname = *++argv;
                     83:                        --argc;
                     84:                } else
                     85:                        tempname = *argv;
                     86:        }
                     87:        readtemplate(tempname ? tempname : TEMPLATE);
                     88: 
                     89:        if ((refer = fopen(refname ? refname : REFER, "a")) == NULL)
                     90:                errexit(1, "Can't open reference file, %s\n", REFER);
                     91: 
                     92:        doreferences();
                     93: }
                     94: 
                     95: /*
                     96:  * Process all user input.
                     97:  */
                     98: doreferences()
                     99: {
                    100:        int cont;
                    101:        struct ref
                    102:                *rr,
                    103:                *r
                    104:        ;
                    105:        struct att *a;
                    106:        char buf[BUFSIZ];
                    107:        register char
                    108:                *p,
                    109:                *bufp
                    110:        ;
                    111:        char comm[80];
                    112: 
                    113:        tmpref = mktemp(TMPREF);
                    114:        sr = NULL;
                    115:        for (;;) {
                    116:                sprintf(comm, "Reference type [%s] ", ref->r_prompt);
                    117:                if (getln(comm, buf, sizeof(buf)) == NULL)
                    118:                        cleanup();
                    119: 
                    120:                if ((p = strchr(&buf[0], '\n')) != NULL)
                    121:                        *p = '\0';
                    122: 
                    123:                if (!strlen(&buf[0]))
                    124:                        strcpy(&buf[0], ref->r_prompt);
                    125: 
                    126:                switch (match(&rr, buf)) {
                    127:                case 0:
                    128:                        printf("Legal reference types are:\n");
                    129:                        for (r = ref; r; r = r->r_next)
                    130:                                printf("%s\n", r->r_prompt);
                    131:                        continue;
                    132: 
                    133:                case 1:
                    134:                        r = rr;
                    135:                        break;
                    136: 
                    137:                default:                /* handled in match() */
                    138:                        continue;
                    139:                }
                    140: 
                    141:                if (!strcmp(r->r_prompt, "quit"))
                    142:                        cleanup();
                    143: 
                    144:                fixrefer();
                    145: 
                    146:                if (!strcmp(r->r_prompt, "help")) {
                    147:                        help();
                    148:                        continue;
                    149:                }
                    150: 
                    151:                printf("referencing a %s\n", r->r_prompt);
                    152:                sr = r;
                    153:                if ((tmp = fopen(tmpref, "w")) == NULL)
                    154:                        errexit(1, "Can't open %s\n", tmpref);
                    155: 
                    156:                for (a = r->r_att; a; a = a->a_next) {
                    157:                        if (a->a_flag == '!')
                    158:                                continue;
                    159:                        do {
                    160:                                do {
                    161:                                        if (a->a_def[0])
                    162:                                                sprintf(comm, "%s [%s]: ",
                    163:                                                     a->a_prompt, a->a_def);
                    164:                                        else
                    165:                                                sprintf(comm, "%s: ", a->a_prompt);
                    166:                                        if (getln(comm, buf, sizeof(buf)) == NULL)
                    167:                                                cleanup();
                    168: 
                    169:                                        p = strchr(buf, '\n');
                    170:                                        *p = '\0';
                    171: 
                    172:                                        if (a->a_flag == '\0' && !strlen(buf)
                    173:                                            && !a->a_def[0])
                    174:                                                printf("The %s field is not optional\n",
                    175:                                                     a->a_prompt);
                    176:                                        else if (a->a_def[0])
                    177:                                                break;
                    178:                                } while (a->a_flag == '\0' && !strlen(buf));
                    179: 
                    180:                                if ((cont = strlen(buf)) != 0 && buf[strlen(buf) - 1] == '&')
                    181:                                        buf[strlen(buf) - 1] = '\0';
                    182:                                else
                    183:                                        cont = 0;
                    184: 
                    185:                                bufp = buf;
                    186:                                while (*bufp == ' ' || *bufp == '\t')
                    187:                                        ++bufp;
                    188:                                if (strlen(buf))
                    189:                                        fprintf(tmp, "%s: %s\n", a->a_prompt, bufp);
                    190:                                else
                    191:                                        fprintf(tmp, "%s: %s\n", a->a_prompt, a->a_def);
                    192:                                fflush(tmp);
                    193:                        } while (cont != 0);
                    194:                        fflush(tmp);
                    195:                }
                    196:                fprintf(tmp, "\n");
                    197:                fclose(tmp);
                    198:        }
                    199: }
                    200: 
                    201: /*
                    202:  * Print out all attributes for a given reference; ``?'' for all.
                    203:  */
                    204: help()
                    205: {
                    206:        register struct att *a;
                    207:        char helpref[BUFSIZ];
                    208:        struct ref *r;
                    209: 
                    210:        printf("which reference type: ");
                    211:        fgets(helpref, sizeof(helpref), stdin);
                    212:        helpref[strlen(&helpref[0]) - 1] = '\0';
                    213:        switch (match(&r, helpref)) {
                    214:        case 0:
                    215:                if (!strcmp(helpref, "?")) {
                    216:                        for (r = ref; r; r = r->r_next) {
                    217:                                printf("%s:\n", r->r_prompt);
                    218:                                for (a = r->r_att; a; a = a->a_next)
                    219:                                        printf("\t%s\n", a->a_prompt);
                    220:                        }
                    221:                } else
                    222:                        printf("No matches for %s\n", helpref);
                    223:                break;
                    224: 
                    225:        case 1:
                    226:                printf("Attributes for `%s':\n", r->r_prompt);
                    227:                for (a = r->r_att; a; a = a->a_next)
                    228:                        printf("\t%s\n", a->a_prompt);
                    229:                break;
                    230:        }
                    231: }
                    232: 
                    233: /*
                    234:  * Read in references from template file
                    235:  */
                    236: readtemplate(file)
                    237: char *file;
                    238: {
                    239:        FILE *template;
                    240:        register char
                    241:                *p,
                    242:                *pp
                    243:        ;
                    244:        register struct att *a = NULL;
                    245:        char buf[BUFSIZ];
                    246:        struct ref *r = NULL;
                    247: 
                    248:        template = tmpopen(file);
                    249:        while (fgets(&buf[0], sizeof(buf), template) != NULL) {
                    250:                if ((p = strchr(&buf[0], '\n')) != NULL)
                    251:                        *p = '\0';
                    252: 
                    253:                switch (buf[0]) {
                    254:                case ':':
                    255:                        continue;
                    256: 
                    257:                case '\t':
                    258:                        if (r == NULL)
                    259:                                errexit(1, "Attribute without reference active\n");
                    260: 
                    261:                        if (a == NULL) {
                    262:                                if ((a = r->r_att =
                    263:                                    (struct att *)malloc((unsigned)sizeof(struct att)))
                    264:                                    == NULL)
                    265:                                        errexit(1, "Out of memory for attributes\n");
                    266:                        } else if ((a = a->a_next =
                    267:                            (struct att *)malloc((unsigned)sizeof(struct att))) == NULL)
                    268:                                errexit(1, "Out of memory for attributes\n");
                    269:                        p = &buf[1];
                    270: 
                    271:                        switch (*p) {
                    272:                        case '?':
                    273:                        case '-':
                    274:                        case '!':
                    275:                                a->a_flag = *p++;
                    276:                                break;
                    277: 
                    278:                        default:
                    279:                                a->a_flag = '\0';
                    280:                        }
                    281: 
                    282:                        if ((p = strtok(p, "\n\t")) == NULL)
                    283:                                errexit(1, "Attribute without prompt\n");
                    284: 
                    285:                        if ((a->a_prompt = malloc((unsigned)strlen(p) + 1)) == NULL)
                    286:                                errexit(1, "Out of memory for attribute prompt\n");
                    287:                        strcpy(a->a_prompt, p);
                    288:                        if ((pp = strchr(a->a_prompt, '[')) != NULL) {
                    289:                                *pp = '\0';
                    290:                                while (a->a_prompt[strlen(a->a_prompt) - 1] == ' ')
                    291:                                        a->a_prompt[strlen(a->a_prompt) - 1] = '\0';
                    292:                                if ((a->a_def = malloc((unsigned)strlen(pp + 1) + 1))
                    293:                                    == NULL)
                    294:                                        errexit(1, "Out of memory for attribute default\n");
                    295:                                strcpy(a->a_def, pp + 1);
                    296:                                if ((pp = strchr(a->a_def, ']')) == NULL)
                    297:                                        errexit(1, "Unmatched []\n");
                    298:                                *pp = '\0';
                    299:                        } else
                    300:                                a->a_def = "";
                    301: 
                    302:                        if ((p = strtok(NULL, "\t\n")) == NULL)
                    303:                                errexit(1, "Attribute without refer\n");
                    304: 
                    305:                        if ((a->a_refer = malloc((unsigned)strlen(p) + 1)) == NULL)
                    306:                                errexit(1, "Out of memory for attribute refer\n");
                    307: 
                    308:                        strcpy(a->a_refer, p);
                    309: 
                    310:                        a->a_next = NULL;
                    311: 
                    312:                        if ((p = strtok(NULL, "\n\t")) == NULL || !strcmp(p, "NULL"))
                    313:                                a->a_mcont = "";
                    314:                        else {
                    315:                                if ((a->a_mcont = malloc((unsigned)strlen(p) + 1))
                    316:                                    == NULL)
                    317:                                        errexit(1, "Out of memory for attribute continue\n");
                    318:                                strcpy(a->a_mcont, p);
                    319:                        }
                    320: 
                    321:                        if ((p = strtok(NULL, "\n\t")) == NULL || !strcmp(p, "NULL"))
                    322:                                a->a_econt = "";
                    323:                        else {
                    324:                                if ((a->a_econt = malloc((unsigned)strlen(p) + 1))
                    325:                                    == NULL)
                    326:                                        errexit(1, "Out of memory for attribute continue\n");
                    327:                                strcpy(a->a_econt, p);
                    328:                        }
                    329: 
                    330:                        break;
                    331: 
                    332:                default:
                    333:                        addref(&r, buf);
                    334:                        a = NULL;
                    335:                }
                    336:        }
                    337:        fclose(template);
                    338: 
                    339:        addref(&r, "help");
                    340:        addref(&r, "quit");
                    341:        r->r_next = NULL;
                    342: }
                    343: 
                    344: /*
                    345:  * Add a reference with prompt.
                    346:  */
                    347: addref(r, prompt)
                    348: register struct ref **r;
                    349: char *prompt;
                    350: {
                    351:        if (ref == NULL) {
                    352:                if ((*r = ref = (struct ref *)malloc((unsigned)sizeof(struct ref)))
                    353:                    == NULL)
                    354:                        errexit(1, "Out of memory for reference.\n");
                    355:        } else if ((*r = (*r)->r_next = (struct ref *)malloc((unsigned)sizeof(struct ref)))
                    356:            == NULL)
                    357:                errexit(1, "Out of memory for references\n");
                    358: 
                    359:        if (((*r)->r_prompt = malloc((unsigned)strlen(prompt) + 1)) == NULL)
                    360:                errexit(1, "Out of memory for reference prompt\n");
                    361:        strcpy((*r)->r_prompt, prompt);
                    362:        (*r)->r_next = NULL;
                    363:        (*r)->r_att = NULL;
                    364: }
                    365: 
                    366: /*
                    367:  * Get a line to process; if ~e or ~v call editors.
                    368:  */
                    369: getln(msg, str, sz)
                    370: register char *msg, *str;
                    371: int sz;
                    372: {
                    373:        for (;;) {
                    374:                printf(msg);
                    375:                if (fgets(str, sz, stdin) == NULL)
                    376:                        return(NULL);
                    377: 
                    378:                if (!strcmp(str, "~e\n"))
                    379:                        edit(EDITOR);
                    380:                else if (!strcmp(str, "~v\n"))
                    381:                        edit(VISUAL);
                    382:                else
                    383:                        return(1);
                    384:        }
                    385: }
                    386: 
                    387: char
                    388:        editor[80],
                    389:        veditor[80]
                    390: ;
                    391: 
                    392: /*
                    393:  * Call one of the editors on the text entered so far.
                    394:  */
                    395: void
                    396: edit(which)
                    397: char *which;
                    398: {
                    399:        char command[100];
                    400: 
                    401:        if (!editor[0])
                    402:                open_ed(editor, EDITOR);
                    403:        if (!veditor[0])
                    404:                open_ed(veditor, VISUAL);
                    405: 
                    406:        if (tmp)
                    407:                fclose(tmp);
                    408:        else {
                    409:                printf("There is no file yet.\n");
                    410:                return;
                    411:        }
                    412: 
                    413:        sprintf(command, "%s %s", (!strcmp(which, EDITOR) ? editor : veditor),
                    414:            tmpref);
                    415:        system(command);
                    416:        tmp = fopen(tmpref, "a+");
                    417: }
                    418: 
                    419: /*
                    420:  * Get user's editors as set in environment or else use ed or vi.
                    421:  */
                    422: open_ed(ed, which)
                    423: register char *ed, *which;
                    424: {
                    425:        char *p;
                    426:        struct stat e_stat;
                    427: 
                    428:        if (p = getenv(which))
                    429:                strcpy(ed, p);
                    430:        if (!ed[0] || stat(ed, &e_stat) == -1)
                    431:                strcpy(ed, (!strcmp(which, EDITOR) ? "/bin/ed" : "/usr/bin/vi"));
                    432: }
                    433: 
                    434: /*
                    435:  * Write out to file.
                    436:  */
                    437: void
                    438: fixrefer()
                    439: {
                    440:        char
                    441:                buf[BUFSIZ],
                    442:                savestr[BUFSIZ]
                    443:        ;
                    444:        register char
                    445:                *bufp,
                    446:                *p
                    447:        ;
                    448:        register struct ref *r;
                    449:        register struct att
                    450:                *a,
                    451:                *t
                    452:        ;
                    453:        int
                    454:                first = 1,
                    455:                printed
                    456:        ;
                    457: 
                    458:        if ((tmp = fopen(tmpref, "r")) == NULL)
                    459:                return;
                    460: 
                    461:        if ((r = sr) == NULL)
                    462:                return;
                    463: 
                    464:        a = r->r_att;
                    465:        if (fgets(buf, sizeof buf, tmp) == NULL)
                    466:                return;
                    467: #ifdef PREFER
                    468:        putrefer(refer, "%s %s\n", TYPE, r->r_prompt);
                    469: #endif /* PREFER */
                    470: 
                    471:        if ((p = strchr(buf, '\n')) != NULL)
                    472:                *p = '\0';
                    473: 
                    474:        for (t = a; t; t = t->a_next)
                    475:                if (!strncmp(t->a_prompt, buf, strlen(t->a_prompt)))
                    476:                        break;
                    477: 
                    478:        if (t) {
                    479:                bufp = buf + strlen(t->a_prompt);
                    480:                if (*bufp == ':')
                    481:                        bufp += 2;
                    482:        } else
                    483:                return;
                    484:        a = t;
                    485:        if (a->a_flag != '!')
                    486:                strcpy(savestr, bufp);
                    487:        while (fgets(&buf[0], sizeof(buf), tmp) != NULL) {
                    488:                if ((p = strchr(buf, '\n')) != NULL)
                    489:                        *p = '\0';
                    490: 
                    491:                for (t = a; t; t = t->a_next) {
                    492:                        if (!strncmp(t->a_prompt, buf, strlen(t->a_prompt)))
                    493:                                break;
                    494:                }
                    495: 
                    496:                if (t && t != a) {
                    497:                        if (first && a->a_flag != '!')          /* first line */
                    498:                                putrefer(refer, "%s %s\n", a->a_refer, savestr);
                    499:                        else if (a->a_flag != '!')              /* last line */
                    500:                                putrefer(refer, "%s %s\n", a->a_econt, savestr);
                    501:                        first = TRUE;
                    502:                        a = t;
                    503:                        bufp = buf + strlen(t->a_prompt);
                    504:                        if (*bufp == ':')
                    505:                                bufp += 2;
                    506:                } else {
                    507:                        printed = FALSE;
                    508:                        if (first && a->a_flag != '!')          /* first line */
                    509:                                printed = putrefer(refer, "%s %s\n", a->a_refer,
                    510:                                    savestr);
                    511:                        else if (a->a_flag != '!')              /* middle line */
                    512:                                putrefer(refer, "%s %s\n", a->a_mcont, savestr);
                    513:                        if (printed)
                    514:                                first = FALSE;
                    515:                        bufp = (t ? buf + strlen(t->a_prompt) : buf);
                    516:                        if (*bufp == ':')
                    517:                                bufp += 2;
                    518:                }
                    519:                strcpy(savestr, bufp);
                    520:        }
                    521:        if (first)
                    522:                putrefer(refer, "%s %s\n", a->a_refer, savestr);
                    523:        else
                    524:                putrefer(refer, "%s %s\n", a->a_econt, savestr);
                    525:        fprintf(refer, "\n");
                    526: }
                    527: 
                    528: /*
                    529:  * Print string onto fp, or nothing if arg2 is NULL.
                    530:  */
                    531: putrefer(fp, str, arg1, arg2)
                    532: FILE *fp;
                    533: char *str, *arg1, *arg2;
                    534: {
                    535:        if (strlen(arg2)) {
                    536:                fprintf(fp, str, arg1, arg2);
                    537:                return(1);
                    538:        }
                    539:        return(0);
                    540: }
                    541: 
                    542: /*
                    543:  * End of program.
                    544:  */
                    545: cleanup()
                    546: {
                    547:        signal(SIGINT, SIG_IGN);
                    548:        signal(SIGQUIT, SIG_IGN);
                    549:        if (tmp) {
                    550:                fflush(tmp);
                    551:                fclose(tmp);
                    552:        }
                    553:        fixrefer();
                    554:        unlink(tmpref);
                    555:        printf("\n");
                    556:        exit(0);
                    557: }
                    558: 
                    559: /*
                    560:  * Open template file.
                    561:  */
                    562: FILE *
                    563: tmpopen(file)
                    564: char *file;
                    565: {
                    566:        FILE *fp;
                    567: 
                    568:        if ((fp = fopen(file, "r")) == NULL)
                    569:                errexit(1, "Can't open template file, %s\n", file);
                    570:        return(fp);
                    571: }
                    572: 
                    573: /*
                    574:  * Find matches for buf in ref; set rr to last match.
                    575:  */
                    576: match(rr, buf)
                    577: register struct ref **rr;
                    578: char *buf;
                    579: {
                    580:        register struct ref *r;
                    581:        register matches;
                    582: 
                    583:        for (r = ref, matches = 0; r; r = r->r_next)
                    584:                if (!strncmp(buf, r->r_prompt, strlen(buf))) {
                    585:                        ++matches;
                    586:                        *rr = r;
                    587:                }
                    588: 
                    589:        if (matches >= 2) {
                    590:                printf("`%s' is not unique: ", &buf[0]);
                    591:                for (r = ref; r; r = r->r_next)
                    592:                        if (!strncmp(buf, r->r_prompt, strlen(buf)))
                    593:                                printf("`%s' ", r->r_prompt);
                    594:                printf("all match\n");
                    595:        }
                    596:        return(matches);
                    597: }

unix.superglobalmegacorp.com

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