|
|
1.1 root 1: %{
2:
3: /*
4: * Copyright (c) 1988 Regents of the University of California.
5: * All rights reserved.
6: *
7: * Redistribution and use in source and binary forms are permitted
8: * provided that this notice is preserved and that due credit is given
9: * to the University of California at Berkeley. The name of the University
10: * may not be used to endorse or promote products derived from this
11: * software without specific prior written permission. This software
12: * is provided ``as is'' without express or implied warranty.
13: *
14: * @(#)mkmake.y 1.18 (Berkeley) 3/28/88
15: */
16:
17: typedef struct string {
18: int
19: hashval,
20: length;
21: char
22: *string;
23: struct string
24: *next;
25: } string_t;
26:
27: /*
28: * The deal with these is that they exist on various lists.
29: *
30: * First off, they are on a temporary list during the time they
31: * are in the active focus of the parser.
32: *
33: * Secondly, they live on one of three queues:
34: * 1. Variables
35: * 2. Targets
36: * 3. Actions
37: * (and, we restrict any given one to live on one and only one such list)
38: *
39: * Also, they may live on the list of values for someone else's variable,
40: * or as someone's dependancy.
41: */
42:
43: typedef struct same {
44: string_t
45: *string; /* My name */
46: struct same
47: *nexttoken, /* Next pointer */
48: *lasttoken, /* Back pointer */
49: *depend_list, /* If target, dependancies */
50: *action_list, /* If target, actions */
51: *value_list, /* If variable, value list */
52: *shell_item; /* If a shell variable, current value */
53: } same_t;
54:
55: %}
56:
57: %union {
58: string_t *string;
59: same_t *same;
60: int intval;
61: }
62:
63: %start makefile
64: %token <string> TOKEN QUOTED_STRING
65: %token <intval> FOR IN DO DONE
66: %token <intval> MACRO_CHAR NL WHITE_SPACE
67: %token <intval> ':' '=' '$' '{' '}' ';' '-' '@' '(' ')' ' ' '\t'
68: %type <same> target target1 assignment assign1 actions action
69: %type <same> command_list list list_element
70: %type <same> for_statement maybe_at_minus tokens token
71: %type <same> maybe_white_space
72: %type <intval> white_space macro_char
73: %%
74:
75: makefile : lines;
76:
77: lines : line
78: | lines line
79: ;
80:
81: line : NL
82: | assignment
83: | target_action
84: ;
85:
86: assignment : assign1 tokens NL
87: {
88: assign($1, $2);
89: }
90: | assign1 NL
91: {
92: assign($1, same_copy(null));
93: }
94: ;
95:
96: assign1: token maybe_white_space '=' maybe_white_space
97: ;
98:
99: target_action: target actions
100: {
101: add_targets_actions($1, $2);
102: }
103: | target
104: {
105: add_targets_actions($1, 0);
106: }
107: ;
108:
109: target : target1 tokens NL
110: {
111: $$ = add_depends($1, $2);
112: }
113: | target1 NL
114: {
115: $$ = add_depends($1, same_copy(null));
116: }
117: ;
118:
119: target1: tokens maybe_white_space ':' maybe_white_space
120: {
121: $$ = ws_merge($1);
122: }
123: ;
124:
125: actions: action
126: | actions action
127: {
128: $$ = same_cat(same_cat($1, same_copy(newline)), $2);
129: }
130: ;
131:
132: action: white_space command_list NL
133: {
134: $$ = $2;
135: }
136: | white_space for_statement do command_list semi_colon done NL
137: {
138: $$ = do_command($2, $4);
139: }
140: ;
141:
142: for_statement: maybe_at_minus FOR white_space token
143: in tokens semi_colon
144: {
145: $$ = for_statement($1, $4, ws_merge(expand_variables($6, 0)));
146: }
147: ;
148:
149: in: white_space IN white_space
150: do: white_space DO white_space
151: ;
152:
153: done: white_space DONE
154: ;
155:
156: semi_colon: ';'
157: ;
158:
159: command_list: list
160: | '(' list maybe_white_space ')'
161: {
162: $$ = same_cat($2, same_copy(cwd_line));
163: }
164: ;
165:
166: list: token
167: | list list_element
168: {
169: $$ = same_cat($1, $2);
170: }
171: | list white_space list_element
172: {
173: $$ = same_cat($1, same_cat(same_copy(blank), $3));
174: }
175: ;
176:
177: list_element: token
178: | semi_colon
179: {
180: $$ = same_copy(newline);
181: }
182: ;
183:
184: maybe_at_minus: /* empty */
185: {
186: $$ = same_copy(null);
187: }
188: | '@'
189: {
190: char buffer[2];
191:
192: buffer[0] = $1;
193: buffer[1] = 0;
194: $$ = same_item(string_lookup(buffer));
195: }
196: | '-'
197: {
198: char buffer[2];
199:
200: buffer[0] = $1;
201: buffer[1] = 0;
202: $$ = same_item(string_lookup(buffer));
203: }
204: ;
205:
206: tokens : token
207: | tokens maybe_white_space token
208: {
209: $$ = same_cat($1, same_cat($2, $3));
210: }
211: ;
212:
213: token: TOKEN
214: {
215: $$ = same_item($1);
216: }
217: | QUOTED_STRING
218: {
219: $$ = same_item($1);
220: }
221: | '$' macro_char
222: {
223: char buffer[3];
224:
225: buffer[0] = '$';
226: buffer[1] = $2;
227: buffer[2] = 0;
228:
229: $$ = same_item(string_lookup(buffer));
230: }
231: | '$' '$' TOKEN
232: {
233: $$ = shell_variable(same_item($3));
234: }
235: | MACRO_CHAR
236: {
237: $$ = same_char($1);
238: }
239: | '$' '{' TOKEN '}'
240: {
241: $$ = variable(same_item($3));
242: }
243: | '$' '(' TOKEN ')'
244: {
245: $$ = variable(same_item($3));
246: }
247: | '$' TOKEN
248: {
249: $$ = variable(same_item($2));
250: }
251: | '-'
252: {
253: $$ = same_char('-');
254: }
255: | '@'
256: {
257: $$ = same_char('@');
258: }
259: ;
260:
261: macro_char: MACRO_CHAR
262: | '@'
263: ;
264:
265: maybe_white_space:
266: {
267: $$ = same_copy(null);
268: }
269: | white_space
270: {
271: $$ = same_char($1);
272: }
273: ;
274:
275: white_space : WHITE_SPACE
276: | white_space WHITE_SPACE
277: ;
278: %%
279: #include <stdio.h>
280: #include <ctype.h>
281:
282: static int last_char, last_saved = 0;
283: static int column = 0, lineno = 1;
284:
285:
286: static string_t
287: *strings = 0;
288:
289: static same_t
290: *shell_variables = 0,
291: *shell_special = 0,
292: *variables = 0,
293: *targets = 0,
294: *actions = 0;
295:
296: static same_t
297: *null,
298: *blank,
299: *cwd_line,
300: *newline;
301:
302: extern char *malloc();
303:
304: static unsigned int
305: clock = -1;
306:
307: struct {
308: same_t *first;
309: int next;
310: } visit_stack[20]; /* 20 maximum */
311:
312: #define visit(what,via) \
313: (visit_stack[++clock].next = 0, visit_stack[clock].first = via = what)
314: #define visited(via) (visitcheck(via) || ((via) == 0) \
315: || (visit_stack[clock].next && (via == visit_stack[clock].first)))
316: #define visit_next(via) (visit_stack[clock].next = 1, (via) = (via)->nexttoken)
317: #define visit_end() (clock--)
318:
319: yyerror(s)
320: char *s;
321: {
322: fprintf(stderr, "line %d, character %d: %s\n", lineno, column, s);
323: do_dump();
324: }
325:
326: int
327: visitcheck(same)
328: same_t *same;
329: {
330: if (same->string == 0) {
331: yyerror("BUG - freed 'same' in use...");
332: exit(1);
333: }
334: return 0;
335: }
336:
337: int
338: string_hashof(string, length)
339: char *string;
340: int length;
341: {
342: register int i = 0;
343:
344: while (length--) {
345: i = (i<<3) + *string ^ ((i>>28)&0x7);
346: }
347: return i;
348: }
349:
350: int
351: string_same(s1, s2)
352: string_t
353: *s1, *s2;
354: {
355: if ((s1->hashval == s2->hashval) && (s1->length == s2->length)
356: && (memcmp(s1->string, s2->string, s1->length) == 0)) {
357: return 1;
358: } else {
359: return 0;
360: }
361: }
362:
363: string_t *
364: string_lookup(string)
365: char *string;
366: {
367: string_t ours;
368: string_t *ptr;
369:
370: ours.length = strlen(string);
371: ours.hashval = string_hashof(string, ours.length);
372: ours.string = string;
373:
374: for (ptr = strings; ptr; ptr = ptr->next) {
375: if (string_same(&ours, ptr)) {
376: return ptr;
377: }
378: }
379: if ((ptr = (string_t *)malloc(sizeof *ptr)) == 0) {
380: fprintf(stderr, "No space to add string *%s*!\n", string);
381: exit(1);
382: }
383: ptr->hashval = ours.hashval;
384: ptr->length = ours.length;
385: if ((ptr->string = malloc(ours.length+1)) == 0) {
386: fprintf(stderr, "No space to add literal *%s*!\n", string);
387: exit(1);
388: }
389: memcpy(ptr->string, string, ours.length+1);
390: ptr->next = strings;
391: strings = ptr;
392: return ptr;
393: }
394:
395: #define same_singleton(s) ((s)->nexttoken == (s))
396:
397: same_t *
398: same_search(list, token)
399: same_t
400: *list,
401: *token;
402: {
403: same_t *ptr;
404:
405: ptr = list;
406: for (visit(list, ptr); !visited(ptr); visit_next(ptr)) {
407: string_t *string;
408:
409: string = ptr->string;
410: if (string_same(string, token->string)) {
411: visit_end();
412: return ptr;
413: }
414: }
415: visit_end();
416: return 0;
417: }
418:
419: same_t *
420: same_cat(list, tokens)
421: same_t
422: *list,
423: *tokens;
424: {
425: same_t *last;
426:
427: if (tokens == 0) {
428: return list;
429: }
430: if (list) {
431: last = tokens->lasttoken;
432: tokens->lasttoken = list->lasttoken;
433: list->lasttoken = last;
434: tokens->lasttoken->nexttoken = tokens;
435: last->nexttoken = list;
436: return list;
437: } else {
438: return tokens;
439: }
440: }
441:
442: same_t *
443: same_item(string)
444: string_t *string;
445: {
446: same_t *ptr;
447:
448: if ((ptr = (same_t *)malloc(sizeof *ptr)) == 0) {
449: fprintf(stderr, "No more space for tokens!\n");
450: exit(1);
451: }
452: memset((char *)ptr, 0, sizeof *ptr);
453: ptr->nexttoken = ptr->lasttoken = ptr;
454: ptr->string = string;
455: return ptr;
456: }
457:
458: same_t *
459: same_copy(same)
460: same_t *same;
461: {
462: same_t *head, *copy;
463:
464: head = 0;
465: for (visit(same, copy); !visited(copy); visit_next(copy)) {
466: same_t *ptr;
467:
468: ptr = same_item(copy->string);
469: head = same_cat(head, ptr);
470: }
471: visit_end();
472: return head;
473: }
474:
475:
476: same_t *
477: same_merge(t1, t2)
478: same_t
479: *t1,
480: *t2;
481: {
482: if (same_singleton(t1) && same_singleton(t2)) {
483: int length = strlen(t1->string->string)+strlen(t2->string->string);
484: char *buffer = malloc(length+1);
485: same_t *value;
486:
487: if (buffer == 0) {
488: yyerror("No space to merge strings in same_merge!");
489: exit(1);
490: }
491: strcpy(buffer, t1->string->string);
492: strcat(buffer, t2->string->string);
493: value = same_item(string_lookup(buffer));
494: free(buffer);
495: return value;
496: } else {
497: yyerror("Internal error - same_merge with non-singletons");
498: exit(1);
499: }
500: }
501:
502:
503: void
504: same_free(list)
505: same_t *list;
506: {
507: same_t *token, *ptr;
508:
509: if (list == 0) {
510: return;
511: }
512:
513: token = list;
514: do {
515: ptr = token->nexttoken;
516: token->string = 0;
517: (void) free((char *)token);
518: token = ptr;
519: } while (token != list);
520: }
521:
522: same_t *
523: same_unlink(token)
524: same_t
525: *token;
526: {
527: same_t *tmp;
528:
529: if (token == 0) {
530: return 0;
531: }
532: if ((tmp = token->nexttoken) == token) {
533: tmp = 0;
534: }
535: token->lasttoken->nexttoken = token->nexttoken;
536: token->nexttoken->lasttoken = token->lasttoken;
537: token->nexttoken = token->lasttoken = token;
538: return tmp;
539: }
540:
541: void
542: same_replace(old, new)
543: same_t
544: *old,
545: *new;
546: {
547: new->lasttoken->nexttoken = old->nexttoken;
548: old->nexttoken->lasttoken = new->lasttoken;
549: new->lasttoken = old->lasttoken;
550: /* rather than
551: * old->lasttoken->nexttoken = new
552: * we update in place (for the case where there isn't anything else)
553: */
554: *old = *new;
555: }
556:
557:
558: same_t *
559: same_char(ch)
560: char ch;
561: {
562: char buffer[2];
563:
564: buffer[0] = ch;
565: buffer[1] = 0;
566:
567: return same_item(string_lookup(buffer));
568: }
569:
570:
571: void
572: add_target(target, actions)
573: same_t
574: *target,
575: *actions;
576: {
577: same_t *ptr;
578:
579: if ((ptr = same_search(targets, target)) == 0) {
580: targets = same_cat(targets, target);
581: ptr = target;
582: } else {
583: ptr->depend_list = same_cat(ptr->depend_list, target->depend_list);
584: }
585: if (actions) {
586: if (ptr->action_list) {
587: same_free(ptr->action_list);
588: }
589: ptr->action_list = same_copy(actions);
590: }
591: }
592:
593:
594: same_t *
595: add_targets_actions(target, actions)
596: same_t
597: *target,
598: *actions;
599: {
600: same_t *ptr;
601:
602: if (target == 0) {
603: return 0;
604: }
605: do {
606: ptr = same_unlink(target);
607: add_target(target, actions);
608: target = ptr;
609: } while (target);
610:
611: same_free(actions);
612: return 0;
613: }
614:
615: same_t *
616: add_depends(target, depends)
617: same_t
618: *target,
619: *depends;
620: {
621: same_t *original = target;
622:
623: depends = same_cat(depends, same_copy(blank)); /* Separator */
624:
625: for (visit(original, target); !visited(target); visit_next(target)) {
626: target->depend_list = same_cat(target->depend_list, same_copy(depends));
627: }
628: visit_end();
629: same_free(depends);
630:
631: return original;
632: }
633:
634:
635: /*
636: * We know that variable is a singleton
637: */
638:
639: void
640: assign(variable, value)
641: same_t
642: *variable,
643: *value;
644: {
645: same_t *ptr;
646:
647: if ((ptr = same_search(variables, variable)) != 0) {
648: same_free(ptr->value_list);
649: variables = same_unlink(ptr);
650: same_free(ptr);
651: }
652: variable->value_list = value;
653: variables = same_cat(variables, variable);
654: }
655:
656: same_t *
657: value_of(variable)
658: same_t *variable;
659: {
660: same_t *ptr = same_search(variables, variable);
661:
662: if (ptr == 0) {
663: return same_copy(null);
664: } else {
665: return same_copy(ptr->value_list);
666: }
667: }
668:
669:
670: same_t *
671: expand_variables(token, free)
672: same_t *token;
673: int free;
674: {
675: same_t *head = 0;
676:
677: if (!free) {
678: token = same_copy(token); /* Get our private copy */
679: }
680:
681: while (token) {
682: char *string = token->string->string;
683: same_t *tmp = same_unlink(token);
684:
685: if ((string[0] == '$') && (string[1] == '{')) { /* Expand time */
686: int len = strlen(string);
687:
688: string[len-1] = 0;
689: head = same_cat(head, expand_variables(
690: value_of(same_item(string_lookup(string+2))), 1));
691: string[len-1] = '}';
692: } else {
693: head = same_cat(head, token);
694: }
695: token = tmp;
696: }
697: return head;
698: }
699:
700:
701: same_t *
702: ws_merge(list)
703: same_t *list;
704: {
705: same_t *newlist = 0, *item;
706: int what = 0;
707:
708: while (list) {
709: switch (what) {
710: case 0:
711: if (isspace(list->string->string[0])) {
712: ;
713: } else {
714: item = same_item(list->string);
715: what = 1;
716: }
717: break;
718: case 1:
719: if (isspace(list->string->string[0])) {
720: newlist = same_cat(newlist, item);
721: item = 0;
722: what = 0;
723: } else {
724: item = same_merge(item, same_item(list->string));
725: what = 1;
726: }
727: break;
728: }
729: list = same_unlink(list);
730: }
731: return same_cat(newlist, item);
732: }
733:
734:
735: same_t *
736: variable(var_name)
737: same_t *var_name;
738: {
739: int length = strlen(var_name->string->string);
740: same_t *resolved;
741: char *newname;
742:
743: if ((newname = malloc(length+1+3)) == 0) {
744: fprintf("Out of space for a variable name.\n");
745: exit(1);
746: }
747: newname[0] = '$';
748: newname[1] = '{';
749: strcpy(newname+2, var_name->string->string);
750: strcat(newname, "}");
751: resolved = same_item(string_lookup(newname));
752: free(newname);
753:
754: return resolved;
755: }
756:
757:
758: same_t *
759: shell_variable(var_name)
760: same_t *var_name;
761: {
762: int length = strlen(var_name->string->string);
763: same_t *resolved;
764: char *newname;
765:
766: if ((newname = malloc(length+1+2)) == 0) {
767: fprintf("Out of space for a variable name.\n");
768: exit(1);
769: }
770: newname[0] = '$';
771: newname[1] = '$';
772: strcpy(newname+2, var_name->string->string);
773: resolved = same_item(string_lookup(newname));
774: free(newname);
775:
776: return resolved;
777: }
778:
779: same_t *
780: for_statement(special, variable, list)
781: same_t
782: *special,
783: *variable,
784: *list;
785: {
786: variable->shell_item = special;
787: variable->value_list = list;
788: return variable;
789: }
790:
791: same_t *
792: do_command(forlist, commands)
793: same_t
794: *forlist,
795: *commands;
796: {
797: same_t
798: *special,
799: *command_list = 0,
800: *new_commands,
801: *tmp,
802: *shell_item,
803: *value_list = forlist->value_list;
804: char
805: *tmpstr,
806: *variable_name = forlist->string->string;
807:
808: special = forlist->shell_item;
809: if (same_unlink(forlist->shell_item) != 0) {
810: yyerror("Unexpected second item in special part of do_command");
811: exit(1);
812: }
813:
814: while ((shell_item = value_list) != 0) {
815: value_list = same_unlink(shell_item);
816: /* Visit each item in commands. For each shell variable which
817: * matches ours, replace it with ours.
818: */
819: new_commands = same_copy(commands);
820: for (visit(new_commands, tmp); !visited(tmp); visit_next(tmp)) {
821: tmpstr = tmp->string->string;
822: if ((tmpstr[0] == '$') && (tmpstr[1] == '$')) {
823: if (strcmp(tmpstr+2, variable_name) == 0) {
824: same_replace(tmp, same_copy(shell_item));
825: }
826: }
827: }
828: visit_end();
829: command_list = same_cat(command_list, new_commands);
830: }
831: return same_cat(command_list, same_copy(newline));
832: }
833:
834:
835: int
836: Getchar()
837: {
838: if (last_saved) {
839: last_saved = 0;
840: return last_char;
841: } else {
842: int c;
843: c = getchar();
844: switch (c) {
845: case '\n':
846: lineno++;
847: column = 0;
848: break;
849: default:
850: column++;
851: }
852: return c;
853: }
854: }
855:
856:
857: int
858: token_type(string)
859: char *string;
860: {
861: switch (string[0]) {
862: case 'f':
863: if (strcmp(string, "for") == 0) {
864: return FOR;
865: }
866: break;
867: case 'd':
868: if (string[1] == 'o') {
869: if (strcmp(string, "do") == 0) {
870: return DO;
871: } else if (strcmp(string, "done") == 0) {
872: return DONE;
873: }
874: }
875: break;
876: case 'i':
877: if (strcmp(string, "in") == 0) {
878: return IN;
879: }
880: break;
881: default:
882: break;
883: }
884: return TOKEN;
885: }
886:
887:
888: yylex()
889: {
890: #define ret_token(c) if (bufptr != buffer) { \
891: save(c); \
892: *bufptr = 0; \
893: bufptr = buffer; \
894: yylval.string = string_lookup(buffer); \
895: return token_type(buffer); \
896: }
897: #define save(c) { last_char = c; last_saved = 1; }
898: #if defined(YYDEBUG)
899: #define Return(c) if (yydebug) { \
900: printf("[%d]", c); \
901: fflush(stdout); \
902: } \
903: yyval.intval = c; \
904: return c;
905: #else /* defined(YYDEBUG) */
906: #define Return(y,c) { yylval.intval = c; return y; }
907: #endif /* defined(YYDEBUG) */
908:
909:
910: static char buffer[500], *bufptr = buffer;
911: static int eof_found = 0;
912: int c;
913:
914: if (eof_found != 0) {
915: eof_found++;
916: if (eof_found > 2) {
917: fprintf(stderr, "End of file ignored.\n");
918: exit(1);
919: }
920: Return(EOF,0);
921: }
922: while ((c = Getchar()) != EOF) {
923: switch (c) {
924: case '#':
925: ret_token(c);
926: while (((c = Getchar()) != EOF) && (c != '\n')) {
927: ;
928: }
929: save(c);
930: break;
931: case '<':
932: case '?':
933: ret_token(c);
934: Return(MACRO_CHAR, c);
935: case '\t':
936: case ' ':
937: ret_token(c);
938: Return(WHITE_SPACE, c);
939: case '-':
940: case '@':
941: case ':':
942: case ';':
943: case '=':
944: case '$':
945: case '{':
946: case '}':
947: case '(':
948: case ')':
949: ret_token(c);
950: Return(c,c);
951: case '\'':
952: case '"':
953: if (bufptr != buffer) {
954: if (bufptr[-1] == '\\') {
955: bufptr[-1] = c;
956: }
957: break;
958: } else {
959: int newc;
960:
961: ret_token(c);
962: *bufptr++ = c;
963: while (((newc = Getchar()) != EOF) && (newc != c)) {
964: *bufptr++ = newc;
965: }
966: *bufptr++ = c;
967: *bufptr = 0;
968: bufptr = buffer;
969: yylval.string = string_lookup(buffer);
970: return QUOTED_STRING;
971: }
972: case '\n':
973: if (bufptr != buffer) {
974: if (bufptr[-1] == '\\') {
975: bufptr--;
976: if ((c = Getchar()) != '\t') {
977: yyerror("continuation line doesn't begin with a tab");
978: save(c);
979: }
980: ret_token(c);
981: Return(WHITE_SPACE, c);
982: }
983: }
984: ret_token(c);
985: Return(NL, 0);
986: default:
987: *bufptr++ = c;
988: break;
989: }
990: }
991:
992: eof_found = 1;
993:
994: ret_token(' ');
995: Return(EOF, 0);
996: }
997:
998: #ifndef lint
999: static char sccsid[] = "@(#)mkmake.y 1.18 (Berkeley) 3/28/88";
1000: #endif /* not lint */
1001:
1002: main()
1003: {
1004: #define YYDEBUG
1005: extern int yydebug;
1006:
1007: null = same_item(string_lookup(""));
1008: newline = same_item(string_lookup("\n"));
1009: blank = same_item(string_lookup(" "));
1010: cwd_line = same_cat(same_copy(newline),
1011: same_cat(same_item(string_lookup("cd ${CWD}")),
1012: same_copy(newline)));
1013:
1014: yyparse();
1015:
1016: do_dump();
1017:
1018: return 0;
1019: }
1020:
1021: #if defined(YYDEBUG)
1022: dump_same(same)
1023: same_t *same;
1024: {
1025: same_t *same2;
1026:
1027: for (visit(same, same2); !visited(same2); visit_next(same2)) {
1028: printf(same2->string->string);
1029: }
1030: visit_end();
1031: }
1032: #endif /* YYDEBUG */
1033:
1034: do_dump()
1035: {
1036: string_t *string;
1037: same_t *same, *same2;
1038:
1039: if (yydebug > 1) {
1040: printf("strings...\n");
1041: for (string = strings; string; string = string->next) {
1042: printf("\t%s\n", string->string);
1043: }
1044: }
1045:
1046: printf("# variables...\n");
1047: for (visit(variables, same); !visited(same); visit_next(same)) {
1048: printf("%s =\t", same->string->string);
1049: for (visit(same->value_list, same2); !visited(same2);
1050: visit_next(same2)) {
1051: printf(same2->string->string);
1052: }
1053: visit_end();
1054: printf("\n");
1055: }
1056: visit_end();
1057:
1058: printf("\n\n#targets...\n");
1059: for (visit(targets, same); !visited(same); visit_next(same)) {
1060: printf("\n%s:\t", same->string->string);
1061: for (visit(same->depend_list, same2); !visited(same2);
1062: visit_next(same2)) {
1063: printf(same2->string->string);
1064: }
1065: visit_end();
1066: printf("\n\t");
1067: for (visit(same->action_list, same2); !visited(same2);
1068: visit_next(same2)) {
1069: printf(same2->string->string);
1070: if (same2->string->string[0] == '\n') {
1071: printf("\t");
1072: }
1073: }
1074: visit_end();
1075: printf("\n");
1076: }
1077: visit_end();
1078: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.