Annotation of researchv9/jerq/sgs/as/pass0.c, revision 1.1.1.1

1.1       root        1: static char *ID_pass0 = "@(#) pass0.c: 1.16 12/10/83";
                      2: 
                      3: #include <stdio.h>
                      4: #include <signal.h>
                      5: #include <ctype.h>
                      6: #include <paths.h>
                      7: #include "systems.h"
                      8: #include "pass0.h"
                      9: #include "sgs.h"
                     10: 
                     11: /*
                     12:  *
                     13:  *     "pass0.c" is a file containing the source for the setup program
                     14:  *     for the SGS Assemblers.  Routines in this file parse the
                     15:  *     arguments, determining the source and object file names, invent
                     16:  *     names for temporary files, and execute the first pass of the
                     17:  *     assembler.
                     18:  *
                     19:  *     This program can be invoked with the command:
                     20:  *
                     21:  *                     as [flags] ifile [-o ofile]
                     22:  *
                     23:  *     where [flags] are optional user-specified flags,
                     24:  *     "ifile" is the name of the assembly languge source file
                     25:  *     and "ofile" is the name of a file where the object program is
                     26:  *     to be written.  If "ofile" is not specified on the command line,
                     27:  *     it is created from "ifile" by the following algorithm:
                     28:  *
                     29:  *          1. If the name "ifile" ends with the two characters ".s",
                     30:  *             these are replaced with the two characters ".o".
                     31:  *
                     32:  *          2. If the name "ifile" does not end with the two
                     33:  *             characters ".s" and is no more than 12 characters in
                     34:  *             length, the name "ofile" is created by appending the
                     35:  *             characters ".o" to the name "ifile".
                     36:  *
                     37:  *          3. If the name "ifile" does not end with the two
                     38:  *             characters ".s" and is greater than 12 characters in
                     39:  *             length, the name "ofile" is created by appending the
                     40:  *             characters ".o" to the first 12 characters of "ifile".
                     41:  *
                     42:  *     The global variables "name1" through "name6" are used to store
                     43:  *     the six temporary file names.  The variable "pid" is used to
                     44:  *     store a character version of the process ID number.  This is
                     45:  *     used to make temporary file names unique.
                     46:  *
                     47:  */
                     48: 
                     49: #define NO             0
                     50: #define YES            1
                     51: #define        MAXFLAGS        15 - 9  /* sizeof(xargp)-num of args required for pass1 */
                     52: #ifndef P_tmpdir
                     53: #define P_tmpdir       "/usr/tmp"
                     54: #endif
                     55: 
                     56: #if ONEPROC
                     57: short passnbr = 0;
                     58: 
                     59: extern short opt;
                     60: extern short workaround;
                     61: 
                     62: extern short
                     63:        tstlookup,
                     64:        Oflag,
                     65:        dlflag;
                     66: 
                     67: extern char file[];
                     68: 
                     69: extern char *filenames[];
                     70: 
                     71: #if M4ON
                     72: extern short rflag;
                     73: #endif
                     74: 
                     75: #if M32RSTFIX
                     76: extern short rstflag;  /* Don't generate workaround for RESTORE chip bug */
                     77: #endif
                     78: 
                     79: #endif
                     80: 
                     81: char   *infile;
                     82: 
                     83: char   outfile[80];
                     84: 
                     85: char   *tempnam();
                     86: 
                     87: char
                     88:        *name0,
                     89:        *name1,
                     90:        *name2,
                     91:        *name3,
                     92:        *name4,
                     93:        *name5,
                     94:        *name6,
                     95: #if MULTSECT
                     96:        *name7,
                     97:        *name8,
                     98:        *name9,
                     99:        *name10,
                    100:        *name11,
                    101:        *name12,
                    102:        *name13;
                    103: #else
                    104:        *name7;
                    105: #endif
                    106: 
                    107: short  transvec = NO,
                    108:        argindex = 1,
                    109:        flagindex = 0;
                    110: 
                    111: #if !ONEPROC
                    112: static char
                    113:        nextpass[15];
                    114: 
                    115: static char
                    116:        teststr[4] = {'-','t','\0','\0'};
                    117: 
                    118: static char
                    119:        *xargp[16];
                    120: #endif
                    121: 
                    122: static char
                    123:        flagstr[8][3];
                    124: 
                    125: #if M4ON
                    126: static short
                    127:        macro = MACRO;
                    128: #endif
                    129: 
                    130: #if !ONEPROC
                    131: static short
                    132:        testas = -2;
                    133: #endif
                    134: 
                    135: extern char
                    136:        *strcpy(),
                    137:        *strcat(),
                    138:        *strncat();
                    139: 
                    140: #define max(A,B) (((A)<(B))?(B):(A))
                    141: 
                    142: extern char *malloc(), *getenv(), *mktemp();
                    143: extern int access();
                    144: 
                    145: static char *pcopy(), *seed="AAA";
                    146: 
                    147: /*
                    148:  *
                    149:  *     "tempnam" is the routine that allocates the temporary files needed
                    150:  *     by the assembler.  It searches directories for enough space for the
                    151:  *     files, then assigns a (guaranteed) unique filename using the prefix
                    152:  *     in the function call.
                    153:  *
                    154:  */
                    155: 
                    156: char *
                    157: tempnam(dir, pfx)
                    158: char *dir;             /* use this directory please (if non-NULL) */
                    159: char *pfx;             /* use this (if non-NULL) as filename prefix */
                    160: {
                    161:        register char *p, *q, *tdir;
                    162:        int x=0, y=0, z;
                    163: 
                    164:        z=strlen(P_tmpdir);
                    165:        if((tdir = getenv("TMPDIR")) != NULL) {
                    166:                x = strlen(tdir);
                    167:        }
                    168:        if(dir != NULL) {
                    169:                y=strlen(dir);
                    170:        }
                    171:        if((p=malloc((unsigned)(max(max(x,y),z)+16))) == NULL)
                    172:                return(NULL);
                    173:        if(x > 0 && access(pcopy(p, tdir), 3) == 0)
                    174:                goto OK;
                    175:        if(y > 0 && access(pcopy(p, dir), 3) == 0)
                    176:                goto OK;
                    177:        if(access(pcopy(p, P_tmpdir), 3) == 0)
                    178:                goto OK;
                    179:        if(access(pcopy(p, "/tmp"), 3) != 0)
                    180:                return(NULL);
                    181: OK:
                    182:        (void)strcat(p, "/");
                    183:        if(pfx) {
                    184:                *(p+strlen(p)+5) = '\0';
                    185:                (void)strncat(p, pfx, 5);
                    186:        }
                    187:        (void)strcat(p, seed);
                    188:        (void)strcat(p, "XXXXXX");
                    189:        q = seed;
                    190:        while(*q == 'Z')
                    191:                *q++ = 'A';
                    192:        ++*q;
                    193:        (void)mktemp(p);
                    194:        if (*p == '\0')
                    195:                return(NULL);
                    196:        return(p);
                    197: }
                    198: 
                    199: static char*
                    200: pcopy(space, arg)
                    201: register char *space, *arg;
                    202: {
                    203:        register char *p;
                    204: 
                    205:        if(arg) {
                    206:                (void)strcpy(space, arg);
                    207:                p = space-1+strlen(space);
                    208:                if(*p == '/')
                    209:                        *p = '\0';
                    210:        }
                    211:        return(space);
                    212: }
                    213: 
                    214: /*
                    215:  *
                    216:  *     "getargs" is a general purpose argument parsing routine.
                    217:  *     It locates flags (identified by a preceding minus sign ('-'))
                    218:  *     and initializes any associated flags for the assembler.
                    219:  *     If there are any file names in the argument list, then a
                    220:  *     pointer to the name is stored in a global variable for
                    221:  *     later use.
                    222:  *
                    223:  */
                    224: 
                    225: getargs(xargc,xargv)
                    226:        register int xargc;
                    227:        register char **xargv;
                    228: {
                    229:        register char ch;
                    230: 
                    231:        while (xargc-- > 0) {
                    232:                if (**xargv == '-') {
                    233:                        while ((ch = *++*xargv) != '\0')
                    234:                                switch (ch) {
                    235: #if M4ON
                    236:                                case 'm':
                    237:                                        macro = ! macro;
                    238:                                        break;
                    239: #endif
                    240:                                case 'o':
                    241:                                        strcpy(outfile,*(++xargv));
                    242:                                        --xargc;
                    243:                                        while (*++*xargv != '\0') ;
                    244:                                        --*xargv;
                    245:                                        break;
                    246:                                case 'd':
                    247:                                        if (*++*xargv == 'l')
                    248: #if !ONEPROC
                    249:                                                xargp[argindex++] = "-dl";
                    250: #else
                    251:                                                dlflag = YES;
                    252: #endif
                    253:                                        break;
                    254: #if TRANVEC || !ONEPROC
                    255:                                case 't':
                    256:                                        ++*xargv;
                    257: #endif
                    258: #if TRANVEC
                    259:                                        if (**xargv == 'v'){
                    260:                                                transvec = YES;
                    261: #if !ONEPROC
                    262:                                                xargp[argindex++] = "-tv";
                    263: #endif
                    264:                                                break;
                    265:                                        }
                    266: #endif
                    267: #if !ONEPROC
                    268:                                        if (isdigit(**xargv)) {
                    269:                                                testas = **xargv - '0' - 1;
                    270:                                                if (testas > -1) {
                    271:                                                        teststr[2] = (char)(testas + '0');
                    272:                                                }
                    273:                                        }
                    274:                                        else {
                    275:                                                --*xargv;
                    276:                                                testas += 2;
                    277:                                        }
                    278:                                        xargp[argindex++] = teststr;
                    279:                                        break;
                    280: #endif
                    281:                                case 'V':
                    282:                                        /* version flag */
                    283:                                        fprintf(stderr,"%s: assembler - %s\n",
                    284:                                                SGSNAME,RELEASE);
                    285:                                        break;
                    286: #if ONEPROC
                    287:                                case 'n':
                    288:                                        if (*++*xargv == 'f') { /* -nf option */
                    289:                                                /* no frills; disable work-arounds */
                    290:                                                workaround = NO;
                    291: #if M32RSTFIX
                    292:                                                rstflag = NO;
                    293: #endif /* M32RSTFIX */
                    294:                                        } else { /* -n option */
                    295:                                                opt = NO;
                    296:                                                *--*xargv;
                    297:                                        }
                    298:                                        break;
                    299: #if DEBUG
                    300:                                case 'O':
                    301:                                        Oflag = YES;
                    302:                                        break;
                    303:                                case 'T': {
                    304:                                        switch (*++*xargv) {
                    305:                                                case 'L' : {
                    306:                                                        tstlookup = YES;
                    307:                                                        break;
                    308:                                                }
                    309:                                        }
                    310:                                        break;
                    311:                                }
                    312: #endif
                    313: #if M4ON
                    314:                                case 'R':
                    315:                                        rflag = YES;
                    316:                                        break;
                    317: #endif
                    318: #if M32RSTFIX
                    319:                                case 'r': /* Don't generate the workaround
                    320:                                           * for the RESTORE chip bug. 
                    321:                                            */
                    322:                                        rstflag = NO;
                    323:                                        break;
                    324: #endif /* M32RSTFIX */
                    325: #endif
                    326: #if VAX
                    327:                                case 'j': /* invoke ljas instead of as */
                    328:                                        if (strcmp(xargv[0],"ljas")) {
                    329:                                                execvp("ljas",xargv);
                    330:                                                aerror("cannot exec ljas");
                    331:                                                };
                    332:                                        break;
                    333: #endif
                    334:                                default:
                    335: #if ONEPROC
                    336:                                        flags(ch);
                    337: #else
                    338:                                        flagstr[flagindex][0] = '-';
                    339:                                        flagstr[flagindex][1] = ch;
                    340:                                        xargp[argindex++] = &(flagstr[flagindex++][0]);
                    341: #endif
                    342:                                        break;
                    343:                                }
                    344:                        xargv++;
                    345:                }
                    346:                else {
                    347:                        infile = *xargv++;
                    348:                }
                    349:        }
                    350: }
                    351: 
                    352: /*
                    353:  *
                    354:  *     "main" is the main driver for the assembler. It calls "getargs"
                    355:  *     to parse the argument list, set flags, and stores pointers
                    356:  *     to any file names in the argument list .
                    357:  *     If the output file was not specified in the argument list
                    358:  *     then the output file name is generated. Next the temporary
                    359:  *     file names are generated and the first pass of the assembler
                    360:  *     is invoked.
                    361:  *
                    362:  */
                    363: 
                    364: main(argc,argv)
                    365:        int argc;
                    366:        char **argv;
                    367: {
                    368:        register short index, count;
                    369: #if !ONEPROC
                    370:        register char *temp;
                    371: #endif
                    372:        FILE    *fd;
                    373: 
                    374:        argc--;
                    375:        if (argc <= 0) {
                    376:                fprintf(stderr,"Usage: %sas [options] file\n",SGS);
                    377:                exit(1);
                    378:        }
                    379: #if !ONEPROC
                    380:        temp = *argv;
                    381:        index = -1;
                    382:        while (temp[++index] != '\0') ;
                    383:        while (--index >= 0 && temp[index] != '/') ;
                    384:        strcpy(nextpass,&temp[++index]);
                    385:        nextpass[strlen(nextpass)] = '1';
                    386: #endif
                    387:        argv++;
                    388:        getargs(argc, argv);
                    389: /*     Check to see if input file exits */
                    390:        if ((fd = fopen(infile,"r")) != NULL)
                    391:                fclose(fd);
                    392:        else {
                    393:                fprintf(stderr,"Nonexistent file\n");
                    394:                exit(1);
                    395:        }
                    396:        if (outfile[0] == '\0') {
                    397:                for(index=0,count=0;infile[index]!='\0';index++,count++)
                    398:                        if(infile[index]=='/')
                    399:                                count = -1;
                    400:                strcpy(outfile,infile+index-count);
                    401:                if(outfile[count-2]=='.' &&
                    402:                   outfile[count-1]=='s')
                    403:                        outfile[count-1]='o';
                    404:                else
                    405:                {
                    406:                        if(count>12)
                    407:                                count = 12;
                    408:                        strcpy(outfile+count,".o");
                    409:                }
                    410:        }
                    411: 
                    412:        name1 = tempnam(TMPDIR,TMPFILE1);
                    413:        name2 = tempnam(TMPDIR,TMPFILE2);
                    414:        name3 = tempnam(TMPDIR,TMPFILE3);
                    415:        name4 = tempnam(TMPDIR,TMPFILE4);
                    416:        name5 = tempnam(TMPDIR,TMPFILE5);
                    417:        name6 = tempnam(TMPDIR,TMPFILE6);
                    418:        name7 = tempnam(TMPDIR,TMPFILE7);
                    419: #if MULTSECT
                    420:        name8 = tempnam(TMPDIR,TMPFILE8);
                    421:        name9 = tempnam(TMPDIR,TMPFILE9);
                    422:        name10 = tempnam(TMPDIR,TMPFILEA);
                    423:        name11 = tempnam(TMPDIR,TMPFILEB);
                    424:        name12 = tempnam(TMPDIR,TMPFILEC);
                    425:        name13 = tempnam(TMPDIR,TMPFILED);
                    426: #endif
                    427: #if !ONEPROC
                    428:        xargp[0] = nextpass;
                    429: #endif
                    430: #if M4ON
                    431:        if (macro) {
                    432:                /* tell pass1 to unlink its input when through */
                    433: #if ONEPROC
                    434:                rflag = YES;
                    435: #else  
                    436:                xargp[argindex++] = "-R";
                    437: #endif
                    438:                callm4();
                    439:        }
                    440: #endif
                    441: 
                    442: #if ONEPROC
                    443:        strcpy(file,infile);
                    444:        filenames[0] = infile;
                    445:        filenames[1] = outfile;
                    446:        filenames[2] = name1;
                    447:        filenames[3] = name2;
                    448:        filenames[4] = name3;
                    449:        filenames[5] = name4;
                    450:        filenames[6] = name5;
                    451:        filenames[7] = name6;
                    452:        filenames[8] = name7;
                    453: #if MULTSECT
                    454:        filenames[9] = name8;
                    455:        filenames[10] = name9;
                    456:        filenames[11] = name10;
                    457:        filenames[12] = name11;
                    458:        filenames[13] = name12;
                    459:        filenames[14] = name13;
                    460: #endif
                    461:        exit(aspass1());
                    462: #else
                    463:        if (argindex > MAXFLAGS) {
                    464:                fprintf(stderr,"Too many flags\n");
                    465:                exit (1);
                    466:        }
                    467: 
                    468:        xargp[argindex++] = infile;
                    469:        xargp[argindex++] = outfile;
                    470:        xargp[argindex++] = name1;
                    471:        xargp[argindex++] = name2;
                    472:        xargp[argindex++] = name3;
                    473:        xargp[argindex++] = name4;
                    474:        xargp[argindex++] = name5;
                    475:        xargp[argindex++] = name6;
                    476:        xargp[argindex++] = name7;
                    477: #if MULTSECT
                    478:        xargp[argindex++] = name8;
                    479:        xargp[argindex++] = name9;
                    480:        xargp[argindex++] = name10;
                    481:        xargp[argindex++] = name11;
                    482:        xargp[argindex++] = name12;
                    483:        xargp[argindex++] = name13;
                    484: #endif
                    485:        xargp[argindex] = 0;
                    486:        if (testas != -1) {
                    487:                if (testas > -1) {
                    488:                        execv(NAS1,xargp);
                    489:                }
                    490:                else
                    491:                        execv(AS1,xargp);
                    492:        fprintf(stderr,"Assembler Error - Cannot Exec Pass 1\n");
                    493:        exit(1);
                    494:        }
                    495: #endif
                    496: } /* main */
                    497: 
                    498: #if M4ON
                    499: callm4()
                    500: {
                    501:        static char
                    502:                *av[] = { "m4", 0, 0, 0};
                    503: 
                    504:        /*
                    505:        *       The following code had to be added with a 'u370' ifdef due
                    506:        *       to a MAXI bug concerning static pointers. We think it's fixed
                    507:        *       that is why the code is commented out. It can be deleted
                    508:        *       when this fact is verified.
                    509:        *
                    510:        *       char *regdef, *tvdef;
                    511:        *       regdef = CM4DEFS;
                    512:        *       tvdef = CM4TVDEFS;
                    513:        */
                    514: 
                    515: #if !NODEFS
                    516:        static char
                    517:                *regdef = CM4DEFS
                    518: #if TRANVEC
                    519:                ,
                    520:                *tvdef  = CM4TVDEFS
                    521: #endif
                    522:                ;
                    523: 
                    524: #if TRANVEC
                    525:        av[1] = (transvec) ? tvdef : regdef;
                    526:        av[2] = infile;
                    527: #else
                    528:        av[1] = regdef;
                    529:        av[2] = infile;
                    530: #endif
                    531: #else
                    532:        av[1] = infile;
                    533: #endif
                    534:        name0 = tempnam(TMPDIR,TMPFILE0);               /* m4 output file */
                    535:        if (callsys(M4, av, name0) != 0) {
                    536:                unlink(name0);
                    537:                fprintf(stderr,"Assembly inhibited\n");
                    538:                exit(100);
                    539:        }
                    540:        infile = name0;
                    541:        return;
                    542: } /* callm4 */
                    543: 
                    544: callsys(f,v,o)
                    545:        char f[], *v[];
                    546:        char *o;        /* file name, if any, for redirecting stdout */
                    547: {
                    548:        int t, status;
                    549: 
                    550:        if ((t=fork())==0) {
                    551:                if (o != NULL) {        /* redirect stdout */
                    552:                        if (freopen(o, "w", stdout) == NULL) {
                    553:                                fprintf(stderr,"Can't open %s\n", o);
                    554:                                exit(100);
                    555:                        }
                    556:                }
                    557:                execv(f, v);
                    558:                fprintf(stderr,"Can't find %s\n", f);
                    559:                exit(100);
                    560:        } else
                    561:                if (t == -1) {
                    562:                        fprintf(stderr,"Try again\n");
                    563:                        return(100);
                    564:                }
                    565:        while(t!=wait(&status));
                    566:        if ((t=(status&0377)) != 0) {
                    567:                if (t!=SIGINT)          /* interrupt */
                    568:                        {
                    569:                        fprintf(stderr,"status %o\n",status);
                    570:                        fprintf(stderr,"Fatal error in %s\n", f);
                    571:                        }
                    572:                exit(100);
                    573:        }
                    574:        return((status>>8) & 0377);
                    575: } /* callsys */
                    576: #endif

unix.superglobalmegacorp.com

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