| 1 | /* Target file management for GNU Make. | 
|---|
| 2 | Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, | 
|---|
| 3 | 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software | 
|---|
| 4 | Foundation, Inc. | 
|---|
| 5 | This file is part of GNU Make. | 
|---|
| 6 |  | 
|---|
| 7 | GNU Make is free software; you can redistribute it and/or modify it under the | 
|---|
| 8 | terms of the GNU General Public License as published by the Free Software | 
|---|
| 9 | Foundation; either version 2, or (at your option) any later version. | 
|---|
| 10 |  | 
|---|
| 11 | GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY | 
|---|
| 12 | WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR | 
|---|
| 13 | A PARTICULAR PURPOSE.  See the GNU General Public License for more details. | 
|---|
| 14 |  | 
|---|
| 15 | You should have received a copy of the GNU General Public License along with | 
|---|
| 16 | GNU Make; see the file COPYING.  If not, write to the Free Software | 
|---|
| 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.  */ | 
|---|
| 18 |  | 
|---|
| 19 | #include "make.h" | 
|---|
| 20 |  | 
|---|
| 21 | #include <assert.h> | 
|---|
| 22 |  | 
|---|
| 23 | #include "dep.h" | 
|---|
| 24 | #include "filedef.h" | 
|---|
| 25 | #include "job.h" | 
|---|
| 26 | #include "commands.h" | 
|---|
| 27 | #include "variable.h" | 
|---|
| 28 | #include "debug.h" | 
|---|
| 29 | #include "hash.h" | 
|---|
| 30 |  | 
|---|
| 31 |  | 
|---|
| 32 | /* Remember whether snap_deps has been invoked: we need this to be sure we | 
|---|
| 33 | don't add new rules (via $(eval ...)) afterwards.  In the future it would | 
|---|
| 34 | be nice to support this, but it means we'd need to re-run snap_deps() or | 
|---|
| 35 | at least its functionality... it might mean changing snap_deps() to be run | 
|---|
| 36 | per-file, so we can invoke it after the eval... or remembering which files | 
|---|
| 37 | in the hash have been snapped (a new boolean flag?) and having snap_deps() | 
|---|
| 38 | only work on files which have not yet been snapped. */ | 
|---|
| 39 | int snapped_deps = 0; | 
|---|
| 40 |  | 
|---|
| 41 | /* Hash table of files the makefile knows how to make.  */ | 
|---|
| 42 |  | 
|---|
| 43 | static unsigned long | 
|---|
| 44 | file_hash_1 (const void *key) | 
|---|
| 45 | { | 
|---|
| 46 | return_ISTRING_HASH_1 (((struct file const *) key)->hname); | 
|---|
| 47 | } | 
|---|
| 48 |  | 
|---|
| 49 | static unsigned long | 
|---|
| 50 | file_hash_2 (const void *key) | 
|---|
| 51 | { | 
|---|
| 52 | return_ISTRING_HASH_2 (((struct file const *) key)->hname); | 
|---|
| 53 | } | 
|---|
| 54 |  | 
|---|
| 55 | static int | 
|---|
| 56 | file_hash_cmp (const void *x, const void *y) | 
|---|
| 57 | { | 
|---|
| 58 | return_ISTRING_COMPARE (((struct file const *) x)->hname, | 
|---|
| 59 | ((struct file const *) y)->hname); | 
|---|
| 60 | } | 
|---|
| 61 |  | 
|---|
| 62 | #ifndef FILE_BUCKETS | 
|---|
| 63 | #define FILE_BUCKETS    1007 | 
|---|
| 64 | #endif | 
|---|
| 65 | static struct hash_table files; | 
|---|
| 66 |  | 
|---|
| 67 | /* Whether or not .SECONDARY with no prerequisites was given.  */ | 
|---|
| 68 | static int all_secondary = 0; | 
|---|
| 69 |  | 
|---|
| 70 | /* Access the hash table of all file records. | 
|---|
| 71 | lookup_file  given a name, return the struct file * for that name, | 
|---|
| 72 | or nil if there is none. | 
|---|
| 73 | */ | 
|---|
| 74 |  | 
|---|
| 75 | struct file * | 
|---|
| 76 | lookup_file (const char *name) | 
|---|
| 77 | { | 
|---|
| 78 | struct file *f; | 
|---|
| 79 | struct file file_key; | 
|---|
| 80 | #if defined(VMS) && !defined(WANT_CASE_SENSITIVE_TARGETS) | 
|---|
| 81 | char *lname; | 
|---|
| 82 | #endif | 
|---|
| 83 |  | 
|---|
| 84 | assert (*name != '\0'); | 
|---|
| 85 |  | 
|---|
| 86 | /* This is also done in parse_file_seq, so this is redundant | 
|---|
| 87 | for names read from makefiles.  It is here for names passed | 
|---|
| 88 | on the command line.  */ | 
|---|
| 89 | #ifdef VMS | 
|---|
| 90 | # ifndef WANT_CASE_SENSITIVE_TARGETS | 
|---|
| 91 | if (*name != '.') | 
|---|
| 92 | { | 
|---|
| 93 | const char *n; | 
|---|
| 94 | char *ln; | 
|---|
| 95 | lname = xstrdup (name); | 
|---|
| 96 | for (n = name, ln = lname; *n != '\0'; ++n, ++ln) | 
|---|
| 97 | *ln = isupper ((unsigned char)*n) ? tolower ((unsigned char)*n) : *n; | 
|---|
| 98 | *ln = '\0'; | 
|---|
| 99 | name = lname; | 
|---|
| 100 | } | 
|---|
| 101 | # endif | 
|---|
| 102 |  | 
|---|
| 103 | while (name[0] == '[' && name[1] == ']' && name[2] != '\0') | 
|---|
| 104 | name += 2; | 
|---|
| 105 | #endif | 
|---|
| 106 | while (name[0] == '.' && name[1] == '/' && name[2] != '\0') | 
|---|
| 107 | { | 
|---|
| 108 | name += 2; | 
|---|
| 109 | while (*name == '/') | 
|---|
| 110 | /* Skip following slashes: ".//foo" is "foo", not "/foo".  */ | 
|---|
| 111 | ++name; | 
|---|
| 112 | } | 
|---|
| 113 |  | 
|---|
| 114 | if (*name == '\0') | 
|---|
| 115 | /* It was all slashes after a dot.  */ | 
|---|
| 116 | #if defined(VMS) | 
|---|
| 117 | name = "[]"; | 
|---|
| 118 | #elif defined(_AMIGA) | 
|---|
| 119 | name = ""; | 
|---|
| 120 | #else | 
|---|
| 121 | name = "./"; | 
|---|
| 122 | #endif | 
|---|
| 123 |  | 
|---|
| 124 | file_key.hname = name; | 
|---|
| 125 | f = hash_find_item (&files, &file_key); | 
|---|
| 126 | #if defined(VMS) && !defined(WANT_CASE_SENSITIVE_TARGETS) | 
|---|
| 127 | if (*name != '.') | 
|---|
| 128 | free (lname); | 
|---|
| 129 | #endif | 
|---|
| 130 |  | 
|---|
| 131 | return f; | 
|---|
| 132 | } | 
|---|
| 133 |  | 
|---|
| 134 | /* Look up a file record for file NAME and return it. | 
|---|
| 135 | Create a new record if one doesn't exist.  NAME will be stored in the | 
|---|
| 136 | new record so it should be constant or in the strcache etc. | 
|---|
| 137 | */ | 
|---|
| 138 |  | 
|---|
| 139 | struct file * | 
|---|
| 140 | enter_file (const char *name) | 
|---|
| 141 | { | 
|---|
| 142 | struct file *f; | 
|---|
| 143 | struct file *new; | 
|---|
| 144 | struct file **file_slot; | 
|---|
| 145 | struct file file_key; | 
|---|
| 146 |  | 
|---|
| 147 | assert (*name != '\0'); | 
|---|
| 148 | assert (strcache_iscached (name)); | 
|---|
| 149 |  | 
|---|
| 150 | #if defined(VMS) && !defined(WANT_CASE_SENSITIVE_TARGETS) | 
|---|
| 151 | if (*name != '.') | 
|---|
| 152 | { | 
|---|
| 153 | const char *n; | 
|---|
| 154 | char *lname, *ln; | 
|---|
| 155 | lname = xstrdup (name); | 
|---|
| 156 | for (n = name, ln = lname; *n != '\0'; ++n, ++ln) | 
|---|
| 157 | if (isupper ((unsigned char)*n)) | 
|---|
| 158 | *ln = tolower ((unsigned char)*n); | 
|---|
| 159 | else | 
|---|
| 160 | *ln = *n; | 
|---|
| 161 |  | 
|---|
| 162 | *ln = '\0'; | 
|---|
| 163 | name = strcache_add (lname); | 
|---|
| 164 | free (lname); | 
|---|
| 165 | } | 
|---|
| 166 | #endif | 
|---|
| 167 |  | 
|---|
| 168 | file_key.hname = name; | 
|---|
| 169 | file_slot = (struct file **) hash_find_slot (&files, &file_key); | 
|---|
| 170 | f = *file_slot; | 
|---|
| 171 | if (! HASH_VACANT (f) && !f->double_colon) | 
|---|
| 172 | return f; | 
|---|
| 173 |  | 
|---|
| 174 | new = xmalloc (sizeof (struct file)); | 
|---|
| 175 | memset (new, '\0', sizeof (struct file)); | 
|---|
| 176 | new->name = new->hname = name; | 
|---|
| 177 | new->update_status = -1; | 
|---|
| 178 |  | 
|---|
| 179 | if (HASH_VACANT (f)) | 
|---|
| 180 | { | 
|---|
| 181 | new->last = new; | 
|---|
| 182 | hash_insert_at (&files, new, file_slot); | 
|---|
| 183 | } | 
|---|
| 184 | else | 
|---|
| 185 | { | 
|---|
| 186 | /* There is already a double-colon entry for this file.  */ | 
|---|
| 187 | new->double_colon = f; | 
|---|
| 188 | f->last->prev = new; | 
|---|
| 189 | f->last = new; | 
|---|
| 190 | } | 
|---|
| 191 |  | 
|---|
| 192 | #ifdef CONFIG_WITH_2ND_TARGET_EXPANSION | 
|---|
| 193 | /* Check if the name needs 2nd expansion or not. */ | 
|---|
| 194 | if (second_target_expansion && strchr (name, '$') != NULL) | 
|---|
| 195 | new->need_2nd_target_expansion = 1; | 
|---|
| 196 | #endif | 
|---|
| 197 |  | 
|---|
| 198 | return new; | 
|---|
| 199 | } | 
|---|
| 200 |  | 
|---|
| 201 |  | 
|---|
| 202 | /* Rehash FILE to NAME.  This is not as simple as resetting | 
|---|
| 203 | the `hname' member, since it must be put in a new hash bucket, | 
|---|
| 204 | and possibly merged with an existing file called NAME.  */ | 
|---|
| 205 |  | 
|---|
| 206 | void | 
|---|
| 207 | rehash_file (struct file *from_file, const char *to_hname) | 
|---|
| 208 | { | 
|---|
| 209 | struct file file_key; | 
|---|
| 210 | struct file **file_slot; | 
|---|
| 211 | struct file *to_file; | 
|---|
| 212 | struct file *deleted_file; | 
|---|
| 213 | struct file *f; | 
|---|
| 214 |  | 
|---|
| 215 | /* If it's already that name, we're done.  */ | 
|---|
| 216 | file_key.hname = to_hname; | 
|---|
| 217 | if (! file_hash_cmp (from_file, &file_key)) | 
|---|
| 218 | return; | 
|---|
| 219 |  | 
|---|
| 220 | /* Find the end of the renamed list for the "from" file.  */ | 
|---|
| 221 | file_key.hname = from_file->hname; | 
|---|
| 222 | while (from_file->renamed != 0) | 
|---|
| 223 | from_file = from_file->renamed; | 
|---|
| 224 | if (file_hash_cmp (from_file, &file_key)) | 
|---|
| 225 | /* hname changed unexpectedly!! */ | 
|---|
| 226 | abort (); | 
|---|
| 227 |  | 
|---|
| 228 | /* Remove the "from" file from the hash.  */ | 
|---|
| 229 | deleted_file = hash_delete (&files, from_file); | 
|---|
| 230 | if (deleted_file != from_file) | 
|---|
| 231 | /* from_file isn't the one stored in files */ | 
|---|
| 232 | abort (); | 
|---|
| 233 |  | 
|---|
| 234 | /* Find where the newly renamed file will go in the hash.  */ | 
|---|
| 235 | file_key.hname = to_hname; | 
|---|
| 236 | file_slot = (struct file **) hash_find_slot (&files, &file_key); | 
|---|
| 237 | to_file = *file_slot; | 
|---|
| 238 |  | 
|---|
| 239 | /* Change the hash name for this file.  */ | 
|---|
| 240 | from_file->hname = to_hname; | 
|---|
| 241 | for (f = from_file->double_colon; f != 0; f = f->prev) | 
|---|
| 242 | f->hname = to_hname; | 
|---|
| 243 |  | 
|---|
| 244 | /* If the new name doesn't exist yet just set it to the renamed file.  */ | 
|---|
| 245 | if (HASH_VACANT (to_file)) | 
|---|
| 246 | { | 
|---|
| 247 | hash_insert_at (&files, from_file, file_slot); | 
|---|
| 248 | return; | 
|---|
| 249 | } | 
|---|
| 250 |  | 
|---|
| 251 | /* TO_FILE already exists under TO_HNAME. | 
|---|
| 252 | We must retain TO_FILE and merge FROM_FILE into it.  */ | 
|---|
| 253 |  | 
|---|
| 254 | if (from_file->cmds != 0) | 
|---|
| 255 | { | 
|---|
| 256 | if (to_file->cmds == 0) | 
|---|
| 257 | to_file->cmds = from_file->cmds; | 
|---|
| 258 | else if (from_file->cmds != to_file->cmds) | 
|---|
| 259 | { | 
|---|
| 260 | /* We have two sets of commands.  We will go with the | 
|---|
| 261 | one given in the rule explicitly mentioning this name, | 
|---|
| 262 | but give a message to let the user know what's going on.  */ | 
|---|
| 263 | if (to_file->cmds->fileinfo.filenm != 0) | 
|---|
| 264 | error (&from_file->cmds->fileinfo, | 
|---|
| 265 | _("Commands were specified for file `%s' at %s:%lu,"), | 
|---|
| 266 | from_file->name, to_file->cmds->fileinfo.filenm, | 
|---|
| 267 | to_file->cmds->fileinfo.lineno); | 
|---|
| 268 | else | 
|---|
| 269 | error (&from_file->cmds->fileinfo, | 
|---|
| 270 | _("Commands for file `%s' were found by implicit rule search,"), | 
|---|
| 271 | from_file->name); | 
|---|
| 272 | error (&from_file->cmds->fileinfo, | 
|---|
| 273 | _("but `%s' is now considered the same file as `%s'."), | 
|---|
| 274 | from_file->name, to_hname); | 
|---|
| 275 | error (&from_file->cmds->fileinfo, | 
|---|
| 276 | _("Commands for `%s' will be ignored in favor of those for `%s'."), | 
|---|
| 277 | to_hname, from_file->name); | 
|---|
| 278 | } | 
|---|
| 279 | } | 
|---|
| 280 |  | 
|---|
| 281 | /* Merge the dependencies of the two files.  */ | 
|---|
| 282 |  | 
|---|
| 283 | if (to_file->deps == 0) | 
|---|
| 284 | to_file->deps = from_file->deps; | 
|---|
| 285 | else | 
|---|
| 286 | { | 
|---|
| 287 | struct dep *deps = to_file->deps; | 
|---|
| 288 | while (deps->next != 0) | 
|---|
| 289 | deps = deps->next; | 
|---|
| 290 | deps->next = from_file->deps; | 
|---|
| 291 | } | 
|---|
| 292 |  | 
|---|
| 293 | merge_variable_set_lists (&to_file->variables, from_file->variables); | 
|---|
| 294 |  | 
|---|
| 295 | if (to_file->double_colon && from_file->is_target && !from_file->double_colon) | 
|---|
| 296 | fatal (NILF, _("can't rename single-colon `%s' to double-colon `%s'"), | 
|---|
| 297 | from_file->name, to_hname); | 
|---|
| 298 | if (!to_file->double_colon  && from_file->double_colon) | 
|---|
| 299 | { | 
|---|
| 300 | if (to_file->is_target) | 
|---|
| 301 | fatal (NILF, _("can't rename double-colon `%s' to single-colon `%s'"), | 
|---|
| 302 | from_file->name, to_hname); | 
|---|
| 303 | else | 
|---|
| 304 | to_file->double_colon = from_file->double_colon; | 
|---|
| 305 | } | 
|---|
| 306 |  | 
|---|
| 307 | if (from_file->last_mtime > to_file->last_mtime) | 
|---|
| 308 | /* %%% Kludge so -W wins on a file that gets vpathized.  */ | 
|---|
| 309 | to_file->last_mtime = from_file->last_mtime; | 
|---|
| 310 |  | 
|---|
| 311 | to_file->mtime_before_update = from_file->mtime_before_update; | 
|---|
| 312 |  | 
|---|
| 313 | #define MERGE(field) to_file->field |= from_file->field | 
|---|
| 314 | MERGE (precious); | 
|---|
| 315 | MERGE (tried_implicit); | 
|---|
| 316 | MERGE (updating); | 
|---|
| 317 | MERGE (updated); | 
|---|
| 318 | MERGE (is_target); | 
|---|
| 319 | MERGE (cmd_target); | 
|---|
| 320 | MERGE (phony); | 
|---|
| 321 | MERGE (ignore_vpath); | 
|---|
| 322 | #undef MERGE | 
|---|
| 323 |  | 
|---|
| 324 | from_file->renamed = to_file; | 
|---|
| 325 | } | 
|---|
| 326 |  | 
|---|
| 327 | /* Rename FILE to NAME.  This is not as simple as resetting | 
|---|
| 328 | the `name' member, since it must be put in a new hash bucket, | 
|---|
| 329 | and possibly merged with an existing file called NAME.  */ | 
|---|
| 330 |  | 
|---|
| 331 | void | 
|---|
| 332 | rename_file (struct file *from_file, const char *to_hname) | 
|---|
| 333 | { | 
|---|
| 334 | rehash_file (from_file, to_hname); | 
|---|
| 335 | while (from_file) | 
|---|
| 336 | { | 
|---|
| 337 | from_file->name = from_file->hname; | 
|---|
| 338 | from_file = from_file->prev; | 
|---|
| 339 | } | 
|---|
| 340 | } | 
|---|
| 341 |  | 
|---|
| 342 |  | 
|---|
| 343 | #ifdef CONFIG_WITH_2ND_TARGET_EXPANSION | 
|---|
| 344 | /* Performs secondary target name expansion and then renames | 
|---|
| 345 | the file using rename_file. */ | 
|---|
| 346 | static void | 
|---|
| 347 | do_2nd_target_expansion (struct file *f) | 
|---|
| 348 | { | 
|---|
| 349 | char *tmp_name = allocated_variable_expand (f->name); | 
|---|
| 350 | const char *name = strcache_add (tmp_name); | 
|---|
| 351 | free (tmp_name); | 
|---|
| 352 | rename_file (f, name); | 
|---|
| 353 | } | 
|---|
| 354 | #endif /* CONFIG_WITH_2ND_TARGET_EXPANSION */ | 
|---|
| 355 |  | 
|---|
| 356 |  | 
|---|
| 357 | /* Remove all nonprecious intermediate files. | 
|---|
| 358 | If SIG is nonzero, this was caused by a fatal signal, | 
|---|
| 359 | meaning that a different message will be printed, and | 
|---|
| 360 | the message will go to stderr rather than stdout.  */ | 
|---|
| 361 |  | 
|---|
| 362 | void | 
|---|
| 363 | remove_intermediates (int sig) | 
|---|
| 364 | { | 
|---|
| 365 | struct file **file_slot; | 
|---|
| 366 | struct file **file_end; | 
|---|
| 367 | int doneany = 0; | 
|---|
| 368 |  | 
|---|
| 369 | /* If there's no way we will ever remove anything anyway, punt early.  */ | 
|---|
| 370 | if (question_flag || touch_flag || all_secondary) | 
|---|
| 371 | return; | 
|---|
| 372 |  | 
|---|
| 373 | if (sig && just_print_flag) | 
|---|
| 374 | return; | 
|---|
| 375 |  | 
|---|
| 376 | file_slot = (struct file **) files.ht_vec; | 
|---|
| 377 | file_end = file_slot + files.ht_size; | 
|---|
| 378 | for ( ; file_slot < file_end; file_slot++) | 
|---|
| 379 | if (! HASH_VACANT (*file_slot)) | 
|---|
| 380 | { | 
|---|
| 381 | struct file *f = *file_slot; | 
|---|
| 382 | /* Is this file eligible for automatic deletion? | 
|---|
| 383 | Yes, IFF: it's marked intermediate, it's not secondary, it wasn't | 
|---|
| 384 | given on the command-line, and it's either a -include makefile or | 
|---|
| 385 | it's not precious.  */ | 
|---|
| 386 | if (f->intermediate && (f->dontcare || !f->precious) | 
|---|
| 387 | && !f->secondary && !f->cmd_target) | 
|---|
| 388 | { | 
|---|
| 389 | int status; | 
|---|
| 390 | if (f->update_status == -1) | 
|---|
| 391 | /* If nothing would have created this file yet, | 
|---|
| 392 | don't print an "rm" command for it.  */ | 
|---|
| 393 | continue; | 
|---|
| 394 | if (just_print_flag) | 
|---|
| 395 | status = 0; | 
|---|
| 396 | else | 
|---|
| 397 | { | 
|---|
| 398 | status = unlink (f->name); | 
|---|
| 399 | if (status < 0 && errno == ENOENT) | 
|---|
| 400 | continue; | 
|---|
| 401 | } | 
|---|
| 402 | if (!f->dontcare) | 
|---|
| 403 | { | 
|---|
| 404 | if (sig) | 
|---|
| 405 | error (NILF, _("*** Deleting intermediate file `%s'"), f->name); | 
|---|
| 406 | else | 
|---|
| 407 | { | 
|---|
| 408 | if (! doneany) | 
|---|
| 409 | DB (DB_BASIC, (_("Removing intermediate files...\n"))); | 
|---|
| 410 | if (!silent_flag) | 
|---|
| 411 | { | 
|---|
| 412 | if (! doneany) | 
|---|
| 413 | { | 
|---|
| 414 | fputs ("rm ", stdout); | 
|---|
| 415 | doneany = 1; | 
|---|
| 416 | } | 
|---|
| 417 | else | 
|---|
| 418 | putchar (' '); | 
|---|
| 419 | fputs (f->name, stdout); | 
|---|
| 420 | fflush (stdout); | 
|---|
| 421 | } | 
|---|
| 422 | } | 
|---|
| 423 | if (status < 0) | 
|---|
| 424 | perror_with_name ("unlink: ", f->name); | 
|---|
| 425 | } | 
|---|
| 426 | } | 
|---|
| 427 | } | 
|---|
| 428 |  | 
|---|
| 429 | if (doneany && !sig) | 
|---|
| 430 | { | 
|---|
| 431 | putchar ('\n'); | 
|---|
| 432 | fflush (stdout); | 
|---|
| 433 | } | 
|---|
| 434 | } | 
|---|
| 435 |  | 
|---|
| 436 |  | 
|---|
| 437 | struct dep * | 
|---|
| 438 | parse_prereqs (char *p) | 
|---|
| 439 | { | 
|---|
| 440 | struct dep *new = (struct dep *) | 
|---|
| 441 | multi_glob (parse_file_seq (&p, '|', sizeof (struct dep), 1), | 
|---|
| 442 | sizeof (struct dep)); | 
|---|
| 443 |  | 
|---|
| 444 | if (*p) | 
|---|
| 445 | { | 
|---|
| 446 | /* Files that follow '|' are "order-only" prerequisites that satisfy the | 
|---|
| 447 | dependency by existing: their modification times are irrelevant.  */ | 
|---|
| 448 | struct dep *ood; | 
|---|
| 449 |  | 
|---|
| 450 | ++p; | 
|---|
| 451 | ood = (struct dep *) | 
|---|
| 452 | multi_glob (parse_file_seq (&p, '\0', sizeof (struct dep), 1), | 
|---|
| 453 | sizeof (struct dep)); | 
|---|
| 454 |  | 
|---|
| 455 | if (! new) | 
|---|
| 456 | new = ood; | 
|---|
| 457 | else | 
|---|
| 458 | { | 
|---|
| 459 | struct dep *dp; | 
|---|
| 460 | for (dp = new; dp->next != NULL; dp = dp->next) | 
|---|
| 461 | ; | 
|---|
| 462 | dp->next = ood; | 
|---|
| 463 | } | 
|---|
| 464 |  | 
|---|
| 465 | for (; ood != NULL; ood = ood->next) | 
|---|
| 466 | ood->ignore_mtime = 1; | 
|---|
| 467 | } | 
|---|
| 468 |  | 
|---|
| 469 | return new; | 
|---|
| 470 | } | 
|---|
| 471 |  | 
|---|
| 472 | /* Set the intermediate flag.  */ | 
|---|
| 473 |  | 
|---|
| 474 | static void | 
|---|
| 475 | set_intermediate (const void *item) | 
|---|
| 476 | { | 
|---|
| 477 | struct file *f = (struct file *) item; | 
|---|
| 478 | f->intermediate = 1; | 
|---|
| 479 | } | 
|---|
| 480 |  | 
|---|
| 481 | /* Expand and parse each dependency line. */ | 
|---|
| 482 | static void | 
|---|
| 483 | expand_deps (struct file *f) | 
|---|
| 484 | { | 
|---|
| 485 | struct dep *d; | 
|---|
| 486 | struct dep *old = f->deps; | 
|---|
| 487 | const char *file_stem = f->stem; | 
|---|
| 488 | unsigned int last_dep_has_cmds = f->updating; | 
|---|
| 489 | int initialized = 0; | 
|---|
| 490 |  | 
|---|
| 491 | f->updating = 0; | 
|---|
| 492 | f->deps = 0; | 
|---|
| 493 |  | 
|---|
| 494 | for (d = old; d != 0; d = d->next) | 
|---|
| 495 | { | 
|---|
| 496 | size_t buffer_offset; /* bird */ | 
|---|
| 497 | struct dep *new, *d1; | 
|---|
| 498 | char *p; | 
|---|
| 499 |  | 
|---|
| 500 | if (! d->name) | 
|---|
| 501 | continue; | 
|---|
| 502 |  | 
|---|
| 503 | /* Create the dependency list. | 
|---|
| 504 | If we're not doing 2nd expansion, then it's just the name.  We will | 
|---|
| 505 | still need to massage it though.  */ | 
|---|
| 506 | if (! d->need_2nd_expansion) | 
|---|
| 507 | { | 
|---|
| 508 | p = variable_expand (""); | 
|---|
| 509 | buffer_offset = p - variable_buffer; | 
|---|
| 510 | variable_buffer_output (p, d->name, strlen (d->name) + 1); | 
|---|
| 511 | p = variable_buffer + buffer_offset; /* bird - variable_buffer may have been reallocated. (observed it) */ | 
|---|
| 512 | } | 
|---|
| 513 | else | 
|---|
| 514 | { | 
|---|
| 515 | /* If it's from a static pattern rule, convert the patterns into | 
|---|
| 516 | "$*" so they'll expand properly.  */ | 
|---|
| 517 | if (d->staticpattern) | 
|---|
| 518 | { | 
|---|
| 519 | char *o; | 
|---|
| 520 | char *buffer = variable_expand (""); | 
|---|
| 521 | buffer_offset = buffer - variable_buffer; /* bird */ | 
|---|
| 522 |  | 
|---|
| 523 | o = subst_expand (buffer, d->name, "%", "$*", 1, 2, 0); | 
|---|
| 524 | buffer = variable_buffer + buffer_offset; /* bird - variable_buffer may have been reallocated. */ | 
|---|
| 525 |  | 
|---|
| 526 | d->name = strcache_add_len (buffer, o - buffer); | 
|---|
| 527 | d->staticpattern = 0; /* Clear staticpattern so that we don't | 
|---|
| 528 | re-expand %s below. */ | 
|---|
| 529 | } | 
|---|
| 530 |  | 
|---|
| 531 | /* We are going to do second expansion so initialize file variables | 
|---|
| 532 | for the file. Since the stem for static pattern rules comes from | 
|---|
| 533 | individual dep lines, we will temporarily set f->stem to d->stem. | 
|---|
| 534 | */ | 
|---|
| 535 | if (!initialized) | 
|---|
| 536 | { | 
|---|
| 537 | initialize_file_variables (f, 0); | 
|---|
| 538 | initialized = 1; | 
|---|
| 539 | } | 
|---|
| 540 |  | 
|---|
| 541 | if (d->stem != 0) | 
|---|
| 542 | f->stem = d->stem; | 
|---|
| 543 |  | 
|---|
| 544 | set_file_variables (f); | 
|---|
| 545 |  | 
|---|
| 546 | p = variable_expand_for_file (d->name, f); | 
|---|
| 547 |  | 
|---|
| 548 | if (d->stem != 0) | 
|---|
| 549 | f->stem = file_stem; | 
|---|
| 550 | } | 
|---|
| 551 |  | 
|---|
| 552 | /* Parse the prerequisites.  */ | 
|---|
| 553 | new = parse_prereqs (p); | 
|---|
| 554 |  | 
|---|
| 555 | /* If this dep list was from a static pattern rule, expand the %s.  We | 
|---|
| 556 | use patsubst_expand to translate the prerequisites' patterns into | 
|---|
| 557 | plain prerequisite names.  */ | 
|---|
| 558 | if (new && d->staticpattern) | 
|---|
| 559 | { | 
|---|
| 560 | const char *pattern = "%"; | 
|---|
| 561 | char *buffer = variable_expand (""); | 
|---|
| 562 | const size_t buffer_offset = buffer - variable_buffer; /* bird */ | 
|---|
| 563 | struct dep *dp = new, *dl = 0; | 
|---|
| 564 |  | 
|---|
| 565 | while (dp != 0) | 
|---|
| 566 | { | 
|---|
| 567 | char *percent; | 
|---|
| 568 | int nl = strlen (dp->name) + 1; | 
|---|
| 569 | char *nm = alloca (nl); | 
|---|
| 570 | memcpy (nm, dp->name, nl); | 
|---|
| 571 | percent = find_percent (nm); | 
|---|
| 572 | if (percent) | 
|---|
| 573 | { | 
|---|
| 574 | char *o; | 
|---|
| 575 |  | 
|---|
| 576 | /* We have to handle empty stems specially, because that | 
|---|
| 577 | would be equivalent to $(patsubst %,dp->name,) which | 
|---|
| 578 | will always be empty.  */ | 
|---|
| 579 | if (d->stem[0] == '\0') | 
|---|
| 580 | { | 
|---|
| 581 | memmove (percent, percent+1, strlen (percent)); | 
|---|
| 582 | o = variable_buffer_output (buffer, nm, strlen (nm) + 1); | 
|---|
| 583 | } | 
|---|
| 584 | else | 
|---|
| 585 | o = patsubst_expand_pat (buffer, d->stem, pattern, nm, | 
|---|
| 586 | pattern+1, percent+1); | 
|---|
| 587 | buffer = variable_buffer + buffer_offset; /* bird - variable_buffer may have been reallocated. */ | 
|---|
| 588 |  | 
|---|
| 589 |  | 
|---|
| 590 | /* If the name expanded to the empty string, ignore it.  */ | 
|---|
| 591 | if (buffer[0] == '\0') | 
|---|
| 592 | { | 
|---|
| 593 | struct dep *df = dp; | 
|---|
| 594 | if (dp == new) | 
|---|
| 595 | dp = new = new->next; | 
|---|
| 596 | else | 
|---|
| 597 | dp = dl->next = dp->next; | 
|---|
| 598 | free_dep (df); | 
|---|
| 599 | continue; | 
|---|
| 600 | } | 
|---|
| 601 |  | 
|---|
| 602 | /* Save the name.  */ | 
|---|
| 603 | dp->name = strcache_add_len (buffer, o - buffer); | 
|---|
| 604 | } | 
|---|
| 605 | dl = dp; | 
|---|
| 606 | dp = dp->next; | 
|---|
| 607 | } | 
|---|
| 608 | } | 
|---|
| 609 |  | 
|---|
| 610 | /* Enter them as files. */ | 
|---|
| 611 | for (d1 = new; d1 != 0; d1 = d1->next) | 
|---|
| 612 | { | 
|---|
| 613 | d1->file = lookup_file (d1->name); | 
|---|
| 614 | if (d1->file == 0) | 
|---|
| 615 | d1->file = enter_file (d1->name); | 
|---|
| 616 | d1->name = 0; | 
|---|
| 617 | d1->staticpattern = 0; | 
|---|
| 618 | d1->need_2nd_expansion = 0; | 
|---|
| 619 | } | 
|---|
| 620 |  | 
|---|
| 621 | /* Add newly parsed deps to f->deps. If this is the last dependency | 
|---|
| 622 | line and this target has commands then put it in front so the | 
|---|
| 623 | last dependency line (the one with commands) ends up being the | 
|---|
| 624 | first. This is important because people expect $< to hold first | 
|---|
| 625 | prerequisite from the rule with commands. If it is not the last | 
|---|
| 626 | dependency line or the rule does not have commands then link it | 
|---|
| 627 | at the end so it appears in makefile order.  */ | 
|---|
| 628 |  | 
|---|
| 629 | if (new != 0) | 
|---|
| 630 | { | 
|---|
| 631 | if (d->next == 0 && last_dep_has_cmds) | 
|---|
| 632 | { | 
|---|
| 633 | struct dep **d_ptr; | 
|---|
| 634 | for (d_ptr = &new; *d_ptr; d_ptr = &(*d_ptr)->next) | 
|---|
| 635 | ; | 
|---|
| 636 |  | 
|---|
| 637 | *d_ptr = f->deps; | 
|---|
| 638 | f->deps = new; | 
|---|
| 639 | } | 
|---|
| 640 | else | 
|---|
| 641 | { | 
|---|
| 642 | struct dep **d_ptr; | 
|---|
| 643 | for (d_ptr = &f->deps; *d_ptr; d_ptr = &(*d_ptr)->next) | 
|---|
| 644 | ; | 
|---|
| 645 |  | 
|---|
| 646 | *d_ptr = new; | 
|---|
| 647 | } | 
|---|
| 648 | } | 
|---|
| 649 | } | 
|---|
| 650 |  | 
|---|
| 651 | free_dep_chain (old); | 
|---|
| 652 | } | 
|---|
| 653 |  | 
|---|
| 654 | /* For each dependency of each file, make the `struct dep' point | 
|---|
| 655 | at the appropriate `struct file' (which may have to be created). | 
|---|
| 656 |  | 
|---|
| 657 | Also mark the files depended on by .PRECIOUS, .PHONY, .SILENT, | 
|---|
| 658 | and various other special targets.  */ | 
|---|
| 659 |  | 
|---|
| 660 | void | 
|---|
| 661 | snap_deps (void) | 
|---|
| 662 | { | 
|---|
| 663 | struct file *f; | 
|---|
| 664 | struct file *f2; | 
|---|
| 665 | struct dep *d; | 
|---|
| 666 | struct file **file_slot_0; | 
|---|
| 667 | struct file **file_slot; | 
|---|
| 668 | struct file **file_end; | 
|---|
| 669 |  | 
|---|
| 670 | /* Perform second expansion and enter each dependency name as a file. */ | 
|---|
| 671 |  | 
|---|
| 672 | /* Expand .SUFFIXES first; it's dependencies are used for $$* calculation. */ | 
|---|
| 673 | for (f = lookup_file (".SUFFIXES"); f != 0; f = f->prev) | 
|---|
| 674 | expand_deps (f); | 
|---|
| 675 |  | 
|---|
| 676 | #ifdef CONFIG_WITH_2ND_TARGET_EXPANSION | 
|---|
| 677 | /* Perform 2nd target expansion on files which requires this. This will | 
|---|
| 678 | be re-inserting (delete+insert) hash table entries so we have to use | 
|---|
| 679 | hash_dump(). */ | 
|---|
| 680 | file_slot_0 = (struct file **) hash_dump (&files, 0, 0); | 
|---|
| 681 | file_end = file_slot_0 + files.ht_fill; | 
|---|
| 682 | for (file_slot = file_slot_0; file_slot < file_end; file_slot++) | 
|---|
| 683 | for (f = *file_slot; f != 0; f = f->prev) | 
|---|
| 684 | if (f->need_2nd_target_expansion) | 
|---|
| 685 | do_2nd_target_expansion (f); | 
|---|
| 686 | free (file_slot_0); | 
|---|
| 687 |  | 
|---|
| 688 | /* Disable second target expansion now since we won't expand files | 
|---|
| 689 | entered after this point. (saves CPU cycles in enter_file()). */ | 
|---|
| 690 | second_target_expansion = 0; | 
|---|
| 691 | #endif /* CONFIG_WITH_2ND_TARGET_EXPANSION */ | 
|---|
| 692 |  | 
|---|
| 693 | /* For every target that's not .SUFFIXES, expand its dependencies. | 
|---|
| 694 | We must use hash_dump (), because within this loop we might add new files | 
|---|
| 695 | to the table, possibly causing an in-situ table expansion.  */ | 
|---|
| 696 | file_slot_0 = (struct file **) hash_dump (&files, 0, 0); | 
|---|
| 697 | file_end = file_slot_0 + files.ht_fill; | 
|---|
| 698 | for (file_slot = file_slot_0; file_slot < file_end; file_slot++) | 
|---|
| 699 | for (f = *file_slot; f != 0; f = f->prev) | 
|---|
| 700 | if (strcmp (f->name, ".SUFFIXES") != 0) | 
|---|
| 701 | expand_deps (f); | 
|---|
| 702 | free (file_slot_0); | 
|---|
| 703 |  | 
|---|
| 704 | /* Now manage all the special targets.  */ | 
|---|
| 705 |  | 
|---|
| 706 | for (f = lookup_file (".PRECIOUS"); f != 0; f = f->prev) | 
|---|
| 707 | for (d = f->deps; d != 0; d = d->next) | 
|---|
| 708 | for (f2 = d->file; f2 != 0; f2 = f2->prev) | 
|---|
| 709 | f2->precious = 1; | 
|---|
| 710 |  | 
|---|
| 711 | for (f = lookup_file (".LOW_RESOLUTION_TIME"); f != 0; f = f->prev) | 
|---|
| 712 | for (d = f->deps; d != 0; d = d->next) | 
|---|
| 713 | for (f2 = d->file; f2 != 0; f2 = f2->prev) | 
|---|
| 714 | f2->low_resolution_time = 1; | 
|---|
| 715 |  | 
|---|
| 716 | for (f = lookup_file (".PHONY"); f != 0; f = f->prev) | 
|---|
| 717 | for (d = f->deps; d != 0; d = d->next) | 
|---|
| 718 | for (f2 = d->file; f2 != 0; f2 = f2->prev) | 
|---|
| 719 | { | 
|---|
| 720 | /* Mark this file as phony nonexistent target.  */ | 
|---|
| 721 | f2->phony = 1; | 
|---|
| 722 | f2->is_target = 1; | 
|---|
| 723 | f2->last_mtime = NONEXISTENT_MTIME; | 
|---|
| 724 | f2->mtime_before_update = NONEXISTENT_MTIME; | 
|---|
| 725 | } | 
|---|
| 726 |  | 
|---|
| 727 | for (f = lookup_file (".INTERMEDIATE"); f != 0; f = f->prev) | 
|---|
| 728 | /* Mark .INTERMEDIATE deps as intermediate files.  */ | 
|---|
| 729 | for (d = f->deps; d != 0; d = d->next) | 
|---|
| 730 | for (f2 = d->file; f2 != 0; f2 = f2->prev) | 
|---|
| 731 | f2->intermediate = 1; | 
|---|
| 732 | /* .INTERMEDIATE with no deps does nothing. | 
|---|
| 733 | Marking all files as intermediates is useless since the goal targets | 
|---|
| 734 | would be deleted after they are built.  */ | 
|---|
| 735 |  | 
|---|
| 736 | for (f = lookup_file (".SECONDARY"); f != 0; f = f->prev) | 
|---|
| 737 | /* Mark .SECONDARY deps as both intermediate and secondary.  */ | 
|---|
| 738 | if (f->deps) | 
|---|
| 739 | for (d = f->deps; d != 0; d = d->next) | 
|---|
| 740 | for (f2 = d->file; f2 != 0; f2 = f2->prev) | 
|---|
| 741 | f2->intermediate = f2->secondary = 1; | 
|---|
| 742 | /* .SECONDARY with no deps listed marks *all* files that way.  */ | 
|---|
| 743 | else | 
|---|
| 744 | { | 
|---|
| 745 | all_secondary = 1; | 
|---|
| 746 | hash_map (&files, set_intermediate); | 
|---|
| 747 | } | 
|---|
| 748 |  | 
|---|
| 749 | f = lookup_file (".EXPORT_ALL_VARIABLES"); | 
|---|
| 750 | if (f != 0 && f->is_target) | 
|---|
| 751 | export_all_variables = 1; | 
|---|
| 752 |  | 
|---|
| 753 | f = lookup_file (".IGNORE"); | 
|---|
| 754 | if (f != 0 && f->is_target) | 
|---|
| 755 | { | 
|---|
| 756 | if (f->deps == 0) | 
|---|
| 757 | ignore_errors_flag = 1; | 
|---|
| 758 | else | 
|---|
| 759 | for (d = f->deps; d != 0; d = d->next) | 
|---|
| 760 | for (f2 = d->file; f2 != 0; f2 = f2->prev) | 
|---|
| 761 | f2->command_flags |= COMMANDS_NOERROR; | 
|---|
| 762 | } | 
|---|
| 763 |  | 
|---|
| 764 | f = lookup_file (".SILENT"); | 
|---|
| 765 | if (f != 0 && f->is_target) | 
|---|
| 766 | { | 
|---|
| 767 | if (f->deps == 0) | 
|---|
| 768 | silent_flag = 1; | 
|---|
| 769 | else | 
|---|
| 770 | for (d = f->deps; d != 0; d = d->next) | 
|---|
| 771 | for (f2 = d->file; f2 != 0; f2 = f2->prev) | 
|---|
| 772 | f2->command_flags |= COMMANDS_SILENT; | 
|---|
| 773 | } | 
|---|
| 774 |  | 
|---|
| 775 | f = lookup_file (".NOTPARALLEL"); | 
|---|
| 776 | if (f != 0 && f->is_target) | 
|---|
| 777 | #ifndef CONFIG_WITH_EXTENDED_NOTPARALLEL | 
|---|
| 778 | not_parallel = 1; | 
|---|
| 779 | #else /* CONFIG_WITH_EXTENDED_NOTPARALLEL */ | 
|---|
| 780 | { | 
|---|
| 781 | if (f->deps == 0) | 
|---|
| 782 | { | 
|---|
| 783 | DB (DB_KMK, (_("not_parallel -1\n"))); | 
|---|
| 784 | not_parallel = -1; | 
|---|
| 785 | } | 
|---|
| 786 | else | 
|---|
| 787 | for (d = f->deps; d != 0; d = d->next) | 
|---|
| 788 | for (f2 = d->file; f2 != 0; f2 = f2->prev) | 
|---|
| 789 | f2->command_flags |= COMMANDS_NOTPARALLEL; | 
|---|
| 790 | } | 
|---|
| 791 | #endif /* CONFIG_WITH_EXTENDED_NOTPARALLEL */ | 
|---|
| 792 |  | 
|---|
| 793 | #ifndef NO_MINUS_C_MINUS_O | 
|---|
| 794 | /* If .POSIX was defined, remove OUTPUT_OPTION to comply.  */ | 
|---|
| 795 | /* This needs more work: what if the user sets this in the makefile? | 
|---|
| 796 | if (posix_pedantic) | 
|---|
| 797 | define_variable (STRING_SIZE_TUPLE("OUTPUT_OPTION"), "", o_default, 1); | 
|---|
| 798 | */ | 
|---|
| 799 | #endif | 
|---|
| 800 |  | 
|---|
| 801 | /* Remember that we've done this. */ | 
|---|
| 802 | snapped_deps = 1; | 
|---|
| 803 | } | 
|---|
| 804 |  | 
|---|
| 805 |  | 
|---|
| 806 | /* Set the `command_state' member of FILE and all its `also_make's.  */ | 
|---|
| 807 |  | 
|---|
| 808 | void | 
|---|
| 809 | set_command_state (struct file *file, enum cmd_state state) | 
|---|
| 810 | { | 
|---|
| 811 | struct dep *d; | 
|---|
| 812 |  | 
|---|
| 813 | file->command_state = state; | 
|---|
| 814 |  | 
|---|
| 815 | for (d = file->also_make; d != 0; d = d->next) | 
|---|
| 816 | d->file->command_state = state; | 
|---|
| 817 |  | 
|---|
| 818 | #ifdef CONFIG_WITH_EXPLICIT_MULTITARGET | 
|---|
| 819 | if (file->multi_head) | 
|---|
| 820 | for (file = file->multi_head; file != 0; file = file->multi_next) | 
|---|
| 821 | file->command_state = state; | 
|---|
| 822 | #endif | 
|---|
| 823 | } | 
|---|
| 824 |  | 
|---|
| 825 |  | 
|---|
| 826 | /* Convert an external file timestamp to internal form.  */ | 
|---|
| 827 |  | 
|---|
| 828 | FILE_TIMESTAMP | 
|---|
| 829 | file_timestamp_cons (const char *fname, time_t s, int ns) | 
|---|
| 830 | { | 
|---|
| 831 | int offset = ORDINARY_MTIME_MIN + (FILE_TIMESTAMP_HI_RES ? ns : 0); | 
|---|
| 832 | FILE_TIMESTAMP product = (FILE_TIMESTAMP) s << FILE_TIMESTAMP_LO_BITS; | 
|---|
| 833 | FILE_TIMESTAMP ts = product + offset; | 
|---|
| 834 |  | 
|---|
| 835 | if (! (s <= FILE_TIMESTAMP_S (ORDINARY_MTIME_MAX) | 
|---|
| 836 | && product <= ts && ts <= ORDINARY_MTIME_MAX)) | 
|---|
| 837 | { | 
|---|
| 838 | char buf[FILE_TIMESTAMP_PRINT_LEN_BOUND + 1]; | 
|---|
| 839 | ts = s <= OLD_MTIME ? ORDINARY_MTIME_MIN : ORDINARY_MTIME_MAX; | 
|---|
| 840 | file_timestamp_sprintf (buf, ts); | 
|---|
| 841 | error (NILF, _("%s: Timestamp out of range; substituting %s"), | 
|---|
| 842 | fname ? fname : _("Current time"), buf); | 
|---|
| 843 | } | 
|---|
| 844 |  | 
|---|
| 845 | return ts; | 
|---|
| 846 | } | 
|---|
| 847 |  | 
|---|
| 848 |  | 
|---|
| 849 | /* Return the current time as a file timestamp, setting *RESOLUTION to | 
|---|
| 850 | its resolution.  */ | 
|---|
| 851 | FILE_TIMESTAMP | 
|---|
| 852 | file_timestamp_now (int *resolution) | 
|---|
| 853 | { | 
|---|
| 854 | int r; | 
|---|
| 855 | time_t s; | 
|---|
| 856 | int ns; | 
|---|
| 857 |  | 
|---|
| 858 | /* Don't bother with high-resolution clocks if file timestamps have | 
|---|
| 859 | only one-second resolution.  The code below should work, but it's | 
|---|
| 860 | not worth the hassle of debugging it on hosts where it fails.  */ | 
|---|
| 861 | #if FILE_TIMESTAMP_HI_RES | 
|---|
| 862 | # if HAVE_CLOCK_GETTIME && defined CLOCK_REALTIME | 
|---|
| 863 | { | 
|---|
| 864 | struct timespec timespec; | 
|---|
| 865 | if (clock_gettime (CLOCK_REALTIME, ×pec) == 0) | 
|---|
| 866 | { | 
|---|
| 867 | r = 1; | 
|---|
| 868 | s = timespec.tv_sec; | 
|---|
| 869 | ns = timespec.tv_nsec; | 
|---|
| 870 | goto got_time; | 
|---|
| 871 | } | 
|---|
| 872 | } | 
|---|
| 873 | # endif | 
|---|
| 874 | # if HAVE_GETTIMEOFDAY | 
|---|
| 875 | { | 
|---|
| 876 | struct timeval timeval; | 
|---|
| 877 | if (gettimeofday (&timeval, 0) == 0) | 
|---|
| 878 | { | 
|---|
| 879 | r = 1000; | 
|---|
| 880 | s = timeval.tv_sec; | 
|---|
| 881 | ns = timeval.tv_usec * 1000; | 
|---|
| 882 | goto got_time; | 
|---|
| 883 | } | 
|---|
| 884 | } | 
|---|
| 885 | # endif | 
|---|
| 886 | #endif | 
|---|
| 887 |  | 
|---|
| 888 | r = 1000000000; | 
|---|
| 889 | s = time ((time_t *) 0); | 
|---|
| 890 | ns = 0; | 
|---|
| 891 |  | 
|---|
| 892 | #if FILE_TIMESTAMP_HI_RES | 
|---|
| 893 | got_time: | 
|---|
| 894 | #endif | 
|---|
| 895 | *resolution = r; | 
|---|
| 896 | return file_timestamp_cons (0, s, ns); | 
|---|
| 897 | } | 
|---|
| 898 |  | 
|---|
| 899 | /* Place into the buffer P a printable representation of the file | 
|---|
| 900 | timestamp TS.  */ | 
|---|
| 901 | void | 
|---|
| 902 | file_timestamp_sprintf (char *p, FILE_TIMESTAMP ts) | 
|---|
| 903 | { | 
|---|
| 904 | time_t t = FILE_TIMESTAMP_S (ts); | 
|---|
| 905 | struct tm *tm = localtime (&t); | 
|---|
| 906 |  | 
|---|
| 907 | if (tm) | 
|---|
| 908 | sprintf (p, "%04d-%02d-%02d %02d:%02d:%02d", | 
|---|
| 909 | tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, | 
|---|
| 910 | tm->tm_hour, tm->tm_min, tm->tm_sec); | 
|---|
| 911 | else if (t < 0) | 
|---|
| 912 | sprintf (p, "%ld", (long) t); | 
|---|
| 913 | else | 
|---|
| 914 | sprintf (p, "%lu", (unsigned long) t); | 
|---|
| 915 | p += strlen (p); | 
|---|
| 916 |  | 
|---|
| 917 | /* Append nanoseconds as a fraction, but remove trailing zeros.  We don't | 
|---|
| 918 | know the actual timestamp resolution, since clock_getres applies only to | 
|---|
| 919 | local times, whereas this timestamp might come from a remote filesystem. | 
|---|
| 920 | So removing trailing zeros is the best guess that we can do.  */ | 
|---|
| 921 | sprintf (p, ".%09d", FILE_TIMESTAMP_NS (ts)); | 
|---|
| 922 | p += strlen (p) - 1; | 
|---|
| 923 | while (*p == '0') | 
|---|
| 924 | p--; | 
|---|
| 925 | p += *p != '.'; | 
|---|
| 926 |  | 
|---|
| 927 | *p = '\0'; | 
|---|
| 928 | } | 
|---|
| 929 |  | 
|---|
| 930 |  | 
|---|
| 931 | /* Print the data base of files.  */ | 
|---|
| 932 |  | 
|---|
| 933 | static void | 
|---|
| 934 | print_file (const void *item) | 
|---|
| 935 | { | 
|---|
| 936 | const struct file *f = item; | 
|---|
| 937 | struct dep *d; | 
|---|
| 938 | struct dep *ood = 0; | 
|---|
| 939 |  | 
|---|
| 940 | putchar ('\n'); | 
|---|
| 941 | if (!f->is_target) | 
|---|
| 942 | puts (_("# Not a target:")); | 
|---|
| 943 | #ifdef CONFIG_WITH_EXPLICIT_MULTITARGET | 
|---|
| 944 | if (f->multi_head) | 
|---|
| 945 | { | 
|---|
| 946 | const struct file *f2; | 
|---|
| 947 | if (f->multi_head == f) | 
|---|
| 948 | { | 
|---|
| 949 | int multi_maybe = -1; | 
|---|
| 950 | assert (!f->multi_maybe); | 
|---|
| 951 | assert (!f->double_colon); | 
|---|
| 952 |  | 
|---|
| 953 | printf ("%s", f->name); | 
|---|
| 954 | for (f2 = f->multi_next; f2 != 0; f2 = f2->multi_next) | 
|---|
| 955 | { | 
|---|
| 956 | printf (" %s%s", f2->multi_maybe != multi_maybe | 
|---|
| 957 | ? f2->multi_maybe ? "+| " : "+ " : "", | 
|---|
| 958 | f2->name); | 
|---|
| 959 | multi_maybe = f2->multi_maybe; | 
|---|
| 960 | } | 
|---|
| 961 | putchar (':'); | 
|---|
| 962 | } | 
|---|
| 963 | else | 
|---|
| 964 | printf ("%s:%s", f->name, f->double_colon ? ":" : ""); | 
|---|
| 965 | } | 
|---|
| 966 | else | 
|---|
| 967 | #endif | 
|---|
| 968 | printf ("%s:%s", f->name, f->double_colon ? ":" : ""); | 
|---|
| 969 |  | 
|---|
| 970 | /* Print all normal dependencies; note any order-only deps.  */ | 
|---|
| 971 | for (d = f->deps; d != 0; d = d->next) | 
|---|
| 972 | if (! d->ignore_mtime) | 
|---|
| 973 | printf (" %s", dep_name (d)); | 
|---|
| 974 | else if (! ood) | 
|---|
| 975 | ood = d; | 
|---|
| 976 |  | 
|---|
| 977 | /* Print order-only deps, if we have any.  */ | 
|---|
| 978 | if (ood) | 
|---|
| 979 | { | 
|---|
| 980 | printf (" | %s", dep_name (ood)); | 
|---|
| 981 | for (d = ood->next; d != 0; d = d->next) | 
|---|
| 982 | if (d->ignore_mtime) | 
|---|
| 983 | printf (" %s", dep_name (d)); | 
|---|
| 984 | } | 
|---|
| 985 |  | 
|---|
| 986 | putchar ('\n'); | 
|---|
| 987 |  | 
|---|
| 988 | #ifdef CONFIG_WITH_EXPLICIT_MULTITARGET | 
|---|
| 989 | if (f->multi_head && f->multi_head != f) | 
|---|
| 990 | { | 
|---|
| 991 | const struct file *f2; | 
|---|
| 992 | fputs (_("#  In multi target list:"), stdout); | 
|---|
| 993 | for (f2 = f->multi_head; f2 != 0; f2 = f2->multi_next) | 
|---|
| 994 | printf (" %s%s", f2->name, f == f2 ? "(*)" : ""); | 
|---|
| 995 | putchar ('\n'); | 
|---|
| 996 | if (f->multi_maybe) | 
|---|
| 997 | puts (_("#  File is an optional multi target member.")); | 
|---|
| 998 | } | 
|---|
| 999 | #endif | 
|---|
| 1000 |  | 
|---|
| 1001 | if (f->precious) | 
|---|
| 1002 | puts (_("#  Precious file (prerequisite of .PRECIOUS).")); | 
|---|
| 1003 | if (f->phony) | 
|---|
| 1004 | puts (_("#  Phony target (prerequisite of .PHONY).")); | 
|---|
| 1005 | if (f->cmd_target) | 
|---|
| 1006 | puts (_("#  Command-line target.")); | 
|---|
| 1007 | if (f->dontcare) | 
|---|
| 1008 | puts (_("#  A default, MAKEFILES, or -include/sinclude makefile.")); | 
|---|
| 1009 | puts (f->tried_implicit | 
|---|
| 1010 | ? _("#  Implicit rule search has been done.") | 
|---|
| 1011 | : _("#  Implicit rule search has not been done.")); | 
|---|
| 1012 | if (f->stem != 0) | 
|---|
| 1013 | printf (_("#  Implicit/static pattern stem: `%s'\n"), f->stem); | 
|---|
| 1014 | if (f->intermediate) | 
|---|
| 1015 | puts (_("#  File is an intermediate prerequisite.")); | 
|---|
| 1016 | if (f->also_make != 0) | 
|---|
| 1017 | { | 
|---|
| 1018 | fputs (_("#  Also makes:"), stdout); | 
|---|
| 1019 | for (d = f->also_make; d != 0; d = d->next) | 
|---|
| 1020 | printf (" %s", dep_name (d)); | 
|---|
| 1021 | putchar ('\n'); | 
|---|
| 1022 | } | 
|---|
| 1023 | if (f->last_mtime == UNKNOWN_MTIME) | 
|---|
| 1024 | puts (_("#  Modification time never checked.")); | 
|---|
| 1025 | else if (f->last_mtime == NONEXISTENT_MTIME) | 
|---|
| 1026 | puts (_("#  File does not exist.")); | 
|---|
| 1027 | else if (f->last_mtime == OLD_MTIME) | 
|---|
| 1028 | puts (_("#  File is very old.")); | 
|---|
| 1029 | else | 
|---|
| 1030 | { | 
|---|
| 1031 | char buf[FILE_TIMESTAMP_PRINT_LEN_BOUND + 1]; | 
|---|
| 1032 | file_timestamp_sprintf (buf, f->last_mtime); | 
|---|
| 1033 | printf (_("#  Last modified %s\n"), buf); | 
|---|
| 1034 | } | 
|---|
| 1035 | puts (f->updated | 
|---|
| 1036 | ? _("#  File has been updated.") : _("#  File has not been updated.")); | 
|---|
| 1037 | switch (f->command_state) | 
|---|
| 1038 | { | 
|---|
| 1039 | case cs_running: | 
|---|
| 1040 | puts (_("#  Commands currently running (THIS IS A BUG).")); | 
|---|
| 1041 | break; | 
|---|
| 1042 | case cs_deps_running: | 
|---|
| 1043 | puts (_("#  Dependencies commands running (THIS IS A BUG).")); | 
|---|
| 1044 | break; | 
|---|
| 1045 | case cs_not_started: | 
|---|
| 1046 | case cs_finished: | 
|---|
| 1047 | switch (f->update_status) | 
|---|
| 1048 | { | 
|---|
| 1049 | case -1: | 
|---|
| 1050 | break; | 
|---|
| 1051 | case 0: | 
|---|
| 1052 | puts (_("#  Successfully updated.")); | 
|---|
| 1053 | break; | 
|---|
| 1054 | case 1: | 
|---|
| 1055 | assert (question_flag); | 
|---|
| 1056 | puts (_("#  Needs to be updated (-q is set).")); | 
|---|
| 1057 | break; | 
|---|
| 1058 | case 2: | 
|---|
| 1059 | puts (_("#  Failed to be updated.")); | 
|---|
| 1060 | break; | 
|---|
| 1061 | default: | 
|---|
| 1062 | puts (_("#  Invalid value in `update_status' member!")); | 
|---|
| 1063 | fflush (stdout); | 
|---|
| 1064 | fflush (stderr); | 
|---|
| 1065 | abort (); | 
|---|
| 1066 | } | 
|---|
| 1067 | break; | 
|---|
| 1068 | default: | 
|---|
| 1069 | puts (_("#  Invalid value in `command_state' member!")); | 
|---|
| 1070 | fflush (stdout); | 
|---|
| 1071 | fflush (stderr); | 
|---|
| 1072 | abort (); | 
|---|
| 1073 | } | 
|---|
| 1074 |  | 
|---|
| 1075 | if (f->variables != 0) | 
|---|
| 1076 | print_file_variables (f); | 
|---|
| 1077 |  | 
|---|
| 1078 | if (f->cmds != 0) | 
|---|
| 1079 | print_commands (f->cmds); | 
|---|
| 1080 |  | 
|---|
| 1081 | if (f->prev) | 
|---|
| 1082 | print_file ((const void *) f->prev); | 
|---|
| 1083 | } | 
|---|
| 1084 |  | 
|---|
| 1085 | void | 
|---|
| 1086 | print_file_data_base (void) | 
|---|
| 1087 | { | 
|---|
| 1088 | puts (_("\n# Files")); | 
|---|
| 1089 |  | 
|---|
| 1090 | hash_map (&files, print_file); | 
|---|
| 1091 |  | 
|---|
| 1092 | fputs (_("\n# files hash-table stats:\n# "), stdout); | 
|---|
| 1093 | hash_print_stats (&files, stdout); | 
|---|
| 1094 | } | 
|---|
| 1095 |  | 
|---|
| 1096 |  | 
|---|
| 1097 | /* Verify the integrity of the data base of files.  */ | 
|---|
| 1098 |  | 
|---|
| 1099 | #define VERIFY_CACHED(_p,_n) \ | 
|---|
| 1100 | do{\ | 
|---|
| 1101 | if (_p->_n && _p->_n[0] && !strcache_iscached (_p->_n)) \ | 
|---|
| 1102 | printf ("%s: Field %s not cached: %s\n", _p->name, # _n, _p->_n); \ | 
|---|
| 1103 | }while(0) | 
|---|
| 1104 |  | 
|---|
| 1105 | static void | 
|---|
| 1106 | verify_file (const void *item) | 
|---|
| 1107 | { | 
|---|
| 1108 | const struct file *f = item; | 
|---|
| 1109 | const struct dep *d; | 
|---|
| 1110 |  | 
|---|
| 1111 | VERIFY_CACHED (f, name); | 
|---|
| 1112 | VERIFY_CACHED (f, hname); | 
|---|
| 1113 | VERIFY_CACHED (f, vpath); | 
|---|
| 1114 | VERIFY_CACHED (f, stem); | 
|---|
| 1115 |  | 
|---|
| 1116 | /* Check the deps.  */ | 
|---|
| 1117 | for (d = f->deps; d != 0; d = d->next) | 
|---|
| 1118 | { | 
|---|
| 1119 | VERIFY_CACHED (d, name); | 
|---|
| 1120 | VERIFY_CACHED (d, stem); | 
|---|
| 1121 | } | 
|---|
| 1122 | } | 
|---|
| 1123 |  | 
|---|
| 1124 | void | 
|---|
| 1125 | verify_file_data_base (void) | 
|---|
| 1126 | { | 
|---|
| 1127 | hash_map (&files, verify_file); | 
|---|
| 1128 | } | 
|---|
| 1129 |  | 
|---|
| 1130 | #define EXPANSION_INCREMENT(_l)  ((((_l) / 500) + 1) * 500) | 
|---|
| 1131 |  | 
|---|
| 1132 | char * | 
|---|
| 1133 | build_target_list (char *value) | 
|---|
| 1134 | { | 
|---|
| 1135 | static unsigned long last_targ_count = 0; | 
|---|
| 1136 |  | 
|---|
| 1137 | if (files.ht_fill != last_targ_count) | 
|---|
| 1138 | { | 
|---|
| 1139 | unsigned long max = EXPANSION_INCREMENT (strlen (value)); | 
|---|
| 1140 | unsigned long len; | 
|---|
| 1141 | char *p; | 
|---|
| 1142 | struct file **fp = (struct file **) files.ht_vec; | 
|---|
| 1143 | struct file **end = &fp[files.ht_size]; | 
|---|
| 1144 |  | 
|---|
| 1145 | /* Make sure we have at least MAX bytes in the allocated buffer.  */ | 
|---|
| 1146 | value = xrealloc (value, max); | 
|---|
| 1147 |  | 
|---|
| 1148 | p = value; | 
|---|
| 1149 | len = 0; | 
|---|
| 1150 | for (; fp < end; ++fp) | 
|---|
| 1151 | if (!HASH_VACANT (*fp) && (*fp)->is_target) | 
|---|
| 1152 | { | 
|---|
| 1153 | struct file *f = *fp; | 
|---|
| 1154 | int l = strlen (f->name); | 
|---|
| 1155 |  | 
|---|
| 1156 | len += l + 1; | 
|---|
| 1157 | if (len > max) | 
|---|
| 1158 | { | 
|---|
| 1159 | unsigned long off = p - value; | 
|---|
| 1160 |  | 
|---|
| 1161 | max += EXPANSION_INCREMENT (l + 1); | 
|---|
| 1162 | value = xrealloc (value, max); | 
|---|
| 1163 | p = &value[off]; | 
|---|
| 1164 | } | 
|---|
| 1165 |  | 
|---|
| 1166 | memcpy (p, f->name, l); | 
|---|
| 1167 | p += l; | 
|---|
| 1168 | *(p++) = ' '; | 
|---|
| 1169 | } | 
|---|
| 1170 | *(p-1) = '\0'; | 
|---|
| 1171 |  | 
|---|
| 1172 | last_targ_count = files.ht_fill; | 
|---|
| 1173 | } | 
|---|
| 1174 |  | 
|---|
| 1175 | return value; | 
|---|
| 1176 | } | 
|---|
| 1177 |  | 
|---|
| 1178 | void | 
|---|
| 1179 | init_hash_files (void) | 
|---|
| 1180 | { | 
|---|
| 1181 | #ifdef KMK | 
|---|
| 1182 | hash_init (&files, 8192, file_hash_1, file_hash_2, file_hash_cmp); | 
|---|
| 1183 | #else | 
|---|
| 1184 | hash_init (&files, 1000, file_hash_1, file_hash_2, file_hash_cmp); | 
|---|
| 1185 | #endif | 
|---|
| 1186 | } | 
|---|
| 1187 |  | 
|---|
| 1188 | /* EOF */ | 
|---|