source: trunk/third/gmake/commands.c @ 15972

Revision 15972, 13.6 KB checked in by ghudson, 24 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r15971, which included commits to RCS files with non-trunk default branches.
Line 
1/* Command processing for GNU Make.
2Copyright (C) 1988,89,91,92,93,94,95,96,97 Free Software Foundation, Inc.
3This file is part of GNU Make.
4
5GNU Make is free software; you can redistribute it and/or modify
6it under the terms of the GNU General Public License as published by
7the Free Software Foundation; either version 2, or (at your option)
8any later version.
9
10GNU Make is distributed in the hope that it will be useful,
11but WITHOUT ANY WARRANTY; without even the implied warranty of
12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with GNU Make; see the file COPYING.  If not, write to
17the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18Boston, MA 02111-1307, USA.  */
19
20#include "make.h"
21#include "dep.h"
22#include "filedef.h"
23#include "variable.h"
24#include "job.h"
25#include "commands.h"
26
27extern int remote_kill PARAMS ((int id, int sig));
28
29#ifndef HAVE_UNISTD_H
30extern int getpid ();
31#endif
32
33/* Set FILE's automatic variables up.  */
34
35static void
36set_file_variables (file)
37     register struct file *file;
38{
39  register char *p;
40  char *at, *percent, *star, *less;
41
42#ifndef NO_ARCHIVES
43  /* If the target is an archive member `lib(member)',
44     then $@ is `lib' and $% is `member'.  */
45
46  if (ar_name (file->name))
47    {
48      unsigned int len;
49      p = strchr (file->name, '(');
50      at = (char *) alloca (p - file->name + 1);
51      bcopy (file->name, at, p - file->name);
52      at[p - file->name] = '\0';
53      len = strlen (p + 1);
54      percent = (char *) alloca (len);
55      bcopy (p + 1, percent, len - 1);
56      percent[len - 1] = '\0';
57    }
58  else
59#endif  /* NO_ARCHIVES.  */
60    {
61      at = file->name;
62      percent = "";
63    }
64
65  /* $* is the stem from an implicit or static pattern rule.  */
66  if (file->stem == 0)
67    {
68      /* In Unix make, $* is set to the target name with
69         any suffix in the .SUFFIXES list stripped off for
70         explicit rules.  We store this in the `stem' member.  */
71      register struct dep *d;
72      char *name;
73      unsigned int len;
74
75#ifndef NO_ARCHIVES
76      if (ar_name (file->name))
77        {
78          name = strchr (file->name, '(') + 1;
79          len = strlen (name) - 1;
80        }
81      else
82#endif
83        {
84          name = file->name;
85          len = strlen (name);
86        }
87
88      for (d = enter_file (".SUFFIXES")->deps; d != 0; d = d->next)
89        {
90          unsigned int slen = strlen (dep_name (d));
91          if (len > slen && strneq (dep_name (d), name + (len - slen), slen))
92            {
93              file->stem = savestring (name, len - slen);
94              break;
95            }
96        }
97      if (d == 0)
98        file->stem = "";
99    }
100  star = file->stem;
101
102  /* $< is the first dependency.  */
103  less = file->deps != 0 ? dep_name (file->deps) : "";
104
105  if (file->cmds == default_file->cmds)
106    /* This file got its commands from .DEFAULT.
107       In this case $< is the same as $@.  */
108    less = at;
109
110#define DEFINE_VARIABLE(name, len, value) \
111  (void) define_variable_for_file (name,len,value,o_automatic,0,file)
112
113  /* Define the variables.  */
114
115  DEFINE_VARIABLE ("<", 1, less);
116  DEFINE_VARIABLE ("*", 1, star);
117  DEFINE_VARIABLE ("@", 1, at);
118  DEFINE_VARIABLE ("%", 1, percent);
119
120  /* Compute the values for $^, $+, and $?.  */
121
122  {
123    register unsigned int qmark_len, plus_len;
124    char *caret_value, *plus_value;
125    register char *cp;
126    char *qmark_value;
127    register char *qp;
128    register struct dep *d;
129    unsigned int len;
130
131    /* Compute first the value for $+, which is supposed to contain
132       duplicate dependencies as they were listed in the makefile.  */
133
134    plus_len = 0;
135    for (d = file->deps; d != 0; d = d->next)
136      plus_len += strlen (dep_name (d)) + 1;
137
138    len = plus_len == 0 ? 1 : plus_len;
139    cp = plus_value = (char *) alloca (len);
140
141    qmark_len = plus_len;       /* Will be this or less.  */
142    for (d = file->deps; d != 0; d = d->next)
143      {
144        char *c = dep_name (d);
145
146#ifndef NO_ARCHIVES
147        if (ar_name (c))
148          {
149            c = strchr (c, '(') + 1;
150            len = strlen (c) - 1;
151          }
152        else
153#endif
154          len = strlen (c);
155
156        bcopy (c, cp, len);
157        cp += len;
158#if VMS
159        *cp++ = ',';
160#else
161        *cp++ = ' ';
162#endif
163        if (! d->changed)
164          qmark_len -= len + 1; /* Don't space in $? for this one.  */
165      }
166
167    /* Kill the last space and define the variable.  */
168
169    cp[cp > plus_value ? -1 : 0] = '\0';
170    DEFINE_VARIABLE ("+", 1, plus_value);
171
172    /* Make sure that no dependencies are repeated.  This does not
173       really matter for the purpose of updating targets, but it
174       might make some names be listed twice for $^ and $?.  */
175
176    uniquize_deps (file->deps);
177
178    /* Compute the values for $^ and $?.  */
179
180    cp = caret_value = plus_value; /* Reuse the buffer; it's big enough.  */
181    len = qmark_len == 0 ? 1 : qmark_len;
182    qp = qmark_value = (char *) alloca (len);
183
184    for (d = file->deps; d != 0; d = d->next)
185      {
186        char *c = dep_name (d);
187
188#ifndef NO_ARCHIVES
189        if (ar_name (c))
190          {
191            c = strchr (c, '(') + 1;
192            len = strlen (c) - 1;
193          }
194        else
195#endif
196          len = strlen (c);
197
198        bcopy (c, cp, len);
199        cp += len;
200#if VMS
201        *cp++ = ',';
202#else
203        *cp++ = ' ';
204#endif
205        if (d->changed)
206          {
207            bcopy (c, qp, len);
208            qp += len;
209#if VMS
210            *qp++ = ',';
211#else
212            *qp++ = ' ';
213#endif
214          }
215      }
216
217    /* Kill the last spaces and define the variables.  */
218
219    cp[cp > caret_value ? -1 : 0] = '\0';
220    DEFINE_VARIABLE ("^", 1, caret_value);
221
222    qp[qp > qmark_value ? -1 : 0] = '\0';
223    DEFINE_VARIABLE ("?", 1, qmark_value);
224  }
225
226#undef  DEFINE_VARIABLE
227}
228
229/* Chop CMDS up into individual command lines if necessary.
230   Also set the `lines_flag' and `any_recurse' members.  */
231
232void
233chop_commands (cmds)
234     register struct commands *cmds;
235{
236  register char *p;
237  unsigned int nlines, idx;
238  char **lines;
239
240  /* If we don't have any commands,
241     or we already parsed them, never mind.  */
242
243  if (!cmds || cmds->command_lines != 0)
244    return;
245
246  /* Chop CMDS->commands up into lines in CMDS->command_lines.
247         Also set the corresponding CMDS->lines_flags elements,
248         and the CMDS->any_recurse flag.  */
249
250  nlines = 5;
251  lines = (char **) xmalloc (5 * sizeof (char *));
252  idx = 0;
253  p = cmds->commands;
254  while (*p != '\0')
255    {
256      char *end = p;
257    find_end:;
258      end = strchr (end, '\n');
259      if (end == 0)
260        end = p + strlen (p);
261      else if (end > p && end[-1] == '\\')
262        {
263          int backslash = 1;
264          register char *b;
265          for (b = end - 2; b >= p && *b == '\\'; --b)
266            backslash = !backslash;
267          if (backslash)
268            {
269              ++end;
270              goto find_end;
271            }
272        }
273
274      if (idx == nlines)
275        {
276          nlines += 2;
277          lines = (char **) xrealloc ((char *) lines,
278                                      nlines * sizeof (char *));
279        }
280      lines[idx++] = savestring (p, end - p);
281      p = end;
282      if (*p != '\0')
283        ++p;
284    }
285
286  if (idx != nlines)
287    {
288      nlines = idx;
289      lines = (char **) xrealloc ((char *) lines,
290                                  nlines * sizeof (char *));
291    }
292
293  cmds->ncommand_lines = nlines;
294  cmds->command_lines = lines;
295
296  cmds->any_recurse = 0;
297  cmds->lines_flags = (char *) xmalloc (nlines);
298  for (idx = 0; idx < nlines; ++idx)
299    {
300      int flags = 0;
301
302      for (p = lines[idx];
303           isblank ((unsigned char)*p) || *p == '-' || *p == '@' || *p == '+';
304           ++p)
305        switch (*p)
306          {
307          case '+':
308            flags |= COMMANDS_RECURSE;
309            break;
310          case '@':
311            flags |= COMMANDS_SILENT;
312            break;
313          case '-':
314            flags |= COMMANDS_NOERROR;
315            break;
316          }
317      if (!(flags & COMMANDS_RECURSE))
318        {
319          unsigned int len = strlen (p);
320          if (sindex (p, len, "$(MAKE)", 7) != 0
321              || sindex (p, len, "${MAKE}", 7) != 0)
322            flags |= COMMANDS_RECURSE;
323        }
324
325      cmds->lines_flags[idx] = flags;
326      cmds->any_recurse |= flags & COMMANDS_RECURSE;
327    }
328}
329
330/* Execute the commands to remake FILE.  If they are currently executing,
331   return or have already finished executing, just return.  Otherwise,
332   fork off a child process to run the first command line in the sequence.  */
333
334void
335execute_file_commands (file)
336     struct file *file;
337{
338  register char *p;
339
340  /* Don't go through all the preparations if
341     the commands are nothing but whitespace.  */
342
343  for (p = file->cmds->commands; *p != '\0'; ++p)
344    if (!isspace ((unsigned char)*p) && *p != '-' && *p != '@')
345      break;
346  if (*p == '\0')
347    {
348      /* If there are no commands, assume everything worked.  */
349      set_command_state (file, cs_running);
350      file->update_status = 0;
351      notice_finished_file (file);
352      return;
353    }
354
355  /* First set the automatic variables according to this file.  */
356
357  initialize_file_variables (file, 0);
358
359  set_file_variables (file);
360
361  /* Start the commands running.  */
362  new_job (file);
363}
364
365/* This is set while we are inside fatal_error_signal,
366   so things can avoid nonreentrant operations.  */
367
368int handling_fatal_signal = 0;
369
370/* Handle fatal signals.  */
371
372RETSIGTYPE
373fatal_error_signal (sig)
374     int sig;
375{
376#ifdef __MSDOS__
377  extern int dos_status, dos_command_running;
378
379  if (dos_command_running)
380    {
381      /* That was the child who got the signal, not us.  */
382      dos_status |= (sig << 8);
383      return;
384    }
385  remove_intermediates (1);
386  exit (EXIT_FAILURE);
387#else /* not __MSDOS__ */
388#ifdef _AMIGA
389  remove_intermediates (1);
390  if (sig == SIGINT)
391     fputs (_("*** Break.\n"), stderr);
392
393  exit (10);
394#else /* not Amiga */
395  handling_fatal_signal = 1;
396
397  /* Set the handling for this signal to the default.
398     It is blocked now while we run this handler.  */
399  signal (sig, SIG_DFL);
400
401  /* A termination signal won't be sent to the entire
402     process group, but it means we want to kill the children.  */
403
404  if (sig == SIGTERM)
405    {
406      register struct child *c;
407      for (c = children; c != 0; c = c->next)
408        if (!c->remote)
409          (void) kill (c->pid, SIGTERM);
410    }
411
412  /* If we got a signal that means the user
413     wanted to kill make, remove pending targets.  */
414
415  if (sig == SIGTERM || sig == SIGINT
416#ifdef SIGHUP
417    || sig == SIGHUP
418#endif
419#ifdef SIGQUIT
420    || sig == SIGQUIT
421#endif
422    )
423    {
424      register struct child *c;
425
426      /* Remote children won't automatically get signals sent
427         to the process group, so we must send them.  */
428      for (c = children; c != 0; c = c->next)
429        if (c->remote)
430          (void) remote_kill (c->pid, sig);
431
432      for (c = children; c != 0; c = c->next)
433        delete_child_targets (c);
434
435      /* Clean up the children.  We don't just use the call below because
436         we don't want to print the "Waiting for children" message.  */
437      while (job_slots_used > 0)
438        reap_children (1, 0);
439    }
440  else
441    /* Wait for our children to die.  */
442    while (job_slots_used > 0)
443      reap_children (1, 1);
444
445  /* Delete any non-precious intermediate files that were made.  */
446
447  remove_intermediates (1);
448
449#ifdef SIGQUIT
450  if (sig == SIGQUIT)
451    /* We don't want to send ourselves SIGQUIT, because it will
452       cause a core dump.  Just exit instead.  */
453    exit (EXIT_FAILURE);
454#endif
455
456  /* Signal the same code; this time it will really be fatal.  The signal
457     will be unblocked when we return and arrive then to kill us.  */
458  if (kill (getpid (), sig) < 0)
459    pfatal_with_name ("kill");
460#endif /* not Amiga */
461#endif /* not __MSDOS__  */
462}
463
464/* Delete FILE unless it's precious or not actually a file (phony),
465   and it has changed on disk since we last stat'd it.  */
466
467static void
468delete_target (file, on_behalf_of)
469     struct file *file;
470     char *on_behalf_of;
471{
472  struct stat st;
473
474  if (file->precious || file->phony)
475    return;
476
477#ifndef NO_ARCHIVES
478  if (ar_name (file->name))
479    {
480      time_t file_date = (file->last_mtime == NONEXISTENT_MTIME
481                          ? (time_t) -1
482                          : (time_t) FILE_TIMESTAMP_S (file->last_mtime));
483      if (ar_member_date (file->name) != file_date)
484        {
485          if (on_behalf_of)
486            error (NILF, _("*** [%s] Archive member `%s' may be bogus; not deleted"),
487                   on_behalf_of, file->name);
488          else
489            error (NILF, _("*** Archive member `%s' may be bogus; not deleted"),
490                   file->name);
491        }
492      return;
493    }
494#endif
495
496  if (stat (file->name, &st) == 0
497      && S_ISREG (st.st_mode)
498      && FILE_TIMESTAMP_STAT_MODTIME (file->name, st) != file->last_mtime)
499    {
500      if (on_behalf_of)
501        error (NILF, _("*** [%s] Deleting file `%s'"), on_behalf_of, file->name);
502      else
503        error (NILF, _("*** Deleting file `%s'"), file->name);
504      if (unlink (file->name) < 0
505          && errno != ENOENT)   /* It disappeared; so what.  */
506        perror_with_name ("unlink: ", file->name);
507    }
508}
509
510
511/* Delete all non-precious targets of CHILD unless they were already deleted.
512   Set the flag in CHILD to say they've been deleted.  */
513
514void
515delete_child_targets (child)
516     struct child *child;
517{
518  struct dep *d;
519
520  if (child->deleted)
521    return;
522
523  /* Delete the target file if it changed.  */
524  delete_target (child->file, (char *) 0);
525
526  /* Also remove any non-precious targets listed in the `also_make' member.  */
527  for (d = child->file->also_make; d != 0; d = d->next)
528    delete_target (d->file, child->file->name);
529
530  child->deleted = 1;
531}
532
533/* Print out the commands in CMDS.  */
534
535void
536print_commands (cmds)
537     register struct commands *cmds;
538{
539  register char *s;
540
541  fputs (_("#  commands to execute"), stdout);
542
543  if (cmds->fileinfo.filenm == 0)
544    puts (_(" (built-in):"));
545  else
546    printf (_(" (from `%s', line %lu):\n"),
547            cmds->fileinfo.filenm, cmds->fileinfo.lineno);
548
549  s = cmds->commands;
550  while (*s != '\0')
551    {
552      char *end;
553
554      while (isspace ((unsigned char)*s))
555        ++s;
556
557      end = strchr (s, '\n');
558      if (end == 0)
559        end = s + strlen (s);
560
561      printf ("\t%.*s\n", (int) (end - s), s);
562
563      s = end;
564    }
565}
Note: See TracBrowser for help on using the repository browser.