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