Changeset 903 for trunk/src/gmakenew/rule.c
- Timestamp:
- May 23, 2007, 7:31:19 AM (18 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/gmakenew/rule.c
r503 r903 18 18 19 19 #include "make.h" 20 21 #include <assert.h> 22 20 23 #include "dep.h" 21 24 #include "filedef.h" … … 25 28 #include "rule.h" 26 29 27 static void freerule PARAMS ((struct rule *rule, struct rule *lastrule));30 static void freerule (struct rule *rule, struct rule *lastrule); 28 31 29 32 … … 72 75 char *name; 73 76 int namelen; 74 registerstruct rule *rule, *lastrule;77 struct rule *rule, *lastrule; 75 78 76 79 num_pattern_rules = max_pattern_targets = max_pattern_deps = 0; … … 84 87 { 85 88 unsigned int ndeps = 0; 86 registerstruct dep *dep;89 struct dep *dep; 87 90 struct rule *next = rule->next; 88 unsigned int ntargets;89 91 90 92 ++num_pattern_rules; 91 93 92 ntargets = 0; 93 while (rule->targets[ntargets] != 0) 94 ++ntargets; 95 96 if (ntargets > max_pattern_targets) 97 max_pattern_targets = ntargets; 94 if (rule->num > max_pattern_targets) 95 max_pattern_targets = rule->num; 98 96 99 97 for (dep = rule->deps; dep != 0; dep = dep->next) … … 102 100 103 101 #ifdef VMS 104 c har *p = strrchr (dep->name, ']');105 c har *p2;102 const char *p = strrchr (dep->name, ']'); 103 const char *p2; 106 104 if (p == 0) 107 105 p = strrchr (dep->name, ':'); 108 106 p2 = p != 0 ? strchr (dep->name, '%') : 0; 109 107 #else 110 c har *p = strrchr (dep->name, '/');111 c har *p2 = p != 0 ? strchr (dep->name, '%') : 0;108 const char *p = strrchr (dep->name, '/'); 109 const char *p2 = p != 0 ? strchr (dep->name, '%') : 0; 112 110 #endif 113 111 ndeps++; … … 124 122 if (p - dep->name > namelen) 125 123 { 126 if (name != 0)127 free (name);128 124 namelen = p - dep->name; 129 name = (char *) xmalloc (namelen + 1);125 name = xrealloc (name, namelen + 1); 130 126 } 131 bcopy (dep->name,name, p - dep->name);127 memcpy (name, dep->name, p - dep->name); 132 128 name[p - dep->name] = '\0'; 133 129 … … 162 158 163 159 static void 164 convert_suffix_rule (c har *target, char *source, struct commands *cmds)165 { 166 char *targname, *targpercent, *depname; 167 c har **names, **percents;160 convert_suffix_rule (const char *target, const char *source, 161 struct commands *cmds) 162 { 163 const char **names, **percents; 168 164 struct dep *deps; 169 unsigned int len; 165 166 names = xmalloc (sizeof (const char *)); 167 percents = xmalloc (sizeof (const char *)); 170 168 171 169 if (target == 0) 172 /* Special case: TARGET being nil means we are defining a173 `.X.a' suffix rule; the target pattern is always `(%.o)'. */174 {170 { 171 /* Special case: TARGET being nil means we are defining a `.X.a' suffix 172 rule; the target pattern is always `(%.o)'. */ 175 173 #ifdef VMS 176 targname = savestring("(%.obj)", 7);174 *names = strcache_add_len ("(%.obj)", 7); 177 175 #else 178 targname = savestring("(%.o)", 5);176 *names = strcache_add_len ("(%.o)", 5); 179 177 #endif 180 targpercent = targname+ 1;178 *percents = *names + 1; 181 179 } 182 180 else 183 181 { 184 182 /* Construct the target name. */ 185 len = strlen (target); 186 targname = xmalloc (1 + len + 1); 187 targname[0] = '%'; 188 bcopy (target, targname + 1, len + 1); 189 targpercent = targname; 190 } 191 192 names = (char **) xmalloc (2 * sizeof (char *)); 193 percents = (char **) alloca (2 * sizeof (char *)); 194 names[0] = targname; 195 percents[0] = targpercent; 196 names[1] = percents[1] = 0; 183 unsigned int len = strlen (target); 184 char *p = alloca (1 + len + 1); 185 p[0] = '%'; 186 memcpy (p + 1, target, len + 1); 187 *names = strcache_add_len (p, len + 1); 188 *percents = *names; 189 } 197 190 198 191 if (source == 0) … … 201 194 { 202 195 /* Construct the dependency name. */ 203 len = strlen (source);204 depname = xmalloc(1 + len + 1);205 depname[0] = '%';206 bcopy (source, depname + 1, len + 1);196 unsigned int len = strlen (source); 197 char *p = alloca (1 + len + 1); 198 p[0] = '%'; 199 memcpy (p + 1, source, len + 1); 207 200 deps = alloc_dep (); 208 deps->name = depname;209 } 210 211 create_pattern_rule (names, percents, 0, deps, cmds, 0);201 deps->name = strcache_add_len (p, len + 1); 202 } 203 204 create_pattern_rule (names, percents, 1, 0, deps, cmds, 0); 212 205 } 213 206 214 207 /* Convert old-style suffix rules to pattern rules. 215 All rules for the suffixes on the .SUFFIXES list 216 are converted and added tothe chain of pattern rules. */208 All rules for the suffixes on the .SUFFIXES list are converted and added to 209 the chain of pattern rules. */ 217 210 218 211 void 219 212 convert_to_pattern (void) 220 213 { 221 registerstruct dep *d, *d2;222 register struct file *f;223 register char *rulename; 224 register unsigned int slen, s2len;225 226 /* Compute maximum length of allthe suffixes. */214 struct dep *d, *d2; 215 char *rulename; 216 217 /* We will compute every potential suffix rule (.x.y) from the list of 218 suffixes in the .SUFFIXES target's dependencies and see if it exists. 219 First find the longest of the suffixes. */ 227 220 228 221 maxsuffix = 0; 229 222 for (d = suffix_file->deps; d != 0; d = d->next) 230 223 { 231 register unsigned int namelen = strlen (dep_name (d)); 232 if (namelen > maxsuffix) 233 maxsuffix = namelen; 234 } 235 236 rulename = (char *) alloca ((maxsuffix * 2) + 1); 224 unsigned int l = strlen (dep_name (d)); 225 if (l > maxsuffix) 226 maxsuffix = l; 227 } 228 229 /* Space to construct the suffix rule target name. */ 230 rulename = alloca ((maxsuffix * 2) + 1); 237 231 238 232 for (d = suffix_file->deps; d != 0; d = d->next) 239 233 { 234 unsigned int slen; 235 240 236 /* Make a rule that is just the suffix, with no deps or commands. 241 237 This rule exists solely to disqualify match-anything rules. */ 242 convert_suffix_rule (dep_name (d), (char *) 0, (struct commands *) 0); 243 244 f = d->file; 245 if (f->cmds != 0) 238 convert_suffix_rule (dep_name (d), 0, 0); 239 240 if (d->file->cmds != 0) 246 241 /* Record a pattern for this suffix's null-suffix rule. */ 247 convert_suffix_rule ("", dep_name (d), f->cmds); 248 249 /* Record a pattern for each of this suffix's two-suffix rules. */ 242 convert_suffix_rule ("", dep_name (d), d->file->cmds); 243 244 /* Add every other suffix to this one and see if it exists as a 245 two-suffix rule. */ 250 246 slen = strlen (dep_name (d)); 251 bcopy (dep_name (d), rulename, slen); 247 memcpy (rulename, dep_name (d), slen); 248 252 249 for (d2 = suffix_file->deps; d2 != 0; d2 = d2->next) 253 250 { 251 struct file *f; 252 unsigned int s2len; 253 254 254 s2len = strlen (dep_name (d2)); 255 255 256 /* Can't build something from itself. */ 256 257 if (slen == s2len && streq (dep_name (d), dep_name (d2))) 257 258 continue; 258 259 259 bcopy (dep_name (d2), rulename + slen, s2len + 1);260 memcpy (rulename + slen, dep_name (d2), s2len + 1); 260 261 f = lookup_file (rulename); 261 262 if (f == 0 || f->cmds == 0) … … 265 266 /* A suffix rule `.X.a:' generates the pattern rule `(%.o): %.X'. 266 267 It also generates a normal `%.a: %.X' rule below. */ 267 convert_suffix_rule ( (char *) 0, /* Indicates `(%.o)'. */268 convert_suffix_rule (NULL, /* Indicates `(%.o)'. */ 268 269 dep_name (d), 269 270 f->cmds); … … 277 278 278 279 279 /* Install the pattern rule RULE (whose fields have been filled in) 280 at the end of the list (so that any rules previously defined 281 will take precedence). If this rule duplicates a previous one 282 (identical target and dependencies), the old one is replaced 283 if OVERRIDE is nonzero, otherwise this new one is thrown out. 284 When an old rule is replaced, the new one is put at the end of the 285 list. Return nonzero if RULE is used; zero if not. */ 286 287 int 280 /* Install the pattern rule RULE (whose fields have been filled in) at the end 281 of the list (so that any rules previously defined will take precedence). 282 If this rule duplicates a previous one (identical target and dependencies), 283 the old one is replaced if OVERRIDE is nonzero, otherwise this new one is 284 thrown out. When an old rule is replaced, the new one is put at the end of 285 the list. Return nonzero if RULE is used; zero if not. */ 286 287 static int 288 288 new_pattern_rule (struct rule *rule, int override) 289 289 { 290 registerstruct rule *r, *lastrule;291 registerunsigned int i, j;290 struct rule *r, *lastrule; 291 unsigned int i, j; 292 292 293 293 rule->in_use = 0; … … 299 299 lastrule = 0; 300 300 for (r = pattern_rules; r != 0; lastrule = r, r = r->next) 301 for (i = 0; rule->targets[i] != 0; ++i)301 for (i = 0; i < rule->num; ++i) 302 302 { 303 for (j = 0; r->targets[j] != 0; ++j)303 for (j = 0; j < r->num; ++j) 304 304 if (!streq (rule->targets[i], r->targets[j])) 305 305 break; 306 if (r->targets[j] == 0) 307 /* All the targets matched. */306 /* If all the targets matched... */ 307 if (j == r->num) 308 308 { 309 registerstruct dep *d, *d2;309 struct dep *d, *d2; 310 310 for (d = rule->deps, d2 = r->deps; 311 311 d != 0 && d2 != 0; d = d->next, d2 = d2->next) … … 363 363 install_pattern_rule (struct pspec *p, int terminal) 364 364 { 365 registerstruct rule *r;365 struct rule *r; 366 366 char *ptr; 367 367 368 r = (struct rule *) xmalloc (sizeof (struct rule)); 369 370 r->targets = (char **) xmalloc (2 * sizeof (char *)); 371 r->suffixes = (char **) xmalloc (2 * sizeof (char *)); 372 r->lens = (unsigned int *) xmalloc (2 * sizeof (unsigned int)); 373 374 r->targets[1] = 0; 375 r->suffixes[1] = 0; 376 r->lens[1] = 0; 368 r = xmalloc (sizeof (struct rule)); 369 370 r->num = 1; 371 r->targets = xmalloc (sizeof (const char *)); 372 r->suffixes = xmalloc (sizeof (const char *)); 373 r->lens = xmalloc (sizeof (unsigned int)); 377 374 378 375 r->lens[0] = strlen (p->target); 379 /* These will all be string literals, but we malloc space for 380 them anyway because somebody might want to free them later on. */ 381 r->targets[0] = savestring (p->target, r->lens[0]); 382 r->suffixes[0] = find_percent (r->targets[0]); 383 if (r->suffixes[0] == 0) 384 /* Programmer-out-to-lunch error. */ 385 abort (); 386 else 387 ++r->suffixes[0]; 376 r->targets[0] = p->target; 377 r->suffixes[0] = find_percent_cached (&r->targets[0]); 378 assert (r->suffixes[0] != NULL); 379 ++r->suffixes[0]; 388 380 389 381 ptr = p->dep; … … 395 387 { 396 388 r->terminal = terminal; 397 r->cmds = (struct commands *)xmalloc (sizeof (struct commands));389 r->cmds = xmalloc (sizeof (struct commands)); 398 390 r->cmds->fileinfo.filenm = 0; 399 391 r->cmds->fileinfo.lineno = 0; … … 414 406 { 415 407 struct rule *next = rule->next; 416 register unsigned int i; 417 register struct dep *dep; 418 419 for (i = 0; rule->targets[i] != 0; ++i) 420 free (rule->targets[i]); 408 struct dep *dep; 421 409 422 410 dep = rule->deps; 423 411 while (dep) 424 412 { 425 struct dep *t; 426 427 t = dep->next; 428 /* We might leak dep->name here, but I'm not sure how to fix this: I 429 think that pointer might be shared (e.g., in the file hash?) */ 430 dep->name = 0; /* Make sure free_dep does not free name. */ 413 struct dep *t = dep->next; 431 414 free_dep (dep); 432 415 dep = t; 433 416 } 434 417 435 free ( (char *)rule->targets);436 free ( (char *)rule->suffixes);437 free ( (char *)rule->lens);418 free (rule->targets); 419 free (rule->suffixes); 420 free (rule->lens); 438 421 439 422 /* We can't free the storage for the commands because there … … 448 431 pointer from the `struct file' for the suffix rule. */ 449 432 450 free ( (char *)rule);433 free (rule); 451 434 452 435 if (pattern_rules == rule) … … 462 445 463 446 464 /* Create a new pattern rule with the targets in the nil-terminated 465 array TARGETS. If TARGET_PERCENTS is not nil, it is an array of466 pointers into the elements of TARGETS, where the `%'s are.467 The new rule has dependencies DEPS and commands from COMMANDS.447 /* Create a new pattern rule with the targets in the nil-terminated array 448 TARGETS. TARGET_PERCENTS is an array of pointers to the % in each element 449 of TARGETS. N is the number of items in the array (not counting the nil 450 element). The new rule has dependencies DEPS and commands from COMMANDS. 468 451 It is a terminal rule if TERMINAL is nonzero. This rule overrides 469 452 identical rules with different commands if OVERRIDE is nonzero. 470 453 471 The storage for TARGETS and its elements is used and must not be freed 472 until the rule is destroyed. The storage for TARGET_PERCENTS is not used; 473 it may be freed. */ 454 The storage for TARGETS and its elements and TARGET_PERCENTS is used and 455 must not be freed until the rule is destroyed. */ 474 456 475 457 void 476 create_pattern_rule (c har **targets,char **target_percents,477 458 create_pattern_rule (const char **targets, const char **target_percents, 459 unsigned int n, int terminal, struct dep *deps, 478 460 struct commands *commands, int override) 479 461 { 480 unsigned int max_targets, i; 481 struct rule *r = (struct rule *) xmalloc (sizeof (struct rule)); 482 462 unsigned int i; 463 struct rule *r = xmalloc (sizeof (struct rule)); 464 465 r->num = n; 483 466 r->cmds = commands; 484 467 r->deps = deps; 485 468 r->targets = targets; 486 487 max_targets = 2; 488 r->lens = (unsigned int *) xmalloc (2 * sizeof (unsigned int)); 489 r->suffixes = (char **) xmalloc (2 * sizeof (char *)); 490 for (i = 0; targets[i] != 0; ++i) 491 { 492 if (i == max_targets - 1) 493 { 494 max_targets += 5; 495 r->lens = (unsigned int *) 496 xrealloc ((char *) r->lens, max_targets * sizeof (unsigned int)); 497 r->suffixes = (char **) 498 xrealloc ((char *) r->suffixes, max_targets * sizeof (char *)); 499 } 469 r->suffixes = target_percents; 470 r->lens = xmalloc (n * sizeof (unsigned int)); 471 472 for (i = 0; i < n; ++i) 473 { 500 474 r->lens[i] = strlen (targets[i]); 501 r->suffixes[i] = (target_percents == 0 ? find_percent (targets[i]) 502 : target_percents[i]) + 1; 503 if (r->suffixes[i] == 0) 504 abort (); 505 } 506 507 if (i < max_targets - 1) 508 { 509 r->lens = (unsigned int *) xrealloc ((char *) r->lens, 510 (i + 1) * sizeof (unsigned int)); 511 r->suffixes = (char **) xrealloc ((char *) r->suffixes, 512 (i + 1) * sizeof (char *)); 475 assert (r->suffixes[i] != NULL); 476 ++r->suffixes[i]; 513 477 } 514 478 … … 523 487 print_rule (struct rule *r) 524 488 { 525 registerunsigned int i;526 registerstruct dep *d;527 528 for (i = 0; r->targets[i] != 0; ++i)489 unsigned int i; 490 struct dep *d; 491 492 for (i = 0; i < r->num; ++i) 529 493 { 530 494 fputs (r->targets[i], stdout); 531 if (r->targets[i + 1] != 0) 532 putchar (' '); 533 else 534 putchar (':'); 495 putchar ((i + 1 == r->num) ? ':' : ' '); 535 496 } 536 497 if (r->terminal) … … 548 509 print_rule_data_base (void) 549 510 { 550 registerunsigned int rules, terminal;551 registerstruct rule *r;511 unsigned int rules, terminal; 512 struct rule *r; 552 513 553 514 puts (_("\n# Implicit Rules"));
Note:
See TracChangeset
for help on using the changeset viewer.