|
|
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
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.