Annotation of researchv10no/cmd/prefer/misc/mypubenter.c, revision 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.