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

unix.superglobalmegacorp.com

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