Annotation of researchv8dc/cmd/cyntax/cem/cyntax.c, revision 1.1.1.1

1.1       root        1: #include       <sys/types.h>
                      2: #include       <sys/stat.h>
                      3: #include       <errno.h>
                      4: #include       <signal.h>
                      5: #include       <stdio.h>
                      6: 
                      7: /*
                      8:  *     Compiler front end program.
                      9:  *
                     10:  *     Bruce Ellis     - September 1984.
                     11:  */
                     12: 
                     13: /*
                     14:  *     Argument list structures.
                     15:  */
                     16: typedef struct arg     arg;
                     17: 
                     18: struct arg
                     19: {
                     20:        char    *a_str;
                     21:        arg     *a_next;
                     22: };
                     23: 
                     24: typedef struct
                     25: {
                     26:        arg     *a_head;
                     27:        arg     **a_tail;
                     28: }
                     29:        args;
                     30: 
                     31: /*
                     32:  *     Option structures.
                     33:  */
                     34: typedef enum
                     35: {
                     36:        c_bad,
                     37:        c_flag,
                     38:        c_function,
                     39:        c_negate,
                     40:        c_str_arg,
                     41:        c_str_func,
                     42:        c_string,
                     43: }
                     44:        opcode;
                     45: 
                     46: typedef struct
                     47: {
                     48:        opcode  o_code;
                     49:        args    **o_args;
                     50:        int     *o_flag;
                     51:        int     (*o_func)();
                     52: }
                     53:        option;
                     54: 
                     55: /*
                     56:  *     Exec argument structures.
                     57:  */
                     58: typedef enum
                     59: {
                     60:        e_args,
                     61:        e_input,
                     62:        e_literal,
                     63:        e_output,
                     64:        e_splice,
                     65:        e_string,
                     66: }
                     67:        eatype;
                     68: 
                     69: typedef struct earg    earg;
                     70: 
                     71: struct earg
                     72: {
                     73:        eatype  e_code;
                     74:        char    *e_str;
                     75:        char    **e_strp;
                     76:        args    **e_args;
                     77:        int     e_count;
                     78:        earg    *e_next;
                     79: };
                     80: 
                     81: typedef struct
                     82: {
                     83:        char    *e_path;
                     84:        earg    *e_list;
                     85: }
                     86:        eargs;
                     87: 
                     88: args           *files;
                     89: char           **tempv;
                     90: char           *input;
                     91: char           *my_name;
                     92: char           *output;
                     93: char           *object;
                     94: int            ntemps;
                     95: int            verbose;
                     96: 
                     97: extern int     errno;
                     98: extern char    *strcpy();
                     99: extern char    *strrchr();
                    100: extern int     strlen();
                    101: 
                    102: /*
                    103:  *     Cyntax.
                    104:  */
                    105: args           *comp_args;
                    106: args           *cpp_args;
                    107: args           *load_args;
                    108: char           *load_out;
                    109: char           *src_name;
                    110: int            cflag;
                    111: int            gflag;
                    112: int            hflag;
                    113: int            jerq;
                    114: int            multi_cfile;
                    115: int            pflag;
                    116: int            sflag;
                    117: int            ugflag;
                    118: int            ulflag;
                    119: int            uoflag;
                    120: int            upflag;
                    121: int            uzflag;
                    122: 
                    123: /*
                    124:  *     Path names.
                    125:  */
                    126: #define        CPP_PATH        "/lib/cpp"
                    127: #define        CPP_NAME        "cpp"
                    128: #define        COMP_PATH       "/usr/lib/cyntax/ccom"
                    129: #define        COMP_NAME       "ccom"
                    130: #define        SETS_PATH       "/lib/sets"
                    131: #define        SETS_NAME       "sets"
                    132: #define        COMP_PATH       "/usr/lib/cyntax/ccom"
                    133: #define        DEBUG_PATH      "/user1/other/brucee/mh/c/bin/ccom.debug"
                    134: #define        LPROF_PATH      "/user1/other/brucee/mh/c/bin/ccom.lcomp"
                    135: #define        PROFILE_PATH    "/user1/other/brucee/mh/c/bin/ccom.prof"
                    136: #define        COMP_NAME       "ccom"
                    137: #define        LOAD_PATH       "/usr/lib/cyntax/cem"
                    138: #define        LOAD_NAME       "cem"
                    139: 
                    140: #define        DEF_OUT         "a.out"
                    141: #define        DEF_LIB         "-lc"
                    142: #define        JERQ_INCLUDE    "-I/usr/jerq/include"
                    143: #define        JERQ_LIB        "-lj"
                    144: #define        DEF_MUX         "-DMUX"
                    145: #define        TMP_DIR         "/tmp"
                    146: 
                    147: extern int     dflag();
                    148: extern int     jflag();
                    149: extern int     mflag();
                    150: extern int     wflag();
                    151: extern int     ostring();
                    152: 
                    153: /*
                    154:  *     Lower case option table.
                    155:  */
                    156: option lcase[26]       =
                    157: {
                    158: /* a */        {c_bad,         NULL,           NULL,           NULL},  
                    159: /* b */        {c_bad,         NULL,           NULL,           NULL},  
                    160: /* c */        {c_flag,        NULL,           &cflag,         NULL},  
                    161: /* d */        {c_str_func,    NULL,           NULL,           dflag}, 
                    162: /* e */        {c_bad,         NULL,           NULL,           NULL},  
                    163: /* f */        {c_bad,         NULL,           NULL,           NULL},  
                    164: /* g */        {c_flag,        NULL,           &gflag,         NULL},  
                    165: /* h */        {c_flag,        NULL,           &hflag,         NULL},  
                    166: /* i */        {c_bad,         NULL,           NULL,           NULL},  
                    167: /* j */        {c_function,    NULL,           NULL,           jflag}, 
                    168: /* k */        {c_bad,         NULL,           NULL,           NULL},  
                    169: /* l */        {c_string,      &files,         NULL,           NULL},  
                    170: /* m */        {c_function,    NULL,           NULL,           mflag}, 
                    171: /* n */        {c_bad,         NULL,           NULL,           NULL},  
                    172: /* o */        {c_str_func,    NULL,           NULL,           ostring},       
                    173: /* p */        {c_flag,        NULL,           &pflag,         NULL},  
                    174: /* q */        {c_bad,         NULL,           NULL,           NULL},  
                    175: /* r */        {c_bad,         NULL,           NULL,           NULL},  
                    176: /* s */        {c_flag,        NULL,           &sflag,         NULL},  
                    177: /* t */        {c_bad,         NULL,           NULL,           NULL},  
                    178: /* u */        {c_bad,         NULL,           NULL,           NULL},  
                    179: /* v */        {c_flag,        NULL,           &verbose,       NULL},  
                    180: /* w */        {c_function,    NULL,           NULL,           wflag}, 
                    181: /* x */        {c_bad,         NULL,           NULL,           NULL},  
                    182: /* y */        {c_bad,         NULL,           NULL,           NULL},  
                    183: /* z */        {c_bad,         NULL,           NULL,           NULL},  
                    184: };
                    185: 
                    186: /*
                    187:  *     Upper case option table.
                    188:  */
                    189: option ucase[26]       =
                    190: {
                    191: /* A */        {c_bad,         NULL,           NULL,           NULL},  
                    192: /* B */        {c_bad,         NULL,           NULL,           NULL},  
                    193: /* C */        {c_bad,         NULL,           NULL,           NULL},  
                    194: /* D */        {c_string,      &cpp_args,      NULL,           NULL},  
                    195: /* E */        {c_bad,         NULL,           NULL,           NULL},  
                    196: /* F */        {c_bad,         NULL,           NULL,           NULL},  
                    197: /* G */        {c_flag,        NULL,           &ugflag,        NULL},  
                    198: /* H */        {c_bad,         NULL,           NULL,           NULL},  
                    199: /* I */        {c_string,      &cpp_args,      NULL,           NULL},  
                    200: /* J */        {c_bad,         NULL,           NULL,           NULL},  
                    201: /* K */        {c_bad,         NULL,           NULL,           NULL},  
                    202: /* L */        {c_flag,        NULL,           &ulflag,        NULL},  
                    203: /* M */        {c_bad,         NULL,           NULL,           NULL},  
                    204: /* N */        {c_bad,         NULL,           NULL,           NULL},  
                    205: /* O */        {c_flag,        NULL,           &uoflag,        NULL},  
                    206: /* P */        {c_flag,        NULL,           &upflag,        NULL},  
                    207: /* Q */        {c_bad,         NULL,           NULL,           NULL},  
                    208: /* R */        {c_bad,         NULL,           NULL,           NULL},  
                    209: /* S */        {c_bad,         NULL,           NULL,           NULL},  
                    210: /* T */        {c_bad,         NULL,           NULL,           NULL},  
                    211: /* U */        {c_string,      &cpp_args,      NULL,           NULL},  
                    212: /* V */        {c_string,      &comp_args,     NULL,           NULL},  
                    213: /* W */        {c_bad,         NULL,           NULL,           NULL},  
                    214: /* X */        {c_bad,         NULL,           NULL,           NULL},  
                    215: /* Y */        {c_bad,         NULL,           NULL,           NULL},  
                    216: /* Z */        {c_flag,        NULL,           &uzflag,        NULL},  
                    217: };
                    218: 
                    219: /*
                    220:  *     Programs to be called.
                    221:  */
                    222: earg   cpp_list[]      =
                    223: {
                    224:        {e_literal,     CPP_NAME, NULL, NULL, 0,        &cpp_list[1]},
                    225:        {e_literal,     "-M", NULL, NULL, 0,            &cpp_list[2]},
                    226:        {e_args,        NULL, NULL, &cpp_args, 0,       &cpp_list[3]},
                    227:        {e_input,       NULL, NULL, NULL, 0,            &cpp_list[4]},
                    228:        {e_output,      NULL, NULL, NULL, 0,            NULL},
                    229: };
                    230: 
                    231: earg   sets_list[]     =
                    232: {
                    233:        {e_literal,     SETS_NAME, NULL, NULL, 0,       &sets_list[1]},
                    234:        {e_input,       NULL, NULL, NULL, 0,            &sets_list[2]},
                    235:        {e_output,      NULL, NULL, NULL, 0,            NULL},
                    236: };
                    237: 
                    238: earg   comp_list[]     =
                    239: {
                    240:        {e_literal,     COMP_NAME, NULL, NULL, 0,       &comp_list[1]},
                    241:        {e_literal,     "-O", NULL, NULL, 0,            &comp_list[2]},
                    242:        {e_splice,      NULL, NULL, NULL, 2,            &comp_list[3]},
                    243:        {e_literal,     "-f", NULL, NULL, 0,            &comp_list[4]},
                    244:        {e_string,      NULL, &src_name, NULL, 0,       &comp_list[5]},
                    245:        {e_args,        NULL, NULL, &comp_args, 0,      &comp_list[6]},
                    246:        {e_input,       NULL, NULL, NULL, 0,            &comp_list[7]},
                    247:        {e_output,      NULL, NULL, NULL, 0,            NULL},
                    248: };
                    249: 
                    250: earg   load_list[]     =
                    251: {
                    252:        {e_literal,     LOAD_NAME, NULL, NULL, 0,       &load_list[1]},
                    253:        {e_args,        NULL, NULL, &load_args, 0,      &load_list[2]},
                    254:        {e_args,        NULL, NULL, &files, 0,          &load_list[3]},
                    255:        {e_literal,     "-o", NULL, NULL, 0,            &load_list[4]},
                    256:        {e_output,      NULL, NULL, NULL, 0,            NULL},
                    257: };
                    258: 
                    259: eargs  cpp_eargs       =       {CPP_PATH, cpp_list};
                    260: eargs  sets_eargs      =       {SETS_PATH, sets_list};
                    261: eargs  comp_eargs      =       {COMP_PATH, comp_list};
                    262: eargs  load_eargs      =       {LOAD_PATH, load_list};
                    263: 
                    264: /*
                    265:  *     General ruotines.
                    266:  */
                    267: 
                    268: #define        talloc(t)       (t *)salloc(sizeof (t))
                    269: 
                    270: /*
                    271:  *     Remove temporaries and exit.
                    272:  */
                    273: void
                    274: quit(s)
                    275: int    s;
                    276: {
                    277:        register int    i;
                    278: 
                    279:        for (i = 0; i < ntemps; i++)
                    280:        {
                    281:                if (tempv[i] != NULL)
                    282:                        (void)unlink(tempv[i]);
                    283:        }
                    284: 
                    285:        if (object != NULL)
                    286:                (void)unlink(object);
                    287: 
                    288:        exit(s);
                    289: }
                    290: 
                    291: /*
                    292:  *     Internal error.
                    293:  */
                    294: void
                    295: internal(s)
                    296: char   *s;
                    297: {
                    298:        fprintf(stderr, "%s: internal error - %s\n", my_name, s);
                    299:        quit(1);
                    300: }
                    301: 
                    302: /*
                    303:  *     Interrupt routine.
                    304:  */
                    305: int
                    306: rubbed()
                    307: {
                    308:        quit(1);
                    309: }
                    310: 
                    311: /*
                    312:  *     System error.
                    313:  */
                    314: perr(s)
                    315: char   *s;
                    316: {
                    317:        fprintf(stderr, "%s: ", my_name);
                    318:        perror(s);
                    319:        quit(1);
                    320: }
                    321: 
                    322: /*
                    323:  *     Memory allocation.
                    324:  */
                    325: char   *
                    326: salloc(n)
                    327: int    n;
                    328: {
                    329:        register char   *p;
                    330:        extern char     *malloc();
                    331: 
                    332:        if ((p = malloc((unsigned int)n)) == NULL)
                    333:        {
                    334:                fprintf(stderr, "%s: ran out of memory\n", my_name);
                    335:                quit(1);
                    336:        }
                    337: 
                    338:        return p;
                    339: }
                    340: 
                    341: char   *
                    342: srealloc(p, n)
                    343: register char  *p;
                    344: int            n;
                    345: {
                    346:        extern char     *realloc();
                    347: 
                    348:        if (p == NULL)
                    349:                return salloc(n);
                    350:        else if ((p = realloc(p, (unsigned int)n)) == NULL)
                    351:        {
                    352:                fprintf(stderr, "%s: ran out of memory\n", my_name);
                    353:                quit(1);
                    354:        }
                    355: 
                    356:        return p;
                    357: }
                    358: 
                    359: /*
                    360:  *     Copy a string.
                    361:  */
                    362: char   *
                    363: copy(s)
                    364: char   *s;
                    365: {
                    366:        return strcpy(salloc(strlen(s) + 1), s);
                    367: }
                    368: 
                    369: /*
                    370:  *     File suffix.
                    371:  */
                    372: int
                    373: suffix(s)
                    374: register char  *s;
                    375: {
                    376:        register int    i;
                    377: 
                    378:        if ((i = strlen(s)) < 2 || s[i - 2] != '.')
                    379:                return '\0';
                    380:        else
                    381:                return s[i - 1];
                    382: }
                    383: 
                    384: /*
                    385:  *     Replace file suffix.
                    386:  */
                    387: void
                    388: replace_suffix(s, c)
                    389: char   *s;
                    390: int    c;
                    391: {
                    392:        s[strlen(s) - 1] = c;
                    393: }
                    394: 
                    395: /*
                    396:  *     Construct a temporary file name.
                    397:  */
                    398: char   *
                    399: make_temp(sp, i)
                    400: char   **sp;
                    401: int    i;
                    402: {
                    403:        char            letter;
                    404:        char            buff[64];
                    405:        struct stat     statb;
                    406:        static int      pid;
                    407: 
                    408:        if (*sp != NULL)
                    409:                return *sp;
                    410: 
                    411:        if (pid == 0)
                    412:                pid = getpid();
                    413: 
                    414:        letter = 'a';
                    415: 
                    416:        for (;;)
                    417:        {
                    418:                sprintf(buff, "%s/ctm%05d_%02d%c", TMP_DIR, pid, i, letter);
                    419: 
                    420:                if (stat(buff, &statb) == -1)
                    421:                {
                    422:                        if (errno == ENOENT)
                    423:                        {
                    424:                                *sp = copy(buff);
                    425:                                return *sp;
                    426:                        }
                    427: 
                    428:                        perr(buff);
                    429:                        quit(1);
                    430:                }
                    431: 
                    432:                letter++;
                    433:        }
                    434: }
                    435: 
                    436: /*
                    437:  *     Add an argument to a list.
                    438:  */
                    439: void
                    440: add_arg(s, p)
                    441: char           *s;
                    442: register args  *p;
                    443: {
                    444:        register arg    *a;
                    445: 
                    446:        a = talloc(arg);
                    447:        a->a_str = s;
                    448:        a->a_next = NULL;
                    449:        *p->a_tail = a;
                    450:        p->a_tail = &a->a_next;
                    451: }
                    452: 
                    453: /*
                    454:  *     Construct a new argument list.
                    455:  */
                    456: args   *
                    457: new_args()
                    458: {
                    459:        register args   *p;
                    460: 
                    461:        p = talloc(args);
                    462:        p->a_head = NULL;
                    463:        p->a_tail = &p->a_head;
                    464:        return p;
                    465: }
                    466: 
                    467: /*
                    468:  *     Free an argument list.
                    469:  */
                    470: void
                    471: free_args(a)
                    472: args   *a;
                    473: {
                    474:        register arg    *p;
                    475:        register arg    *q;
                    476: 
                    477:        for (p = a->a_head; p != NULL; p = q)
                    478:        {
                    479:                q = p->a_next;
                    480:                free((char *)p);
                    481:        }
                    482: 
                    483:        free((char *)a);
                    484: }
                    485: 
                    486: /*
                    487:  *     Make a string out of the catenation of an argument list.
                    488:  */
                    489: char   *
                    490: cat_args(a)
                    491: args   *a;
                    492: {
                    493:        register arg    *p;
                    494:        register int    i;
                    495:        register char   *s;
                    496:        register char   *t;
                    497: 
                    498:        for (i = 1, p = a->a_head; p != NULL; p = p->a_next)
                    499:                i += strlen(p->a_str);
                    500: 
                    501:        s = salloc(i);
                    502:        t = s;
                    503: 
                    504:        for (p = a->a_head; p != NULL; p = p->a_next)
                    505:        {
                    506:                (void)strcpy(s, p->a_str);
                    507:                s += strlen(p->a_str);
                    508:        }
                    509: 
                    510:        return t;
                    511: }
                    512: 
                    513: /*
                    514:  *     Copy an argument list.
                    515:  */
                    516: void
                    517: cp_args(from, to)
                    518: args           *from;
                    519: register args  *to;
                    520: {
                    521:        register arg    *p;
                    522: 
                    523:        for (p = from->a_head; p != NULL; p = p->a_next)
                    524:                add_arg(p->a_str, to);
                    525: }
                    526: 
                    527: /*
                    528:  *     Add an exec argument and return a pointer to the next item.
                    529:  */
                    530: earg   *
                    531: add_exec_arg(e, a)
                    532: register earg  *e;
                    533: register args  *a;
                    534: {
                    535:        register int    i;
                    536:        register char   *s;
                    537:        register char   *t;
                    538:        args            *temp;
                    539: 
                    540:        switch (e->e_code)
                    541:        {
                    542:        case e_args:
                    543:                cp_args(*e->e_args, a);
                    544:                break;
                    545: 
                    546:        case e_input:
                    547:                add_arg(input, a);
                    548:                break;
                    549: 
                    550:        case e_literal:
                    551:                add_arg(e->e_str, a);
                    552:                break;
                    553: 
                    554:        case e_output:
                    555:                add_arg(output, a);
                    556:                break;
                    557: 
                    558:        case e_splice:
                    559:                s = copy("");
                    560:                i = e->e_count;
                    561:                e = e->e_next;
                    562: 
                    563:                while (--i >= 0)
                    564:                {
                    565:                        if (e == NULL)
                    566:                                internal("bad splice");
                    567: 
                    568:                        temp = new_args();
                    569:                        add_arg(s, temp);
                    570:                        e = add_exec_arg(e, temp);
                    571:                        t = cat_args(temp);
                    572:                        free(s);
                    573:                        free_args(temp);
                    574:                        s = t;
                    575:                }
                    576: 
                    577:                add_arg(s, a);
                    578:                return e;
                    579: 
                    580:        case e_string:
                    581:                add_arg(*e->e_strp, a);
                    582:                break;
                    583: 
                    584:        default:
                    585:                internal("bad ecode switch");
                    586:        }
                    587: 
                    588:        return e->e_next;
                    589: }
                    590: 
                    591: /*
                    592:  *     Argument processing.
                    593:  */
                    594: int
                    595: options(n, v)
                    596: register int   n;
                    597: register char  **v;
                    598: {
                    599:        register char   *p;
                    600:        register int    c;
                    601:        register option *o;
                    602: 
                    603:        while (--n >= 0)
                    604:        {
                    605:                if (**v == '-')
                    606:                {
                    607:                        p = *v++;
                    608: 
                    609:                        while ((c = *++p) != '\0')
                    610:                        {
                    611:                                if (c >= 'a' && c <= 'z')
                    612:                                        o = &lcase[c - 'a'];
                    613:                                else if (c >= 'A' && c <= 'Z')
                    614:                                        o = &ucase[c - 'A'];
                    615:                                else
                    616:                                {
                    617:                                        fprintf(stderr, "%s: unknown option '%c'\n", my_name, c);
                    618:                                        return 1;
                    619:                                }
                    620: 
                    621:                                switch (o->o_code)
                    622:                                {
                    623:                                case c_bad:
                    624:                                        /*
                    625:                                         *      Unknown flag.
                    626:                                         */
                    627:                                        fprintf(stderr, "%s: unknown option '%c'\n", my_name, c);
                    628:                                        return 1;
                    629: 
                    630:                                case c_flag:
                    631:                                        /*
                    632:                                         *      Set a flag.
                    633:                                         */
                    634:                                        *o->o_flag = 1;
                    635:                                        continue;
                    636: 
                    637:                                case c_function:
                    638:                                        /*
                    639:                                         *      Call a function.
                    640:                                         */
                    641:                                        if ((*o->o_func)(o))
                    642:                                                return 1;
                    643: 
                    644:                                        continue;
                    645: 
                    646:                                case c_negate:
                    647:                                        /*
                    648:                                         *      Reset a flag.
                    649:                                         */
                    650:                                        *o->o_flag = 0;
                    651:                                        continue;
                    652: 
                    653:                                case c_str_arg:
                    654:                                        /*
                    655:                                         *      Pick up a string argument.
                    656:                                         */
                    657:                                        if (*++p == '\0')
                    658:                                        {
                    659:                                                if (--n < 0 || *(p = *v++) == '-')
                    660:                                                {
                    661:                                                        fprintf(stderr, "%s: argument expected for '-%c' option\n", my_name, c);
                    662:                                                        return 1;
                    663:                                                }
                    664:                                        }
                    665: 
                    666:                                        add_arg(p, *o->o_args);
                    667:                                        break;
                    668: 
                    669:                                case c_str_func:
                    670:                                        /*
                    671:                                         *      Pick up a string and call a function.
                    672:                                         */
                    673:                                        if (*++p == '\0')
                    674:                                        {
                    675:                                                if (--n < 0 || *(p = *v++) == '-')
                    676:                                                {
                    677:                                                        fprintf(stderr, "%s: argument expected for '-%c' option\n", my_name, c);
                    678:                                                        return 1;
                    679:                                                }
                    680:                                        }
                    681: 
                    682:                                        if ((*o->o_func)(o, p))
                    683:                                                return 1;
                    684: 
                    685:                                        break;
                    686: 
                    687:                                case c_string:
                    688:                                        /*
                    689:                                         *      Pick up a complete argument.
                    690:                                         */
                    691:                                        if (p != &v[-1][1])
                    692:                                        {
                    693:                                                fprintf(stderr, "%s: bad '%c' option\n", my_name, c);
                    694:                                                return 1;
                    695:                                        }
                    696: 
                    697:                                        if (p[1] == '\0')
                    698:                                        {
                    699:                                                fprintf(stderr, "%s: no string for '%c' option\n", my_name, c);
                    700:                                                return 1;
                    701:                                        }
                    702: 
                    703:                                        add_arg(v[-1], *o->o_args);
                    704:                                        break;
                    705: 
                    706:                                default:
                    707:                                        internal("bad option switch");
                    708:                                        return 1;
                    709:                                }
                    710: 
                    711:                                break;
                    712:                        }
                    713:                }
                    714:                else
                    715:                        add_arg(*v++, files);
                    716:        }
                    717: 
                    718:        return 0;
                    719: }
                    720: 
                    721: /*
                    722:  *     Catch a signal if it isn't being ignored.
                    723:  */
                    724: void
                    725: set_signal(i)
                    726: int    i;
                    727: {
                    728:        if (signal(i, SIG_IGN) != SIG_IGN)
                    729:                (void)signal(i, rubbed);
                    730: }
                    731: 
                    732: /*
                    733:  *     Initialise.
                    734:  */
                    735: void
                    736: init(s)
                    737: char   *s;
                    738: {
                    739:        if ((my_name = strrchr(s, '/')) == NULL || *++my_name == '\0')
                    740:                my_name = s;
                    741: 
                    742:        files = new_args();
                    743: 
                    744:        set_signal(SIGINT);
                    745:        set_signal(SIGTERM);
                    746: }
                    747: 
                    748: /*
                    749:  *     Run s on argv.
                    750:  */
                    751: int
                    752: run(s, argv)
                    753: char   *s;
                    754: char   **argv;
                    755: {
                    756:        register int    pid;
                    757:        register int    ret;
                    758:        register int    (*isig)();
                    759:        register int    (*qsig)();
                    760:        int             status;
                    761: 
                    762:        switch (pid = fork())
                    763:        {
                    764:        case 0:
                    765:                execv(s, argv);
                    766:                perr(s);
                    767: 
                    768:        case -1:
                    769:                perr("fork");
                    770: 
                    771:        default:
                    772:                isig = signal(SIGINT, SIG_IGN);
                    773:                qsig = signal(SIGQUIT, SIG_IGN);
                    774: 
                    775:                while ((ret = wait(&status)) != pid)
                    776:                {
                    777:                        if (ret == -1)
                    778:                                perr("wait");
                    779:                }
                    780: 
                    781:                if (isig != SIG_IGN)
                    782:                        signal(SIGINT, isig);
                    783: 
                    784:                if (qsig != SIG_IGN)
                    785:                        signal(SIGQUIT, qsig);
                    786:        }
                    787: 
                    788:        if ((status & 0xFF) != 0)
                    789:        {
                    790:                if ((status & 0x80) != 0)
                    791:                        fprintf(stderr, "%s: fatal error in %s (core dumped)\n", my_name, s);
                    792: 
                    793:                quit(1);
                    794:        }
                    795: 
                    796:        return (status >> 8) & 0xFF;
                    797: }
                    798: 
                    799: /*
                    800:  *     Execute an exec arglist.
                    801:  */
                    802: int
                    803: execute(e)
                    804: eargs  *e;
                    805: {
                    806:        register int    i;
                    807:        register earg   *p;
                    808:        register arg    *q;
                    809:        args            *a;
                    810:        static char     **argv;
                    811:        static int      argc;
                    812: 
                    813:        a = new_args();
                    814: 
                    815:        for (p = e->e_list; p != NULL; p = add_exec_arg(p, a))
                    816:                ;
                    817: 
                    818:        for (i = 1, q = a->a_head; q != NULL; q = q->a_next)
                    819:                i++;
                    820: 
                    821:        if (i > argc)
                    822:                argv = (char **)srealloc((char *)argv, i * sizeof (char *));
                    823: 
                    824:        for (i = 0, q = a->a_head; q != NULL; q = q->a_next)
                    825:                argv[i++] = q->a_str;
                    826: 
                    827:        if (verbose)
                    828:        {
                    829:                printf("%s:", e->e_path);
                    830: 
                    831:                for (q = a->a_head; q != NULL; q = q->a_next)
                    832:                        printf(" %s", q->a_str);
                    833: 
                    834:                printf("\n");
                    835:                fflush(stdout);
                    836:        }
                    837: 
                    838:        free_args(a);
                    839:        argv[i] = NULL;
                    840: 
                    841:        return run(e->e_path, argv);
                    842: }
                    843: 
                    844: /*
                    845:  *     Cyntax.
                    846:  */
                    847: 
                    848: /*
                    849:  *     User initialisation.
                    850:  */
                    851: void
                    852: uinit()
                    853: {
                    854:        cpp_args = new_args();
                    855:        comp_args = new_args();
                    856:        load_args = new_args();
                    857: }
                    858: 
                    859: /*
                    860:  *     Handle '-d' flag.
                    861:  */
                    862: int
                    863: dflag(o, s)
                    864: option *o;
                    865: char   *s;
                    866: {
                    867:        return 0;
                    868: }
                    869: 
                    870: /*
                    871:  *     Handle '-j' flag.
                    872:  */
                    873: int
                    874: jflag(o, s)
                    875: option *o;
                    876: char   *s;
                    877: {
                    878:        jerq = 1;
                    879:        add_arg(JERQ_INCLUDE, cpp_args);
                    880:        return 0;
                    881: }
                    882: 
                    883: /*
                    884:  *     Handle '-m' flag.
                    885:  */
                    886: int
                    887: mflag(o, s)
                    888: option *o;
                    889: char   *s;
                    890: {
                    891:        add_arg(DEF_MUX, cpp_args);
                    892:        return 0;
                    893: }
                    894: 
                    895: /*
                    896:  *     Handle '-w' flag.
                    897:  */
                    898: int
                    899: wflag(o, s)
                    900: option *o;
                    901: char   *s;
                    902: {
                    903:        add_arg("-w", comp_args);
                    904:        return 0;
                    905: }
                    906: 
                    907: /*
                    908:  *     Handle '-o' string.
                    909:  */
                    910: int
                    911: ostring(o, s)
                    912: option *o;
                    913: char   *s;
                    914: {
                    915:        if (load_out != NULL)
                    916:        {
                    917:                fprintf(stderr, "%s: repeat '-o' option\n", my_name);
                    918:                return 1;
                    919:        }
                    920: 
                    921:        load_out = s;
                    922:        return 0;
                    923: }
                    924: 
                    925: /*
                    926:  *     Compile the '.c's.
                    927:  */
                    928: int
                    929: compile()
                    930: {
                    931:        register int    i;
                    932:        register int    ret;
                    933:        register arg    *p;
                    934:        register char   *s;
                    935:        struct stat     statb;
                    936: 
                    937:        ret = 0;
                    938: 
                    939:        if (ugflag)
                    940:                comp_eargs.e_path = DEBUG_PATH;
                    941:        else if (ulflag)
                    942:                comp_eargs.e_path = LPROF_PATH;
                    943:        else if (upflag)
                    944:                comp_eargs.e_path = PROFILE_PATH;
                    945: 
                    946:        ntemps = 1;
                    947: 
                    948:        if (uzflag)
                    949:                ntemps++;
                    950: 
                    951:        tempv = (char **)salloc(ntemps * sizeof (char *));
                    952: 
                    953:        for (i = 0; i < ntemps; i++)
                    954:                tempv[i] = NULL;
                    955: 
                    956:        for (p = files->a_head; p != NULL; p = p->a_next)
                    957:        {
                    958:                switch (suffix(p->a_str))
                    959:                {
                    960:                case 'c':
                    961:                        if (src_name != NULL)
                    962:                                free(src_name);
                    963: 
                    964:                        if (stat(p->a_str, &statb) == -1)
                    965:                                src_name = copy(p->a_str);
                    966:                        else
                    967:                        {
                    968:                                src_name = salloc(strlen(p->a_str) + 1 + 12 + 1);
                    969:                                sprintf(src_name, "%s@%ld", p->a_str, statb.st_mtime);
                    970:                        }
                    971: 
                    972:                        if (multi_cfile)
                    973:                        {
                    974:                                printf("%s:\n", p->a_str);
                    975:                                fflush(stdout);
                    976:                        }
                    977: 
                    978:                        i = 0;
                    979:                        input = p->a_str;
                    980:                        output = make_temp(&tempv[i], i);
                    981: 
                    982:                        if (execute(&cpp_eargs))
                    983:                        {
                    984:                                ret = 1;
                    985:                                break;
                    986:                        }
                    987: 
                    988:                        if (uzflag)
                    989:                        {
                    990:                                input = output;
                    991:                                i = 1 - i;
                    992:                                output = make_temp(&tempv[i], i);
                    993: 
                    994:                                if (execute(&sets_eargs))
                    995:                                {
                    996:                                        ret = 1;
                    997:                                        break;
                    998:                                }
                    999:                        }
                   1000: 
                   1001:                        if (hflag && (s = strrchr(p->a_str, '/')) != NULL)
                   1002:                                p->a_str = s + 1;
                   1003: 
                   1004:                        replace_suffix(p->a_str, 'O');
                   1005:                        input = output;
                   1006:                        output = p->a_str;
                   1007:                        object = p->a_str;
                   1008: 
                   1009:                        if (execute(&comp_eargs))
                   1010:                        {
                   1011:                                (void)unlink(object);
                   1012:                                ret = 1;
                   1013:                                break;
                   1014:                        }
                   1015:                        else
                   1016:                                object = NULL;
                   1017: 
                   1018:                        break;
                   1019: 
                   1020:                case 'A':
                   1021:                case 'O':
                   1022:                case '\0':
                   1023:                        break;
                   1024: 
                   1025:                default:
                   1026:                        fprintf(stderr, "%s: unknown file type '%s'\n", my_name, p->a_str);
                   1027:                        ret = 1;
                   1028:                }
                   1029:        }
                   1030: 
                   1031:        return ret;
                   1032: }
                   1033: 
                   1034: /*
                   1035:  *     Load the resultant objects and the rest.
                   1036:  */
                   1037: int
                   1038: load()
                   1039: {
                   1040:        if (cflag)
                   1041:                return 0;
                   1042: 
                   1043:        if (load_out != NULL)
                   1044:                output = load_out;
                   1045:        else
                   1046:                output = DEF_OUT;
                   1047: 
                   1048:        if (jerq)
                   1049:                add_arg(JERQ_LIB, files);
                   1050:        else
                   1051:                add_arg(DEF_LIB, files);
                   1052: 
                   1053:        return execute(&load_eargs);
                   1054: }
                   1055: 
                   1056: /*
                   1057:  *     Find out if there are more than one '.c' and at least one file.
                   1058:  */
                   1059: int
                   1060: scan_files()
                   1061: {
                   1062:        register arg    *p;
                   1063:        register int    i;
                   1064: 
                   1065:        p = files->a_head;
                   1066: 
                   1067:        if (p == NULL)
                   1068:        {
                   1069:                fprintf(stderr, "%s: no files specified\n", my_name);
                   1070:                return 1;
                   1071:        }
                   1072: 
                   1073:        i = 0;
                   1074: 
                   1075:        do
                   1076:        {
                   1077:                if (suffix(p->a_str) == 'c')
                   1078:                {
                   1079:                        if (i)
                   1080:                        {
                   1081:                                multi_cfile = 1;
                   1082:                                break;
                   1083:                        }
                   1084: 
                   1085:                        i = 1;
                   1086:                }
                   1087:        }
                   1088:        while ((p = p->a_next) != NULL);
                   1089: 
                   1090:        return 0;
                   1091: }
                   1092: 
                   1093: /*
                   1094:  *     User action routine.
                   1095:  */
                   1096: int
                   1097: do_it()
                   1098: {
                   1099:        return scan_files() || compile() || load();
                   1100: }
                   1101: 
                   1102: /*
                   1103:  *     Compiler front end.
                   1104:  */
                   1105: int
                   1106: main(argc, argv)
                   1107: int    argc;
                   1108: char   *argv[];
                   1109: {
                   1110:        init(argv[0]);
                   1111:        uinit();
                   1112:        quit(options(argc - 1, &argv[1]) || do_it());
                   1113: }

unix.superglobalmegacorp.com

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