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

  1. /* Command processing for GNU Make.
  2. Copyright (C) 1988, 1989 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 1, 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. /*
  20.  * MS-DOS port (c) 1990 by Thorsten Ohl <ohl@gnu.ai.mit.edu>
  21.  *
  22.  * To this port, the same copying conditions apply as to the
  23.  * original release.
  24.  *
  25.  * IMPORTANT:
  26.  * This file is not identical to the original GNU release!
  27.  * You should have received this code as patch to the official
  28.  * GNU release.
  29.  *
  30.  * MORE IMPORTANT:
  31.  * This port comes with ABSOLUTELY NO WARRANTY.
  32.  *
  33.  * $Header: e:/gnu/make/RCS/commands.c'v 3.58.0.4 90/08/27 01:24:46 tho Exp $
  34.  */
  35.  
  36. #include "make.h"
  37. #include "dep.h"
  38. #include "commands.h"
  39. #include "file.h"
  40. #include "variable.h"
  41. #include "job.h"
  42.  
  43. #ifdef MSDOS            /* really ? */
  44. #define    sigmask(signal)        1
  45. #endif /* MSDOS */
  46.  
  47. #ifndef    sigmask
  48. #define    sigmask(sig)    (1 << ((sig) - 1))
  49. #endif
  50.  
  51. extern int remote_kill ();
  52.  
  53. extern int getpid ();
  54.  
  55. #ifdef MSDOS
  56. static  void set_file_variables (struct file *file);
  57. #endif /* MSDOS */
  58.  
  59. /* Set FILE's automatic variables up.  */
  60.  
  61. static void
  62. set_file_variables (file)
  63.      register struct file *file;
  64. {
  65.   register char *p;
  66.   char *at, *percent, *star, *less;
  67.  
  68. #define    DEFINE_VARIABLE(name, len, value) \
  69.   (void) define_variable_for_file (name, len, value, o_automatic, 0, file)
  70.  
  71. #ifndef    NO_ARCHIVES
  72.   /* If the target is an archive member `lib(member)',
  73.      then $@ is `lib' and $% is `member'.  */
  74.  
  75.   if (ar_name (file->name))
  76.     {
  77.       p = index (file->name, '(');
  78.       at = savestring (file->name, p - file->name);
  79.       ++p;
  80.       percent = savestring (p, strlen (p) - 1);
  81.     }
  82.   else
  83. #endif    /* NO_ARCHIVES.  */
  84.     {
  85.       at = savestring (file->name, strlen (file->name));
  86.       percent = "";
  87.     }
  88.  
  89.   DEFINE_VARIABLE ("@", 1, at);
  90.   DEFINE_VARIABLE ("%", 1, percent);
  91.  
  92. #define    LASTSLASH(s)    rindex ((s), '/')
  93. #define    FILEONLY(s)    (p != 0 ? p + 1 : (s))
  94. #define    DIRONLY(s)    (p == 0 ? "./" : p == (s) ? "/" \
  95.              : savestring ((s), (p - (s)) + 1))
  96.  
  97.   /* $* is the stem from an implicit or static pattern rule.  */
  98.   if (file->stem == 0)
  99.     {
  100.       /* In Unix make, $* is set to the target name with
  101.      any suffix in the .SUFFIXES list stripped off for
  102.      explicit rules.  We store this in the `stem' member.  */
  103.       register struct dep *d;
  104.       for (d = enter_file (".SUFFIXES")->deps; d != 0; d = d->next)
  105.     {
  106.       unsigned int len = strlen (file->name);
  107.       unsigned int slen = strlen (dep_name (d));
  108.       if (len > slen && streq (dep_name (d), file->name + len - slen))
  109.         {
  110.           file->stem = savestring (file->name, len - slen);
  111.           break;
  112.         }
  113.     }
  114.       if (d == 0)
  115.     file->stem = "";
  116.     }
  117.   star = file->stem;
  118.  
  119.   DEFINE_VARIABLE ("*", 1, star);
  120.  
  121.   /* $< is the first dependency.  */
  122.   less = file->deps != 0 ? dep_name (file->deps) : "";
  123.   DEFINE_VARIABLE ("<", 1, less);
  124.  
  125.   /* Set up the D and F versions.  */
  126.   p = LASTSLASH (at);
  127.   DEFINE_VARIABLE ("@D", 2, DIRONLY (at));
  128.   DEFINE_VARIABLE ("@F", 2, FILEONLY (at));
  129.   p = LASTSLASH (star);
  130.   DEFINE_VARIABLE ("*D", 2, DIRONLY (star));
  131.   DEFINE_VARIABLE ("*F", 2, FILEONLY (star));
  132.   p = LASTSLASH (less);
  133.   DEFINE_VARIABLE ("<D", 2, DIRONLY (less));
  134.   DEFINE_VARIABLE ("<F", 2, FILEONLY (less));
  135.   p = LASTSLASH (percent);
  136.   DEFINE_VARIABLE ("%D", 2, DIRONLY (percent));
  137.   DEFINE_VARIABLE ("%F", 2, FILEONLY (percent));
  138.  
  139.   /* Compute the values for $^ and $? and their F and D versions.  */
  140.  
  141.   {
  142.     register unsigned int caret_len, qmark_len;
  143.     char *caret_value, *caretD_value, *caretF_value;
  144.     register char *cp, *cDp, *cFp;
  145.     char *qmark_value, *qmarkD_value, *qmarkF_value;
  146.     register char *qp, *qDp, *qFp;
  147.     register struct dep *d;
  148.     unsigned int len;
  149.  
  150.     caret_len = qmark_len = 0;
  151.     for (d = file->deps; d != 0; d = d->next)
  152.       {
  153.     register unsigned int i = strlen (dep_name (d)) + 1;
  154.     caret_len += i;
  155.     if (d->changed)
  156.       qmark_len += i;
  157.       }
  158.  
  159.     len = caret_len == 0 ? 1 : caret_len;
  160.     cp = caret_value = (char *) xmalloc (len);
  161.     cDp = caretD_value = (char *) xmalloc (len);
  162.     cFp = caretF_value = (char *) xmalloc (len);
  163.     len = qmark_len == 0 ? 1 : qmark_len;
  164.     qp = qmark_value = (char *) xmalloc (len);
  165.     qDp = qmarkD_value = (char *) xmalloc (len);
  166.     qFp = qmarkF_value = (char *) xmalloc (len);
  167.  
  168.     for (d = file->deps; d != 0; d = d->next)
  169.       {
  170.     char *c, *cD, *cF;
  171.     unsigned int Dlen, Flen;
  172.  
  173.     c = dep_name (d);
  174.     len = strlen (c);
  175.     bcopy (c, cp, len);
  176.     cp += len;
  177.     *cp++ = ' ';
  178.  
  179.     p = LASTSLASH (c);
  180.     if (p == 0)
  181.       {
  182.         cF = c;
  183.         Flen = len;
  184.         cD = "./";
  185.         Dlen = 2;
  186.       }
  187.     else if (p == c)
  188.       {
  189.         cD = c;
  190.         Dlen = 1;
  191.         cF = c + 1;
  192.         Flen = len - 1;
  193.       }
  194.     else
  195.       {
  196.         cF = p + 1;
  197.         Flen = len - (p - c);
  198.         cD = c;
  199.         Dlen = (p - c);
  200.       }
  201.     bcopy (cD, cDp, Dlen);
  202.     cDp += Dlen;
  203.     *cDp++ = ' ';
  204.     bcopy (cF, cFp, Flen);
  205.     cFp += Flen;
  206.     *cFp++ = ' ';
  207.  
  208.     if (d->changed)
  209.       {
  210.         bcopy (c, qp, len);
  211.         qp += len;
  212.         *qp++ = ' ';
  213.         bcopy (cD, qDp, Dlen);
  214.         qDp += Dlen;
  215.         *qDp++ = ' ';
  216.         bcopy (cF, qFp, Flen);
  217.         qFp += Flen;
  218.         *qFp++ = ' ';
  219.       }
  220.       }
  221.  
  222.     /* Kill the last spaces and define the variables.  */
  223.  
  224.     cp[cp > caret_value ? -1 : 0] = '\0';
  225.     DEFINE_VARIABLE ("^", 1, caret_value);
  226.     cDp[cDp > caretD_value ? -1 : 0] = '\0';
  227.     DEFINE_VARIABLE ("^D", 2, caretD_value);
  228.     cFp[cFp > caretF_value ? -1 : 0] = '\0';
  229.     DEFINE_VARIABLE ("^F", 2, caretF_value);
  230.  
  231.     qp[qp > qmark_value ? -1 : 0] = '\0';
  232.     DEFINE_VARIABLE ("?", 1, qmark_value);
  233.     qDp[qDp > qmarkD_value ? -1 : 0] = '\0';
  234.     DEFINE_VARIABLE ("?D", 2, qmarkD_value);
  235.     qFp[qFp > qmarkF_value ? -1 : 0] = '\0';
  236.     DEFINE_VARIABLE ("?F", 2, qmarkF_value);
  237.   }
  238.  
  239. #undef    LASTSLASH
  240. #undef    FILEONLY
  241. #undef    DIRONLY
  242.  
  243. #undef    DEFINE_VARIABLE
  244. }
  245.  
  246. /* Chop CMDS up into individual command lines if necessary.  */
  247.  
  248. void
  249. chop_commands (cmds)
  250.      register struct commands *cmds;
  251. {
  252.   if (cmds != 0 && cmds->command_lines == 0)
  253.     {
  254.       /* Chop CMDS->commands up into lines in CMDS->command_lines.
  255.      Also set the corresponding CMDS->lines_recurse elements,
  256.      and the CMDS->any_recurse flag.  */
  257.       register char *p;
  258.       unsigned int nlines, idx;
  259.       char **lines;
  260.  
  261.       nlines = 5;
  262.       lines = (char **) xmalloc (5 * sizeof (char *));
  263.       idx = 0;
  264.       p = cmds->commands;
  265.       while (*p != '\0')
  266.     {
  267.       char *end = p;
  268.     find_end:;
  269.       end = index (end, '\n');
  270.       if (end == 0)
  271.         end = p + strlen (p);
  272.       else if (end > p && end[-1] == '\\')
  273.         {
  274.           int backslash = 1;
  275.           register char *b;
  276.           for (b = end - 2; b >= p && *b == '\\'; --b)
  277.         backslash = !backslash;
  278.           if (backslash)
  279.         {
  280.           ++end;
  281.           goto find_end;
  282.         }
  283.         }
  284.  
  285.       if (idx == nlines - 1)
  286.         {
  287.           nlines += 2;
  288.           lines = (char **) xrealloc ((char *) lines,
  289.                       nlines * sizeof (char *));
  290.         }
  291.       lines[idx++] = savestring (p, end - p);
  292.       p = end;
  293.       if (*p != '\0')
  294.         ++p;
  295.     }
  296.       lines[idx++] = 0;
  297.  
  298.       if (idx != nlines)
  299.     {
  300.       nlines = idx;
  301.       lines = (char **) xrealloc ((char *) lines,
  302.                       nlines * sizeof (char *));
  303.     }
  304.  
  305.       cmds->command_lines = lines;
  306.  
  307.       cmds->any_recurse = 0;
  308.       --nlines;
  309.       cmds->lines_recurse = (char *) xmalloc (nlines);
  310.       for (idx = 0; idx < nlines; ++idx)
  311.     {
  312.       unsigned int len;
  313.       int recursive;
  314.       p = lines[idx];
  315.       len = strlen (p);
  316.       recursive = (sindex (p, len, "$(MAKE)", 7) != 0
  317.                || sindex (p, len, "${MAKE}", 7) != 0);
  318.       cmds->lines_recurse[idx] = recursive;
  319.       cmds->any_recurse |= recursive;
  320.     }
  321.     }
  322. }
  323.  
  324. /* Execute the commands to remake FILE.  If they are currently executing,
  325.    return or have already finished executing, just return.  Otherwise,
  326.    fork off a child process to run the first command line in the sequence.  */
  327.  
  328. void
  329. execute_file_commands (file)
  330.      struct file *file;
  331. {
  332.   register char *p;
  333.   struct child *c;
  334.   int status;
  335.  
  336.   /* Don't go through all the preparations if
  337.      the commands are nothing but whitespace.  */
  338.  
  339.   for (p = file->cmds->commands; *p != '\0'; ++p)
  340.     if (*p != ' ' && *p != '\t' && *p != '\n' && *p != '-' && *p != '@')
  341.       break;
  342.   if (*p == '\0')
  343.     {
  344.       file->command_state = cs_finished;
  345.       file->update_status = 0;
  346.       notice_finished_file (file);
  347.       return;
  348.     }
  349.  
  350.   /* First set the automatic variables according to this file.  */
  351.  
  352.   initialize_file_variables (file);
  353.  
  354.   set_file_variables (file);
  355.  
  356.   /* Start the commands running.  */
  357.   new_job (file);
  358. }
  359.  
  360. #define    PROPAGATED_SIGNAL_MASK \
  361.   (sigmask (SIGTERM) | sigmask (SIGINT) | sigmask (SIGHUP) | sigmask (SIGQUIT))
  362.  
  363. /* Handle fatal signals.  */
  364.  
  365. int
  366. fatal_error_signal (sig)
  367.      int sig;
  368. {
  369.   signal (sig, SIG_DFL);
  370. #ifndef USG
  371.   (void) sigsetmask (0);
  372. #endif
  373.  
  374.   /* A termination signal won't be sent to the entire
  375.      process group, but it means we want to kill the children.  */
  376.  
  377. #ifndef MSDOS
  378.   if (sig == SIGTERM)
  379.     {
  380.       register struct child *c;
  381.       block_children ();
  382.       for (c = children; c != 0; c = c->next)
  383.     if (!c->remote)
  384.       (void) kill (c->pid, SIGTERM);
  385.       unblock_children ();
  386.     }
  387. #endif /* ! MSDOS */
  388.  
  389.   /* If we got a signal that means the user
  390.      wanted to kill make, remove pending targets.  */
  391.  
  392.   if (PROPAGATED_SIGNAL_MASK & sigmask (sig))
  393.     {
  394.       register struct child *c;
  395.       block_children ();
  396.  
  397.       /* Remote children won't automatically get signals sent
  398.      to the process group, so we must send them.  */
  399.       for (c = children; c != 0; c = c->next)
  400.     if (c->remote)
  401.       (void) remote_kill (c->pid, sig);
  402.  
  403.       for (c = children; c != 0; c = c->next)
  404.     delete_child_targets (c);
  405.  
  406.       unblock_children ();
  407.  
  408.       /* Clean up the children.  We don't just use the call below because
  409.      we don't want to print the "Waiting for children" message.  */
  410.       wait_for_children (0, 0);
  411.     }
  412.   else
  413.     /* Wait for our children to die.  */
  414.     wait_for_children (0, 1);
  415.  
  416.   /* Delete any non-precious intermediate files that were made.  */
  417.  
  418.   remove_intermediates (1);
  419.  
  420. #ifndef MSDOS
  421.   if (sig == SIGQUIT)
  422.     /* We don't want to send ourselves SIGQUIT, because it will
  423.        cause a core dump.  Just exit instead.  */
  424.     exit (1);
  425. #endif /* !MSDOS */
  426.  
  427. #ifdef MSDOS
  428.   abort ();
  429. #else
  430.   /* Signal the same code; this time it will really be fatal.  */
  431.   if (kill (getpid (), sig) < 0)
  432.     /* It shouldn't return, but if it does, die anyway.  */
  433.     pfatal_with_name ("kill");
  434. #endif /* MSDOS */
  435.  
  436.   return 0;
  437. }
  438.  
  439. /* Delete all non-precious targets of CHILD unless they were already deleted.
  440.    Set the flag in CHILD to say they've been deleted.  */
  441.  
  442. void
  443. delete_child_targets (child)
  444.      struct child *child;
  445. {
  446.   struct stat st;
  447.  
  448.   if (child->deleted)
  449.     return;
  450.  
  451.   /* Delete the file unless it's precious.  */
  452.   if (!child->file->precious
  453.       && stat (child->file->name, &st) == 0
  454.       && (st.st_mode & S_IFMT) == S_IFREG
  455.       && (time_t) st.st_mtime != child->file->last_mtime)
  456.     {
  457.       error ("*** Deleting file `%s'", child->file->name);
  458.       if (unlink (child->file->name) < 0)
  459.     perror_with_name ("unlink: ", child->file->name);
  460.     }
  461.  
  462.   /* Also remove any non-precious targets listed
  463.      in the `also_make' member.  */
  464.   if (child->file->also_make != 0)
  465.     {
  466.       register unsigned int i;
  467.       for (i = 0; child->file->also_make[i] != 0; ++i)
  468.     {
  469.       char *name = child->file->also_make[i];
  470.       struct file *f = lookup_file (name);
  471.       if (f != 0 && f->precious)
  472.         continue;
  473.       if (stat (name, &st) == 0
  474.           && (st.st_mode & S_IFMT) == S_IFREG
  475.           && (f == 0 ||
  476.           (time_t) st.st_mtime == f->last_mtime))
  477.         {
  478.           error ("*** [%s] Deleting file `%s'", child->file->name, name);
  479.           if (unlink (name) < 0)
  480.         perror_with_name ("unlink: ", name);
  481.         }
  482.     }
  483.     }
  484.  
  485.   child->deleted = 1;
  486. }
  487.  
  488. /* Print out the commands in CMDS.  */
  489.  
  490. void
  491. print_commands (cmds)
  492.      register struct commands *cmds;
  493. {
  494.   register char *s;
  495.  
  496.   fputs ("#  commands to execute", stdout);
  497.  
  498.   if (cmds->filename == 0)
  499.     puts (" (built-in):");
  500.   else
  501.     printf (" (from `%s', line %u):\n", cmds->filename, cmds->lineno);
  502.  
  503.   s = cmds->commands;
  504.   while (*s != '\0')
  505.     {
  506.       char *end;
  507.  
  508.       while (*s == ' ' || *s == '\t' || *s == '\n')
  509.     ++s;
  510.  
  511.       end = index (s, '\n');
  512.       if (end == 0)
  513.     end = s + strlen (s);
  514.  
  515.       printf ("\t%.*s\n", end - s, s);
  516.  
  517.       s = end;
  518.     }
  519. }
  520.