home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 4 / FreshFish_May-June1994.bin / bbs / gnu / make-3.70-src.lha / src / amiga / make-3.70 / file.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-15  |  12.2 KB  |  513 lines

  1. /* Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993
  2.     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, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  18.  
  19. #include "make.h"
  20. #include "commands.h"
  21. #include "dep.h"
  22. #include "file.h"
  23. #include "variable.h"
  24.  
  25.  
  26. /* Hash table of files the makefile knows how to make.  */
  27.  
  28. #ifndef    FILE_BUCKETS
  29. #define FILE_BUCKETS    1007
  30. #endif
  31. static struct file *files[FILE_BUCKETS];
  32.  
  33. /* Number of files with the `intermediate' flag set.  */
  34.  
  35. unsigned int num_intermediates = 0;
  36.  
  37.  
  38. /* Access the hash table of all file records.
  39.    lookup_file  given a name, return the struct file * for that name,
  40.            or nil if there is none.
  41.    enter_file   similar, but create one if there is none.  */
  42.  
  43. struct file *
  44. lookup_file (name)
  45.      char *name;
  46. {
  47.   register struct file *f;
  48.   register char *n;
  49.   register unsigned int hashval;
  50.  
  51.   if (*name == '\0')
  52.     abort ();
  53.  
  54.   /* This is also done in parse_file_seq, so this is redundant
  55.      for names read from makefiles.  It is here for names passed
  56.      on the command line.  */
  57.   while (name[0] == '.' && name[1] == '/' && name[2] != '\0')
  58.     {
  59.       name += 2;
  60.       while (*name == '/')
  61.     /* Skip following slashes: ".//foo" is "foo", not "/foo".  */
  62.     ++name;
  63.     }
  64.  
  65.   if (*name == '\0')
  66.     /* It was all slashes after a dot.  */
  67.     name = "./";
  68.  
  69.   hashval = 0;
  70.   for (n = name; *n != '\0'; ++n)
  71.     HASH (hashval, *n);
  72.   hashval %= FILE_BUCKETS;
  73.  
  74.   for (f = files[hashval]; f != 0; f = f->next)
  75.     if (streq (f->name, name))
  76.       return f;
  77.   return 0;
  78. }
  79.  
  80. struct file *
  81. enter_file (name)
  82.      char *name;
  83. {
  84.   register struct file *f, *new;
  85.   register char *n;
  86.   register unsigned int hashval;
  87.  
  88.   if (*name == '\0')
  89.     abort ();
  90.  
  91.   hashval = 0;
  92.   for (n = name; *n != '\0'; ++n)
  93.     HASH (hashval, *n);
  94.   hashval %= FILE_BUCKETS;
  95.  
  96.   for (f = files[hashval]; f != 0; f = f->next)
  97.     if (streq (f->name, name))
  98.       break;
  99.  
  100.   if (f != 0 && !f->double_colon)
  101.     return f;
  102.  
  103.   new = (struct file *) xmalloc (sizeof (struct file));
  104.   bzero ((char *) new, sizeof (struct file));
  105.   new->name = name;
  106.   new->update_status = -1;
  107.  
  108.   if (f == 0)
  109.     {
  110.       /* This is a completely new file.  */
  111.       new->next = files[hashval];
  112.       files[hashval] = new;
  113.     }
  114.   else
  115.     {
  116.       /* There is already a double-colon entry for this file.  */
  117.       while (f->prev != 0)
  118.     f = f->prev;
  119.       f->prev = new;
  120.     }
  121.  
  122.   return new;
  123. }
  124.  
  125. /* Rename FILE to NAME.  This is not as simple as resetting
  126.    the `name' member, since it must be put in a new hash bucket,
  127.    and possibly merged with an existing file called NAME.  */
  128.  
  129. void
  130. rename_file (file, name)
  131.      register struct file *file;
  132.      char *name;
  133. {
  134.   char *oldname = file->name;
  135.   register unsigned int oldhash;
  136.   register char *n;
  137.  
  138.   while (file->renamed != 0)
  139.     file = file->renamed;
  140.  
  141.   /* Find the hash values of the old and new names.  */
  142.  
  143.   oldhash = 0;
  144.   for (n = oldname; *n != '\0'; ++n)
  145.     HASH (oldhash, *n);
  146.  
  147.   file_hash_enter (file, name, oldhash, file->name);
  148. }
  149.  
  150. void
  151. file_hash_enter (file, name, oldhash, oldname)
  152.      register struct file *file;
  153.      char *name;
  154.      unsigned int oldhash;
  155.      char *oldname;
  156. {
  157.   unsigned int oldbucket = oldhash % FILE_BUCKETS;
  158.   register unsigned int newhash, newbucket;
  159.   struct file *oldfile;
  160.   register char *n;
  161.   register struct file *f;
  162.  
  163.   newhash = 0;
  164.   for (n = name; *n != '\0'; ++n)
  165.     HASH (newhash, *n);
  166.   newbucket = newhash % FILE_BUCKETS;
  167.  
  168.   /* Look for an existing file under the new name.  */
  169.  
  170.   for (oldfile = files[newbucket]; oldfile != 0; oldfile = oldfile->next)
  171.     if (streq (oldfile->name, name))
  172.       break;
  173.  
  174.   if (oldhash != 0 && (newbucket != oldbucket || oldfile != 0))
  175.     {
  176.       /* Remove FILE from its hash bucket.  */
  177.  
  178.       struct file *lastf = 0;
  179.  
  180.       for (f = files[oldbucket]; f != file; f = f->next)
  181.     lastf = f;
  182.  
  183.       if (lastf == 0)
  184.     files[oldbucket] = f->next;
  185.       else
  186.     lastf->next = f->next;
  187.     }
  188.  
  189.   /* Give FILE its new name.  */
  190.  
  191.   for (f = file; f != 0; f = f->prev)
  192.     f->name = name;
  193.  
  194.   if (oldfile == 0)
  195.     {
  196.       /* There is no existing file with the new name.  */
  197.  
  198.       if (newbucket != oldbucket)
  199.     {
  200.       /* Put FILE in its new hash bucket.  */
  201.       file->next = files[newbucket];
  202.       files[newbucket] = file;
  203.     }
  204.     }
  205.   else
  206.     {
  207.       /* There is an existing file with the new name.
  208.      We must merge FILE into the existing file.  */
  209.  
  210.       register struct dep *d;
  211.  
  212.       if (file->cmds != 0)
  213.     {
  214.       if (oldfile->cmds == 0)
  215.         oldfile->cmds = file->cmds;
  216.       else if (file->cmds != oldfile->cmds)
  217.         {
  218.           /* We have two sets of commands.  We will go with the
  219.          one given in the rule explicitly mentioning this name,
  220.          but give a message to let the user know what's going on.  */
  221.           if (oldfile->cmds->filename != 0)
  222.         makefile_error (file->cmds->filename, file->cmds->lineno,
  223.                 "Commands were specified for \
  224. file `%s' at %s:%u,",
  225.                 oldname, oldfile->cmds->filename,
  226.                 oldfile->cmds->lineno);
  227.           else
  228.         makefile_error (file->cmds->filename, file->cmds->lineno,
  229.                 "Commands for file `%s' were found by \
  230. implicit rule search,",
  231.                 oldname);
  232.           makefile_error (file->cmds->filename, file->cmds->lineno,
  233.                   "but `%s' is now considered the same file \
  234. as `%s'.",
  235.                   oldname, name);
  236.           makefile_error (file->cmds->filename, file->cmds->lineno,
  237.                   "Commands for `%s' will be ignored \
  238. in favor of those for `%s'.",
  239.                   name, oldname);
  240.         }
  241.     }
  242.  
  243.       /* Merge the dependencies of the two files.  */
  244.  
  245.       d = oldfile->deps;
  246.       if (d == 0)
  247.     oldfile->deps = file->deps;
  248.       else
  249.     {
  250.       while (d->next != 0)
  251.         d = d->next;
  252.       d->next = file->deps;
  253.     }
  254.  
  255.       merge_variable_set_lists (&oldfile->variables, file->variables);
  256.  
  257.       if (oldfile->double_colon && !file->double_colon)
  258.     fatal ("can't rename single-colon `%s' to double-colon `%s'",
  259.            oldname, name);
  260.       if (!oldfile->double_colon && file->double_colon)
  261.     fatal ("can't rename double-colon `%s' to single-colon `%s'",
  262.            oldname, name);
  263.  
  264.       if (file->last_mtime > oldfile->last_mtime)
  265.     /* %%% Kludge so -W wins on a file that gets vpathized.  */
  266.     oldfile->last_mtime = file->last_mtime;
  267.  
  268. #define MERGE(field) oldfile->field |= file->field
  269.       MERGE (precious);
  270.       MERGE (tried_implicit);
  271.       MERGE (updating);
  272.       MERGE (updated);
  273.       MERGE (is_target);
  274.       MERGE (cmd_target);
  275.       MERGE (phony);
  276. #undef MERGE
  277.  
  278.       file->renamed = oldfile;
  279.     }
  280. }
  281.  
  282. /* Remove all nonprecious intermediate files.
  283.    If SIG is nonzero, this was caused by a fatal signal,
  284.    meaning that a different message will be printed, and
  285.    the message will go to stderr rather than stdout.  */
  286.  
  287. void
  288. remove_intermediates (sig)
  289.      int sig;
  290. {
  291.   register int i;
  292.   register struct file *f;
  293.   char doneany;
  294.   
  295.   if (!sig && just_print_flag)
  296.     return;
  297.  
  298.   doneany = 0;
  299.   for (i = 0; i < FILE_BUCKETS; ++i)
  300.     for (f = files[i]; f != 0; f = f->next)
  301.       if (f->intermediate && (f->dontcare || !f->precious))
  302.     {
  303.       int status;
  304.       if (just_print_flag)
  305.         status = 0;
  306.       else
  307.         {
  308.           status = unlink (f->name);
  309.           if (status < 0 && errno == ENOENT)
  310.         continue;
  311.         }
  312.       if (!f->dontcare)
  313.         {
  314.           if (sig)
  315.         error ("*** Deleting intermediate file `%s'", f->name);
  316.           else if (!silent_flag)
  317.         {
  318.           if (! doneany)
  319.             {
  320.               fputs ("rm ", stdout);
  321.               doneany = 1;
  322.             }
  323.           else
  324.             putchar (' ');
  325.           fputs (f->name, stdout);
  326.           fflush (stdout);
  327.         }
  328.           if (status < 0)
  329.         perror_with_name ("unlink: ", f->name);
  330.         }
  331.     }
  332.  
  333.   if (doneany && !sig)
  334.     {
  335.       putchar ('\n');
  336.       fflush (stdout);
  337.     }
  338. }
  339.  
  340. /* For each dependency of each file, make the `struct dep' point
  341.    at the appropriate `struct file' (which may have to be created).
  342.  
  343.    Also mark the files depended on by .PRECIOUS and .PHONY.  */
  344.  
  345. void
  346. snap_deps ()
  347. {
  348.   register struct file *f, *f2;
  349.   register struct dep *d;
  350.   register int i;
  351.  
  352.   /* Enter each dependency name as a file.  */
  353.   for (i = 0; i < FILE_BUCKETS; ++i)
  354.     for (f = files[i]; f != 0; f = f->next)
  355.       for (f2 = f; f2 != 0; f2 = f2->prev)
  356.     for (d = f2->deps; d != 0; d = d->next)
  357.       if (d->name != 0)
  358.         {
  359.           d->file = lookup_file (d->name);
  360.           if (d->file == 0)
  361.         d->file = enter_file (d->name);
  362.           else
  363.         free (d->name);
  364.           d->name = 0;
  365.         }
  366.   
  367.   for (f = lookup_file (".PRECIOUS"); f != 0; f = f->prev)
  368.     for (d = f->deps; d != 0; d = d->next)
  369.       for (f2 = d->file; f2 != 0; f2 = f2->prev)
  370.     f2->precious = 1;
  371.  
  372.   for (f = lookup_file (".PHONY"); f != 0; f = f->prev)
  373.     for (d = f->deps; d != 0; d = d->next)
  374.       for (f2 = d->file; f2 != 0; f2 = f2->prev)
  375.     {
  376.       /* Mark this file as phony and nonexistent.  */
  377.       f2->phony = 1;
  378.       f2->last_mtime = (time_t) -1;
  379.     }
  380.  
  381.   f = lookup_file (".EXPORT_ALL_VARIABLES");
  382.   if (f != 0 && f->is_target)
  383.     export_all_variables = 1;
  384. }
  385.  
  386. /* Print the data base of files.  */
  387.  
  388. static void
  389. print_file (f)
  390.      struct file *f;
  391. {
  392.   register struct dep *d;
  393.  
  394.   putchar ('\n');
  395.   if (!f->is_target)
  396.     puts ("# Not a target:");
  397.   printf ("%s:%s", f->name, f->double_colon ? ":" : "");
  398.           
  399.   for (d = f->deps; d != 0; d = d->next)
  400.     printf (" %s", dep_name (d));
  401.   putchar ('\n');
  402.           
  403.   if (f->precious)
  404.     puts ("#  Precious file (dependency of .PRECIOUS).");
  405.   if (f->phony)
  406.     puts ("#  Phony target (dependency of .PHONY).");
  407.   if (f->cmd_target)
  408.     puts ("#  Command-line target.");
  409.   if (f->dontcare)
  410.     puts ("#  A default or MAKEFILES makefile.");
  411.   printf ("#  Implicit rule search has%s been done.\n",
  412.       f->tried_implicit ? "" : " not");
  413.   if (f->stem != 0)
  414.     printf ("#  Implicit/static pattern stem: `%s'\n", f->stem);
  415.   if (f->intermediate)
  416.     puts ("#  File is an intermediate dependency.");
  417.   if (f->also_make != 0)
  418.     {
  419.       fputs ("#  Also makes:", stdout);
  420.       for (d = f->also_make; d != 0; d = d->next)
  421.     printf (" %s", dep_name (d));
  422.       putchar ('\n');
  423.     }
  424.   if (f->last_mtime == (time_t) 0)
  425.     puts ("#  Modification time never checked.");
  426.   else if (f->last_mtime == (time_t) -1)
  427.     puts ("#  File does not exist.");
  428.   else
  429.     printf ("#  Last modified %.24s (%ld)\n",
  430.         ctime (&f->last_mtime), (long int) f->last_mtime);
  431.   printf ("#  File has%s been updated.\n",
  432.       f->updated ? "" : " not");
  433.   switch (f->command_state)
  434.     {
  435.     case cs_running:
  436.       puts ("#  Commands currently running (THIS IS A BUG).");
  437.       break;
  438.     case cs_deps_running:
  439.       puts ("#  Dependencies commands running (THIS IS A BUG).");
  440.       break;
  441.     case cs_not_started:
  442.     case cs_finished:
  443.       switch (f->update_status)
  444.     {
  445.     case -1:
  446.       break;
  447.     case 0:
  448.       puts ("#  Successfully updated.");
  449.       break;
  450.     case 1:
  451.       puts ("#  Failed to be updated.");
  452.       break;
  453.     default:
  454.       puts ("#  Invalid value in `update_status' member!");
  455.       fflush (stdout);
  456.       fflush (stderr);
  457.       abort ();
  458.     }
  459.       break;
  460.     default:
  461.       puts ("#  Invalid value in `command_state' member!");
  462.       fflush (stdout);
  463.       fflush (stderr);
  464.       abort ();
  465.     }
  466.  
  467.   if (f->variables != 0)
  468.     print_file_variables (f);
  469.  
  470.   if (f->cmds != 0)
  471.     print_commands (f->cmds);
  472. }
  473.  
  474. void
  475. print_file_data_base ()
  476. {
  477.   register unsigned int i, nfiles, per_bucket;
  478.   register struct file *file;
  479.  
  480.   puts ("\n# Files");
  481.  
  482.   per_bucket = nfiles = 0;
  483.   for (i = 0; i < FILE_BUCKETS; ++i)
  484.     {
  485.       register unsigned int this_bucket = 0;
  486.  
  487.       for (file = files[i]; file != 0; file = file->next)
  488.     {
  489.       register struct file *f;
  490.  
  491.       ++this_bucket;
  492.  
  493.       for (f = file; f != 0; f = f->prev)
  494.         print_file (f);
  495.     }
  496.  
  497.       nfiles += this_bucket;
  498.       if (this_bucket > per_bucket)
  499.     per_bucket = this_bucket;
  500.     }
  501.  
  502.   if (nfiles == 0)
  503.     puts ("\n# No files.");
  504.   else
  505.     {
  506.       printf ("\n# %u files in %u hash buckets.\n", nfiles, FILE_BUCKETS);
  507. #ifndef    NO_FLOAT
  508.       printf ("# average %.1f files per bucket, max %u files in one bucket.\n",
  509.           ((double) nfiles) / ((double) FILE_BUCKETS) * 100.0, per_bucket);
  510. #endif
  511.     }
  512. }
  513.