Annotation of researchv9/cmd/emacs/ecomp.c, revision 1.1.1.1

1.1       root        1: #include <stdio.h>
                      2: #ifdef PC
                      3: #include "../pcompile/adapt.h"
                      4: #define setbin(file) _isbin[file->_file] = 1;
                      5: #undef getchar
                      6: #undef putchar
                      7: #define getchar()      fgetc(stdin)
                      8: #define putchar(x)     fputc((x), stdout)
                      9: #endif
                     10: extern char *getenv();
                     11: 
                     12: #define CTRLX 030
                     13: #define CMENT 034
                     14: #define META(x) (x+0200)
                     15: #define CTRL(x) (x^0100)
                     16: 
                     17: #define BAD 0
                     18: #define SIMPLE 1
                     19: #define SDCL 2
                     20: #define CASE 3
                     21: #define COND 4
                     22: #define BEGIN 5
                     23: #define WHILE 6
                     24: #define PSTRING 7
                     25: #define NUMBER 8
                     26: #define BINARY 9
                     27: #define UNARY 10
                     28: #define QUOTE 11
                     29: #define INSERT 12
                     30: #define XSTRING 13
                     31: #define DCL 14
                     32: #define LOCAL 15
                     33: #define CHAR 16
                     34: #define MAP 17
                     35: #define GLOBAL 18
                     36: #define SGLOBAL 19
                     37: #define SVAL 256                       /* Returns string value */
                     38: #define DOUBLE 512                                     /* Command is really 2 base commands */
                     39: 
                     40: #ifndef PC
                     41: char *defdir = SDIR;
                     42: #define DEFILE "emacs_defs"
                     43: #endif
                     44: 
                     45: int line = 1;
                     46: int DEBUG = 0;
                     47: char *typetable[] = {
                     48:        "BAD","SIMPLE","SDCL","CASE","COND","BEGIN","WHILE",
                     49:        "SSTRING","NUMBER","BINARY","UNARY","QUOTE","INSERT",
                     50:        "STRING","DCL","LOCAL","CHAR","MAP","GLOBAL","SGLOBAL",NULL,
                     51: };
                     52: 
                     53: #define NHOOKS 10
                     54: char *hooks[NHOOKS] = {
                     55:        "No_Hook",
                     56:        "Pre_Read_Hook",
                     57:        "Post_Read_Hook",
                     58:        "Pre_Write_Hook",
                     59:        "Load_Macro_Hook",
                     60:        "Read_Line_Hook",
                     61:        "Mode_Line_Hook",
                     62:        "Exit_Emacs_Hook",
                     63:        "Leave_Buffer_Hook",
                     64:        "Enter_Buffer_Hook",
                     65: };
                     66: 
                     67: extern char *malloc();
                     68: struct defblk {
                     69:        struct defblk *next;
                     70:        char *name;
                     71:        int type;
                     72:        char *body;
                     73: };
                     74: 
                     75: /* Definitions for expression contexts */
                     76: 
                     77: #define CARG 1                                 /* function argument */
                     78: #define CSINGLE 2                      /* Must produce single command */
                     79: #define CSTRING 4                      /* Argument to string type function */
                     80: 
                     81: #define CCONT 8                                /* Must generate pass-last-result after command */
                     82: #define CCLOSE 16                      /* Must generate a closing brace */
                     83: 
                     84: #define NLOCAL 10
                     85: char *locals[NLOCAL];
                     86: int nlocal=NLOCAL;
                     87: 
                     88: #define NHASH 256
                     89: struct defblk *hashtable[NHASH];
                     90: 
                     91: char symbuf[128];
                     92: 
                     93: char *
                     94: mstrcpy(cp,cp1)
                     95: 
                     96: /* Keywords: assignment string-handling */
                     97: register char *cp;
                     98: register char *cp1;
                     99: {
                    100:        while (*cp++ = *cp1++);
                    101:        return(cp-1);
                    102: }
                    103: 
                    104: wrdchr(c)
                    105: int c;
                    106: {
                    107:        if ((c>='a') && (c <= 'z')) return(1);
                    108:        if ((c>='A') && (c <= 'Z')) return(1);
                    109:        if ((c>='0') && (c <= '9')) return(1);
                    110:        return(0);
                    111: }
                    112: 
                    113: char *
                    114: expenv(str)
                    115: register char *str;
                    116: /* Keywords: environment-variables unix-interface user-interface:20 shell-escape:10 */
                    117: {
                    118:        char strtemp[128];
                    119:        char vartemp [64];
                    120:        register char *cp1;
                    121:        char *cp2;
                    122:        register int c;
                    123:        int oc;
                    124:        
                    125:        if (str == NULL) return(NULL);
                    126:                
                    127:        cp1 = strtemp;
                    128:        cp2 = str;
                    129:        while (*cp1++ = *str) {
                    130:                if ((*str== '`')||(*str=='*')||(*str=='{')||(*str=='[')||((*str++)=='?')) {
                    131:                        return("Error");
                    132:                }
                    133:        }
                    134:        cp1 = strtemp;
                    135:        str = symbuf;                   /* always copy back into file name */
                    136:        while (c = *cp1++) {
                    137:                if ((c == '$')|| (c == '~')) {
                    138: 
                    139: /* Environment variable */
                    140:                        
                    141:                        oc = c;
                    142:                        cp2 = vartemp;
                    143:                        while (wrdchr(c=((*cp1++)&0377))) {
                    144:                                *cp2++ = c;
                    145:                        }
                    146:                        cp1--;          /* backspace pointer */
                    147:                        *cp2 = 0;
                    148:                        if (oc == '$') {
                    149:                                cp2 = getenv(vartemp); /* environment variable */
                    150:                        } else {
                    151: /* Home Directory */
                    152:                        
                    153:                                if (*vartemp == 0) {
                    154:                                        cp2 = getenv("HOME"); /* Bare ~ means home */
                    155:                                } else if ((strcmp(vartemp,"exptools")==0) &&
                    156:                                        (cp2 = getenv("TOOLS")) && *cp2) {
                    157:                                        ;
                    158:                                } else {
                    159:                                        return("Error"); /* Can't do it */
                    160:                                        
                    161:                                }
                    162:                        }
                    163:                        if (cp2 != NULL) {      
                    164:                                str = mstrcpy(str,cp2);
                    165:                        } else {
                    166:                                *str++ = oc;
                    167:                                str = mstrcpy(str,vartemp);
                    168:                        }
                    169:                } else {
                    170:                        *str++ = c;
                    171:                }
                    172:        }
                    173:        *str++ = 0;
                    174:        return(symbuf);
                    175: }
                    176: char macb[128];
                    177: char *
                    178: macbody(name)
                    179: char *name;
                    180: {
                    181:        char *bp;
                    182:        bp = macb;
                    183:        *bp++ = META('x');
                    184:        while (*name) *bp++ = *name++;
                    185:        *bp++ = '\n';
                    186:        *bp++ = 0;
                    187:        return(macb);
                    188: }
                    189: struct defblk *
                    190: getname(name)
                    191: 
                    192: char *name;
                    193: {
                    194:        int hash;
                    195:        char *np;
                    196:        struct defblk *defp;
                    197: 
                    198:        np = name;
                    199:        hash = 0;
                    200:        while (*np) hash += *np++;
                    201:        hash = hash %NHASH;
                    202:        defp = hashtable[hash];
                    203:        while (defp && strcmp(name,defp->name)) defp = defp->next;
                    204:        if (defp == NULL) {
                    205:                defp = ((struct defblk *) malloc(sizeof(*defp)));
                    206:                defp->next = hashtable[hash];
                    207:                hashtable[hash] = defp;
                    208:                defp->name = malloc(strlen(name)+1);
                    209:                strcpy(defp->name,name);
                    210:                if ((*name == '-') || ((*name>='0') && (*name <= '9'))) {
                    211:                        defp->type = NUMBER;
                    212:                        defp->body = malloc(strlen(name)+1);
                    213:                        defp->body[0] = defp->name[0]+0200;
                    214:                        strcpy(defp->body+1,defp->name+1);
                    215:                } else if ((*name == '\'')  && (name[2] == '\'') && (name[3] == 0)) {
                    216:                        defp->type = SIMPLE;
                    217:                        defp->body = malloc(3);
                    218:                        defp->body[0] = META(CTRL('Q'));
                    219:                        defp->body[1] = name[1];
                    220:                        defp->body[2] = 0;
                    221:                } else {
                    222:                        fprintf(stderr,"Undefined command name %s at line %d, assumed external\n",name,line);
                    223:                        defp->type = SIMPLE;
                    224:                        name = macbody(name);
                    225:                        defp->body = malloc(strlen(name));
                    226:                        strcpy(defp->body,name);
                    227:                }
                    228:        }
                    229:        return(defp);
                    230: }
                    231: 
                    232: lookhook(name)
                    233: char *name;
                    234: {
                    235:        register int i;
                    236:        for (i = 1; i < NHOOKS; i++) if(strcmp(name,hooks[i]) == 0) return(i);
                    237:        return(0);
                    238: }
                    239: undefine(name)
                    240: 
                    241: char *name;
                    242: {
                    243:        int hash;
                    244:        char *np;
                    245:        struct defblk *defp;
                    246:        struct defblk  *odefp;
                    247:        np = name;
                    248:        hash = 0;
                    249:        while (*np) hash += *np++;
                    250:        hash = hash %NHASH;
                    251:        defp = hashtable[hash];
                    252:        odefp = ((struct defblk *) &hashtable[hash]);
                    253:        while (defp && strcmp(name,defp->name)) {
                    254:                odefp = defp;
                    255:                defp = defp->next;
                    256:        }
                    257:        if (defp) odefp->next = defp->next;
                    258:        else {
                    259:                fprintf(stderr,"Internal error undefining symbol %s\n",name);
                    260:        }
                    261: }
                    262: define(name,type,body)
                    263: 
                    264: char *name;
                    265: char *body;
                    266: int type;
                    267: {
                    268:        int hash;
                    269:        char *np;
                    270:        struct defblk *defp;
                    271: 
                    272:        np = name;
                    273:        hash = 0;
                    274:        while (*np) hash += *np++;
                    275:        hash = hash %NHASH;
                    276:        defp = hashtable[hash];
                    277:        while (defp && strcmp(name,defp->name)) defp = defp->next;
                    278:        if (defp == NULL) {
                    279:                defp = ((struct defblk *) malloc(sizeof(*defp)));
                    280:                defp->next = hashtable[hash];
                    281:                hashtable[hash] = defp;
                    282:                defp->name = malloc(strlen(name)+1);
                    283:                strcpy(defp->name,name);
                    284:        }
                    285:        defp->type = type;
                    286:        defp->body = malloc(strlen(body)+1);
                    287:        strcpy(defp->body,body);
                    288: }
                    289: 
                    290: definit()
                    291: {
                    292:        int i;
                    293:        for (i = 0; i < NHASH; i++) {
                    294:                hashtable[i] = NULL;
                    295:        }
                    296: }
                    297: 
                    298: 
                    299: char *
                    300: symbol()
                    301: {
                    302:        char *sp;
                    303:        int c;
                    304: 
                    305:        sp = symbuf;
                    306:        c = nonblank(1);
                    307:        ungetc(c,stdin);
                    308:        while (1) {
                    309:                c = gochar();
                    310:                if ((c == EOF) || (c == ' ')|| (c == '  ')|| (c == ')') ||
                    311:                        (c == '(') || (c == '\n')) break;
                    312:                *sp++ = c;
                    313:        }
                    314:        ungetc(c,stdin);
                    315:        if (c == '\n') line--;          /* Uncount newline */
                    316:        *sp = 0;
                    317:        return(symbuf);
                    318: }
                    319: 
                    320: read_defs()
                    321: {
                    322:        FILE *fp;
                    323:        char name[128];
                    324:        int type;
                    325:        char body[128];
                    326:        char *cp;
                    327:        int c;
                    328:        
                    329: #ifdef PC
                    330:        fp = fopen ("edefs.dat","r");
                    331:        if (fp == NULL) fp = fopen ("a:edefs.dat","r");
                    332:        if (fp == NULL) fp = fopen ("b:edefs.dat","r");
                    333:        if (fp == NULL) fp = fopen ("c:edefs.dat","r"); 
                    334:        if (fp == NULL) {
                    335:                printf ("Can't find definitions file edefs.dat\n");
                    336:                exit(0);
                    337:        }
                    338:        setbin(fp);
                    339: #else  
                    340:        cp = expenv(defdir);
                    341:        sprintf(name,"%s/%s",cp,DEFILE);
                    342:        fp = fopen (name,"r");
                    343:        if (fp == NULL) {
                    344:                fprintf(stderr,"Can't open definitions file: %s\n",name);
                    345:                fprintf(stderr,"Please contact your local emacs maintainer\n");
                    346:                exit(-1);
                    347:        }
                    348: #endif
                    349:        while ((c = fgetc(fp)) != EOF) {
                    350:                if (c != '(') fprintf(stderr,"Internal error, bad def file format %c\n",c);
                    351:                symbin(fp,name);
                    352:                symbin(fp,body);
                    353:                type = gtype(body);
                    354:                if ((type&0377) == BAD) fprintf(stderr,"Internal error, Bad type %s for symbol %s in defs file\n",body,name);
                    355:                symbin(fp,body);
                    356:                while ((c = fgetc(fp)) != '\n');
                    357:                define(name,type,body);
                    358:        }
                    359:        fclose(fp);
                    360: }
                    361: 
                    362: gtype(name)
                    363: 
                    364: /* Returns type of name is a type definition, 0 otherwise */
                    365: 
                    366: char *name;
                    367: {
                    368:        int c;
                    369:        int type;
                    370:        
                    371:        type = BAD;
                    372:        if (*name == '$') {
                    373:                type |= SVAL;
                    374:                name++;
                    375:        }
                    376:        c = 0;
                    377:        while (typetable[c]) if (strcmp(typetable[c],name) == 0) {
                    378:                type |= c;
                    379:                break;
                    380:        } else c++;
                    381:        return(type);
                    382: }
                    383: 
                    384: symbin(fp,xp)
                    385: FILE *fp;
                    386: char *xp;
                    387: {
                    388:        int c;
                    389:        do {
                    390:                c = fgetc(fp);
                    391:        } while ((c == ' ') || (c == '\n'));
                    392:        ungetc(c,fp);
                    393:        while (1) {
                    394:                c = fgetc(fp);
                    395:                if ((c == EOF) || (c == ' ') || (c == ')') ||
                    396:                        (c == '(') || (c == '\n')) break;
                    397:                if (c == '\\') {
                    398:                        c = fgetc(fp)-'0';
                    399:                        c = c * 8 + (fgetc(fp)-'0');
                    400:                        c = c * 8 + (fgetc(fp)-'0');
                    401:                }
                    402:                *xp++ = c;
                    403:        }
                    404:        ungetc(c,fp);
                    405:        *xp = 0;
                    406: }
                    407: 
                    408:                
                    409: main(argc, argv)
                    410: 
                    411: int argc;
                    412: char *argv [];
                    413: 
                    414: {
                    415:        int c;
                    416:        
                    417:        if (argc>1) {
                    418:                char buf[256];
                    419:                int x;
                    420:                strcpy(buf,argv[1]);
                    421:                x = strlen(buf);
                    422:                if ((buf[x-2] != '.') || (buf[x-1] != 'e')) {
                    423:                        buf[x++]= '.';
                    424:                        buf[x++] = 'e';
                    425:                        buf[x]=0;
                    426:                }
                    427:                if (freopen(buf,"r",stdin) == NULL) {
                    428:                        fprintf(stderr,"Can't open input file %s\n",buf);
                    429:                        exit(-1);
                    430:                }
                    431:                buf[x-2]=0;
                    432:                if (freopen(buf,"w",stdout) == NULL) {
                    433:                        fprintf(stderr,"Can't open output file %s\n",buf);
                    434:                        exit(-1);
                    435:                }
                    436: #ifdef PC
                    437:                setbin(stdout);
                    438: #endif
                    439:        }
                    440:        definit();
                    441:        read_defs();
                    442:        c = getchar();
                    443:        if (c == '#') {
                    444:                DEBUG=1;
                    445:        } else {
                    446:                ungetc(c,stdin);
                    447:        }
                    448:        while ((c = nonblank(0)) != EOF) {
                    449:                if (c == '(' ) function();
                    450:        }
                    451: }
                    452: 
                    453: 
                    454: char *
                    455: glob(name,body,arg)
                    456: char *name;
                    457: char *body;
                    458: int arg;
                    459: {
                    460:        char *bp;
                    461:        bp = macb;
                    462:        *bp++ = CTRL('X');
                    463:        *bp++ = '<';
                    464:        while (*name) *bp++ = *name++;
                    465:        *bp++ = '\n';
                    466:        *bp++ = arg;
                    467:        while (*body) *bp++ = *body++;
                    468:        *bp=0;
                    469:        return(macb);
                    470: }
                    471: 
                    472: 
                    473: function()
                    474: {
                    475:        char *name;
                    476:        
                    477:        int c;
                    478:        int type;
                    479:        int nobind;
                    480:        
                    481:        c = nonblank(0);
                    482:        if (c == '(') {
                    483:                c = gochar();
                    484:                while (c != ')') {
                    485:                        if (c == EOF) {
                    486:                                fprintf(stderr,"Error, macro binding sequence does not terminate\n");
                    487:                                return;
                    488:                        }
                    489:                        putchar(c);
                    490:                        c = gochar();
                    491:                        nobind = 0;
                    492:                }
                    493:        } else {
                    494:                ungetc(c,stdin);
                    495:                nobind=1;
                    496:        }
                    497: 
                    498:        name = symbol();
                    499:        if (type=gtype(name)) {         /* Name is a symbol declaration */
                    500:                name = symbol();        /* Now get real symbol */
                    501:        } else type = SIMPLE;           /* Defaults to simple macro */
                    502:        if (nobind) {
                    503:                nobind = lookhook(name);
                    504:                putchar(CTRL('Z'));
                    505:                putchar(nobind);
                    506:        }
                    507:        putchar (CMENT);                        /* ^/ */
                    508:        PUTS(name);
                    509:        define(name,type,macbody(name));
                    510:        putchar (' ');
                    511:        c = nonblank(0);
                    512:        if (c != '(') fprintf(stderr,"Bad syntax for macro definition at line %d\n",line);
                    513:        while ((c = getchar()) != ')') {
                    514:                if (c == EOF) break;
                    515:                putchar(c);
                    516:                if (c == '\n') {
                    517:                        putchar(CMENT);
                    518:                        line++;
                    519:                }
                    520:        }
                    521:        putchar('\n');
                    522:        parseform(0);
                    523:        putchar (CTRL('Z'));
                    524:        putchar('\n');
                    525:        
                    526:        while (nlocal < NLOCAL) {
                    527:                undefine(locals[nlocal]);
                    528:                locals[nlocal] [strlen(locals[nlocal])-1] = 0;
                    529:                undefine(locals[nlocal]);
                    530:                nlocal++;
                    531:        }
                    532: }
                    533: parseform(flags)
                    534: int flags;
                    535: {
                    536:        int c;
                    537:        
                    538:        if (DEBUG) fprintf(stderr,"parseform\n");
                    539:        /* Now parse the form */
                    540:        while ((c = nonblank(1)) != ')') {
                    541:                if (c == EOF) {
                    542:                                                                                                                                                /* ARGH!! unterminated form */
                    543:                        fprintf(stderr,"Unterminated form at line %d\n",line);
                    544:                        return;
                    545:                }
                    546:                if (parsememb(c,flags)&CCLOSE) fprintf(stderr,"Internal error in parsememb at line %d\n",line); 
                    547:                flags = 0;
                    548:        }
                    549: }
                    550: parsememb(c,context)
                    551: int c;
                    552: int context;
                    553: {
                    554:        char *oname;
                    555:        char *name;
                    556:        struct defblk *defp;    
                    557:        int retflags,retval;
                    558: 
                    559:        retflags = 0;   
                    560:        if (c == ')') {
                    561:                ungetc(c,stdin); /* handle users typing '(foo)'  */
                    562:                return(0);
                    563:        }
                    564:        if (c == '(') {
                    565:                name = symbol();
                    566:                defp = getname(name);
                    567:                if (DEBUG) fprintf(stderr,"parsememb complex %s type %s context %d\n",name,typetable[(defp->type&0377)],context);
                    568:                if (defp->type & SVAL) retflags |= CSTRING;
                    569:                if ((defp->type & DOUBLE) && (context & CSINGLE)) {
                    570:                        putchar(META('{'));
                    571:                        retflags |= CCLOSE;
                    572:                        context^= CSINGLE;
                    573:                }
                    574:                if (context & CARG) {
                    575:                        if ((defp->type & SVAL) == 0) retflags |= CCONT;
                    576:                        if (context&CSINGLE)   {
                    577:                                putchar(META('{'));
                    578:                                retflags |= CCLOSE;
                    579:                                context ^= CSINGLE;
                    580:                        }
                    581:                }
                    582:                switch(defp->type&0377) {
                    583: 
                    584:                case GLOBAL:
                    585:                        name = symbol();
                    586:                        define (name,SIMPLE+DOUBLE,glob(name,defp->body,META('1')));
                    587:                        c = strlen(name);
                    588:                        oname = glob(name,defp->body,META('2'));
                    589:                        name[c]='=';
                    590:                        name[c+1] = 0;
                    591:                        define (name,UNARY+DOUBLE,oname);
                    592:                        closep(defp->name);
                    593:                        break;
                    594:                case SGLOBAL:
                    595:                {
                    596:                        char sbuf[128];
                    597:                        
                    598:                        name = symbol();
                    599:                        sprintf(sbuf,"%c<%s\n%s",CTRL('X'),name,defp->body);
                    600:                        define (name,SIMPLE+DOUBLE+SVAL,sbuf);
                    601:                        
                    602:                        sprintf(sbuf,"%s=",defp->name);
                    603:                        defp = getname(sbuf); /* Look up giberish for def */
                    604:                        sprintf(sbuf,"%c<%s\n%s",CTRL('X'),name,defp->body);
                    605:                        c = strlen(name);
                    606:                        name[c]='=';
                    607:                        name[c+1] = 0;
                    608:                        define (name,XSTRING+DOUBLE,sbuf);
                    609:                        closep(defp->name);
                    610:                        }
                    611:                        break;
                    612: 
                    613:                case DCL:
                    614:                        name = symbol();
                    615:                        if (c = gtype(name)) {
                    616:                                name = symbol();
                    617:                        } else c = SIMPLE;
                    618:                        define(name,c,macbody(name));
                    619:                        closep(name);
                    620:                        break;
                    621:                case LOCAL:
                    622:                        name = symbol();
                    623:                        if (--nlocal <= 1) {
                    624:                                fprintf (stderr,"Too many local declarations, symbol %s ignored at line %d\n",name,line);
                    625:                                ++nlocal;
                    626:                        } else {
                    627:                                char bod[4];
                    628:                                int x;
                    629:                                
                    630:                                bod[0] = META('0')+nlocal;
                    631:                                bod[1] = CTRL(']');
                    632:                                bod[2] = 0;
                    633:                                
                    634:                                define(name,NUMBER,bod);
                    635:                                x = strlen(name);
                    636:                                name[x]='=';
                    637:                                name[x+1] = 0;
                    638:                                bod[1] = META(CTRL(']'));
                    639:                                define(name,UNARY,bod);
                    640:                                defp = getname(name);
                    641:                                locals[nlocal] = defp->name;  
                    642:                        }
                    643:                        closep(name);
                    644:                        break;
                    645:                case SDCL:
                    646:                        name = symbol();
                    647:                        if (--nlocal <= 1) {
                    648:                                fprintf (stderr,"Too many local declarations, symbol %s ignored at line %d\n",name,line);
                    649:                                ++nlocal;
                    650:                        } else {
                    651:                                char bod[10];
                    652:                                int x;
                    653:                                
                    654:                                bod[0] = META('1');
                    655:                                bod[1] = '2';
                    656:                                bod[2] = CTRL('X');
                    657:                                bod[3] = '&';
                    658:                                bod[4] = META('0')+nlocal;
                    659:                                bod[5] = CTRL(']');
                    660:                                bod[6] = CTRL('Z');
                    661:                                bod[7] = 0;
                    662:                                define(name,SIMPLE+SVAL,bod);
                    663:                                x = strlen(name);
                    664:                                name[x]='=';
                    665:                                name[x+1] = 0;
                    666:                                bod[0] = META('0')+nlocal;
                    667:                                bod[1] = META(CTRL(']'));
                    668:                                bod[2] = META('1');
                    669:                                bod[3] = '1';
                    670:                                bod[4] = CTRL('X');
                    671:                                bod[5] = '&';
                    672:                                bod[6] = 0;
                    673:                                define(name,XSTRING,bod);
                    674:                                defp = getname(name);
                    675:                                locals[nlocal] = defp->name;  
                    676:                        }
                    677:                        closep(name);
                    678:                        break;
                    679:                case SIMPLE:
                    680:                        {
                    681:                                char nbuf[128];
                    682:                                
                    683:                                strcpy(nbuf,name);
                    684:                                c = nonblank(1);
                    685:                                retflags |= parsememb(c,CARG|(context&CSINGLE));
                    686:                                PUTS(defp->body);
                    687:                                closep(nbuf);
                    688:                        }
                    689:                        break;
                    690:                case NUMBER:
                    691:                        PUTS (defp->body);
                    692:                        putchar(CTRL('Z'));
                    693:                        closep(name);
                    694:                        break;
                    695:                case QUOTE:
                    696:                        PUTS(defp->body);
                    697:                        putchar(nonblank(1));
                    698:                        closep(name);
                    699:                        break;
                    700:                case BINARY:
                    701:                        PUTS(defp->body);
                    702:                        c = nonblank(1);
                    703:                        parsememb(c,CSINGLE);
                    704:                        c = nonblank(1);
                    705:                        parsememb(c,CSINGLE);
                    706:                        closep(name);
                    707:                        break;
                    708:                case UNARY:
                    709:                        PUTS(defp->body);
                    710:                        c = nonblank(1);
                    711:                        parsememb(c,CSINGLE);
                    712:                        closep(name);
                    713:                        break;
                    714:                case BEGIN:
                    715:                        putchar (META('{'));
                    716:                        parseform(0);
                    717:                        putchar (META('}'));
                    718:                        break;
                    719:                case WHILE:
                    720:                        putchar (CTRLX);
                    721:                        putchar ('^');
                    722:                        putchar (META('{'));
                    723:                        parseform(CSINGLE);
                    724:                        putchar (META('}'));
                    725:                        break;
                    726:                case CASE:
                    727:                        putchar (CTRLX);
                    728:                        putchar ('!');
                    729:                        putchar (META('{'));
                    730:                        c = nonblank(1);
                    731:                        parsememb(c,CSINGLE);
                    732:                        while (1) {
                    733:                                c = nonblank(1);
                    734:                                if (c == ')') break;
                    735:                                if (c != '(') {
                    736:                                        fprintf(stderr,"Syntax error in case at line %d, character %c\n",line,c);
                    737:                                        if (c == EOF) break;                    /* Best we can do */
                    738:                                        continue;
                    739:                                }
                    740:                                putchar (META('{'));
                    741:                                c = gochar();
                    742:                                if (c == 'e') {
                    743:                                        int c1;
                    744:                                        c1 = gochar();
                    745:                                        if (c1 == 'l') {
                    746:                                                c1 = gochar();
                    747:                                                c1 = gochar();
                    748:                                                c = 0377; /* Default case */
                    749:                                        } else ungetc(c1,stdin);
                    750:                                }
                    751:                                putchar(c);
                    752:                                parseform(0);
                    753:                                putchar (META('}'));
                    754:                        }
                    755:                        putchar (META('}'));
                    756:                        break;
                    757:                case COND:
                    758:                        putchar(CTRLX);
                    759:                        putchar ('|');
                    760:                        putchar (META('{'));
                    761:                        while (1) {
                    762:                                c = nonblank(1);
                    763:                                if (c == ')') {
                    764:                                        putchar (META('}'));
                    765:                                        break;
                    766:                                }
                    767:                                if (c != '(') {
                    768:                                        fprintf(stderr,"Syntax error in conditional at line %d, character %c\n",line,c);
                    769:                                        continue;
                    770:                                }
                    771:                                putchar(META('{'));
                    772:                                parseform(CSINGLE);
                    773:                                putchar(META('}'));
                    774:                        }
                    775:                        break;
                    776:                case INSERT:
                    777:                        c = nonblank(1);
                    778:                        if (c == '"') {
                    779:                                while ((c=gochar())  != '"') {
                    780:                                        if ((c <= 040) || ((c&0377) >= 0177)) {
                    781:                                                if ((c&0377) >= 0200) putchar(META('q'));
                    782:                                                else putchar(CTRL('Q'));
                    783:                                        }
                    784:                                        putchar(c&0177);
                    785:                                }
                    786:                        } else {
                    787:                                fprintf(stderr,"Argument to %s at line %d must be enclosed in quotes\n",name,line);
                    788:                        }
                    789:                        closep(name);
                    790:                        break;
                    791:                case MAP:
                    792:                        {
                    793:                                char buf[256];
                    794:                                char *cp;
                    795:                                c = nonblank(1);
                    796:                                if (c == '"') {
                    797:                                        pstring(buf);
                    798:                                } else {
                    799:                                        fprintf(stderr,"Argument to %s at line %d must be enclosed in quotes\n",name,line);
                    800:                                }
                    801:                                
                    802:                                while ((c = nonblank(1)) != ')') {
                    803:                                        retval = parsememb(c,CARG|CSTRING|(context&CSINGLE));
                    804:                                        if (retval & CCLOSE) {
                    805:                                                context &= ~CSINGLE;
                    806:                                                retflags |= CCLOSE;
                    807:                                        }
                    808:                                }
                    809:                                PUTS(defp->body);
                    810:                                cp = buf;
                    811:                                while (*cp) {
                    812:                                        putchar(*cp);
                    813:                                        cp++;
                    814:                                }
                    815:                        }
                    816:                        break;
                    817:                case CHAR:
                    818:                        {
                    819:                                char buf[10];
                    820:                                
                    821:                                buf[0] = nonblank(1);
                    822:                                if (buf[0] == CTRL('X')) {
                    823:                                        buf[1] = nonblank(1);
                    824:                                        buf[2]= 0;
                    825:                                } else buf[1] = 0;
                    826:                                c = nonblank(1);
                    827:                                if (c != ')') {
                    828:                                        retflags |= parsememb(c,CARG|(context&CSINGLE));
                    829:                                        closep(defp->name);
                    830:                                }
                    831:                                PUTS(buf);
                    832:                        }
                    833:                        break;
                    834:                case PSTRING:
                    835:                        {
                    836:                                char buf[256];
                    837:                                char *cp;
                    838:                                c = nonblank(1);
                    839:                                if (c == '"') {
                    840:                                        pstring(buf);
                    841:                                } else {
                    842: /* Argument is not a literal, must use the long form */
                    843:                                        ungetc(c,stdin);
                    844:                                        sprintf(buf,"L%s",defp->name);
                    845:                                        defp = getname(buf);
                    846:                                        goto xstring;   /* Process long form */
                    847:                                }
                    848:                                
                    849:                                while ((c = nonblank(1)) != ')') {
                    850:                                        retval = parsememb(c,CARG|CSTRING|(context&CSINGLE));
                    851:                                        if (retval & CCLOSE) {
                    852:                                                context &= ~CSINGLE;
                    853:                                                retflags |= CCLOSE;
                    854:                                        }
                    855:                                }
                    856:                                PUTS(defp->body);
                    857:                                cp = buf;
                    858:                                while (*cp) {
                    859:                                        if (*cp == '\n') putchar (CTRL('Q'));
                    860:                                        if (*cp == CTRL('Z')) putchar (CTRL('Q'));
                    861:                                        putchar(*cp);
                    862:                                        cp++;
                    863:                                }
                    864:                                putchar('\n');
                    865:                        }
                    866:                        break;
                    867:                case XSTRING:
                    868: xstring:               while ((c = nonblank(1)) != ')') {
                    869:                                retval = parsememb(c,CARG|CSTRING|(context&CSINGLE));
                    870:                                if (retval & CCLOSE) {
                    871:                                        context &= ~CSINGLE;
                    872:                                        retflags |= CCLOSE;
                    873:                                }
                    874:                        }
                    875:                        PUTS(defp->body);
                    876:                        break;
                    877:                default:
                    878:                        fprintf(stderr,"Error in parser at line %d, name %s\n",line,name);
                    879:                }
                    880:        } else {
                    881:                if (c == '"') {         /* String argument, if appropriate, push it */
                    882:                        if ((context & CSTRING) == 0) {
                    883:                                fprintf(stderr,"Misplaced character string at line %d\n",line);
                    884:                        }
                    885:                        if (context & CSINGLE) {
                    886:                                retflags |= CCLOSE;
                    887:                                putchar(META('{'));
                    888:                        }
                    889:                        putchar (CTRL('X'));
                    890:                        putchar ('<');
                    891:                        pstring (NULL);
                    892:                        retflags |= CSTRING;
                    893:                } else {
                    894:                        ungetc(c,stdin);
                    895:                        name = symbol();
                    896:                        defp = getname(name);
                    897:                        if (defp->type & SVAL) retflags |= CSTRING;
                    898:                        if ((defp->type & DOUBLE) && (context & CSINGLE)) {
                    899:                                putchar(META('{'));
                    900:                                retflags |= CCLOSE;
                    901:                                context^= CSINGLE;
                    902:                        }
                    903:                        if (DEBUG) fprintf(stderr,"parsememb simple %s type %s, context: %d\n",name,typetable[defp->type&0377],context);
                    904:                        switch(defp->type&0377) {
                    905:                        case SIMPLE:
                    906:                        case XSTRING:
                    907:                                if (context & CARG) {
                    908:                                        if ((defp->type & SVAL) == 0) retflags |= CCONT;
                    909:                                        if (context&CSINGLE)   {
                    910:                                                putchar(META('{'));
                    911:                                                retflags |= CCLOSE;
                    912:                                        }
                    913:                                }
                    914:                                PUTS(defp->body);
                    915:                                break;
                    916:                        case NUMBER:
                    917:                                PUTS (defp->body);
                    918:                                if ((context &CARG) == 0) putchar(CTRL('Z'));
                    919:                                break;
                    920:                        default:
                    921:                                fprintf(stderr,"function %s at line %d requires arguments\n",name,line);
                    922:                        }
                    923:                }
                    924:        }
                    925:        if (DEBUG) {
                    926:                c = getchar();
                    927:                fprintf(stderr,"exiting parsememb before %c\n",c);
                    928:                ungetc(c,stdin);
                    929:        }
                    930: 
                    931:        if (((context & CARG) == 0) && (retflags & CCLOSE)) {
                    932:                putchar(CTRL('^'));
                    933:                putchar(META('}'));
                    934:                retflags &= ~(CCLOSE|CARG);
                    935:        }
                    936:        if (retflags & CCONT) putchar(CTRL('^'));
                    937:        return(retflags & (CCLOSE^CSTRING));
                    938: }
                    939: closep(name)
                    940: char *name;
                    941: {
                    942:        int c;
                    943:        
                    944:        c = nonblank(1);
                    945:        if (c != ')') {
                    946:                fprintf(stderr,"Syntax error at line %d, extraneous characters in form after %s\n       Ignoring characters:",line,name);
                    947:                while ((c = getchar()) != ')') {
                    948:                        if (c == EOF) break;
                    949:                        fputc(c,stderr);
                    950:                }
                    951:                fputc('\n',stderr);
                    952:        }
                    953: }
                    954: gochar()
                    955: {
                    956:        int c;
                    957:        
                    958:        c = getchar();
                    959:        if (c == '\n') line++;
                    960:        if (c != '\\') return(c);
                    961:        else {
                    962:                c = getchar();
                    963:                if (c == 'n') return('\n'+01000);
                    964:                if ((c >= '0') && (c <= '7')) {
                    965:                        c -= '0';
                    966:                        c = c*8 + getchar() - '0';
                    967:                        c = c*8 + getchar() - '0';
                    968:                }
                    969:                return(c+01000);        /* Make sure it doesn't match anything */
                    970:        }
                    971: }
                    972: nonblank(cment)
                    973: int cment;
                    974: {
                    975:        int c;
                    976:        while (1) {
                    977:                c = gochar();
                    978:                if (c == EOF) return(c);
                    979:                if ((c == ' ') || (c == '       ')) continue;
                    980:                if (c == '\n') {
                    981:                        continue;
                    982:                }
                    983:                if (c == '/') {
                    984:                        if (cment) putchar(CMENT);
                    985:                        while ((c = getchar()) != '/') {
                    986:                                if (c == EOF) {
                    987:                                        fprintf(stderr,"unterminated comment");
                    988:                                        return(c);
                    989:                                }
                    990:                                if (cment) putchar(c);
                    991:                                if (c == '\n') {
                    992:                                        if (cment) putchar(CMENT);
                    993:                                        line++;
                    994:                                }
                    995:                        }
                    996:                        if (cment) putchar('\n');
                    997:                        continue;
                    998:                }
                    999:                return(c);
                   1000:        }
                   1001: }
                   1002: 
                   1003: PUTS(string)
                   1004: char *string;
                   1005: {
                   1006:        while (*string){
                   1007:                putchar(*string);
                   1008:                string++;
                   1009:        }
                   1010: }
                   1011: pstring(ptr)
                   1012: char *ptr;
                   1013: {
                   1014:        int c;  
                   1015:        int oline;
                   1016:        oline = line;
                   1017:        while ((c = gochar()) != '"') {
                   1018:                if (c == EOF) {
                   1019:                        fprintf(stderr,"Unterminated string starting at line %d\n",oline);
                   1020:                        break;
                   1021:                }
                   1022:                if (ptr) {
                   1023:                        *ptr++ = c;
                   1024:                } else {
                   1025:                        if ((c&0377) == '\n')  putchar(CTRL('Q'));
                   1026:                        if ((c&0377) == CTRL('Z'))  putchar(CTRL('Q'));
                   1027:                        putchar(c);
                   1028:                }
                   1029:        }
                   1030:        if (ptr) {
                   1031:                *ptr++ = 0;
                   1032:        } else {
                   1033:                putchar('\n');
                   1034:        }
                   1035: }
                   1036: 
                   1037: xgetc(fp)
                   1038: FILE *fp;
                   1039: {
                   1040:        int c;
                   1041:        
                   1042:        c= fgetc(fp);
                   1043:        fprintf(stderr,"got '%c' %o\n",c);
                   1044:        return(c);
                   1045: }

unix.superglobalmegacorp.com

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