Use size-dependant no. of words, with OPEN_MAX as default for fd_set size.
[minix3.git] / commands / make / input.c
blob9eb2a82989a19dd04c47fac9231828ea679d31b0
1 /*************************************************************************
3 * m a k e : i n p u t . c
5 * Parse a makefile
6 *========================================================================
7 * Edition history
9 * # Date Comments By
10 * --- -------- ---------------------------------------------------- ---
11 * 1 ?? ??
12 * 2 23.08.89 new name tree structure introduced to speed up make,
13 * testname introduced to shrink the memory usage RAL
14 * 3 30.08.89 indention changed PSH,RAL
15 * 4 03.09.89 fixed LZ eliminated RAL
16 * 5 06.09.89 ; command added RAL
17 * ------------ Version 2.0 released ------------------------------- RAL
19 *************************************************************************/
22 #include "h.h"
25 static struct name *lastrrp;
26 static struct name *freerp = (struct name *)NULL;
28 void init()
30 if( (suffparray = (struct name **) malloc( sizesuffarray *
31 sizeof(struct name *))) == (struct name **) NULL)
32 fatal("No memory for suffarray",(char *)0,0);
33 if ((*suffparray = (struct name *)malloc(sizeof (struct name)))
34 == (struct name *)0)
35 fatal("No memory for name",(char *)0,0);
36 (*suffparray)->n_next = (struct name *)0;
38 if ((str1 = (char *) malloc(LZ1)) == ((char *)0))
39 fatal("No memory for str1",(char *)0,0);
40 str1s.ptr = &str1;
41 str1s.len = LZ1;
42 if ((str2 = (char *) malloc(LZ2)) == (char *)0)
43 fatal("No memory for str2",(char *)0,0);
44 str2s.ptr = &str2;
45 str2s.len = LZ2;
48 void strrealloc(strs)
49 struct str *strs;
51 strs->len *= 2;
52 *strs->ptr = (char *) realloc(*strs->ptr, strs->len + 16);
53 if(*strs->ptr == (char *) NULL)
54 fatal("No memory for string reallocation",(char *)0,0);
58 * Intern a name. Return a pointer to the name struct
60 struct name *newname(name)
61 char *name;
63 register struct name *rp;
64 register struct name *rrp;
65 register char *cp;
67 register int i;
68 register char *suff; /* ptr. to suffix in current name */
69 register struct name **sp; /* ptr. to ptr. to chain of names */
71 if ( (suff = suffix(name)) != (char *)NULL) {
72 for (i = 1, sp = suffparray, sp++;
73 i <= maxsuffarray && strcmp(suff, (*sp)->n_name) != 0;
74 sp++,i++);
75 if (i > maxsuffarray) {
76 if ( i >= sizesuffarray) { /* must realloc suffarray */
77 sizesuffarray *= 2;
78 if( (suffparray = (struct name **) realloc((char *) suffparray,
79 sizesuffarray * sizeof(struct name *))) == (struct name **) NULL)
80 fatal("No memory for suffarray",(char *)0,0);
82 maxsuffarray++;
83 sp = &suffparray[i];
84 if ((*sp = (struct name *)malloc(sizeof (struct name)))
85 == (struct name *)0)
86 fatal("No memory for name",(char *)0,0);
87 (*sp)->n_next = (struct name *)0;
88 if ((cp = (char *) malloc(strlen(suff)+1)) == (char *)0)
89 fatal("No memory for name",(char *)0,0);
90 strcpy(cp, suff);
91 (*sp)->n_name = cp;
94 else
95 sp = suffparray;
97 for ( rp = (*sp)->n_next, rrp = *sp; rp; rp = rp->n_next, rrp = rrp->n_next )
98 if (strcmp(name, rp->n_name) == 0) return rp;
100 if ( freerp == (struct name *)NULL) {
101 if ((rp = (struct name *)malloc(sizeof (struct name))) == (struct name *)0)
102 fatal("No memory for name",(char *)0,0);
104 else {
105 rp = freerp;
106 freerp = (struct name *)NULL;
108 rrp->n_next = rp;
109 rp->n_next = (struct name *)0;
110 if ((cp = (char *) malloc(strlen(name)+1)) == (char *)0)
111 fatal("No memory for name",(char *)0,0);
112 strcpy(cp, name);
113 rp->n_name = cp;
114 rp->n_line = (struct line *)0;
115 rp->n_time = (time_t)0;
116 rp->n_flag = 0;
117 lastrrp = rrp;
119 return rp;
123 * Test a name.
124 * If the name already exists return the ptr. to its name structure.
125 * Else if the file exists 'intern' the name and return the ptr.
126 * Otherwise don't waste memory and return a NULL pointer
128 struct name *testname(name)
129 char *name;
131 register struct name *rp;
133 lastrrp = (struct name *)NULL;
134 rp = newname( name);
135 if (rp->n_line || rp->n_flag & N_EXISTS)
136 return(rp);
137 modtime(rp);
138 if (rp->n_flag & N_EXISTS)
139 return(rp);
140 if (lastrrp != (struct name *)NULL) {
141 free (rp->n_name);
142 lastrrp->n_next = (struct name *)NULL;
143 freerp = rp;
145 return((struct name *)NULL);
151 * Add a dependant to the end of the supplied list of dependants.
152 * Return the new head pointer for that list.
154 struct depend *newdep(np, dp)
155 struct name *np;
156 struct depend *dp;
158 register struct depend *rp;
159 register struct depend *rrp;
162 if ((rp = (struct depend *)malloc(sizeof (struct depend)))
163 == (struct depend *)0)
164 fatal("No memory for dependant",(char *)0,0);
165 rp->d_next = (struct depend *)0;
166 rp->d_name = np;
168 if (dp == (struct depend *)0) return rp;
170 for (rrp = dp; rrp->d_next; rrp = rrp->d_next) ;
172 rrp->d_next = rp;
174 return dp;
179 * Add a command to the end of the supplied list of commands.
180 * Return the new head pointer for that list.
182 struct cmd *newcmd(str, cp)
183 char *str;
184 struct cmd *cp;
186 register struct cmd *rp;
187 register struct cmd *rrp;
188 register char *rcp;
191 if (rcp = strrchr(str, '\n')) *rcp = '\0'; /* Loose newline */
193 while (isspace(*str)) str++;
195 if (*str == '\0') return cp; /* If nothing left, the exit */
197 if ((rp = (struct cmd *)malloc(sizeof (struct cmd))) == (struct cmd *)0)
198 fatal("No memory for command",(char *)0,0);
199 rp->c_next = (struct cmd *)0;
200 if ((rcp = (char *) malloc(strlen(str)+1)) == (char *)0)
201 fatal("No memory for command",(char *)0,0);
202 strcpy(rcp, str);
203 rp->c_cmd = rcp;
205 if (cp == (struct cmd *)0) return rp;
207 for (rrp = cp; rrp->c_next; rrp = rrp->c_next) ;
209 rrp->c_next = rp;
211 return cp;
216 * Add a new 'line' of stuff to a target. This check to see
217 * if commands already exist for the target. If flag is set,
218 * the line is a double colon target.
220 * Kludges:
221 * i) If the new name begins with a '.', and there are no dependents,
222 * then the target must cease to be a target. This is for .SUFFIXES.
223 * ii) If the new name begins with a '.', with no dependents and has
224 * commands, then replace the current commands. This is for
225 * redefining commands for a default rule.
226 * Neither of these free the space used by dependents or commands,
227 * since they could be used by another target.
230 void newline(np, dp, cp, flag)
231 struct name *np;
232 struct depend *dp;
233 struct cmd *cp;
234 int flag;
236 bool hascmds = FALSE; /* Target has commands */
237 register struct line *rp;
238 register struct line *rrp;
241 /* Handle the .SUFFIXES case */
242 if (np->n_name[0] == '.' && !dp && !cp) {
243 for (rp = np->n_line; rp; rp = rrp) {
244 rrp = rp->l_next;
245 free(rp);
247 np->n_line = (struct line *)0;
248 np->n_flag &= ~N_TARG;
249 return;
252 /* This loop must happen since rrp is used later. */
253 for ( rp = np->n_line, rrp = (struct line *)0; rp; rrp = rp, rp = rp->l_next)
254 if (rp->l_cmd) hascmds = TRUE;
256 if (hascmds && cp && !(np->n_flag & N_DOUBLE))
257 /* Handle the implicit rules redefinition case */
258 if (np->n_name[0] == '.' && dp == (struct depend *)0) {
259 np->n_line->l_cmd = cp;
260 return;
262 else
263 error("Commands defined twice for target %s", np->n_name);
264 if (np->n_flag & N_TARG)
265 if (!(np->n_flag & N_DOUBLE) != !flag) /* like xor */
266 error("Inconsistent rules for target %s", np->n_name);
268 if ((rp = (struct line *)malloc(sizeof (struct line))) == (struct line *)0)
269 fatal("No memory for line",(char *)0,0);
270 rp->l_next = (struct line *)0;
271 rp->l_dep = dp;
272 rp->l_cmd = cp;
274 if (rrp)
275 rrp->l_next = rp;
276 else
277 np->n_line = rp;
279 np->n_flag |= N_TARG;
280 if (flag) np->n_flag |= N_DOUBLE;
285 * Parse input from the makefile, and construct a tree structure
286 * of it.
288 void input(fd)
289 FILE *fd;
291 char *p; /* General */
292 char *q;
293 register char *a;
294 struct name *np;
295 struct depend *dp;
296 struct cmd *cp;
297 bool dbl;
300 if (getline(&str1s, fd)) return; /* Read the first line */
302 for(;;) {
303 if (*str1 == TABCHAR) /* Rules without targets */
304 error("Rules not allowed here",(char *)0);
306 p = str1;
308 while (isspace(*p)) p++; /* Find first target */
311 while (((q = strchr(p, '=')) != (char *)0) &&
312 (p != q) && (q[-1] == '\\')) /* Find value */
314 a = q - 1; /* Del \ chr; move rest back */
315 p = q;
316 while(*a++ = *q++)
320 if (q != (char *)0) {
322 *q++ = '\0'; /* Separate name and val */
323 while (isspace(*q))
324 q++;
325 if (p = strrchr(q, '\n'))
326 *p = '\0';
328 p = str1;
329 if ((a = gettok(&p)) == (char *)0)
330 error("No macro name",(char *)0);
332 setmacro(a, q);
334 if (getline(&str1s, fd))
335 return;
336 continue;
339 /* include? */
340 p = str1;
341 while (isspace(*p)) p++;
342 if (strncmp(p, "include", 7) == 0 && isspace(p[7])) {
343 char *old_makefile = makefile;
344 int old_lineno = lineno;
345 FILE *ifd;
347 p += 8;
348 memmove(str1, p, strlen(p)+1);
349 expand(&str1s);
350 p = str1;
351 while (isspace(*p)) p++;
353 if ((q = malloc(strlen(p)+1)) == (char *)0)
354 fatal("No memory for include",(char *)0,0);
356 strcpy(q, p);
357 p = q;
358 while ((makefile = gettok(&q)) != (char *)0) {
359 if ((ifd = fopen(makefile, "r")) == (FILE *)0)
360 fatal("Can't open %s: %s", makefile, errno);
361 lineno = 0;
362 input(ifd);
363 fclose(ifd);
365 free(p);
366 makefile = old_makefile;
367 lineno = old_lineno;
369 if (getline(&str1s, fd))
370 return;
371 continue;
374 /* Search for commands on target line --- do not expand them ! */
375 q = str1;
376 cp = (struct cmd *)0;
377 if ((a = strchr(q, ';')) != (char *)0) {
378 *a++ = '\0'; /* Separate dependents and commands */
379 if ( a) cp = newcmd(a, cp);
382 expand(&str1s);
383 p = str1;
385 while (isspace(*p)) p++;
387 while (((q = strchr(p, ':')) != (char *)0) &&
388 (p != q) && (q[-1] == '\\')) /* Find dependents */
390 a = q - 1; /* Del \ chr; move rest back */
391 p = q;
392 while(*a++ = *q++) ;
395 if (q == (char *)0)
396 error("No targets provided",(char *)0);
398 *q++ = '\0'; /* Separate targets and dependents */
400 if (*q == ':') { /* Double colon */
401 dbl = 1;
402 q++;
404 else
405 dbl = 0;
407 for (dp = (struct depend *)0; ((p = gettok(&q)) != (char *)0);)
408 /* get list of dep's */
410 np = newname(p); /* Intern name */
411 dp = newdep(np, dp); /* Add to dep list */
414 *((q = str1) + strlen(str1) + 1) = '\0';
415 /* Need two nulls for gettok (Remember separation) */
417 if (getline(&str2s, fd) == FALSE) { /* Get commands */
418 while (*str2 == TABCHAR) {
419 cp = newcmd(&str2[0], cp);
420 if (getline(&str2s, fd))
421 break;
425 while ((p = gettok(&q)) != (char *)0) /* Get list of targ's */
427 np = newname(p); /* Intern name */
428 newline(np, dp, cp, dbl);
429 if (!firstname && p[0] != '.')
430 firstname = np;
433 if (feof(fd)) /* EOF? */
434 return;
436 while (strlen(str2) >= str1s.len) strrealloc(&str1s);
437 strcpy(str1, str2);