Changeset 1802 for trunk/src/kmk
- Timestamp:
- Sep 21, 2008, 8:40:44 PM (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kmk/incdep.c
r1801 r1802 30 30 * Header Files * 31 31 *******************************************************************************/ 32 /*#define PARSE_IN_WORKER*/ 33 32 34 #ifdef __OS2__ 33 35 # define INCL_BASE … … 78 80 * Structures and Typedefs * 79 81 *******************************************************************************/ 82 83 struct incdep_variable_in_set 84 { 85 struct incdep_variable_in_set *next; 86 /* the parameters */ 87 char *name; /* xmalloc'ed -> strcache */ 88 unsigned int name_length; 89 const char *value; /* xmalloc'ed */ 90 unsigned int value_length; 91 int duplicate_value; /* 0 */ 92 enum variable_origin origin; 93 int recursive; 94 struct variable_set *set; 95 const struct floc *flocp; /* NILF */ 96 }; 97 98 struct incdep_variable_def 99 { 100 struct incdep_variable_def *next; 101 /* the parameters */ 102 const struct floc *flocp; /* NILF */ 103 char *name; /* xmalloc'ed -> strcache */ 104 unsigned int name_length; /* (not an actual parameter) */ 105 char *value; /* xmalloc'ed, free it */ 106 enum variable_origin origin; 107 enum variable_flavor flavor; 108 int target_var; 109 }; 110 111 struct incdep_recorded_files 112 { 113 struct incdep_recorded_files *next; 114 115 /* the parameters */ 116 struct nameseq *filenames; /* only one file? its name needs be strcache'ed */ 117 const char *pattern; /* NULL */ 118 const char *pattern_percent; /* NULL */ 119 struct dep *deps; /* names need to be strcache'ed */ 120 unsigned int cmds_started; /* 0 */ 121 char *commands; /* NULL */ 122 unsigned int commands_idx; /* 0 */ 123 int two_colon; /* 0 */ 124 const struct floc *flocp; /* NILF */ 125 }; 126 127 80 128 /* per dep file structure. */ 81 129 struct incdep … … 84 132 char *file_base; 85 133 char *file_end; 134 135 int is_worker; 136 #ifdef PARSE_IN_WORKER 137 unsigned int err_line_no; 138 const char *err_msg; 139 140 struct incdep_variable_in_set *recorded_variables_in_set_head; 141 struct incdep_variable_in_set *recorded_variables_in_set_tail; 142 143 struct incdep_variable_def *recorded_variable_defs_head; 144 struct incdep_variable_def *recorded_variable_defs_tail; 145 146 struct incdep_recorded_files *recorded_files_head; 147 struct incdep_recorded_files *recorded_files_tail; 148 #endif 149 86 150 char name[1]; 87 151 }; … … 146 210 *******************************************************************************/ 147 211 static void incdep_flush_it (struct floc *); 212 static void eval_include_dep_file (struct incdep *, struct floc *, int); 148 213 149 214 … … 301 366 cur->file_base = cur->file_end = NULL; 302 367 return -1; 368 } 369 370 /* Free the incdep structure. */ 371 static void 372 incdep_free (struct incdep *cur) 373 { 374 #ifdef PARSE_IN_WORKER 375 assert (!cur->recorded_variables_in_set_head); 376 assert (!cur->recorded_variable_defs_head); 377 assert (!cur->recorded_files_head); 378 #endif 379 380 free (cur->file_base); 381 free (cur); 303 382 } 304 383 … … 329 408 incdep_unlock (); 330 409 incdep_read_file (cur, NILF); 410 #ifdef PARSE_IN_WORKER 411 eval_include_dep_file (cur, NILF, 1 /* is_worker */); 412 #endif 331 413 incdep_lock (); 332 414 … … 506 588 } 507 589 508 /* A quick wrapper around strcache_add_len which avoid the unnecessary 509 copying of the string in order to terminate it. The incdep buffer is 510 always writable, but the eval function like to use const char to avoid 511 silly mistakes and encourage compiler optimizations. */ 512 static char * 513 incdep_strcache_add_len (const char *str, int len) 514 { 515 #if 1 516 char *ret; 517 char ch = str[len]; 518 ((char *)str)[len] = '\0'; 519 ret = strcache_add_len (str, len); 520 ((char *)str)[len] = ch; 590 #ifdef PARSE_IN_WORKER 591 /* Flushes the recorded instructions. */ 592 static void 593 incdep_flush_recorded_instructions (struct incdep *cur) 594 { 595 struct incdep_variable_in_set *rec_vis; 596 struct incdep_variable_def *rec_vd; 597 struct incdep_recorded_files *rec_f; 598 599 /* define_variable_in_set */ 600 601 rec_vis = cur->recorded_variables_in_set_head; 602 cur->recorded_variables_in_set_head = cur->recorded_variables_in_set_tail = NULL; 603 if (rec_vis) 604 do 605 { 606 void *free_me = rec_vis; 607 define_variable_in_set (strcache_add_len (rec_vis->name, rec_vis->name_length), 608 rec_vis->name_length, 609 rec_vis->value, 610 rec_vis->value_length, 611 rec_vis->duplicate_value, 612 rec_vis->origin, 613 rec_vis->recursive, 614 rec_vis->set, 615 rec_vis->flocp); 616 free (rec_vis->name); 617 rec_vis = rec_vis->next; 618 free (free_me); 619 } 620 while (rec_vis); 621 622 /* do_variable_definition */ 623 624 rec_vd = cur->recorded_variable_defs_head; 625 cur->recorded_variable_defs_head = cur->recorded_variable_defs_tail = NULL; 626 if (rec_vd) 627 do 628 { 629 void *free_me = rec_vd; 630 do_variable_definition (rec_vd->flocp, 631 strcache_add_len(rec_vd->name, rec_vd->name_length), 632 rec_vd->value, 633 rec_vd->origin, 634 rec_vd->flavor, 635 rec_vd->target_var); 636 free (rec_vd->name); 637 free (rec_vd->value); 638 rec_vd = rec_vd->next; 639 free (free_me); 640 } 641 while (rec_vd); 642 643 /* record_files */ 644 645 rec_f = cur->recorded_files_head; 646 cur->recorded_files_head = cur->recorded_files_tail = NULL; 647 if (rec_f) 648 do 649 { 650 void *free_me = rec_f; 651 struct dep *dep; 652 const char *newname; 653 654 for (dep = rec_f->deps; dep; dep = dep->next) 655 { 656 newname = strcache_add (dep->name); 657 free ((char *)dep->name); 658 dep->name = newname; 659 } 660 661 newname = strcache_add (rec_f->filenames->name); 662 free ((char *)rec_f->filenames->name); 663 rec_f->filenames->name = newname; 664 665 record_files (rec_f->filenames, 666 rec_f->pattern, 667 rec_f->pattern_percent, 668 rec_f->deps, 669 rec_f->cmds_started, 670 rec_f->commands, 671 rec_f->commands_idx, 672 rec_f->two_colon, 673 rec_f->flocp); 674 675 rec_f = rec_f->next; 676 free (free_me); 677 } 678 while (rec_f); 679 } 680 #endif /* PARSE_IN_WORKER */ 681 682 /* Record / issue a warning about a misformed dep file. */ 683 static void 684 incdep_warn (struct incdep *cur, unsigned int line_no, const char *msg) 685 { 686 if (!cur->is_worker) 687 error (NILF, "%s(%d): %s", cur->name, line_no, msg); 688 #ifdef PARSE_IN_WORKER 689 else 690 { 691 cur->err_line_no = line_no; 692 cur->err_msg = msg; 693 } 694 #endif 695 } 696 697 /* Record / execute a strcache add. */ 698 static const char * 699 incdep_record_strcache (struct incdep *cur, const char *str, int len) 700 { 701 const char *ret; 702 if (!cur->is_worker) 703 { 704 /* Make sure the string is terminated before we hand it to 705 strcache_add_len so it does have to make a temporary copy 706 of it on the stack. */ 707 char ch = str[len]; 708 ((char *)str)[len] = '\0'; 709 ret = strcache_add_len (str, len); 710 ((char *)str)[len] = ch; 711 } 712 else 713 { 714 /* Duplicate the string. The other recorders knows which arguments 715 needs to be added to the string cache later. */ 716 char *newstr = xmalloc (len + 1); 717 memcpy (newstr, str, len); 718 newstr[len] = '\0'; 719 ret = newstr; 720 } 521 721 return ret; 522 #else 523 return strcache_add_len (str, len); 524 #endif 525 } 722 } 723 724 /* Record / perform a variable definition in a set. 725 The NAME is in the string cache. 726 The VALUE is on the heap. 727 The DUPLICATE_VALUE is always 0. */ 728 static void 729 incdep_record_variable_in_set (struct incdep *cur, 730 const char *name, unsigned int name_length, 731 const char *value, 732 unsigned int value_length, 733 int duplicate_value, 734 enum variable_origin origin, 735 int recursive, 736 struct variable_set *set, 737 const struct floc *flocp) 738 { 739 assert (!duplicate_value); 740 if (!cur->is_worker) 741 define_variable_in_set (name, name_length, value, value_length, 742 duplicate_value, origin, recursive, set, flocp); 743 #ifdef PARSE_IN_WORKER 744 else 745 { 746 struct incdep_variable_in_set *rec = xmalloc (sizeof (*rec)); 747 rec->name = (char *)name; 748 rec->name_length = name_length; 749 rec->value = value; 750 rec->value_length = value_length; 751 rec->duplicate_value = duplicate_value; 752 rec->origin = origin; 753 rec->recursive = recursive; 754 rec->set = set; 755 rec->flocp = flocp; 756 757 rec->next = NULL; 758 if (cur->recorded_variables_in_set_tail) 759 cur->recorded_variables_in_set_tail->next = rec; 760 else 761 cur->recorded_variables_in_set_head = rec; 762 cur->recorded_variables_in_set_tail = rec; 763 } 764 #endif 765 } 766 767 /* Record / perform a variable definition. The VALUE should be disposed of. */ 768 static void 769 incdep_record_variable_def (struct incdep *cur, 770 const struct floc *flocp, 771 const char *name, 772 unsigned int name_length, 773 char *value, 774 enum variable_origin origin, 775 enum variable_flavor flavor, 776 int target_var) 777 { 778 if (!cur->is_worker) 779 { 780 do_variable_definition (flocp, name, value, origin, flavor, target_var); 781 free (value); 782 } 783 #ifdef PARSE_IN_WORKER 784 else 785 { 786 struct incdep_variable_def *rec = xmalloc (sizeof (*rec)); 787 rec->flocp = flocp; 788 rec->name = (char *)name; 789 rec->name_length = name_length; 790 rec->value = value; 791 rec->origin = origin; 792 rec->flavor = flavor; 793 rec->target_var = target_var; 794 795 rec->next = NULL; 796 if (cur->recorded_variable_defs_tail) 797 cur->recorded_variable_defs_tail->next = rec; 798 else 799 cur->recorded_variable_defs_head = rec; 800 cur->recorded_variable_defs_tail = rec; 801 } 802 #endif 803 } 804 805 /* Record files.*/ 806 static void 807 incdep_record_files (struct incdep *cur, 808 struct nameseq *filenames, const char *pattern, 809 const char *pattern_percent, struct dep *deps, 810 unsigned int cmds_started, char *commands, 811 unsigned int commands_idx, int two_colon, 812 const struct floc *flocp) 813 { 814 if (!cur->is_worker) 815 record_files (filenames, pattern, pattern_percent, deps, cmds_started, 816 commands, commands_idx, two_colon, flocp); 817 #ifdef PARSE_IN_WORKER 818 else 819 { 820 struct incdep_recorded_files *rec = xmalloc (sizeof (*rec)); 821 822 rec->filenames = filenames; 823 rec->pattern = pattern; 824 rec->pattern_percent = pattern_percent; 825 rec->deps = deps; 826 rec->cmds_started = cmds_started; 827 rec->commands = commands; 828 rec->commands_idx = commands_idx; 829 rec->two_colon = two_colon; 830 rec->flocp = flocp; 831 832 rec->next = NULL; 833 if (cur->recorded_files_tail) 834 cur->recorded_files_tail->next = rec; 835 else 836 cur->recorded_files_head = rec; 837 cur->recorded_files_tail = rec; 838 } 839 #endif 840 } 841 526 842 527 843 /* no nonsense dependency file including. … … 545 861 */ 546 862 static void 547 eval_include_dep_file (struct incdep *curdep, struct floc *f )863 eval_include_dep_file (struct incdep *curdep, struct floc *f, int is_worker) 548 864 { 549 865 unsigned line_no = 1; … … 554 870 /* if no file data, just return immediately. */ 555 871 if (!cur) 556 { 557 free (curdep); 558 return; 559 } 872 return; 873 curdep->is_worker = is_worker; 560 874 561 875 /* now parse the file. */ … … 617 931 if (!var_len) 618 932 { 619 error (f, "%s(%d): bogus define statement.", 620 curdep->name, line_no); 933 incdep_warn (curdep, line_no, "bogus define statement."); 621 934 break; 622 935 } 623 var = incdep_ strcache_add_len (cur, var_len);936 var = incdep_record_strcache (curdep, cur, var_len); 624 937 625 938 /* find the end of the variable. */ … … 654 967 if (!found_endef) 655 968 { 656 error (f, "%s(%d): missing endef, dropping the rest of the file.", 657 curdep->name, line_no); 969 incdep_warn (curdep, line_no, "missing endef, dropping the rest of the file."); 658 970 break; 659 971 } … … 661 973 if (memchr (value_start, '\0', value_len)) 662 974 { 663 error (f, "%s(%d): '\\0' in define, dropping the rest of the file.", 664 curdep->name, line_no); 975 incdep_warn (curdep, line_no, "'\\0' in define, dropping the rest of the file."); 665 976 break; 666 977 } … … 693 1004 value [value_len] = '\0'; 694 1005 695 define_variable_in_set (var, var_len, value, value_len, 696 0 /* don't duplicate */, o_file, 697 0 /* defines are recursive but this is faster */, 698 NULL /* global set */, f); 1006 incdep_record_variable_in_set (curdep, 1007 var, var_len, value, value_len, 1008 0 /* don't duplicate */, o_file, 1009 0 /* defines are recursive but this is faster */, 1010 NULL /* global set */, f); 699 1011 } 700 1012 … … 730 1042 || (!endp && memchr (cur, '\n', equalp - cur))) 731 1043 { 732 error (f, "%s(%d): no colon.", 733 curdep->name, line_no); 1044 incdep_warn (curdep, line_no, "no colon."); 734 1045 break; 735 1046 } … … 771 1082 if (!var_len) 772 1083 { 773 error (f, "%s(%d): empty variable. (includedep)", 774 curdep->name, line_no); 1084 incdep_warn (curdep, line_no, "empty variable. (includedep)"); 775 1085 break; 776 1086 } … … 779 1089 || memchr (cur, '\t', var_len)) 780 1090 { 781 error (f, "%s(%d): fancy variable name. (includedep)", 782 curdep->name, line_no); 1091 incdep_warn (curdep, line_no, "fancy variable name. (includedep)"); 783 1092 break; 784 1093 } 785 var = incdep_ strcache_add_len (cur, var_len);1094 var = incdep_record_strcache (curdep, cur, var_len); 786 1095 787 1096 /* find the start of the value. */ … … 808 1117 if (value_end - 1 >= cur && value_end[-1] == '\\') 809 1118 { 810 error (f, "%s(%d): fancy escaping! (includedep)", 811 curdep->name, line_no); 1119 incdep_warn (curdep, line_no, "fancy escaping! (includedep)"); 812 1120 cur = NULL; 813 1121 break; … … 865 1173 || ( flavor == f_simple 866 1174 && !memchr (value, '$', value_len))) 867 define_variable_in_set (var, var_len, value, value_len, 868 0 /* don't duplicate */, o_file, 869 flavor == f_recursive /* recursive */, 870 NULL /* global set */, f); 1175 incdep_record_variable_in_set (curdep, 1176 var, var_len, value, value_len, 1177 0 /* don't duplicate */, o_file, 1178 flavor == f_recursive /* recursive */, 1179 NULL /* global set */, f); 871 1180 else 872 { 873 do_variable_definition (f, var, value, o_file, flavor, 874 0 /* not target var */); 875 free (value); 876 } 1181 incdep_record_variable_def (curdep, 1182 f, var, var_len, value, o_file, flavor, 1183 0 /* not target var */); 877 1184 } 878 1185 else … … 884 1191 struct dep **nextdep = &deps; 885 1192 struct dep *dep; 886 /* int next_line = 1; */887 1193 888 1194 /* extract the filename, ASSUME a single one. */ … … 892 1198 if (cur == endp) 893 1199 { 894 error (f, "%s(%d): empty filename.", 895 curdep->name, line_no); 1200 incdep_warn (curdep, line_no, "empty filename."); 896 1201 break; 897 1202 } … … 900 1205 || memchr (cur, '\t', endp - cur)) 901 1206 { 902 error (f, "%s(%d): multiple / fancy file name. (includedep)", 903 curdep->name, line_no); 1207 incdep_warn (curdep, line_no, "multiple / fancy file name. (includedep)"); 904 1208 break; 905 1209 } 906 1210 filenames = xmalloc (sizeof (struct nameseq)); 907 1211 memset (filenames, 0, sizeof (*filenames)); 908 filenames->name = incdep_ strcache_add_len (cur, endp - cur);1212 filenames->name = incdep_record_strcache (curdep, cur, endp - cur); 909 1213 910 1214 /* parse any dependencies. */ … … 945 1249 /* add it to the list. */ 946 1250 *nextdep = dep = alloc_dep (); 947 dep->name = incdep_ strcache_add_len (cur, endp - cur);1251 dep->name = incdep_record_strcache (curdep, cur, endp - cur); 948 1252 nextdep = &dep->next; 949 1253 … … 952 1256 953 1257 /* enter the file with its dependencies. */ 954 record_files (filenames, NULL, NULL, deps, 0, NULL, 0, 0, f); 1258 incdep_record_files (curdep, 1259 filenames, NULL, NULL, deps, 0, NULL, 0, 0, f); 955 1260 } 956 1261 } 957 1262 } 958 1263 959 free (curdep->file_base); 960 free (curdep); 1264 /* free the file data */ 1265 if (is_worker) 1266 { 1267 free (curdep->file_base); 1268 curdep->file_base = curdep->file_end = NULL; 1269 } 961 1270 } 962 1271 … … 981 1290 982 1291 incdep_read_file (cur, f); 983 eval_include_dep_file (cur, f); /* eats cur */ 1292 eval_include_dep_file (cur, f, 0); 1293 incdep_free (cur); 984 1294 985 1295 incdep_lock (); … … 1005 1315 { 1006 1316 struct incdep *next = cur->next; 1007 eval_include_dep_file (cur, f); /* eats cur */ 1317 #ifdef PARSE_IN_WORKER 1318 incdep_flush_recorded_instructions (cur); 1319 #else 1320 eval_include_dep_file (cur, f, 0); 1321 #endif 1322 incdep_free (cur); 1008 1323 cur = next; 1009 1324 } … … 1035 1350 memcpy (cur->name, name, name_len); 1036 1351 cur->name[name_len] = '\0'; 1352 cur->is_worker = 0; 1353 #ifdef PARSE_IN_WORKER 1354 cur->err_line_no = 0; 1355 cur->err_msg = NULL; 1356 cur->recorded_variables_in_set_head = NULL; 1357 cur->recorded_variables_in_set_tail = NULL; 1358 cur->recorded_variable_defs_head = NULL; 1359 cur->recorded_variable_defs_tail = NULL; 1360 cur->recorded_files_head = NULL; 1361 cur->recorded_files_tail = NULL; 1362 #endif 1037 1363 1038 1364 cur->next = NULL; … … 1053 1379 struct incdep *next = cur->next; 1054 1380 incdep_read_file (cur, f); 1055 eval_include_dep_file (cur, f ); /* eats cur */1381 eval_include_dep_file (cur, f, 0); /* eats cur */ 1056 1382 cur = next; 1057 1383 }
Note:
See TracChangeset
for help on using the changeset viewer.