Annotation of researchv9/jerq/sgs/as/pass0.c, revision 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.