1 /* @(#)parse.c 1.129 21/08/06 Copyright 1985-2021 J. Schilling */
2 #include <schily/mconfig.h>
3 #ifndef lint
4 static UConst char sccsid[] =
5 "@(#)parse.c 1.129 21/08/06 Copyright 1985-2021 J. Schilling";
6 #endif
7 /*
8 * Make program
9 * Parsing routines
10 *
11 * Copyright (c) 1985-2021 by J. Schilling
12 */
13 /*
14 * The contents of this file are subject to the terms of the
15 * Common Development and Distribution License, Version 1.0 only
16 * (the "License"). You may not use this file except in compliance
17 * with the License.
18 *
19 * See the file CDDL.Schily.txt in this distribution for details.
20 * A copy of the CDDL is also available via the Internet at
21 * http://www.opensource.org/licenses/cddl1.txt
22 *
23 * When distributing Covered Code, include this CDDL HEADER in each
24 * file and include the License file CDDL.Schily.txt from this distribution.
25 */
26
27 #include <schily/stdio.h>
28 #include <schily/standard.h>
29 #include <schily/varargs.h>
30 #include <schily/stdlib.h>
31 #include <schily/unistd.h> /* include sys/types.h for schily/schily.h */
32 #include <schily/string.h>
33 #include <schily/schily.h>
34 #include <schily/ccomdefs.h>
35 #include "make.h"
36
37 #ifdef pdp11
38 #define MAXOBJS 64 /* Max # of targets in target list. */
39 #else
40 #define MAXOBJS 512 /* Max # of targets in target list. */
41 #endif
42
43
44 EXPORT void parsefile __PR((void));
45 LOCAL void define_obj __PR((obj_t * obj, int n, int objcnt, int type, list_t * dep, cmd_t * cmd));
46 LOCAL obj_t *define_dcolon __PR((obj_t *obj));
47 LOCAL void listappend __PR((obj_t *obj, list_t *dep));
48 LOCAL void define_patrule __PR((obj_t * obj, list_t * dep, cmd_t * cmd, int type));
49 LOCAL void print_patrules __PR((FILE *f));
50 LOCAL obj_t *check_ssuffrule __PR((obj_t *obj, list_t *dep));
51 EXPORT char *get_var __PR((char *name));
52 EXPORT void define_var __PR((char *name, char *val));
53 LOCAL int getobjname __PR((void));
54 LOCAL obj_t *getobj __PR((void));
55 LOCAL int getname __PR((int type));
56 LOCAL obj_t *getnam __PR((int type));
57 LOCAL int getln __PR((void));
58 LOCAL list_t **listcat __PR((obj_t * obj, list_t ** tail));
59 LOCAL list_t **mklist __PR((char *line, list_t ** tail, BOOL doexpand));
60 LOCAL list_t *cplist __PR((list_t * l));
61 LOCAL list_t **exp_list __PR((obj_t * o, list_t ** tail));
62 LOCAL list_t *getlist __PR((int *typep));
63 LOCAL BOOL is_shvar __PR((obj_t ** op, int *typep, list_t *** tailp));
64 LOCAL list_t *getshvar __PR((int *typep));
65 LOCAL cmd_t *getcmd __PR((void));
66 LOCAL int exp_ovec __PR((obj_t ** ovec, int objcnt));
67 LOCAL int read_ovec __PR((obj_t ** ovec, int *typep));
68 EXPORT list_t *cvtvpath __PR((list_t *l));
69 EXPORT BOOL is_inlist __PR((char *objname, char *name));
70 LOCAL BOOL obj_in_list __PR((obj_t *obj, list_t *l));
71 EXPORT BOOL nowarn __PR((char *name));
72 LOCAL void warn __PR((char *, ...)) __printflike__(1, 2);
73 LOCAL void exerror __PR((char *, ...)) __printflike__(1, 2);
74 LOCAL obj_t *_objlook __PR((obj_t *table[], char *name, BOOL create));
75 EXPORT obj_t *objlook __PR((char *name, BOOL create));
76 EXPORT list_t *objlist __PR((char *name));
77 EXPORT obj_t *ssufflook __PR((char *name, BOOL create));
78 EXPORT BOOL check_ssufftab __PR((void));
79 LOCAL void clear_ssufftab __PR((void));
80 LOCAL BOOL is_suffix_rule __PR((obj_t *obj));
81 LOCAL void prvar __PR((obj_t * p));
82 LOCAL void ptree __PR((obj_t * p, int n));
83 EXPORT void printtree __PR((void));
84 EXPORT void probj __PR((FILE *f, obj_t * o, int type, int dosuff));
85 EXPORT void prtree __PR((void));
86 LOCAL char *typestr __PR((int type));
87 LOCAL void printobj __PR((FILE *f, obj_t ** ovec, int objcnt, int type, list_t * deplist, cmd_t * cmdlist));
88
89 /*
90 * parse the dependency file
91 *
92 * <obj1> {<obj2> ...} : <dependency list>
93 * { <cmdlist>}
94 *
95 * <macro>= <macro value>
96 *
97 * <macro> += <macro value>
98 *
99 * <macro> :sh= <shell command>
100 */
101 EXPORT void
parsefile()102 parsefile()
103 {
104 int i, objcnt;
105 int type = 0; /* init to make GCC quiet */
106 obj_t *ovec[MAXOBJS];
107 list_t *deplist;
108 cmd_t *cmdlist;
109
110 if (Do_Warn)
111 error("Parsing file '%s'\n", mfname);
112
113 if (Dmake > 0)
114 error(">>>>>>>>>>>>>>>> Reading makefile '%s'\n", mfname);
115
116 ovec[0] = 0;
117 lineno = 1;
118 col = 0;
119 getch();
120 while (lastc != EOF) {
121 if (lastc == '\t') {
122 /*
123 * Skip leading white space that follows a TAB.
124 */
125 while (lastc != EOF && (lastc == ' ' || lastc == '\t'))
126 getch();
127 /*
128 * Abort if such a line is not empty or contains more
129 * than only a comment. This has the side effect that
130 * '^<TAB> include' will not work anymore.
131 */
132 if (lastc != '\n') {
133 exerror(
134 "Unexpected <TAB> character followed by nonblank '%c' <%o>",
135 lastc, lastc);
136 }
137 getch(); /* Eat up new line character */
138 continue; /* Continue with next line */
139 }
140 type = 0;
141 if ((objcnt = read_ovec(ovec, &type)) == 0) {
142 if (Do_Warn && (type & NWARN) == 0) {
143 /*
144 * This is when $(EMPTY) was expanded to nothing
145 * in exp_ovec() inside read_ovec().
146 */
147 warn("Missing object name");
148 }
149 type = ntype(type);
150 if (type != COLON && type != DCOLON)
151 continue;
152 }
153 type = ntype(type);
154
155 if (objcnt < 0) {
156 errmsgno(EX_BAD, "Objcount: %d Objects: ", -objcnt);
157 for (i = 0; i < -objcnt; i++)
158 error("'%s' ", ovec[i]->o_name);
159 error("\n");
160 exerror("Too many target items");
161 }
162
163 #ifdef XXX /* Begin new code for include */
164 printf("objcnt: %d ovec[0]: %s lastc: '%c'\n", objcnt, ovec[0]->o_name, lastc);
165 for (i = 0; i < objcnt; i++)
166 printf("name[%d] = %s ", i, ovec[i]->o_name);
167 printf("\n");
168 #endif
169 if (lastc == '\n') {
170 if (streql(ovec[0]->o_name, "include") ||
171 streql(ovec[0]->o_name, "-include")) {
172 for (i = 1; i < objcnt; i++) {
173 doinclude(ovec[i]->o_name,
174 ovec[0]->o_name[0] != '-');
175 }
176 /* XXX freeobj ??? */
177 continue;
178 }
179 if (streql(ovec[0]->o_name, "export")) {
180 for (i = 1; i < objcnt; i++) {
181 doexport(ovec[i]->o_name);
182 }
183 /* XXX freeobj ??? */
184 continue;
185 }
186 if (streql(ovec[0]->o_name, "unexport")) {
187 for (i = 1; i < objcnt; i++) {
188 dounexport(ovec[i]->o_name);
189 }
190 /* XXX freeobj ??? */
191 continue;
192 }
193 if (streql(ovec[0]->o_name, "readonly")) {
194 for (i = 1; i < objcnt; i++) {
195 ovec[i]->o_flags |= F_READONLY;
196 }
197 /* XXX freeobj ??? */
198 continue;
199 }
200 /*
201 * Any other word on the beginning of a line
202 * that is not followed by a ':' or a '=' is an error.
203 */
204 } /* end new code for include */
205
206 if (lastc != ':' && lastc != '=') {
207 errmsgno(EX_BAD, "Objcount: %d Objects: ", objcnt);
208 for (i = 0; i < objcnt; i++)
209 error("'%s' ", ovec[i]->o_name);
210 error("\n");
211 exerror("Missing : or =, got '%c' <%o>", lastc, lastc);
212 }
213 getch();
214 /*
215 * If the macro type is ::= (GNU style assgignment),
216 * the + operator expands variables on the right hand side
217 * and we need to replace the operator + by +:= first.
218 * ::= followed by + results in unpredictable behavior and for
219 * this reason, it is recommended to have at least one
220 * lowercase char in ::= types macro name to tell people about
221 * the unusual behavior of the + operator.
222 */
223 if (type == ADDMAC && ovec[0]->o_type == GNU_ASSIGN)
224 type = ADD_VARMAC;
225 in_parser = -1; /* In parser but no ::= expansion */
226 deplist = getlist(&type);
227 in_parser = 0;
228 if (type == SHVAR)
229 deplist = getshvar(&type);
230
231 if (lastc == ';') {
232 lastc = '\t';
233 firstc = '\t';
234 }
235
236 /*
237 * We should test for type == COLON only but unfortunately,
238 * the makefilesystem contained some simple pattern rule
239 * definitions that are written as: tgt_suff = list.
240 * We only allow what has been used in the makefilesystem.
241 * This changed in late 1999, we should keep support
242 * for it for at least 5 years.
243 */
244 /* if (basetype(type) == COLON) {*/
245 if (basetype(type) == COLON ||
246 (basetype(type) == EQUAL && deplist && objcnt > 0 &&
247 ovec[0]->o_name[0] == '.')) {
248 cmdlist = getcmd();
249 } else {
250 cmdlist = NULL;
251 }
252 while (lastc == '\n')
253 getch();
254 for (i = 0; i < objcnt; i++)
255 define_obj(ovec[i], i, objcnt, type, deplist, cmdlist);
256
257 if (Dmake > 0)
258 printobj(stderr, ovec, objcnt, type, deplist, cmdlist);
259 }
260 if (Dmake > 0)
261 error(">>>>>>>>>>>>>>>> End of makefile '%s'\n", mfname);
262 }
263
264 /*
265 * Add dependency and command lists to a node in the object tree.
266 * Allow definitions to be overridden if the new definition in in
267 * a different file.
268 */
269 LOCAL void
define_obj(obj,n,objcnt,type,dep,cmd)270 define_obj(obj, n, objcnt, type, dep, cmd)
271 register obj_t *obj;
272 int n;
273 int objcnt;
274 int type;
275 register list_t *dep;
276 cmd_t *cmd;
277 {
278 /*
279 * For a conditional macro assignment ?=, we do nothing if the
280 * object already has a value list assigned.
281 */
282 if (type == CONDEQUAL && obj->o_list)
283 return;
284
285 /*
286 * First check for possible direct recursions to avoid to blow
287 * up memory immediately.
288 */
289 if (type != '=' && obj_in_list(obj, dep))
290 exerror("Recursion in dependencies for '%s'", obj->o_name);
291
292 /*
293 * If we have a list of targets with the same dependency list,
294 * we copy the list structure to be able to separately
295 * append new elements to each of the targets.
296 */
297 if (n > 0)
298 dep = cplist(dep);
299
300 if (objcnt == 1) {
301 if (basetype(type) == COLON &&
302 strchr(obj->o_name, '%') != NULL) {
303 define_patrule(obj, dep, cmd, type);
304 return;
305 }
306 /*
307 * We should test for type == COLON too but unfortunately,
308 * the makefilesystem contained some simple pattern rule
309 * definitions that are written as: tgt_suff = list.
310 * This changed in late 1999, we should keep support
311 * for it for at least 5 years.
312 */
313 /* if (type == COLON && && dep != NULL && cmd != NULL) {*/
314 if (dep != NULL && cmd != NULL) {
315 obj = check_ssuffrule(obj, dep);
316 }
317 } else {
318 obj->o_flags |= F_MULTITARGET;
319 }
320 if (obj->o_type == 0)
321 obj->o_type = type;
322
323 /*
324 * Save first target that does not start with
325 * a dot in case no arguments have been supplied
326 * to make.
327 */
328 if (n == 0 && !default_tgt && basetype(type) == COLON &&
329 (obj->o_name[0] != '.' || obj->o_name[1] == SLASH ||
330 (obj->o_name[1] == '.' && obj->o_name[2] == SLASH)))
331 default_tgt = obj;
332
333 if (n == 0 && basetype(type) == COLON &&
334 obj->o_name[0] == '.' && streql(obj->o_name, ".POSIX"))
335 posixmode = TRUE;
336
337 if (type == DCOLON)
338 obj = define_dcolon(obj);
339
340 /*
341 * XXX Probleme gibt es mit der Gleichbehandlung von ':' und '=' typen.
342 * XXX So definiert 'smake' MAKE_NAME= smake und sp�ter kommt evt.
343 * XXX smake: $(OBJLIST)
344 */
345
346
347 if (obj->o_flags & F_READONLY) { /* Check for "read only" */
348 if (!((obj->o_flags & F_IDXOVERWRT) &&
349 (obj->o_fileindex == Mfileindex)))
350 return;
351 }
352 obj->o_flags |= Mflags; /* Add current global flags */
353
354 /*
355 * Old:
356 * Definition in new Makefile overrides existing definitions
357 *
358 * New:
359 * Definitions in Makefiles from commandline override
360 * existing definitions. Further definitions in cmdline Makefiles
361 * append.
362 */
363 if ((obj->o_fileindex < MF_IDX_MAKEFILE || basetype(obj->o_type) == EQUAL) &&
364 (type != ADDMAC && type != ADD_VARMAC) &&
365 !streql(obj->o_name, ".SUFFIXES")) {
366
367 /*
368 * We unfortunately also print this warning in case that "obj"
369 * just has been created by the parser.
370 */
371 if (Do_Warn && (obj->o_flags & F_NEWNODE) == 0)
372 warn("'%s' RE-defined", obj->o_name);
373 if (obj->o_fileindex == MF_IDX_ENVIRON) {
374 obj->o_fileindex = Mfileindex;
375 obj->o_type = type;
376 }
377 obj->o_list = dep;
378 obj->o_cmd = cmd;
379 obj->o_flags &= ~F_NEWNODE;
380 return;
381 }
382
383 /*
384 * Add new definitions to list.
385 * Ignore definitions already in list.
386 */
387 listappend(obj, dep);
388
389 if (obj->o_cmd != (cmd_t *) NULL) {
390 if (cmd != (cmd_t *) NULL) {
391 warn("Multiple commands defined for '%s'", obj->o_name);
392 /* XXX freelist()/freecmd() ??? */
393 }
394 } else {
395 obj->o_cmd = cmd;
396 }
397 }
398
399 /*
400 * Define an intermediate target for Double Colon :: Rules
401 *
402 * a:: b
403 * cmd_b
404 * a:: c
405 * cmd_c
406 *
407 * results in:
408 * a:: ::1@a ::2@a
409 * and
410 * ::1@a: b
411 * cmd_b
412 * ::2@a: c
413 * cmd_c
414 */
415 LOCAL obj_t *
define_dcolon(obj)416 define_dcolon(obj)
417 register obj_t *obj;
418 {
419 static int serial = 0;
420 obj_t *o;
421 list_t *lo;
422 char _name[TYPICAL_NAMEMAX];
423 char *name = _name;
424 size_t namelen = sizeof (_name);
425 char *np = NULL;
426
427 if (obj->o_namelen + 16 >= namelen) {
428 namelen = obj->o_namelen + 16;
429 name = np = ___realloc(np, namelen, "dcolon target");
430 }
431 snprintf(name, namelen, "::%d@%s", ++serial, obj->o_name);
432 o = objlook(name, TRUE);
433 if (np)
434 free(np);
435 o->o_type = ':';
436 o->o_flags |= F_DCOLON; /* Mark as intermediate :: object */
437 lo = (list_t *) fastalloc(sizeof (list_t));
438 lo->l_next = NULL;
439 lo->l_obj = o;
440
441 listappend(obj, lo); /* Append this intermediate to list */
442
443 o->o_node = obj; /* Make this inter. obj aux to orig */
444 return (o); /* Return intermediate object */
445 }
446
447 /*
448 * Append new definitions to dependencies in o_list, but
449 * ignore them if they are already in the list.
450 */
451 LOCAL void
listappend(obj,dep)452 listappend(obj, dep)
453 register obj_t *obj;
454 register list_t *dep;
455 {
456 if (dep == NULL && obj->o_name[0] == '.' &&
457 streql(obj->o_name, ".SSUFFIX_RULES"))
458 clear_ssufftab();
459 if (obj->o_list != (list_t *) NULL) {
460 register list_t *l = obj->o_list;
461
462 if (dep == NULL && obj->o_name[0] == '.') {
463 /*
464 * Allow to clear special targets.
465 */
466 if (streql(obj->o_name, ".SUFFIXES") ||
467 streql(obj->o_name, ".SSUFFIX_RULES") ||
468 streql(obj->o_name, ".DEFAULT") ||
469 streql(obj->o_name, ".NO_WARN") ||
470 streql(obj->o_name, ".SCCS_GET") ||
471 streql(obj->o_name, ".SPACE_IN_NAMES"))
472 obj->o_list = NULL;
473 obj->o_flags &= ~F_NEWNODE;
474 return;
475 }
476
477 if (Do_Warn && (obj->o_flags & F_NEWNODE) == 0) {
478 if (obj->o_type != ':' || Do_Warn > 1)
479 warn("'%s' ADD-defined", obj->o_name);
480 }
481
482 /*
483 * if not already head of list, try to append ...
484 */
485 if (l != dep) {
486 while (l->l_next && l->l_next != dep)
487 l = l->l_next;
488 if (l->l_next == (list_t *) NULL)
489 l->l_next = dep;
490 }
491 } else {
492 obj->o_list = dep;
493 }
494 obj->o_flags &= ~F_NEWNODE;
495 }
496
497 patr_t *Patrules;
498 patr_t **pattail = &Patrules;
499
500 /*
501 * Parse a pattern rule definition. This is a special type of implicit rules.
502 */
503 LOCAL void
define_patrule(obj,dep,cmd,type)504 define_patrule(obj, dep, cmd, type)
505 obj_t *obj;
506 list_t *dep;
507 cmd_t *cmd;
508 int type;
509 {
510 patr_t *p;
511 char *s;
512 register list_t *l;
513
514 p = (patr_t *) fastalloc(sizeof (*p)); /* larger than list_t */
515
516 p->p_name = obj;
517 p->p_list = dep;
518 p->p_cmd = cmd;
519 s = strchr(obj->o_name, '%');
520 if (s != NULL) {
521 *s = '\0';
522 p->p_tgt_prefix = strsave(obj->o_name);
523 p->p_tgt_suffix = strsave(&s[1]);
524 *s = '%';
525 } else { /* This can never happen! */
526 p->p_tgt_prefix = strsave(Nullstr);
527 p->p_tgt_suffix = strsave(obj->o_name);
528 }
529 p->p_tgt_pfxlen = strlen(p->p_tgt_prefix);
530 p->p_tgt_suflen = strlen(p->p_tgt_suffix);
531
532 for (l = dep; l; l = l->l_next) {
533 if (strchr(l->l_obj->o_name, '%'))
534 l->l_obj->o_flags |= F_PERCENT;
535 }
536 if (dep == NULL) {
537 p->p_src_prefix = 0;
538 p->p_src_suffix = 0;
539 p->p_src_pfxlen = 0;
540 p->p_src_suflen = 0;
541 } else {
542 s = strchr(dep->l_obj->o_name, '%');
543 if (s != NULL) {
544 *s = '\0';
545 p->p_src_prefix = strsave(dep->l_obj->o_name);
546 p->p_src_suffix = strsave(&s[1]);
547 *s = '%';
548 } else {
549 p->p_src_prefix = strsave(Nullstr);
550 p->p_src_suffix = strsave(dep->l_obj->o_name);
551 }
552 p->p_src_pfxlen = strlen(p->p_src_prefix);
553 p->p_src_suflen = strlen(p->p_src_suffix);
554 }
555 p->p_flags = 0;
556 if (type == DCOLON)
557 p->p_flags |= PF_TERM; /* Make it a termiator rule */
558 *pattail = p;
559 pattail = &p->p_next;
560 p->p_next = 0;
561 }
562
563 /*
564 * Print the complete list of pattern rules.
565 */
566 LOCAL void
print_patrules(f)567 print_patrules(f)
568 FILE *f;
569 {
570 patr_t *p = Patrules;
571 cmd_t *c;
572
573 while (p) {
574 register list_t *l;
575
576 fprintf(f, "%s%%%s:%s",
577 p->p_tgt_prefix, p->p_tgt_suffix,
578 (p->p_flags & PF_TERM) ? ":":"");
579
580 for (l = p->p_list; l; l = l->l_next) {
581 fprintf(f, " %s", l->l_obj->o_name);
582 }
583 printf("\n");
584
585 for (c = p->p_cmd; c; c = c->c_next)
586 fprintf(f, "\t%s\n", c->c_line);
587 p = p->p_next;
588 }
589 }
590
591 /*
592 * Check for a simple suffix rule definition.
593 * In case we found a simple suffix rule definition, return a new obj_t *.
594 */
595 LOCAL obj_t *
check_ssuffrule(obj,dep)596 check_ssuffrule(obj, dep)
597 obj_t *obj;
598 list_t *dep;
599 {
600 register char *name = obj->o_name;
601 register list_t *l;
602 extern int xssrules;
603
604 /*
605 * Check if the first character of the target is a '.' or
606 * if the target name equals "", but make sure this is
607 * not a vanilla target that just starts with "./".
608 */
609 if ((name[0] == '.' && strchr(name, SLASH) == NULL) ||
610 (name[0] == '"' && name[1] == '"' && name[2] == '\0')) {
611
612 /*
613 * All dependency names must start with a '.'
614 * and may not contain a SLASH.
615 */
616 for (l = dep; l; l = l->l_next) {
617 if (l->l_obj->o_name[0] != '.')
618 return (obj);
619 if (strchr(l->l_obj->o_name, SLASH) != NULL)
620 return (obj);
621 }
622 obj = ssufflook(obj->o_name, TRUE);
623 xssrules++;
624 }
625 return (obj);
626 }
627
628 /*
629 * Get the macro value as in the form macro=value.
630 */
631 EXPORT char *
get_var(name)632 get_var(name)
633 char *name;
634 {
635 obj_t *o = objlook(name, FALSE);
636
637 if (o == (obj_t *)NULL)
638 return ((char *)NULL);
639
640 if (basetype(o->o_type) == EQUAL && o->o_list != NULL)
641 return (o->o_list->l_obj->o_name);
642 return ((char *)NULL);
643 }
644
645 /*
646 * Define a macro as in the form macro=value.
647 * Value may only be one word.
648 */
649 EXPORT void
define_var(name,val)650 define_var(name, val)
651 char *name;
652 char *val;
653 {
654 obj_t *o;
655 obj_t *ov;
656 list_t *list;
657 list_t **tail = &list;
658
659 o = objlook(name, TRUE);
660 if (o->o_flags & F_READONLY) { /* Check for "read only" */
661 if (!((o->o_flags & F_IDXOVERWRT) &&
662 (o->o_fileindex == Mfileindex)))
663 return;
664 }
665 o->o_flags |= Mflags; /* Add current global flags */
666 if (val && *val) { /* Only if not empty */
667 ov = objlook(val, TRUE);
668 tail = listcat(ov, tail);
669 }
670 *tail = (list_t *) NULL;
671 o->o_list = list;
672 o->o_type = EQUAL;
673 o->o_flags &= ~F_NEWNODE;
674 }
675
676 #ifdef NEEDED
677 /*
678 * Define a macro as in the form macro=vallist.
679 * Vallist may be a list of words that is white space separated in one string.
680 */
681 EXPORT void
define_lvar(name,vallist)682 define_lvar(name, vallist)
683 char *name;
684 char *vallist;
685 {
686 obj_t *o;
687 obj_t *ov;
688 list_t *list;
689 list_t **tail = &list;
690
691 o = objlook(name, TRUE);
692 if (o->o_flags & F_READONLY) /* Check for "read only" */
693 return;
694 o->o_flags |= Mflags; /* Add current global flags */
695 tail = mklist(vallist, tail, FALSE);
696 *tail = (list_t *) NULL;
697 o->o_list = list;
698 o->o_type = EQUAL;
699 o->o_flags &= ~F_NEWNODE;
700 }
701
702 /*
703 * Return a list_t pointer to the nth word in a macro value list.
704 */
705 list_t *
varvaln(name,n)706 varvaln(name, n)
707 char *name;
708 int n;
709 {
710 obj_t *o = objlook(name, FALSE);
711
712 if (o)
713 return (list_nth(o->o_list, n));
714 return ((list_t *)0);
715 }
716 #endif /* NEEDED */
717
718 #define white(c) (c == ' ' || c == '\t')
719
720 /*
721 * Read a space separated word from current Makefile.
722 * Used for target list. Stop at space, ':' '=' and ','.
723 * Returns the length of the word.
724 */
725 LOCAL int
getobjname()726 getobjname()
727 {
728 register char *p = gbuf;
729 register int beg = 0;
730 register int end = 0;
731 register int nestlevel = 0;
732
733 while (white(lastc))
734 getch(); /* Skip white space. */
735 if (lastc == '$') {
736 switch (beg = peekch()) {
737
738 case '(': end = ')'; break;
739 case '{': end = '}'; break;
740
741 default:
742 beg = end = -1;
743 }
744 }
745 while (lastc != EOF && (' ' < lastc || nestlevel > 0)) {
746 if (lastc == beg)
747 nestlevel++;
748 else if (lastc == end)
749 nestlevel--;
750 if (nestlevel <= 0) {
751 if (lastc == ':' || lastc == '=' || lastc == ',')
752 break;
753 }
754 #ifdef __CHECK_NAMEMAX_IN_GETOBJNAME__
755 if (n >= NAMEMAX - 2)
756 exerror("Name more than %d chars long", NAMEMAX - 2);
757 #endif /* __CHECK_NAMEMAX_IN_GETOBJNAME__ */
758 if (p >= gbufend)
759 p = growgbuf(p);
760 *p++ = lastc;
761 if (istext(lastc)) /* Can we avoid getch()? */
762 p = gtext(p); /* Get usual text faster */
763
764 if (nestlevel <= 0 && lastc == '\\') {
765 if (white(peekch()) && objlist(".SPACE_IN_NAMES")) {
766 getch();
767 p--;
768 *p++ = lastc;
769 }
770 }
771 getch();
772 }
773 if (p >= gbufend)
774 p = growgbuf(p);
775 *p = '\0'; /* Terminate with null char */
776 return (p - gbuf);
777 }
778
779 /*
780 * Read a target file name.
781 */
782 LOCAL obj_t
getobj()783 *getobj()
784 {
785 return (getobjname() ? objlook(gbuf, TRUE) : (obj_t *) NULL);
786 }
787
788 /*
789 * Read a space separated word from current Makefile.
790 * General purpose version for dependency list.
791 * Returns the length of the word.
792 */
793 LOCAL int
getname(type)794 getname(type)
795 int type;
796 {
797 register char *p = gbuf;
798 register int beg = 0;
799 register int end = 0;
800 register int nestlevel = 0;
801
802 if (type == ':')
803 type = ';';
804 else
805 type = '\0';
806
807 while (white(lastc))
808 getch(); /* Skip white space. */
809 if (lastc == '$') {
810 switch (beg = peekch()) {
811
812 case '(': end = ')'; break;
813 case '{': end = '}'; break;
814
815 default:
816 beg = end = -1;
817 }
818 }
819 while (lastc != EOF && (' ' < lastc || nestlevel > 0)) {
820 if (lastc == beg)
821 nestlevel++;
822 else if (lastc == end)
823 nestlevel--;
824 if (nestlevel <= 0) {
825 if (lastc == type)
826 break;
827 }
828 #ifdef __CHECK_NAMEMAX_IN_GETNAME__
829 if (n >= NAMEMAX - 2)
830 exerror("Name more than %d chars long", NAMEMAX - 2);
831 #endif /* __CHECK_NAMEMAX_IN_GETNAME__ */
832 if (p >= gbufend)
833 p = growgbuf(p);
834 *p++ = lastc;
835 if (istext(lastc)) /* Can we avoid getch()? */
836 p = gtext(p); /* Get usual text faster */
837
838 if (nestlevel <= 0 && lastc == '\\') {
839 if (white(peekch()) && objlist(".SPACE_IN_NAMES")) {
840 getch();
841 p--;
842 *p++ = lastc;
843 }
844 }
845 getch();
846 }
847 if (p >= gbufend)
848 p = growgbuf(p);
849 *p = '\0'; /* Terminate with null char */
850 return (p - gbuf);
851 }
852
853 /*
854 * Read a dependency file name.
855 */
856 LOCAL obj_t *
getnam(type)857 getnam(type)
858 int type;
859 {
860 return (getname(type) ? objlook(gbuf, TRUE) : (obj_t *) NULL);
861 }
862
863 /*
864 * Reads a line from current Makefile.
865 * Returns the length of the string.
866 */
867 LOCAL int
getln()868 getln()
869 {
870 register char *p = gbuf;
871
872 while (white(lastc))
873 getch(); /* Skip white space. */
874 while (lastc != EOF && lastc != '\n') {
875 #ifdef __CHECK_NAMEMAX_IN_GETLN__
876 if (n >= NAMEMAX - 2) {
877 exerror("Line more than %d chars long", NAMEMAX - 2);
878 }
879 #endif /* __CHECK_NAMEMAX_IN_GETLN__ */
880 if (p >= gbufend)
881 p = growgbuf(p);
882 *p++ = lastc;
883 p = gtext(p); /* Get usual text faster */
884 getch();
885 }
886 if (p >= gbufend)
887 p = growgbuf(p);
888 *p = '\0'; /* Terminate with null char */
889 return (p - gbuf);
890 }
891
892 /*
893 * Add one new object to the end of a list of objects.
894 */
895 LOCAL list_t **
listcat(obj,tail)896 listcat(obj, tail)
897 obj_t *obj;
898 list_t **tail;
899 {
900 list_t *item;
901
902 *tail = item = (list_t *) fastalloc(sizeof (list_t));
903 item->l_obj = obj;
904 tail = &item->l_next;
905 return (tail);
906 }
907
908 /*
909 * Make a list of objects by parsing a line
910 * and cutting it at whitespaces.
911 */
912 LOCAL list_t **
mklist(line,tail,doexpand)913 mklist(line, tail, doexpand)
914 register char *line;
915 register list_t **tail;
916 BOOL doexpand;
917 {
918 register obj_t *o;
919 register char *p;
920
921 /*printf("Line: '%s'\n", line);*/
922
923 for (p = line; *p; ) {
924 while (*p && white(*p))
925 p++;
926 line = p;
927 while (*p) {
928 if (white(*p)) {
929 *p++ = '\0';
930 if (*line)
931 break;
932 }
933 p++;
934 }
935 /*printf("line: '%s'\n", line);*/
936 /*
937 * If the list ends with white space, we will see
938 * an empty string at the end of the list unless
939 * we apply this test.
940 */
941 if (*line == '\0')
942 break;
943 o = objlook(line, TRUE);
944 if (doexpand)
945 tail = exp_list(o, tail);
946 else
947 tail = listcat(o, tail);
948 }
949 return (tail);
950 }
951
952 /*
953 * Copy a list.
954 * Generate new list pointers and re-use the old obj pointers.
955 */
956 LOCAL list_t *
cplist(l)957 cplist(l)
958 list_t *l;
959 {
960 list_t *list;
961 register list_t **tail = &list;
962
963 while (l) {
964 tail = listcat(l->l_obj, tail);
965 l = l->l_next;
966 }
967 *tail = (list_t *) NULL;
968 return (list);
969 }
970
971 EXPORT BOOL in_parser;
972 EXPORT BOOL in_varassign;
973
974 /*
975 * Expand one object name using make macro definitions.
976 * Add the new objects to the end of a list of objects.
977 */
978 LOCAL list_t **
exp_list(o,tail)979 exp_list(o, tail)
980 obj_t *o;
981 list_t **tail;
982 {
983 char *name;
984 char *xname;
985
986 name = o->o_name;
987 if (strchr(name, '$')) {
988
989 if (in_parser == FALSE)
990 in_parser = TRUE;
991 xname = substitute(name, NullObj, 0, 0);
992 if (in_parser == TRUE)
993 in_parser = FALSE;
994 if (streql(name, xname)) {
995 printf("eql: %s\n", name);
996 tail = listcat(o, tail);
997 } else {
998 /*printf("Sxname: %s <- %s\n", xname, name);*/
999 tail = mklist(xname, tail, FALSE);
1000 }
1001 } else {
1002 tail = listcat(o, tail);
1003 }
1004 *tail = (list_t *) NULL;
1005 return (tail);
1006 }
1007
1008 #ifdef NEEDED
1009 /*
1010 * Expand a list of object names using make macro definitions.
1011 * Add the new objects to the end of a list of objects.
1012 */
1013 LOCAL list_t *
exp_olist(l)1014 exp_olist(l)
1015 list_t *l;
1016 {
1017 list_t *list;
1018 list_t **tail = &list;
1019
1020 while (l) {
1021 tail = exp_list(l->l_obj, tail);
1022 l = l->l_next;
1023 }
1024 *tail = (list_t *) NULL;
1025 return (list);
1026 }
1027 #endif /* NEEDED */
1028
1029 /*
1030 * Read a list of dependency file names.
1031 */
1032 LOCAL list_t *
getlist(typep)1033 getlist(typep)
1034 int *typep;
1035 {
1036 list_t *list;
1037 list_t **tail = &list;
1038 obj_t *o;
1039 int type = basetype(*typep);
1040 BOOL first = TRUE;
1041
1042 if (type == '=') {
1043 int n;
1044 #ifdef nono
1045 char *p;
1046 #endif
1047
1048 n = getln();
1049
1050 #ifdef nono /* Do not kill trailing whitespace !!! */
1051
1052 p = &gbuf[n-1];
1053 while (white(*p))
1054 p--;
1055 *++p = '\0';
1056 #endif
1057 /*
1058 * Only add to list if right hand side is not completely white.
1059 */
1060 if (n) {
1061 o = objlook(gbuf, TRUE);
1062 if (*typep == VAR_ASSIGN || *typep == GNU_ASSIGN ||
1063 *typep == ADD_VARMAC) {
1064 if (*typep == VAR_ASSIGN || *typep == ADD_VARMAC)
1065 in_varassign++; /* Inhibit $$ expans. */
1066 tail = exp_list(o, tail);
1067 if (*typep == VAR_ASSIGN || *typep == ADD_VARMAC)
1068 in_varassign--;
1069 } else
1070 tail = listcat(o, tail);
1071 }
1072 } else while ((o = getnam(type)) != (obj_t *) NULL) {
1073 if (type == '=') {
1074 tail = listcat(o, tail);
1075 } else {
1076 if (first) {
1077 first = FALSE;
1078 if (is_shvar(&o, typep, &tail))
1079 break;
1080 }
1081 tail = exp_list(o, tail);
1082 }
1083 }
1084 *tail = (list_t *) NULL;
1085 return (list);
1086 }
1087
1088 /*
1089 * Check if a definition for immediate shell expansion follows.
1090 */
1091 LOCAL BOOL
is_shvar(op,typep,tailp)1092 is_shvar(op, typep, tailp)
1093 obj_t **op;
1094 int *typep;
1095 list_t ***tailp;
1096 {
1097 obj_t *o = *op;
1098
1099 if (o->o_name[0] != 's')
1100 return (FALSE);
1101
1102 if (streql(o->o_name, "sh=")) {
1103 *typep = SHVAR;
1104 return (TRUE);
1105 }
1106 if (streql(o->o_name, "sh")) {
1107 if ((o = getnam(*typep)) == (obj_t *)NULL) {
1108 return (FALSE);
1109 }
1110 if (streql(o->o_name, "=")) {
1111 *typep = SHVAR;
1112 return (TRUE);
1113 } else {
1114 *tailp = exp_list(*op, *tailp);
1115 *op = o;
1116 }
1117 }
1118 return (FALSE);
1119 }
1120
1121 /*
1122 * read a line and expand by shell
1123 */
1124 LOCAL list_t *
getshvar(typep)1125 getshvar(typep)
1126 int *typep;
1127 {
1128 list_t *list;
1129 register list_t **tail = &list;
1130 char *p;
1131
1132 *typep = '=';
1133 getln();
1134 p = shout(gbuf);
1135
1136 tail = mklist(p, tail, FALSE);
1137 *tail = (list_t *) NULL;
1138 return (list);
1139 }
1140
1141 /*
1142 * Read a list of command lines that follow a dependency list.
1143 */
1144 LOCAL cmd_t *
getcmd()1145 getcmd()
1146 {
1147 cmd_t *list;
1148 register cmd_t *item, **tail = &list;
1149 register char *p;
1150
1151 setincmd(TRUE); /* Switch reader to command mode */
1152 if (lastc == '\n') /* Not a ';' command type */
1153 getch();
1154
1155 while (lastc != EOF && (firstc == '\t' || firstc == '#')) {
1156 /*
1157 * We handle comment in command lines as in old UNIX 'make' and
1158 * not as required by POSIX. A command line that starts with
1159 * a '#' (the following code) is handled as usual.
1160 * A '#' inside a command line and escaped newlines are
1161 * forwarded to the shell. This is needed to allow something
1162 * like cc -# with SunPRO C.
1163 */
1164 if (firstc == '#') {
1165 skipline(); /* Skip commented out line */
1166 getch(); /* Skip newline character. */
1167 continue;
1168 }
1169 while (white(lastc))
1170 getch(); /* Skip white space. */
1171
1172 for (p = gbuf; lastc != EOF; getch()) {
1173 if (lastc == '\n' && (p == gbuf || p[-1] != '\\'))
1174 break;
1175 if (p >= gbufend)
1176 p = growgbuf(p);
1177 *p++ = lastc;
1178 }
1179 if (p >= gbufend)
1180 p = growgbuf(p);
1181 *p = '\0';
1182 *tail = item = (cmd_t *) fastalloc(sizeof (cmd_t));
1183 item->c_line = strsave(gbuf);
1184 tail = &item->c_next;
1185
1186 if (lastc == '\n') /* Skip newline character. */
1187 getch();
1188 }
1189 /*printf("getcmd: lastc: %c %CX '%.20s'\n", lastc, lastc, readbufp);*/
1190 setincmd(FALSE);
1191 *tail = (cmd_t *) NULL;
1192 return (list);
1193 }
1194
1195 /*
1196 * Expand a list of target names using make macro definitions.
1197 */
1198 LOCAL int
exp_ovec(ovec,objcnt)1199 exp_ovec(ovec, objcnt)
1200 obj_t *ovec[];
1201 int objcnt;
1202 {
1203 list_t *list;
1204 list_t *l;
1205 register list_t **tail = &list;
1206 int i;
1207
1208 if (objcnt == 0)
1209 return (0);
1210 /*
1211 * Catch easy case.
1212 */
1213 if (objcnt == 1 && (strchr(ovec[0]->o_name, '$') == NULL))
1214 return (objcnt);
1215
1216 for (i = 0; i < objcnt; i++) {
1217 tail = exp_list(ovec[i], tail);
1218 *tail = (list_t *) NULL;
1219 }
1220
1221 for (i = 0; list; i++) {
1222 if (i >= MAXOBJS) {
1223 warn("Too many expanded target items");
1224 return (-i);
1225 }
1226 ovec[i] = list->l_obj;
1227 l = list;
1228 list = list->l_next;
1229 fastfree((char *)l, sizeof (*l));
1230 }
1231 return (i);
1232 }
1233
1234 /*
1235 * Read a list of target names.
1236 * Stop if ':', '=', ',' or space is found.
1237 */
1238 LOCAL int
read_ovec(ovec,typep)1239 read_ovec(ovec, typep)
1240 obj_t *ovec[];
1241 int *typep;
1242 {
1243 obj_t *o;
1244 int objcnt;
1245 char *p;
1246 int c;
1247 BOOL didwarn = FALSE;
1248
1249 /*printf("read_ovec\n");*/
1250 for (objcnt = 0; lastc != EOF; ) {
1251 o = getobj();
1252 c = lastc;
1253 while (white(lastc))
1254 getch();
1255 /*printf("lastc: '%c'", lastc); if (o) printf(" nameL %s\n", o->o_name);*/
1256 if (o != (obj_t *) NULL) {
1257 p = o->o_name;
1258 if (p[0] == '+' && p[1] == '\0') {
1259 if (c == '=') {
1260 *typep = ADDMAC;
1261 break;
1262 } else if (c == ':' && peekch() == '=') {
1263 getch();
1264 *typep = ADD_VARMAC;
1265 break;
1266 }
1267 }
1268 if (objcnt >= MAXOBJS) {
1269 warn("Too many target items");
1270 return (-objcnt);
1271 }
1272 ovec[objcnt++] = o;
1273 } else {
1274 if (lastc == '\n') {
1275 getch();
1276 continue;
1277 }
1278 if (lastc == EOF && objcnt == 0)
1279 break;
1280 /*
1281 * Empty variable name or target.
1282 * The POSIX standard says that this is always illegal.
1283 * There are makefiles that include $(EMPTY): something
1284 * and we like to support them, so allow empty targets
1285 * with ':' and '::', but abort with '=', '+=' or ':='
1286 *
1287 * We come here only with a definitely empty list. An
1288 * empty list still can be created later if $(EMPTY)
1289 * gets expanded in exp_ovec() below.
1290 */
1291 if (lastc != ':' || peekch() == '=')
1292 exerror("Missing object name");
1293 if (!nowarn(":")) {
1294 warn("Missing object name");
1295 didwarn = TRUE;
1296 }
1297 }
1298 /*
1299 * end of definition:
1300 * colon, equal or end of line
1301 */
1302 if (lastc == '?' && peekch() == '=') {
1303 getch();
1304 *typep = CONDEQUAL;
1305 break;
1306 }
1307 if (lastc == ':' && peekch() == ':') {
1308 getch();
1309 if (lastc == ':' && peekch() == ':') {
1310 getch();
1311 if (peekch() == '=') { /* :::= */
1312 getch();
1313 *typep = VAR_ASSIGN;
1314 break;
1315 } else {
1316 ungetch(':');
1317 lastc = ':';
1318 }
1319 }
1320 #ifdef GNU_ASSIGN_BY_DEFAULT
1321 if (
1322 #else
1323 if (posixmode &&
1324 #endif
1325 lastc == ':' && peekch() == '=') {
1326 getch();
1327 *typep = GNU_ASSIGN;
1328 break;
1329 }
1330 *typep = DCOLON;
1331 break;
1332 }
1333 if (lastc == ':' && peekch() == '=') {
1334 getch();
1335 *typep = VAR_ASSIGN; /* Use Sun CONDMACRO later */
1336 if (!nowarn(":=")) {
1337 warn(
1338 "Nonportable ':=' assignment found for macro '%s'",
1339 o ? o->o_name : "<empty>");
1340 }
1341 break;
1342 }
1343 if (lastc == ':' || lastc == '=' || lastc == '\n') {
1344 *typep = lastc;
1345 break;
1346 }
1347 if (lastc == ',')
1348 getch();
1349 }
1350 /*
1351 * XXX Achtung: UNIX make expandiert alles was links und rechts von ':'
1352 * steht, sowie Variablennamen (links von '=').
1353 */
1354 in_parser = -1; /* In parser but no ::= expansion */
1355 objcnt = exp_ovec(ovec, objcnt);
1356 in_parser = 0;
1357
1358 if (didwarn)
1359 *typep |= NWARN;
1360 return (objcnt);
1361 }
1362
1363 /*
1364 *
1365 */
1366 EXPORT list_t *
cvtvpath(l)1367 cvtvpath(l)
1368 list_t *l;
1369 {
1370 list_t *lsave;
1371 list_t *list = (list_t *)0;
1372 list_t **tail = &list;
1373 char vpath[NAMEMAX];
1374 char *vpe = &vpath[NAMEMAX-1];
1375 char *p1, *p2;
1376
1377 if (l != NULL) {
1378 for (p1 = l->l_obj->o_name, p2 = vpath; *p1; p2++) {
1379 if (p2 >= vpe)
1380 break;
1381 if ((*p2 = *p1++) == ':')
1382 *p2 = ' ';
1383 }
1384 *p2 = '\0';
1385 tail = mklist(vpath, tail, TRUE);
1386 *tail = (list_t *) NULL;
1387 lsave = l = list;
1388
1389 tail = &list;
1390
1391 for (; l; l = l->l_next) {
1392 tail = listcat(l->l_obj, tail);
1393 tail = listcat(l->l_obj, tail);
1394 }
1395 *tail = (list_t *) NULL;
1396 freelist(lsave);
1397 }
1398 if (Do_Warn)
1399 error("VPATH but no .SEARCHLIST\n");
1400 return (list);
1401 }
1402
1403
1404 EXPORT BOOL
is_inlist(objname,name)1405 is_inlist(objname, name)
1406 char *objname;
1407 char *name;
1408 {
1409 list_t *l;
1410
1411 for (l = objlist(objname); l != NULL; l = l->l_next) {
1412 if (streql(l->l_obj->o_name, name))
1413 return (TRUE);
1414 }
1415 return (FALSE);
1416 }
1417
1418 LOCAL BOOL
obj_in_list(obj,l)1419 obj_in_list(obj, l)
1420 register obj_t *obj;
1421 register list_t *l;
1422 {
1423 while (l) {
1424 if (obj == l->l_obj)
1425 return (TRUE);
1426 l = l->l_next;
1427 }
1428 return (FALSE);
1429 }
1430
1431 EXPORT BOOL
nowarn(name)1432 nowarn(name)
1433 char *name;
1434 {
1435 return (is_inlist(".NO_WARN", name));
1436 }
1437
1438 /*
1439 * NOTE: as long as warn() and exerror() use the global vars
1440 * lineno, col and Mfileindex,
1441 * we cannot use them at any other time than parse time.
1442 */
1443
1444 /*
1445 * Print a warning with text, line number, column and filename.
1446 */
1447
1448 /* VARARGS1 */
1449 #ifdef PROTOTYPES
1450 LOCAL void
warn(char * msg,...)1451 warn(char *msg, ...)
1452 #else
1453 LOCAL void
1454 warn(msg, va_alist)
1455 char *msg;
1456 va_dcl
1457 #endif
1458 {
1459 va_list args;
1460
1461 #ifdef PROTOTYPES
1462 va_start(args, msg);
1463 #else
1464 va_start(args);
1465 #endif
1466 if (!No_Warn)
1467 errmsgno(EX_BAD,
1468 "WARNING: %r in line %d col %d of '%s'\n", msg, args,
1469 lineno, col, mfname);
1470 va_end(args);
1471 }
1472
1473 /*
1474 * Print an error message with text, line number, column and filename, then exit.
1475 */
1476
1477 /* VARARGS1 */
1478 #ifdef PROTOTYPES
1479 LOCAL void
exerror(char * msg,...)1480 exerror(char *msg, ...)
1481 #else
1482 LOCAL void
1483 exerror(msg, va_alist)
1484 char *msg;
1485 va_dcl
1486 #endif
1487 {
1488 va_list args;
1489 int len;
1490
1491 #ifdef PROTOTYPES
1492 va_start(args, msg);
1493 #else
1494 va_start(args);
1495 #endif
1496 errmsgno(EX_BAD, "%r in line %d col %d of '%s'\n", msg, args,
1497 lineno, col, mfname);
1498 va_end(args);
1499
1500 len = getrdbufsize();
1501 if (len > 80)
1502 len = 80;
1503 if (Debug > 0)
1504 errmsgno(EX_BAD, "Current read buffer is: '%.*s'\n", len, getrdbuf());
1505 comerrno(EX_BAD, "Bad syntax in '%s'.\n", mfname);
1506 }
1507
1508
1509 #define MyObjTabSize 128 /* # of Hash table entries (power of two) .*/
1510
1511 #define ObjHash(name, h) { \
1512 register unsigned char *str = (unsigned char *)(name); \
1513 register int sum = 0; \
1514 register int i; \
1515 register int c; \
1516 \
1517 for (i = 0; (c = *str++) != '\0'; i++) \
1518 sum ^= (c << (i&7)); \
1519 (h) = sum & (MyObjTabSize -1); \
1520 }
1521
1522 LOCAL obj_t *ObjTab[MyObjTabSize];
1523 LOCAL obj_t *SuffTab[MyObjTabSize];
1524 EXPORT obj_t *NullObj;
1525
1526 /*
1527 * Look up name in 'table'.
1528 * First look up in hash table then do binary search.
1529 */
1530 LOCAL obj_t *
_objlook(table,name,create)1531 _objlook(table, name, create)
1532 obj_t *table[];
1533 char *name;
1534 BOOL create;
1535 {
1536 register obj_t **pp;
1537 register obj_t *p;
1538 register char *new;
1539 register char *old;
1540 int hash;
1541
1542 ObjHash(name, hash);
1543 for (pp = &table[hash]; (p = *pp) != NULL; ) {
1544 for (new = name, old = p->o_name; *new++ == *old; ) {
1545 if (*old++ == '\0') /* Found 'name' */
1546 return (p);
1547 }
1548 if (*--new < *old)
1549 pp = &p->o_left;
1550 else
1551 pp = &p->o_right;
1552 }
1553 if (!create)
1554 return ((obj_t *) NULL);
1555
1556 /*
1557 * Add new entry to ObjTab.
1558 */
1559 *pp = p = (obj_t *) fastalloc(sizeof (obj_t)); /* larger than list_t */
1560 /* insert into list */
1561 p->o_left = p->o_right = (obj_t *) NULL; /* old 'p' was NULL */
1562 p->o_cmd = (cmd_t *) NULL;
1563 p->o_list = (list_t *) NULL;
1564 p->o_date = NOTIME;
1565 p->o_level = MAXLEVEL;
1566 p->o_type = 0;
1567 p->o_flags = 0;
1568 p->o_flags = F_NEWNODE;
1569 p->o_fileindex = Mfileindex;
1570 p->o_name = strsave(name);
1571 p->o_namelen = strlen(name);
1572 p->o_node = NULL;
1573 return (p);
1574 }
1575
1576 /*
1577 * Look up name in ObjTab.
1578 */
1579 EXPORT obj_t *
objlook(name,create)1580 objlook(name, create)
1581 char *name;
1582 BOOL create;
1583 {
1584 return (_objlook(ObjTab, name, create));
1585 }
1586
1587 EXPORT list_t *
objlist(name)1588 objlist(name)
1589 char *name;
1590 {
1591 obj_t *o;
1592
1593 if ((o = objlook(name, FALSE)) == NULL)
1594 return ((list_t *)NULL);
1595 return (o->o_list);
1596 }
1597
1598 /*
1599 * Look up name in SuffTab.
1600 */
1601 EXPORT obj_t *
ssufflook(name,create)1602 ssufflook(name, create)
1603 char *name;
1604 BOOL create;
1605 {
1606 return (_objlook(SuffTab, name, create));
1607 }
1608
1609 /*
1610 * Check is SuffTab contains any entry.
1611 */
1612 EXPORT BOOL
check_ssufftab()1613 check_ssufftab()
1614 {
1615 int i;
1616
1617 for (i = 0; i < MyObjTabSize; i++)
1618 if (SuffTab[i])
1619 return (TRUE);
1620 return (FALSE);
1621 }
1622
1623 /*
1624 * Clear all entries in SuffTab.
1625 */
1626 LOCAL void
clear_ssufftab()1627 clear_ssufftab()
1628 {
1629 int i;
1630
1631 for (i = 0; i < MyObjTabSize; i++)
1632 SuffTab[i] = NULL;
1633 SSuffrules = FALSE;
1634 }
1635
1636 /*
1637 * Check whether obj->o_name is a Suffix Rule.
1638 * Name must either be identical to one of the .SUFFIXES (Single Suffix Rule)
1639 * or a concatenation of two .SUFFIXES.
1640 */
1641 LOCAL BOOL
is_suffix_rule(obj)1642 is_suffix_rule(obj)
1643 register obj_t *obj;
1644 {
1645 list_t *l;
1646 list_t *l2;
1647 char *suffix;
1648 char *rp;
1649 int rlen;
1650
1651 if (Suffixes == NULL)
1652 return (FALSE);
1653
1654 for (l = Suffixes; l; l = l->l_next) {
1655 suffix = l->l_obj->o_name;
1656 rlen = strlen(suffix);
1657 if (strncmp(obj->o_name, suffix, rlen) == 0) {
1658 rp = &obj->o_name[rlen];
1659
1660 if (*rp == '\0') /* Single Suffix Rule */
1661 return (TRUE);
1662
1663 for (l2 = Suffixes; l2; l2 = l2->l_next) {
1664 if (streql(rp, l2->l_obj->o_name))
1665 return (TRUE);
1666 }
1667 }
1668 }
1669 return (FALSE);
1670 }
1671
1672 /*
1673 * Used by ptree() to print one single object.
1674 */
1675 LOCAL void
prvar(p)1676 prvar(p)
1677 register obj_t *p;
1678 {
1679 register list_t *q;
1680 register cmd_t *c;
1681
1682 if (!p)
1683 return;
1684
1685 error("%s:", p->o_name);
1686 for (q = p->o_list; q; q = q->l_next)
1687 error(" %s", q->l_obj->o_name);
1688 putc('\n', stderr);
1689 for (c = p->o_cmd; c; c = c->c_next)
1690 error("\t...%s\n", c->c_line);
1691 }
1692
1693 /*
1694 * Currently only used by printtree() to implement the -probj option.
1695 */
1696 LOCAL void
ptree(p,n)1697 ptree(p, n)
1698 register obj_t *p;
1699 int n;
1700 {
1701 register int i;
1702
1703 for (; p; p = p->o_right) {
1704 ptree(p->o_left, ++n);
1705 for (i = 1; i < n; i++)
1706 putc(' ', stderr);
1707 prvar(p);
1708 }
1709 }
1710
1711 /*
1712 * Used by -probj Flag
1713 */
1714 EXPORT void
printtree()1715 printtree()
1716 {
1717 int i;
1718
1719 print_patrules(stderr);
1720 for (i = 0; i < MyObjTabSize; i++)
1721 ptree(ObjTab[i], 0);
1722 }
1723
1724 /*
1725 * Currently only used by prtree() to implement the -p option.
1726 */
1727 #define SUFF_ONLY 1 /* Print only Suffix Rules */
1728 #define SUFF_SPECIAL 2 /* Print only special targets */
1729 #define SUFF_NONE 0 /* Print only plain target rules */
1730 #define SUFF_ANY -1 /* Print without filtering */
1731 EXPORT void
probj(f,o,type,dosuff)1732 probj(f, o, type, dosuff)
1733 FILE *f;
1734 obj_t *o;
1735 int type;
1736 int dosuff;
1737 {
1738 for (; o; o = o->o_right) {
1739 probj(f, o->o_left, type, dosuff);
1740 if (type >= 0 && type != o->o_type)
1741 continue;
1742 if (type < 0 && (o->o_type == ':' || o->o_type == '='))
1743 continue;
1744 if (Debug <= 0 && o->o_type == 0)
1745 continue; /* Ommit target only strings */
1746
1747 if (dosuff >= 0) {
1748 if (dosuff == SUFF_ONLY && !is_suffix_rule(o))
1749 continue;
1750 else if (dosuff == SUFF_NONE && (is_suffix_rule(o) ||
1751 !(o->o_name[0] != '.' || o->o_name[1] == SLASH ||
1752 (o->o_name[1] == '.' && o->o_name[2] == SLASH))))
1753 continue;
1754 else if (dosuff == SUFF_SPECIAL && (is_suffix_rule(o) ||
1755 (o->o_name[0] != '.' || o->o_name[1] == SLASH ||
1756 (o->o_name[1] == '.' && o->o_name[2] == SLASH))))
1757 continue;
1758
1759 }
1760
1761 printobj(f, &o, 1, o->o_type, o->o_list, o->o_cmd);
1762 }
1763 }
1764
1765 /*
1766 * Used by -p Flag, called from main().
1767 */
1768 EXPORT void
prtree()1769 prtree()
1770 {
1771 int i;
1772
1773 printf("# Implicit Pattern Rules:\n");
1774 print_patrules(stdout);
1775 printf("# Implicit Suffix Rules:\n");
1776 for (i = 0; i < MyObjTabSize; i++) {
1777 probj(stdout, ObjTab[i], ':', SUFF_ONLY);
1778 }
1779 printf("# Simple Suffix Rules:\n");
1780 for (i = 0; i < MyObjTabSize; i++) {
1781 probj(stdout, SuffTab[i], ':', SUFF_ANY);
1782 }
1783 printf("# Special Targets:\n");
1784 for (i = 0; i < MyObjTabSize; i++) {
1785 probj(stdout, ObjTab[i], ':', SUFF_SPECIAL);
1786 }
1787 printf("# Target Rules:\n");
1788 for (i = 0; i < MyObjTabSize; i++) {
1789 probj(stdout, ObjTab[i], ':', SUFF_NONE);
1790 }
1791 printf("# Macro definitions:\n");
1792 for (i = 0; i < MyObjTabSize; i++) {
1793 probj(stdout, ObjTab[i], '=', SUFF_ANY);
1794 }
1795 printf("# Various other definitions:\n");
1796 for (i = 0; i < MyObjTabSize; i++) {
1797 probj(stdout, ObjTab[i], -1, SUFF_ANY);
1798 }
1799 }
1800
1801 /*
1802 * Convert the object type into a human readable string.
1803 */
1804 LOCAL char *
typestr(type)1805 typestr(type)
1806 int type;
1807 {
1808 if (type == 0)
1809 return ("(%)");
1810 if (type == EQUAL)
1811 return ("=");
1812 if (type == COLON)
1813 return (":");
1814 if (type == DCOLON)
1815 return ("::");
1816 if (type == SEMI)
1817 return (";");
1818 if (type == CONDEQUAL)
1819 return ("?=");
1820 if (type == ADDMAC)
1821 return ("+=");
1822 if (type == ADD_VARMAC)
1823 return ("+:=");
1824 if (type == GNU_ASSIGN)
1825 return ("::=");
1826 if (type == VAR_ASSIGN)
1827 return (":::=");
1828 if (type == CONDMACRO)
1829 return (":=");
1830 if (type == SHVAR)
1831 return (":sh=");
1832 return ("UNKNOWN TYPE");
1833 }
1834
1835 /*
1836 * This is the central routine to print an object.
1837 */
1838 LOCAL void
printobj(f,ovec,objcnt,type,deplist,cmdlist)1839 printobj(f, ovec, objcnt, type, deplist, cmdlist)
1840 FILE *f;
1841 obj_t *ovec[];
1842 int objcnt;
1843 int type;
1844 list_t *deplist;
1845 cmd_t *cmdlist;
1846 {
1847 register list_t *l;
1848 register cmd_t *c;
1849 register int i;
1850
1851 for (i = 0; i < objcnt; i++)
1852 fprintf(f, "%s ", ovec[i]->o_name);
1853 fprintf(f, "%2s\t", typestr(type));
1854
1855 for (l = deplist; l; l = l->l_next)
1856 fprintf(f, "%s ", l->l_obj->o_name);
1857 fprintf(f, "\n");
1858
1859 for (c = cmdlist; c; c = c->c_next)
1860 fprintf(f, "\t%s\n", c->c_line);
1861 fflush(f);
1862 }
1863