~ubuntu-branches/ubuntu/utopic/gridengine/utopic

« back to all changes in this revision

Viewing changes to source/3rdparty/qmake/file.c

  • Committer: Bazaar Package Importer
  • Author(s): Mark Hymers
  • Date: 2008-06-25 22:36:13 UTC
  • Revision ID: james.westby@ubuntu.com-20080625223613-tvd9xlhuoct9kyhm
Tags: upstream-6.2~beta2
ImportĀ upstreamĀ versionĀ 6.2~beta2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Target file hash table management for GNU Make.
 
2
Copyright (C) 1988,89,90,91,92,93,94,95,96,97 Free Software Foundation, Inc.
 
3
This file is part of GNU Make.
 
4
 
 
5
GNU Make is free software; you can redistribute it and/or modify
 
6
it under the terms of the GNU General Public License as published by
 
7
the Free Software Foundation; either version 2, or (at your option)
 
8
any later version.
 
9
 
 
10
GNU Make is distributed in the hope that it will be useful,
 
11
but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
GNU General Public License for more details.
 
14
 
 
15
You should have received a copy of the GNU General Public License
 
16
along with GNU Make; see the file COPYING.  If not, write to
 
17
the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 
18
Boston, MA 02111-1307, USA.  */
 
19
 
 
20
#include <assert.h>
 
21
 
 
22
#include "make.h"
 
23
#include "dep.h"
 
24
#include "filedef.h"
 
25
#include "job.h"
 
26
#include "commands.h"
 
27
#include "variable.h"
 
28
 
 
29
 
 
30
/* Hash table of files the makefile knows how to make.  */
 
31
 
 
32
#ifndef FILE_BUCKETS
 
33
#define FILE_BUCKETS    1007
 
34
#endif
 
35
static struct file *files[FILE_BUCKETS];
 
36
 
 
37
/* Number of files with the `intermediate' flag set.  */
 
38
 
 
39
unsigned int num_intermediates = 0;
 
40
 
 
41
/* Current value for pruning the scan of the goal chain (toggle 0/1).  */
 
42
 
 
43
unsigned int considered = 0;
 
44
 
 
45
/* Access the hash table of all file records.
 
46
   lookup_file  given a name, return the struct file * for that name,
 
47
           or nil if there is none.
 
48
   enter_file   similar, but create one if there is none.  */
 
49
 
 
50
struct file *
 
51
lookup_file (name)
 
52
     char *name;
 
53
{
 
54
  register struct file *f;
 
55
  register char *n;
 
56
  register unsigned int hashval;
 
57
#ifdef VMS
 
58
  register char *lname, *ln;
 
59
#endif
 
60
 
 
61
  if (*name == '\0')
 
62
    abort ();
 
63
 
 
64
  /* This is also done in parse_file_seq, so this is redundant
 
65
     for names read from makefiles.  It is here for names passed
 
66
     on the command line.  */
 
67
#ifdef VMS
 
68
  lname = (char *)malloc(strlen(name) + 1);
 
69
  for (n=name, ln=lname; *n != '\0'; ++n, ++ln)
 
70
    *ln = isupper(*n) ? tolower(*n) : *n;
 
71
  *ln = '\0';
 
72
  name = lname;
 
73
 
 
74
  while (name[0] == '[' && name[1] == ']' && name[2] != '\0')
 
75
      name += 2;
 
76
#endif
 
77
  while (name[0] == '.' && name[1] == '/' && name[2] != '\0')
 
78
    {
 
79
      name += 2;
 
80
      while (*name == '/')
 
81
        /* Skip following slashes: ".//foo" is "foo", not "/foo".  */
 
82
        ++name;
 
83
    }
 
84
 
 
85
  if (*name == '\0')
 
86
    /* It was all slashes after a dot.  */
 
87
#ifdef VMS
 
88
    name = "[]";
 
89
#else
 
90
#ifdef _AMIGA
 
91
    name = "";
 
92
#else
 
93
    name = "./";
 
94
#endif /* AMIGA */
 
95
#endif /* VMS */
 
96
 
 
97
  hashval = 0;
 
98
  for (n = name; *n != '\0'; ++n)
 
99
    HASHI (hashval, *n);
 
100
  hashval %= FILE_BUCKETS;
 
101
 
 
102
  for (f = files[hashval]; f != 0; f = f->next)
 
103
    {
 
104
      if (strieq (f->hname, name))
 
105
        {
 
106
#ifdef VMS
 
107
          free (lname);
 
108
#endif
 
109
          return f;
 
110
        }
 
111
    }
 
112
#ifdef VMS
 
113
  free (lname);
 
114
#endif
 
115
  return 0;
 
116
}
 
117
 
 
118
struct file *
 
119
enter_file (name)
 
120
     char *name;
 
121
{
 
122
  register struct file *f, *new;
 
123
  register char *n;
 
124
  register unsigned int hashval;
 
125
#ifdef VMS
 
126
  char *lname, *ln;
 
127
#endif
 
128
 
 
129
  if (*name == '\0')
 
130
    abort ();
 
131
 
 
132
#ifdef VMS
 
133
  lname = (char *)malloc (strlen (name) + 1);
 
134
  for (n = name, ln = lname; *n != '\0'; ++n, ++ln)
 
135
    {
 
136
      if (isupper(*n))
 
137
        *ln = tolower(*n);
 
138
      else
 
139
        *ln = *n;
 
140
    }
 
141
  *ln = 0;
 
142
  name = lname;
 
143
#endif
 
144
 
 
145
  hashval = 0;
 
146
  for (n = name; *n != '\0'; ++n)
 
147
    HASHI (hashval, *n);
 
148
  hashval %= FILE_BUCKETS;
 
149
 
 
150
  for (f = files[hashval]; f != 0; f = f->next)
 
151
    if (strieq (f->hname, name))
 
152
      break;
 
153
 
 
154
  if (f != 0 && !f->double_colon)
 
155
    {
 
156
#ifdef VMS
 
157
      free(lname);
 
158
#endif
 
159
      return f;
 
160
    }
 
161
 
 
162
  new = (struct file *) xmalloc (sizeof (struct file));
 
163
  bzero ((char *) new, sizeof (struct file));
 
164
  new->name = new->hname = name;
 
165
  new->update_status = -1;
 
166
 
 
167
  if (f == 0)
 
168
    {
 
169
      /* This is a completely new file.  */
 
170
      new->next = files[hashval];
 
171
      files[hashval] = new;
 
172
    }
 
173
  else
 
174
    {
 
175
      /* There is already a double-colon entry for this file.  */
 
176
      new->double_colon = f;
 
177
      while (f->prev != 0)
 
178
        f = f->prev;
 
179
      f->prev = new;
 
180
    }
 
181
 
 
182
  return new;
 
183
}
 
184
 
 
185
/* Rehash FILE to NAME.  This is not as simple as resetting
 
186
   the `hname' member, since it must be put in a new hash bucket,
 
187
   and possibly merged with an existing file called NAME.  */
 
188
 
 
189
void
 
190
rehash_file (file, name)
 
191
     register struct file *file;
 
192
     char *name;
 
193
{
 
194
  char *oldname = file->hname;
 
195
  register unsigned int oldhash;
 
196
  register char *n;
 
197
 
 
198
  while (file->renamed != 0)
 
199
    file = file->renamed;
 
200
 
 
201
  /* Find the hash values of the old and new names.  */
 
202
 
 
203
  oldhash = 0;
 
204
  for (n = oldname; *n != '\0'; ++n)
 
205
    HASHI (oldhash, *n);
 
206
 
 
207
  file_hash_enter (file, name, oldhash, file->name);
 
208
}
 
209
 
 
210
/* Rename FILE to NAME.  This is not as simple as resetting
 
211
   the `name' member, since it must be put in a new hash bucket,
 
212
   and possibly merged with an existing file called NAME.  */
 
213
 
 
214
void
 
215
rename_file (file, name)
 
216
     register struct file *file;
 
217
     char *name;
 
218
{
 
219
  rehash_file(file, name);
 
220
  while (file)
 
221
    {
 
222
      file->name = file->hname;
 
223
      file = file->prev;
 
224
    }
 
225
}
 
226
 
 
227
void
 
228
file_hash_enter (file, name, oldhash, oldname)
 
229
     register struct file *file;
 
230
     char *name;
 
231
     unsigned int oldhash;
 
232
     char *oldname;
 
233
{
 
234
  unsigned int oldbucket = oldhash % FILE_BUCKETS;
 
235
  register unsigned int newhash, newbucket;
 
236
  struct file *oldfile;
 
237
  register char *n;
 
238
  register struct file *f;
 
239
 
 
240
  newhash = 0;
 
241
  for (n = name; *n != '\0'; ++n)
 
242
    HASHI (newhash, *n);
 
243
  newbucket = newhash % FILE_BUCKETS;
 
244
 
 
245
  /* Look for an existing file under the new name.  */
 
246
 
 
247
  for (oldfile = files[newbucket]; oldfile != 0; oldfile = oldfile->next)
 
248
    if (strieq (oldfile->hname, name))
 
249
      break;
 
250
 
 
251
  /* If the old file is the same as the new file, something's wrong.  */
 
252
  assert (oldfile != file);
 
253
 
 
254
  if (oldhash != 0 && (newbucket != oldbucket || oldfile != 0))
 
255
    {
 
256
      /* Remove FILE from its hash bucket.  */
 
257
 
 
258
      struct file *lastf = 0;
 
259
 
 
260
      for (f = files[oldbucket]; f != file; f = f->next)
 
261
        lastf = f;
 
262
 
 
263
      if (lastf == 0)
 
264
        files[oldbucket] = f->next;
 
265
      else
 
266
        lastf->next = f->next;
 
267
    }
 
268
 
 
269
  /* Give FILE its new name.  */
 
270
 
 
271
  file->hname = name;
 
272
  for (f = file->double_colon; f != 0; f = f->prev)
 
273
    f->hname = name;
 
274
 
 
275
  if (oldfile == 0)
 
276
    {
 
277
      /* There is no existing file with the new name.  */
 
278
 
 
279
      if (newbucket != oldbucket)
 
280
        {
 
281
          /* Put FILE in its new hash bucket.  */
 
282
          file->next = files[newbucket];
 
283
          files[newbucket] = file;
 
284
        }
 
285
    }
 
286
  else
 
287
    {
 
288
      /* There is an existing file with the new name.
 
289
         We must merge FILE into the existing file.  */
 
290
 
 
291
      register struct dep *d;
 
292
 
 
293
      if (file->cmds != 0)
 
294
        {
 
295
          if (oldfile->cmds == 0)
 
296
            oldfile->cmds = file->cmds;
 
297
          else if (file->cmds != oldfile->cmds)
 
298
            {
 
299
              /* We have two sets of commands.  We will go with the
 
300
                 one given in the rule explicitly mentioning this name,
 
301
                 but give a message to let the user know what's going on.  */
 
302
              if (oldfile->cmds->fileinfo.filenm != 0)
 
303
                error (&file->cmds->fileinfo,
 
304
                                _("Commands were specified for \
 
305
file `%s' at %s:%lu,"),
 
306
                                oldname, oldfile->cmds->fileinfo.filenm,
 
307
                                oldfile->cmds->fileinfo.lineno);
 
308
              else
 
309
                error (&file->cmds->fileinfo,
 
310
                                _("Commands for file `%s' were found by \
 
311
implicit rule search,"),
 
312
                                oldname);
 
313
              error (&file->cmds->fileinfo,
 
314
                              _("but `%s' is now considered the same file \
 
315
as `%s'."),
 
316
                              oldname, name);
 
317
              error (&file->cmds->fileinfo,
 
318
                              _("Commands for `%s' will be ignored \
 
319
in favor of those for `%s'."),
 
320
                              name, oldname);
 
321
            }
 
322
        }
 
323
 
 
324
      /* Merge the dependencies of the two files.  */
 
325
 
 
326
      d = oldfile->deps;
 
327
      if (d == 0)
 
328
        oldfile->deps = file->deps;
 
329
      else
 
330
        {
 
331
          while (d->next != 0)
 
332
            d = d->next;
 
333
          d->next = file->deps;
 
334
        }
 
335
 
 
336
      merge_variable_set_lists (&oldfile->variables, file->variables);
 
337
 
 
338
      if (oldfile->double_colon && file->is_target && !file->double_colon)
 
339
        fatal (NILF, _("can't rename single-colon `%s' to double-colon `%s'"),
 
340
               oldname, name);
 
341
      if (!oldfile->double_colon  && file->double_colon)
 
342
        {
 
343
          if (oldfile->is_target)
 
344
            fatal (NILF, _("can't rename double-colon `%s' to single-colon `%s'"),
 
345
                   oldname, name);
 
346
          else
 
347
            oldfile->double_colon = file->double_colon;
 
348
        }
 
349
 
 
350
      if (file->last_mtime > oldfile->last_mtime)
 
351
        /* %%% Kludge so -W wins on a file that gets vpathized.  */
 
352
        oldfile->last_mtime = file->last_mtime;
 
353
 
 
354
      oldfile->mtime_before_update = file->mtime_before_update;
 
355
 
 
356
#define MERGE(field) oldfile->field |= file->field
 
357
      MERGE (precious);
 
358
      MERGE (tried_implicit);
 
359
      MERGE (updating);
 
360
      MERGE (updated);
 
361
      MERGE (is_target);
 
362
      MERGE (cmd_target);
 
363
      MERGE (phony);
 
364
      MERGE (ignore_vpath);
 
365
#undef MERGE
 
366
 
 
367
      file->renamed = oldfile;
 
368
    }
 
369
}
 
370
 
 
371
/* Remove all nonprecious intermediate files.
 
372
   If SIG is nonzero, this was caused by a fatal signal,
 
373
   meaning that a different message will be printed, and
 
374
   the message will go to stderr rather than stdout.  */
 
375
 
 
376
void
 
377
remove_intermediates (sig)
 
378
     int sig;
 
379
{
 
380
  register int i;
 
381
  register struct file *f;
 
382
  char doneany;
 
383
 
 
384
  if (question_flag || touch_flag)
 
385
    return;
 
386
  if (sig && just_print_flag)
 
387
    return;
 
388
 
 
389
  doneany = 0;
 
390
  for (i = 0; i < FILE_BUCKETS; ++i)
 
391
    for (f = files[i]; f != 0; f = f->next)
 
392
      if (f->intermediate && (f->dontcare || !f->precious)
 
393
          && !f->secondary)
 
394
        {
 
395
          int status;
 
396
          if (f->update_status == -1)
 
397
            /* If nothing would have created this file yet,
 
398
               don't print an "rm" command for it.  */
 
399
            continue;
 
400
          else if (just_print_flag)
 
401
            status = 0;
 
402
          else
 
403
            {
 
404
              status = unlink (f->name);
 
405
              if (status < 0 && errno == ENOENT)
 
406
                continue;
 
407
            }
 
408
          if (!f->dontcare)
 
409
            {
 
410
              if (sig)
 
411
                error (NILF, _("*** Deleting intermediate file `%s'"), f->name);
 
412
              else if (!silent_flag)
 
413
                {
 
414
                  if (! doneany)
 
415
                    {
 
416
                      fputs ("rm ", stdout);
 
417
                      doneany = 1;
 
418
                    }
 
419
                  else
 
420
                    putchar (' ');
 
421
                  fputs (f->name, stdout);
 
422
                  fflush (stdout);
 
423
                }
 
424
              if (status < 0)
 
425
                perror_with_name ("unlink: ", f->name);
 
426
            }
 
427
        }
 
428
 
 
429
  if (doneany && !sig)
 
430
    {
 
431
      putchar ('\n');
 
432
      fflush (stdout);
 
433
    }
 
434
}
 
435
 
 
436
/* For each dependency of each file, make the `struct dep' point
 
437
   at the appropriate `struct file' (which may have to be created).
 
438
 
 
439
   Also mark the files depended on by .PRECIOUS, .PHONY, .SILENT,
 
440
   and various other special targets.  */
 
441
 
 
442
void
 
443
snap_deps ()
 
444
{
 
445
  register struct file *f, *f2;
 
446
  register struct dep *d;
 
447
  register int i;
 
448
 
 
449
  /* Enter each dependency name as a file.  */
 
450
  for (i = 0; i < FILE_BUCKETS; ++i)
 
451
    for (f = files[i]; f != 0; f = f->next)
 
452
      for (f2 = f; f2 != 0; f2 = f2->prev)
 
453
        for (d = f2->deps; d != 0; d = d->next)
 
454
          if (d->name != 0)
 
455
            {
 
456
              d->file = lookup_file (d->name);
 
457
              if (d->file == 0)
 
458
                d->file = enter_file (d->name);
 
459
              else
 
460
                free (d->name);
 
461
              d->name = 0;
 
462
            }
 
463
 
 
464
  for (f = lookup_file (".PRECIOUS"); f != 0; f = f->prev)
 
465
    for (d = f->deps; d != 0; d = d->next)
 
466
      for (f2 = d->file; f2 != 0; f2 = f2->prev)
 
467
        f2->precious = 1;
 
468
 
 
469
  for (f = lookup_file (".PHONY"); f != 0; f = f->prev)
 
470
    for (d = f->deps; d != 0; d = d->next)
 
471
      for (f2 = d->file; f2 != 0; f2 = f2->prev)
 
472
        {
 
473
          /* Mark this file as phony and nonexistent.  */
 
474
          f2->phony = 1;
 
475
          f2->last_mtime = (FILE_TIMESTAMP) -1;
 
476
          f2->mtime_before_update = (FILE_TIMESTAMP) -1;
 
477
        }
 
478
 
 
479
  for (f = lookup_file (".INTERMEDIATE"); f != 0; f = f->prev)
 
480
    {
 
481
      /* .INTERMEDIATE with deps listed
 
482
         marks those deps as intermediate files.  */
 
483
      for (d = f->deps; d != 0; d = d->next)
 
484
        for (f2 = d->file; f2 != 0; f2 = f2->prev)
 
485
          f2->intermediate = 1;
 
486
      /* .INTERMEDIATE with no deps does nothing.
 
487
         Marking all files as intermediates is useless
 
488
         since the goal targets would be deleted after they are built.  */
 
489
    }
 
490
 
 
491
  for (f = lookup_file (".SECONDARY"); f != 0; f = f->prev)
 
492
    {
 
493
      /* .SECONDARY with deps listed
 
494
         marks those deps as intermediate files
 
495
         in that they don't get rebuilt if not actually needed;
 
496
         but unlike real intermediate files,
 
497
         these are not deleted after make finishes.  */
 
498
      if (f->deps)
 
499
        {
 
500
          for (d = f->deps; d != 0; d = d->next)
 
501
            for (f2 = d->file; f2 != 0; f2 = f2->prev)
 
502
              f2->intermediate = f2->secondary = 1;
 
503
        }
 
504
      /* .SECONDARY with no deps listed marks *all* files that way.  */
 
505
      else
 
506
        {
 
507
          int i;
 
508
          for (i = 0; i < FILE_BUCKETS; i++)
 
509
            for (f2 = files[i]; f2; f2= f2->next)
 
510
              f2->intermediate = f2->secondary = 1;
 
511
        }
 
512
    }
 
513
 
 
514
  f = lookup_file (".EXPORT_ALL_VARIABLES");
 
515
  if (f != 0 && f->is_target)
 
516
    export_all_variables = 1;
 
517
 
 
518
  f = lookup_file (".IGNORE");
 
519
  if (f != 0 && f->is_target)
 
520
    {
 
521
      if (f->deps == 0)
 
522
        ignore_errors_flag = 1;
 
523
      else
 
524
        for (d = f->deps; d != 0; d = d->next)
 
525
          for (f2 = d->file; f2 != 0; f2 = f2->prev)
 
526
            f2->command_flags |= COMMANDS_NOERROR;
 
527
    }
 
528
 
 
529
  f = lookup_file (".SILENT");
 
530
  if (f != 0 && f->is_target)
 
531
    {
 
532
      if (f->deps == 0)
 
533
        silent_flag = 1;
 
534
      else
 
535
        for (d = f->deps; d != 0; d = d->next)
 
536
          for (f2 = d->file; f2 != 0; f2 = f2->prev)
 
537
            f2->command_flags |= COMMANDS_SILENT;
 
538
    }
 
539
 
 
540
  f = lookup_file (".POSIX");
 
541
  if (f != 0 && f->is_target)
 
542
    posix_pedantic = 1;
 
543
}
 
544
 
 
545
/* Set the `command_state' member of FILE and all its `also_make's.  */
 
546
 
 
547
void
 
548
set_command_state (file, state)
 
549
     struct file *file;
 
550
     int state;
 
551
{
 
552
  struct dep *d;
 
553
 
 
554
  file->command_state = state;
 
555
 
 
556
  for (d = file->also_make; d != 0; d = d->next)
 
557
    d->file->command_state = state;
 
558
}
 
559
 
 
560
/* Get and print file timestamps.  */
 
561
 
 
562
FILE_TIMESTAMP
 
563
file_timestamp_now ()
 
564
{
 
565
#if HAVE_CLOCK_GETTIME && defined CLOCK_REALTIME
 
566
  struct timespec timespec;
 
567
  if (clock_gettime (CLOCK_REALTIME, &timespec) == 0)
 
568
    return FILE_TIMESTAMP_FROM_S_AND_NS (timespec.tv_sec, timespec.tv_nsec);
 
569
#endif
 
570
  return FILE_TIMESTAMP_FROM_S_AND_NS (time ((time_t *) 0), 0);
 
571
}
 
572
 
 
573
void
 
574
file_timestamp_sprintf (p, ts)
 
575
     char *p;
 
576
     FILE_TIMESTAMP ts;
 
577
{
 
578
  time_t t = FILE_TIMESTAMP_S (ts);
 
579
  struct tm *tm = localtime (&t);
 
580
 
 
581
  if (tm)
 
582
    sprintf (p, "%04d-%02d-%02d %02d:%02d:%02d",
 
583
             tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
 
584
             tm->tm_hour, tm->tm_min, tm->tm_sec);
 
585
  else if (t < 0)
 
586
    sprintf (p, "%ld", (long) t);
 
587
  else
 
588
    sprintf (p, "%lu", (unsigned long) t);
 
589
  p += strlen (p);
 
590
 
 
591
  /* Append nanoseconds as a fraction, but remove trailing zeros.
 
592
     We don't know the actual timestamp resolution, since clock_getres
 
593
     applies only to local times, whereas this timestamp might come
 
594
     from a remote filesystem.  So removing trailing zeros is the
 
595
     best guess that we can do.  */
 
596
  sprintf (p, ".%09ld", (long) FILE_TIMESTAMP_NS (ts));
 
597
  p += strlen (p) - 1;
 
598
  while (*p == '0')
 
599
    p--;
 
600
  p += *p != '.';
 
601
 
 
602
  *p = '\0';
 
603
}
 
604
 
 
605
/* Print the data base of files.  */
 
606
 
 
607
static void
 
608
print_file (f)
 
609
     struct file *f;
 
610
{
 
611
  register struct dep *d;
 
612
 
 
613
  putchar ('\n');
 
614
  if (!f->is_target)
 
615
    puts (_("# Not a target:"));
 
616
  printf ("%s:%s", f->name, f->double_colon ? ":" : "");
 
617
 
 
618
  for (d = f->deps; d != 0; d = d->next)
 
619
    printf (" %s", dep_name (d));
 
620
  putchar ('\n');
 
621
 
 
622
  if (f->precious)
 
623
    puts (_("#  Precious file (prerequisite of .PRECIOUS)."));
 
624
  if (f->phony)
 
625
    puts (_("#  Phony target (prerequisite of .PHONY)."));
 
626
  if (f->cmd_target)
 
627
    puts (_("#  Command-line target."));
 
628
  if (f->dontcare)
 
629
    puts (_("#  A default or MAKEFILES makefile."));
 
630
  printf (_("#  Implicit rule search has%s been done.\n"),
 
631
          f->tried_implicit ? "" : _(" not"));
 
632
  if (f->stem != 0)
 
633
    printf (_("#  Implicit/static pattern stem: `%s'\n"), f->stem);
 
634
  if (f->intermediate)
 
635
    puts (_("#  File is an intermediate prerequisite."));
 
636
  if (f->also_make != 0)
 
637
    {
 
638
      fputs (_("#  Also makes:"), stdout);
 
639
      for (d = f->also_make; d != 0; d = d->next)
 
640
        printf (" %s", dep_name (d));
 
641
      putchar ('\n');
 
642
    }
 
643
  if (f->last_mtime == 0)
 
644
    puts (_("#  Modification time never checked."));
 
645
  else if (f->last_mtime == (FILE_TIMESTAMP) -1)
 
646
    puts (_("#  File does not exist."));
 
647
  else
 
648
    {
 
649
      char buf[FILE_TIMESTAMP_PRINT_LEN_BOUND + 1];
 
650
      file_timestamp_sprintf (buf, f->last_mtime);
 
651
      printf (_("#  Last modified %s\n"), buf);
 
652
    }
 
653
  printf (_("#  File has%s been updated.\n"),
 
654
          f->updated ? "" : _(" not"));
 
655
  switch (f->command_state)
 
656
    {
 
657
    case cs_running:
 
658
      puts (_("#  Commands currently running (THIS IS A BUG)."));
 
659
      break;
 
660
    case cs_deps_running:
 
661
      puts (_("#  Dependencies commands running (THIS IS A BUG)."));
 
662
      break;
 
663
    case cs_not_started:
 
664
    case cs_finished:
 
665
      switch (f->update_status)
 
666
        {
 
667
        case -1:
 
668
          break;
 
669
        case 0:
 
670
          puts (_("#  Successfully updated."));
 
671
          break;
 
672
        case 1:
 
673
          assert (question_flag);
 
674
          puts (_("#  Needs to be updated (-q is set)."));
 
675
          break;
 
676
        case 2:
 
677
          puts (_("#  Failed to be updated."));
 
678
          break;
 
679
        default:
 
680
          puts (_("#  Invalid value in `update_status' member!"));
 
681
          fflush (stdout);
 
682
          fflush (stderr);
 
683
          abort ();
 
684
        }
 
685
      break;
 
686
    default:
 
687
      puts (_("#  Invalid value in `command_state' member!"));
 
688
      fflush (stdout);
 
689
      fflush (stderr);
 
690
      abort ();
 
691
    }
 
692
 
 
693
  if (f->variables != 0)
 
694
    print_file_variables (f);
 
695
 
 
696
  if (f->cmds != 0)
 
697
    print_commands (f->cmds);
 
698
}
 
699
 
 
700
void
 
701
print_file_data_base ()
 
702
{
 
703
  register unsigned int i, nfiles, per_bucket;
 
704
  register struct file *file;
 
705
 
 
706
  puts (_("\n# Files"));
 
707
 
 
708
  per_bucket = nfiles = 0;
 
709
  for (i = 0; i < FILE_BUCKETS; ++i)
 
710
    {
 
711
      register unsigned int this_bucket = 0;
 
712
 
 
713
      for (file = files[i]; file != 0; file = file->next)
 
714
        {
 
715
          register struct file *f;
 
716
 
 
717
          ++this_bucket;
 
718
 
 
719
          for (f = file; f != 0; f = f->prev)
 
720
            print_file (f);
 
721
        }
 
722
 
 
723
      nfiles += this_bucket;
 
724
      if (this_bucket > per_bucket)
 
725
        per_bucket = this_bucket;
 
726
    }
 
727
 
 
728
  if (nfiles == 0)
 
729
    puts (_("\n# No files."));
 
730
  else
 
731
    {
 
732
      printf (_("\n# %u files in %u hash buckets.\n"), nfiles, FILE_BUCKETS);
 
733
#ifndef NO_FLOAT
 
734
      printf (_("# average %.3f files per bucket, max %u files in one bucket.\n"),
 
735
              ((double) nfiles) / ((double) FILE_BUCKETS), per_bucket);
 
736
#endif
 
737
    }
 
738
}
 
739
 
 
740
/* EOF */