Annotation of 43BSD/contrib/icon/link/ilink.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Linker main program that controls the linking process.
        !             3:  */
        !             4: 
        !             5: #include "ilink.h"
        !             6: 
        !             7: #define MAXNAME  256           /* maximum length of file name */
        !             8: 
        !             9: FILE *infile;                  /* input file (.u1 or .u2) */
        !            10: FILE *outfile;                 /* interpreter code output file */
        !            11: FILE *dbgfile;                 /* debug file */
        !            12: char inbuf[BUFSIZ];            /* buffer for input file */
        !            13: char inname[MAXNAME];          /* input file name */
        !            14: char outname[MAXNAME];         /* output file name */
        !            15: char icnname[MAXNAME];         /* icon source file name */
        !            16: char dbgname[MAXNAME];         /* debug file name */
        !            17: char ixhdr[50];                        /* header for directly executable .u files */
        !            18: char *iconx = "/bin/echo iconx path not in";           /* pathname of iconx */
        !            19: int  hdrloc;                   /* location to place hdr at */
        !            20: struct lfile *lfiles;          /* List of files to link */
        !            21: 
        !            22: int line = 0;                  /* current source program line number */
        !            23: char *file = NULL;             /* current source program file */
        !            24: int fatalerrs = 0;             /* number of errors encountered */
        !            25: int Dflag = 0;                 /* debug flag */
        !            26: 
        !            27: char *pname;                   /* name of program that is running */
        !            28: char **filep;                  /* name of current input file */
        !            29: 
        !            30: main(argc, argv)
        !            31: int argc;
        !            32: char **argv;
        !            33:    {
        !            34:    register int i;
        !            35:    extern char *maknam(), *maknam2();
        !            36:    char *p, *getenv();
        !            37:    struct lfile *lf,*lfls;
        !            38: 
        !            39:    pname = argv[0];
        !            40:    meminit(argc, argv);        /* Note that meminit also processes arguments. */
        !            41: 
        !            42:    /*
        !            43:     * Phase I: load global information contained in .u2 files into
        !            44:     *  data structures.
        !            45:     *
        !            46:     * The list of files to link is maintained as a queue with lfiles
        !            47:     *  as the base.  lf moves along the list.  Each file is processed
        !            48:     *  in turn by forming .u2 and .icn names from each file name, each
        !            49:     *  of which ends in .u1.  The .u2 file is opened and globals is called
        !            50:     *  to process it.  When the end of the list is reached, lf becomes
        !            51:     *  NULL and the loop is terminated, completing phase I.  Note that
        !            52:     *  link instructions in the .u2 file cause files to be added to list
        !            53:     *  of files to link.
        !            54:     */
        !            55:    if (!(lf = lfiles))
        !            56:        exit(0);        
        !            57:    while (lf) {
        !            58:       filep = &(lf->lf_name);
        !            59:       maknam2(inname, *filep, ".u2");
        !            60:       maknam(icnname, *filep, ".icn");
        !            61:       infile = fopen(inname, "r");
        !            62:       if (infile == NULL) {
        !            63:          fprintf(stderr, "%s: cannot open %s\n", pname, inname);
        !            64:          exit(1);
        !            65:          }
        !            66:       setbuf(infile, inbuf);
        !            67:       globals(i);
        !            68:       fclose(infile);
        !            69:       lf = lf->lf_link;
        !            70:       }
        !            71: 
        !            72:    /* Phase II: resolve undeclared variables and generate code. */
        !            73: 
        !            74:    /*
        !            75:     * Open the output file.  If no file was named with -o, form the
        !            76:     *  name from that of the first input file named.
        !            77:     */
        !            78:    if (!outname[0])
        !            79:       maknam(outname, lfiles->lf_name, "");
        !            80:    outfile = fopen(outname, "w");
        !            81:    if (outfile == NULL) {
        !            82:       fprintf(stderr, "%s: cannot create %s\n", pname, outname);
        !            83:       exit(1);
        !            84:       }
        !            85:    setbuf(outfile, NULL);
        !            86: 
        !            87:    /*
        !            88:     * Form the #! line.
        !            89:     */
        !            90: #ifdef DIREX
        !            91:    sprintf(ixhdr,"#!%s\n",iconx);
        !            92:    hdrloc = strlen(ixhdr);     /* point past end of #! line */
        !            93:    if (hdrloc > 32)
        !            94:        syserr("interpreter pathname too long--see section 3.1 of installation document");
        !            95: #else
        !            96:    {
        !            97:    /*
        !            98:     * Direct execution of icode files is not available.  Open HDRFILE,
        !            99:     *  which contains the start-up program and copy it to the output
        !           100:     *  file.  Then, set up for an fseek by setting hdrloc to the byte
        !           101:     *  past the end of the start-up program and the #! line.
        !           102:     */
        !           103:    int hfile, hsize;
        !           104:    char hdrdat[MAXHDR];
        !           105:    
        !           106:    sprintf(ixhdr,"#!iconx\n");
        !           107:    hfile = open(HDRFILE,0);
        !           108:    if (hfile == -1) {
        !           109:       fprintf(stderr,"Can't open linker header file %s\n",HDRFILE);
        !           110:       exit(1);
        !           111:       }
        !           112:    hsize = read(hfile,hdrdat,MAXHDR);
        !           113:    fwrite(hdrdat,sizeof(char),hsize,outfile);
        !           114:    fseek(outfile,(long)MAXHDR,0);
        !           115:    hdrloc = MAXHDR + strlen(ixhdr);
        !           116:    }
        !           117: #endif DIREX
        !           118:    /*
        !           119:     * Put the #! line in the file and seek past it and possibly the
        !           120:     *  start-up program, and leave space for the icode file header.
        !           121:     */
        !           122:    genheader();
        !           123:    fseek(outfile, (long)(hdrloc + sizeof(struct header)), 0);
        !           124: 
        !           125:    /*
        !           126:     * Open the .ux file if debugging is on.
        !           127:     */
        !           128:    if (Dflag) {
        !           129:       maknam(dbgname, lfiles->lf_name, ".ux");
        !           130:       dbgfile = fopen(dbgname, "w");
        !           131:       if (dbgfile == NULL) {
        !           132:          fprintf(stderr, "%s: cannot create %s\n", pname, dbgname);
        !           133:          exit(1);
        !           134:          }
        !           135:       setbuf(dbgfile, NULL);
        !           136:       }
        !           137: 
        !           138:    /*
        !           139:     * Loop through input files and generate code for each.
        !           140:     */
        !           141:    lfls = lfiles;
        !           142:    while (lf = getlfile(&lfls)) {
        !           143:       filep = &(lf->lf_name);
        !           144:       maknam2(inname, *filep, ".u1");
        !           145:       maknam(icnname, *filep, ".icn");
        !           146:       infile = fopen(inname, "r");
        !           147:       if (infile == NULL) {
        !           148:          fprintf(stderr, "%s: cannot open %s\n", pname, inname);
        !           149:          exit(1);
        !           150:          }
        !           151:       setbuf(infile, inbuf);
        !           152:       gencode();
        !           153:       fclose(infile);
        !           154:       }
        !           155:    gentables();        /* Generate record, field, global, global names,
        !           156:                     static, and identifier tables. */
        !           157:    if (fatalerrs > 0)
        !           158:       exit(1);
        !           159:    exit(0);
        !           160:    }
        !           161: 
        !           162: /*
        !           163:  * maknam - makes a file name from prefix and suffix.
        !           164:  *
        !           165:  * Uses only the last file specification if name is a path,
        !           166:  * replaces suffix of name with suffix argument.
        !           167:  */
        !           168: char *maknam(dest, name, suffix)
        !           169: char *dest, *name, *suffix;
        !           170:    {
        !           171:    register char *d, *pre, *suf;
        !           172:    char *mark;
        !           173: 
        !           174:    d = dest;
        !           175:    pre = name;
        !           176:    suf = suffix;
        !           177:    mark = pre;
        !           178:    while (*pre)                /* find last slash */
        !           179:       if (*pre++ == '/')
        !           180:          mark = pre;
        !           181:    pre = mark;
        !           182:    mark = 0;
        !           183:    while (*d = *pre++)         /* copy from last slash into dest */
        !           184:       if (*d++ == '.')         /*   look for last dot, too */
        !           185:          mark = d - 1;
        !           186:    if (mark)                   /* if no dot, just append suffix */
        !           187:       d = mark;
        !           188:    while (*d++ = *suf++) ;     /* copy suffix into dest */
        !           189:    return (dest);
        !           190:    }
        !           191: 
        !           192: /*
        !           193:  * maknam2 - makes a file name from prefix and suffix.
        !           194:  *
        !           195:  * Like maknam, but leaves initial pathname component intact.
        !           196:  */
        !           197: char *maknam2(dest, name, suffix)
        !           198: char *dest, *name, *suffix;
        !           199:    {
        !           200:    register char *d, *pre, *suf;
        !           201:    char *mark;
        !           202: 
        !           203:    d = dest;
        !           204:    pre = name;
        !           205:    suf = suffix;
        !           206:    mark = 0;
        !           207:    while (*d = *pre++) {
        !           208:       if (*d == '/')
        !           209:          mark = 0;
        !           210:       if (*d++ == '.')         /*   look for last dot, too */
        !           211:          mark = d - 1;
        !           212:       }
        !           213:    if (mark)                   /* if no dot, just append suffix */
        !           214:       d = mark;
        !           215:    while (*d++ = *suf++) ;     /* copy suffix into dest */
        !           216:    return (dest);
        !           217:    }
        !           218: 
        !           219: /*
        !           220:  * syserr - issue error message and die.
        !           221:  */
        !           222: syserr(s)
        !           223: char *s;
        !           224:    {
        !           225:    fprintf(stderr, "%s\n", s);
        !           226:    exit(1);
        !           227:    }
        !           228: 
        !           229: /*
        !           230:  * warn - issue a warning message.
        !           231:  */
        !           232: warn(s1, s2, s3)
        !           233: char *s1, *s2, *s3;
        !           234:    {
        !           235:    fprintf(stderr, "%s: ", icnname);
        !           236:    if (line)
        !           237:       fprintf(stderr, "%d: ", line);
        !           238:    if (s1)
        !           239:       fprintf(stderr, "\"%s\": ", s1);
        !           240:    if (s2)
        !           241:       fprintf(stderr, "%s", s2);
        !           242:    if (s3)
        !           243:       fprintf(stderr, "%s", s3);
        !           244:    fprintf(stderr, "\n");
        !           245:    }
        !           246: 
        !           247: /*
        !           248:  * err - issue an error message.
        !           249:  */
        !           250: 
        !           251: err(s1, s2, s3)
        !           252: char *s1, *s2, *s3;
        !           253:    {
        !           254:    fprintf(stderr, "%s: ", icnname);
        !           255:    if (line)
        !           256:       fprintf(stderr, "%d: ", line);
        !           257:    if (s1)
        !           258:       fprintf(stderr, "\"%s\": ", s1);
        !           259:    if (s2)
        !           260:       fprintf(stderr, "%s", s2);
        !           261:    if (s3)
        !           262:       fprintf(stderr, "%s", s3);
        !           263:    fprintf(stderr, "\n");
        !           264:    fatalerrs++;
        !           265:    }

unix.superglobalmegacorp.com

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