home *** CD-ROM | disk | FTP | other *** search
/ Openstep 4.2 (Developer) / Openstep Developer 4.2.iso / NextDeveloper / Source / GNU / make / make-3.74 / next.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-02-28  |  5.2 KB  |  229 lines

  1. #if NeXT || NeXT_PDO
  2. #include "make.h"
  3. #include "commands.h"
  4. #include "file.h"
  5. #include "variable.h"
  6. #include "dep.h"
  7. #include <sys/types.h>
  8. #include <sys/stat.h>
  9.  
  10. #if !__STDC__
  11. #define const
  12. #endif
  13.  
  14. /* Search through a pathlist for a file.  `search_path' will parse `path',
  15.  * a list of pathnames separated by colons, prepending each pathname to
  16.  * `filename'.  The resulting filename will be checked for existence via
  17.  * stat().
  18.  */
  19. static int
  20. search_path(path, file)
  21.     const char *path;
  22.     char **file;
  23. {
  24.     int n, length;
  25.     char *filename, *name;
  26.     const char *nextchar, *lastchar;
  27.  
  28.     filename = *file;
  29.     n = strlen(filename);
  30.     length = strlen(path) + n + 10;
  31.     name = alloca(length) + length - 1;
  32.     *name = '\0';
  33.  
  34.     filename += n;
  35.     while (--n >= 0)
  36.     *--name = *--filename;
  37.  
  38.     if (*name == '/' || path == 0)
  39.     path = "";
  40.  
  41.     /* Strip off leading './'s, if any. */
  42.     while (*name == '.' && *(name + 1) == '/')
  43.     name += 2;
  44.  
  45.     do {
  46.     /* Advance to the end of the next path in our path list. */
  47.     nextchar = path;
  48. #if defined (__MSDOS__) || defined (WIN32)
  49.     while ((*nextchar != '\0' && *nextchar != ':' && !isspace (*nextchar))
  50.     || (*nextchar == ':' && nextchar - path == 1
  51.       && (nextchar[1] == '/' || nextchar[1] == '\\')))
  52.         nextchar++;
  53. #else
  54.     while (*nextchar != '\0' && *nextchar != ':' && !isspace (*nextchar))
  55.         nextchar++;
  56. #endif
  57.  
  58.     lastchar = nextchar;
  59.     filename = name;
  60.  
  61.     /* If we actually have a path, prepend the file name with a '/'. */
  62.     if (nextchar != path)
  63.         *--filename = '/';
  64.  
  65.     /* Prepend the file name with the path. */
  66.     while (nextchar != path)
  67.         *--filename = *--nextchar;
  68.  
  69.     path = (*lastchar) ? lastchar + 1 : lastchar;
  70.  
  71.     {
  72.         struct stat s;
  73.         if (stat(filename, &s) >= 0) {
  74.         /* We have found a file.
  75.          * Store the name we found into *FILE for the caller.  */
  76.         *file = savestring(filename, strlen(filename));
  77.         return (1);
  78.         }
  79.     }
  80.     } while (*path != 0);
  81.     return (0);
  82. }
  83.  
  84. int
  85. general_vpath_search(file)
  86.     char **file;
  87. {
  88.     int s;
  89.     int savelen;
  90.     char *vpath, *save;
  91.     
  92.     save = save_variable_output(&savelen);
  93.     vpath = variable_expand ("$(VPATH)");
  94.     if (**file == '/' || *vpath == '\0') {
  95.     restore_variable_output(save, savelen);
  96.     return 0;
  97.     }
  98.     s = search_path(vpath, file);
  99.     restore_variable_output(save, savelen);
  100.     return s;
  101. }
  102.  
  103. static int
  104. match_dep(filename, file)
  105.     char **filename;
  106.     struct file *file;
  107. {
  108.     struct dep *d;
  109.  
  110.     /* don't substitute for . or .. */
  111.     if (!strcmp (*filename, ".") || !strcmp (*filename, ".."))
  112.         return 0;
  113.     
  114.     for (d = file->deps; d != 0; d = d->next) {
  115.     if (d->file->old_name != 0) {
  116.         if (strcmp(*filename, d->file->old_name) == 0) {
  117.         *filename = dep_name(d);
  118.         return 1;
  119.         }
  120.     }
  121.     if (strcmp(*filename, dep_name(d)) == 0) {
  122.         if (general_vpath_search(filename))
  123.         return 1;
  124.     }
  125.     }
  126.     return 0;
  127. }
  128.  
  129. /* Scan LINE for vpath references. */
  130.  
  131. static char *
  132. vpath_expand(line, file)
  133.     char *line;
  134.     struct file *file;
  135. {
  136.     struct variable *v;
  137.     char *p, *p1, *o;
  138.     static char *meta = 0;
  139.  
  140.     if (meta == 0) {
  141.     static char buffer[256] = {0};
  142.     meta = buffer;
  143.     meta['\0'] = 1;
  144.     for (p = "=|^();&<>*?[]:$`'\"\\\n"; *p != 0; p++)
  145.         meta[*p] = 1;
  146.     }
  147.  
  148.     p = line;
  149.     o = initialize_variable_output ();
  150.  
  151.     while (1) {
  152.     /* Copy all following uninteresting chars all at once to the
  153.        variable output buffer, and skip them.  Uninteresting chars end
  154.        at the next space or semicolon. */
  155.  
  156.     for (p1 = p; *p1 != 0 && (isspace(*p1) || meta[*p1]); p1++)
  157.         ;
  158.     o = variable_buffer_output (o, p, p1 - p);
  159.     if (*p1 == 0)
  160.         break;
  161.     p = p1;
  162.     while (*p1 != 0 && !(isspace(*p1) || meta[*p1]))
  163.         p1++;
  164.     {
  165.         unsigned int n = p1 - p;
  166.         char *buffer = malloc(n + 1);
  167.         char *filename = buffer;
  168.         struct dep *dep;
  169.  
  170.         strncpy(filename, p, n);
  171.         filename[n] = 0;
  172.  
  173.         if (match_dep(&filename, file)) {
  174.         static struct file *last_file = 0;
  175.         if (last_file != file) {
  176.             last_file = file;
  177.             if (!(next_flag & NEXT_QUIET_FLAG)) {
  178.               makefile_error(file->cmds->filename, file->cmds->lineno,
  179.                      "Using old-style VPATH substitution.");
  180.               makefile_error(file->cmds->filename, file->cmds->lineno,
  181.                      "Consider using automatic variable substitution instead.");
  182.             }
  183.         }
  184.         o = variable_buffer_output (o, filename, strlen(filename));
  185.         } else {
  186.         o = variable_buffer_output (o, filename, n);
  187.         }
  188.         p = p1;
  189.         free(buffer);
  190.     }
  191.     if (*p == '\0')
  192.         break;
  193.     }
  194.     (void) variable_buffer_output (o, "", 1);
  195.     return initialize_variable_output ();
  196. }
  197.  
  198. char *
  199. allocated_vpath_expand_for_file(line, file)
  200.     char *line;
  201.     struct file *file;
  202. {
  203.     char *save, *value;
  204.     struct variable_set_list *save_set_list;
  205.     int savelen;
  206.  
  207.     if (file == 0)
  208.     makefile_fatal("Can't do VPATH expansion on a null file.\n");
  209.     
  210.     save = save_variable_output (&savelen);
  211.     
  212.     save_set_list = current_variable_set_list;
  213.     current_variable_set_list = file->variables;
  214.     reading_filename = file->cmds->filename;
  215.     reading_lineno_ptr = &file->cmds->lineno;
  216.     value = vpath_expand (line, file);
  217.     current_variable_set_list = save_set_list;
  218.     reading_filename = 0;
  219.     reading_lineno_ptr = 0;
  220.     
  221.  
  222.     value = savestring (value, strlen (value));
  223.     
  224.     restore_variable_output (save, savelen);
  225.     
  226.     return value;
  227. }
  228. #endif    /* NeXT || NeXT_PDO */
  229.