Annotation of coherent/b/bin/troff/misc.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * misc.c
        !             3:  * Nroff/Troff.
        !             4:  * Miscellaneous routines.
        !             5:  */
        !             6: 
        !             7: #include "roff.h"
        !             8: #include <access.h>
        !             9: #include <ctype.h>
        !            10: #include <string.h>
        !            11: 
        !            12: /*
        !            13:  * Define a macro.
        !            14:  * 'mp' is a pointer to a macro descriptor which is
        !            15:  * filled in with the appropriate information and name is the name
        !            16:  * of the macro upon which the definition ends.
        !            17:  */
        !            18: deftext(mp, name) register MAC *mp; char name[2];
        !            19: {
        !            20:        static char residue[4];
        !            21:        register STR *sp;
        !            22:        register char *bp;
        !            23:        int nlflag;
        !            24: 
        !            25:        if (mp != NULL) {
        !            26:                mp->t_div.m_next = NULL;
        !            27:                mp->t_div.m_type = MTEXT;
        !            28:                mp->t_div.m_core = NULL;
        !            29:                mp->t_div.m_seek = tmpseek;
        !            30:        }
        !            31: #if    0
        !            32:        /* Conditionalized out 4/11/91 by steve, seems wrong. */
        !            33:        infalse = 1;
        !            34: #endif
        !            35:        bp = miscbuf;
        !            36:        for (nlflag = 1;;) {
        !            37: 
        !            38:                /* nlflag indicates if last character was \n. */
        !            39:                if (bp > miscbuf)
        !            40:                        nlflag = (*(bp-1) == '\n');
        !            41: 
        !            42:                /* Flush if necessary, leaving room for "..\n" or ".XX". */
        !            43:                if (bp >= &miscbuf[MSCSIZE-3]) {
        !            44:                        if (mp != NULL)
        !            45:                                nwrite(miscbuf, 1, bp-miscbuf);
        !            46:                        bp = miscbuf;
        !            47:                }
        !            48: 
        !            49:                /* Ignore remainder of line not starting with endmark. */
        !            50:                if (!nlflag) {
        !            51:                        *bp++ = getf(2);
        !            52:                        continue;
        !            53:                }
        !            54: 
        !            55:                /* Last character was \n, look for endmark on next line. */
        !            56:                if (name[0]=='\0') {
        !            57:                        if ((*bp++ = getf(2))!='.' || escflag!=0)
        !            58:                                continue;
        !            59:                        if ((*bp++ = getf(2))!='.' || escflag!=0)
        !            60:                                continue;
        !            61:                        if ((*bp++ = getf(2)) != '\n')
        !            62:                                continue;
        !            63:                        bp -= 3;
        !            64:                        break;
        !            65:                } else {
        !            66:                        if ((*bp++ = getf(2))!=ccc || escflag!=0)
        !            67:                                continue;
        !            68:                        if ((*bp++ = getf(2))!=name[0] || escflag!=0)
        !            69:                                continue;
        !            70:                        if ((*bp++ = getf(2))!=name[1] || escflag!=0)
        !            71:                                continue;
        !            72:                        bp -= 3;
        !            73:                        residue[0] = bp[0];
        !            74:                        residue[1] = bp[1];
        !            75:                        residue[2] = bp[2];
        !            76:                        residue[3] = '\0';
        !            77:                        sp = allstr(SCORE);
        !            78:                        sp->x3.s_cp = residue;
        !            79:                        sp->x3.s_srel = NULL;
        !            80:                        break;
        !            81:                }
        !            82:        }
        !            83:        *bp++ = '\0';
        !            84:        if (mp != NULL)
        !            85:                nwrite(miscbuf, 1, bp-miscbuf);
        !            86: #if    0
        !            87:        /* Conditionalized out 4/11/91 by steve, as above. */
        !            88:        infalse = 0;
        !            89: #endif
        !            90: }
        !            91: 
        !            92: /*
        !            93:  * Define a special character.
        !            94:  */
        !            95: spc_def(name, value) char name[2]; char *value;
        !            96: {
        !            97:        register SPECIAL **spp;
        !            98:        register int n;
        !            99:        int len;
        !           100:        SPECIAL *sp;
        !           101:        char *cp;
        !           102: 
        !           103:        len = strlen(value) + 1;
        !           104:        for (spp = &spc_list; *spp != NULL; spp = &((*spp)->spc_link)) {
        !           105:                sp = *spp;
        !           106:                n = strncmp(sp->spc_name, name, 2);
        !           107:                if (n < 0)
        !           108:                        continue;               /* keep looking */
        !           109:                else if (n > 0)
        !           110:                        break;                  /* not found, add it */
        !           111:                /* Gotcha, redefine it. */
        !           112:                nfree(sp->spc_val);             /* free old value */
        !           113:                sp->spc_val = nalloc(len);      /* allocate new space */
        !           114:                strcpy(sp->spc_val, value);     /* and copy in value */
        !           115:                return;
        !           116:        }
        !           117:        /* Add new entry. */
        !           118:        sp = (SPECIAL *)nalloc(sizeof(*sp));    /* allocate new entry */
        !           119:        cp = nalloc(len);                       /* allocate new value space */
        !           120:        sp->spc_link = *spp;                    /* link into SPECIAL list */
        !           121:        *spp = sp;
        !           122:        sp->spc_name[0] = name[0];
        !           123:        sp->spc_name[1] = name[1];
        !           124:        sp->spc_val = cp;
        !           125:        strcpy(cp, value);
        !           126: }
        !           127: 
        !           128: /*
        !           129:  * Find a special character entry in the special character list.
        !           130:  * Print error message and return NULL if not found.
        !           131:  */
        !           132: SPECIAL *
        !           133: spc_find(name) char name[2];
        !           134: {
        !           135:        register SPECIAL *sp;
        !           136:        register int n;
        !           137: 
        !           138:        for (sp = spc_list; sp != NULL; sp = sp->spc_link) {
        !           139:                n = strncmp(sp->spc_name, name, 2);
        !           140:                if (n < 0)
        !           141:                        continue;
        !           142:                else if (n > 0)
        !           143:                        break;
        !           144:                else
        !           145:                        return sp;
        !           146:        }
        !           147:        printe("special character %c%c not found", name[0], name[1]);
        !           148:        return NULL;
        !           149: }
        !           150: 
        !           151: /*
        !           152:  * Process requests from a library file if it exists.
        !           153:  * The flag is 1 if file contains requests, 0 if binary data.
        !           154:  * Return 1 if it exists, 0 if not.
        !           155:  */
        !           156: lib_file(s, flag) char *s; int flag;
        !           157: {
        !           158:        register char file[40];
        !           159: 
        !           160:        /* Look file, process it if found. */
        !           161:        sprintf(file, "%s%s%s", LIBDIR,
        !           162:                (ntroff == NROFF) ? NRDIR : (pflag) ? TPSDIR : TPCLDIR, s);
        !           163:        if (access(file, AREAD) != 0)
        !           164:                return 0;
        !           165:        if (flag) {
        !           166:                adsfile(file);
        !           167:                process();
        !           168:                return 1;
        !           169:        }
        !           170:        return copy_file(file);
        !           171: }
        !           172: 
        !           173: /*
        !           174:  * Copy a file verbatim.
        !           175:  * Return 0 if not found or not readable, 1 on success.
        !           176:  */
        !           177: copy_file(s) char *s;
        !           178: {
        !           179:        register FILE *fp;
        !           180:        register int c;
        !           181: 
        !           182:        if ((fp = fopen(s, "rb")) == NULL)
        !           183:                return 0;
        !           184:        while ((c = fgetc(fp)) != EOF)
        !           185:                putchar(c);
        !           186:        fclose(fp);
        !           187:        return 1;
        !           188: }
        !           189: 
        !           190: /*
        !           191:  * Read a block into the buffer 'bp' starting at seek position
        !           192:  * 'l' in the temp file.
        !           193:  */
        !           194: nread(l, bp)
        !           195: long l;
        !           196: char *bp;
        !           197: {
        !           198:        if (tmpseek-l <= DBFSIZE) {
        !           199:                copystr(bp, diskbuf, DBFSIZE, 1);
        !           200:                return;
        !           201:        }
        !           202:        lseek(fileno(tmp), (long) l, 0);
        !           203:        if (read(fileno(tmp), bp, DBFSIZE) != DBFSIZE)
        !           204:                panic("temporary file read error");
        !           205: }
        !           206: 
        !           207: /*
        !           208:  * Write the buffer 'bp' which contains 'n' elements of size 's'
        !           209:  * onto the end of the temp file.
        !           210:  */
        !           211: nwrite(bp, s, n) register char *bp; unsigned s; register unsigned n;
        !           212: {
        !           213:        unsigned bno, off;
        !           214:        register char *dp;
        !           215: 
        !           216:        bno = tmpseek / DBFSIZE;
        !           217:        off = tmpseek % DBFSIZE;
        !           218:        if (bno!=0 && off==0) {
        !           219:                --bno;
        !           220:                off += DBFSIZE;
        !           221:        }
        !           222:        dp = &diskbuf[off];
        !           223:        s = n *= s;
        !           224:        while (n--) {
        !           225:                if (dp >= &diskbuf[DBFSIZE]) {
        !           226:                        lseek(fileno(tmp), (long) bno++*DBFSIZE, 0);
        !           227:                        if (write(fileno(tmp), diskbuf, DBFSIZE) != DBFSIZE)
        !           228:                                panic("temporary file write error");
        !           229:                        dp = &diskbuf[0];
        !           230:                }
        !           231:                *dp++ = *bp++;
        !           232:        }
        !           233:        tmpseek += s;
        !           234: }
        !           235: 
        !           236: /*
        !           237:  * Given a string, return a pointer to a copy of it.
        !           238:  */
        !           239: char *
        !           240: duplstr(s) register char *s;
        !           241: {
        !           242:        return strcpy(nalloc(strlen(s) + 1), s);
        !           243: }
        !           244: 
        !           245: /*
        !           246:  * Copy the array of 'n' elements containing a structure of size
        !           247:  * 'size' from 's2' to 's1'.
        !           248:  */
        !           249: copystr(s1, s2, size, n) char *s1, *s2; int size; register int n;
        !           250: {
        !           251:        if ((n *= size) == 0)
        !           252:                return;
        !           253:        memcpy(s1, s2, n);
        !           254: }
        !           255: 
        !           256: /*
        !           257:  * Allocate 'n' bytes.
        !           258:  */
        !           259: char   *
        !           260: nalloc(n)
        !           261: {
        !           262:        extern char *calloc();
        !           263:        register char *cp;
        !           264: 
        !           265:        if ((cp = calloc(n, 1)) == NULL)
        !           266: #if    MSDOS
        !           267:                panic("out of space");          /* no memok() in MS-DOS libc */
        !           268: #else
        !           269:                panic("out of space - memory %s", (memok() ? "good" : "bad"));
        !           270: #endif
        !           271:        return cp;
        !           272: }
        !           273: 
        !           274: /*
        !           275:  * Release the given storage.
        !           276:  */
        !           277: nfree(cp)
        !           278: char *cp;
        !           279: {
        !           280:        free(cp);
        !           281: }
        !           282: 
        !           283: /*
        !           284:  * Execute conditional.
        !           285:  * bp points to the remainder of the line.
        !           286:  * Called from .el and .ie.
        !           287:  */
        !           288: do_cond(cond, bp) int cond; unsigned char *bp;
        !           289: {
        !           290:        unsigned char charbuf[CBFSIZE];
        !           291:        register unsigned char *cp;
        !           292:        unsigned char c;
        !           293: 
        !           294:        while (isascii(*bp) && isspace(*bp))
        !           295:                bp++;                           /* skip leading space */
        !           296:        if (cond) {
        !           297:                /* Execute true branch. */
        !           298:                cp = charbuf;
        !           299:                bracelevel = oldbracelevel;     /* restore original brace level */
        !           300:                if (*bp == EBEG) {
        !           301:                        bp++;                   /* ignore \{ */
        !           302:                        bracelevel++;
        !           303:                }
        !           304:                while (c = *bp++)
        !           305:                        if (cp < &charbuf[CBFSIZE-2])
        !           306:                                *cp++ = c;
        !           307:                *cp++ = '\n';
        !           308:                *cp = '\0';
        !           309:                cp = duplstr(charbuf);
        !           310:                adscore(cp);                    /* execute remainder */
        !           311:                strp->x3.s_srel = cp;
        !           312:        } else {
        !           313:                /* Skip false branch. */
        !           314:                if (*bp != EBEG)
        !           315:                        return;                 /* one-line conditional */
        !           316:                for (; *bp; bp++) {
        !           317:                        if (*bp == EBEG)
        !           318:                                ++infalse;
        !           319:                        else if (*bp == EEND)
        !           320:                                --infalse;
        !           321:                }
        !           322:                if (infalse == 0)
        !           323:                        return;                 /* \{ ... \} on one line */
        !           324:                while (infalse && (c = getf(0))) {
        !           325:                        if (c == EBEG)
        !           326:                                ++infalse;
        !           327:                        else if (c == EEND)
        !           328:                                --infalse;      /* scan to matching \} */
        !           329:                }
        !           330:                while (getf(0) != '\n')
        !           331:                        ;                       /* then scan to newline */
        !           332:        }
        !           333: }
        !           334: 
        !           335: /*
        !           336:  * Set a value, saving old value.
        !           337:  * Called by various requests.
        !           338:  */
        !           339: setval(vp, op, arg, mul, div) int *vp, *op; char *arg; long mul, div;
        !           340: {
        !           341:        register int val;
        !           342: 
        !           343:        val = *vp;                                      /* save value */
        !           344:        *vp = number(arg, mul, div, val, 0, *op);       /* set value */
        !           345:        *op = val;                                      /* save old */
        !           346: }
        !           347: 
        !           348: /*
        !           349:  * Return the number of the named font.
        !           350:  * Return -1 if not found.
        !           351:  */
        !           352: int
        !           353: font_num(name) char name[2];
        !           354: {
        !           355:        register FTB *p;
        !           356: 
        !           357:        for (p = fontab; p < &fontab[NFNAMES]; p++) {
        !           358:                if (p->f_name[0] == '\0')
        !           359:                        break;
        !           360:                else if ((p->f_name[0] == name[0]) && (p->f_name[1] == name[1]))
        !           361:                        return p->f_font;
        !           362:        }
        !           363:        return -1;
        !           364: }
        !           365: 
        !           366: /*
        !           367:  * Return the number of the named font.
        !           368:  * Print an error message and return -1 if not found.
        !           369:  */
        !           370: int
        !           371: font_number(name, s) char name[2]; char *s;
        !           372: {
        !           373:        register int n;
        !           374: 
        !           375:        if ((n = font_num(name)) == -1)
        !           376:                printe("%scannot find font %c%c", (s==NULL) ? "" : s, name[0], name[1]);
        !           377:        return n;
        !           378: }
        !           379: 
        !           380: /*
        !           381:  * Assign a font number to a name.
        !           382:  * If there is no font of the given name, add one.
        !           383:  * Return the previously assigned font number, or -1 if none.
        !           384:  */
        !           385: int
        !           386: assign_font(name, c) char *name; int c;
        !           387: {
        !           388:        char a, b;
        !           389:        register FTB *p;
        !           390: 
        !           391:        a = name[0];
        !           392:        b = name[1];
        !           393:        for (p = fontab; p < &fontab[NFNAMES]; p++) {
        !           394:                if ((p->f_name[0] == a) && (p->f_name[1] == b)) {
        !           395: 
        !           396:                        /* Replace existing entry */
        !           397:                        a = p->f_font;
        !           398:                        p->f_font = c;
        !           399: 
        !           400:                        /* Watch for current, tab, underline fonts. */
        !           401:                        if (a == curfont)
        !           402:                                dev_font(c);
        !           403:                        if (a == tfn)
        !           404:                                tfn = c;
        !           405:                        if (a == ufn)
        !           406:                                ufn = c;
        !           407: 
        !           408:                        return a;
        !           409:                } else if (p->f_name[0] == '\0') {
        !           410:                        /* Add new entry */
        !           411:                        p->f_name[0] = a;
        !           412:                        p->f_name[1] = b;
        !           413:                        p->f_font    = c;
        !           414:                        return -1;
        !           415:                }
        !           416:        }
        !           417:        printe("no room for new font name %c%c", a, ((b) ? b : ' '));
        !           418:        return -1;
        !           419: }
        !           420: 
        !           421: /*
        !           422:  * Given a font number, change font.
        !           423:  */
        !           424: setfontnum(n, setflag) register int n; int setflag;
        !           425: {
        !           426:        register FTB *p;
        !           427: 
        !           428:        for (p = fontab; p < &fontab[NFNAMES]; p++) {
        !           429:                if (p->f_font == n) {
        !           430:                        setfont(p->f_name, setflag);
        !           431:                        return;
        !           432:                } else if (p->f_name[0] == '\0')
        !           433:                        break;
        !           434:        }
        !           435:        printe("cannot find font %d", n);
        !           436: }
        !           437: 
        !           438: /*
        !           439:  * Given a font name, change font.
        !           440:  * Understands \fP and \fn, saves previous font in oldfon.
        !           441:  * Return the new font number, or -1 if not found.
        !           442:  * dev_font() does the real work.
        !           443:  */
        !           444: int
        !           445: setfont(name, setflag) char name[2]; int setflag;
        !           446: {
        !           447:        register int n;
        !           448: 
        !           449:        if ((name[0] >= '0') && (name[0] <= '9')) {
        !           450:                n = name[0] - '0';
        !           451:                name[0] = mapfont[n][0];
        !           452:                name[1] = mapfont[n][1];
        !           453:        }
        !           454:        if (name[0]=='P' && name[1]=='\0') {
        !           455:                name[0] = oldfon[0];
        !           456:                name[1] = oldfon[1];
        !           457:        }
        !           458:        if ((n = font_number(name, NULL)) < 0) {
        !           459:                if (setflag) {
        !           460:                        /*
        !           461:                         * Bogus font change sets oldfon so \fP gets back
        !           462:                         * from the bogus font to the present font.
        !           463:                         * The bogus font change is really ignored.
        !           464:                         */
        !           465:                        oldfon[0] = fon[0];
        !           466:                        oldfon[1] = fon[1];
        !           467:                }
        !           468:                return -1;
        !           469:        }
        !           470:        dev_font(n);
        !           471:        if (setflag) {
        !           472:                oldfon[0] = fon[0];
        !           473:                oldfon[1] = fon[1];
        !           474:                fon[0] = name[0];
        !           475:                fon[1] = name[1];
        !           476:        }
        !           477:        return n;
        !           478: }
        !           479: 
        !           480: /*
        !           481:  * Print out a warning.
        !           482:  */
        !           483: /*VARARGS*/
        !           484: printe(a1) char *a1;
        !           485: {
        !           486:        register STR *sp;
        !           487: 
        !           488:        fprintf(stderr, "%s: ", argv0);
        !           489:        for (sp=strp; sp; sp=sp->x1.s_next) {
        !           490:                if (sp->x1.s_type == SFILE) {
        !           491:                        fprintf(stderr, "%s: %d: ", sp->x2.s_fname, sp->x2.s_clnc);
        !           492:                        break;
        !           493:                }
        !           494:        }
        !           495:        fprintf(stderr, "%r\n", &a1);
        !           496:        if (dflag)
        !           497:                fprintf(stderr, "Request: %s\n", miscbuf);
        !           498: }
        !           499: 
        !           500: /*
        !           501:  * Print an unimplemented warning.
        !           502:  */
        !           503: printu(s) char *s;
        !           504: {
        !           505:        printe("%s not implemented yet", s);
        !           506: }
        !           507: 
        !           508: /*
        !           509:  * An irrecoverable error was found.
        !           510:  * Print out an error message and leave.
        !           511:  */
        !           512: /*VARARGS*/
        !           513: panic(s)
        !           514: {
        !           515:        fprintf(stderr, "%s: %r\n", argv0, &s);
        !           516:        leave(1);
        !           517: }
        !           518: 
        !           519: /* Debug stuff follows, used to be in codebug.c. */
        !           520: 
        !           521: #if    (DDEBUG != 0)
        !           522: #if    (DDEBUG & DBGCODE)
        !           523: 
        !           524: static char *codtab[] = {
        !           525:        "DNULL",
        !           526:        "DHMOV (move horizontal)",
        !           527:        "DVMOV (move vertical)",
        !           528:        "DFONT (change font)",
        !           529:        "DPSZE (change pointsize)",
        !           530:        "DSPAR (space down and return)",
        !           531:        "DPADC (Paddable character)",
        !           532:        "DHYPH (Place to hyphenate)",
        !           533:        "DHYPC (Hyphen character)"
        !           534:        };
        !           535: 
        !           536: codebug(code, parm1)
        !           537: {
        !           538:        if (code <= 0) {
        !           539:                printd(DBGCODE, "%s %u\n", codtab[-code], parm1);
        !           540:        } else {
        !           541:                printd(DBGCODE, "%c (width=%d)\n", code, parm1);
        !           542:        }
        !           543: }
        !           544: #endif
        !           545: 
        !           546: static char *dbgtbl[] = {
        !           547:        "CHECKpoints",
        !           548:        "REGisterS",
        !           549:        "REGister eXecution",
        !           550:        "output CODEs",
        !           551:        "DIVeRsions",
        !           552:        "FILEs",
        !           553:        "FUNCtions",
        !           554:        "CHARacters",
        !           555:        "PROCess trace",
        !           556:        "MACro eXecution",
        !           557:        "MISCelaneous",
        !           558:        "MOVEment",
        !           559:        "ENViRonment",
        !           560:        "CALL tracing"
        !           561: };
        !           562: 
        !           563: printd(lvl, fmt)
        !           564: int lvl;
        !           565: char *fmt;
        !           566: {
        !           567:        if (lvl & dbglvl)
        !           568:                fprintf(stderr, "%r", &fmt);
        !           569: }
        !           570: 
        !           571: void dbginit()
        !           572: {
        !           573:        register int t=dbglvl;
        !           574:        register int j;
        !           575:        register int m=1;
        !           576: 
        !           577:        if (dbglvl == 0)
        !           578:                return;
        !           579:        for (j=0; j<15; j++) {
        !           580:                if (t & m)
        !           581:                        fprintf(stderr, "debugging %s\n", dbgtbl[j]);
        !           582:                m <<= 1;
        !           583:        }
        !           584: }
        !           585: #endif
        !           586: 
        !           587: /* end of misc.c */

unix.superglobalmegacorp.com

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