home *** CD-ROM | disk | FTP | other *** search
/ ProfitPress Mega CDROM2 …eeware (MSDOS)(1992)(Eng) / ProfitPress-MegaCDROM2.B6I / MISC / GNU / MAK358AS.ZIP / FILE.C < prev    next >
Encoding:
C/C++ Source or Header  |  1992-02-22  |  12.1 KB  |  486 lines

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