VirtualBox

source: kBuild/vendor/gnumake/3.82-cvs/file.c

Last change on this file was 2580, checked in by bird, 12 years ago

Importing the make-3-82 CVS tag with --auto-props but no keywords.

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

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette