--- /dev/null Fri Oct 29 17:01:51 2004
+++ next.c Fri Oct 29 17:01:41 2004
@@ -0,0 +1,226 @@
+#if defined(__APPLE__) || defined(NeXT) || defined(NeXT_PDO)
+#include "make.h"
+#include "job.h"
+#include "commands.h"
+#include "filedef.h"
+#include "variable.h"
+#include "dep.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#if !__STDC__
+#define const
+#endif
+
+
+static int
+search_path(path, file)
+ const char *path;
+ char **file;
+{
+ int n, length;
+ char *filename, *name;
+ const char *nextchar, *lastchar;
+
+ filename = *file;
+ n = strlen(filename);
+ length = strlen(path) + n + 10;
+ name = alloca(length) + length - 1;
+ *name = '\0';
+
+ filename += n;
+ while (--n >= 0)
+ *--name = *--filename;
+
+ if (*name == '/' || path == 0)
+ path = "";
+
+
+ while (*name == '.' && *(name + 1) == '/')
+ name += 2;
+
+ do {
+
+ nextchar = path;
+#if defined (__MSDOS__) || defined (WIN32)
+ while ((*nextchar != '\0' && *nextchar != ':' && !isspace (*nextchar))
+ || (*nextchar == ':' && nextchar - path == 1
+ && (nextchar[1] == '/' || nextchar[1] == '\\')))
+ nextchar++;
+#else
+ while (*nextchar != '\0' && *nextchar != ':' && !isspace (*nextchar))
+ nextchar++;
+#endif
+
+ lastchar = nextchar;
+ filename = name;
+
+
+ if (nextchar != path)
+ *--filename = '/';
+
+
+ while (nextchar != path)
+ *--filename = *--nextchar;
+
+ path = (*lastchar) ? lastchar + 1 : lastchar;
+
+ {
+ struct stat s;
+ if (stat(filename, &s) >= 0) {
+
+ *file = savestring(filename, strlen(filename));
+ return (1);
+ }
+ }
+ } while (*path != 0);
+ return (0);
+}
+
+int
+general_vpath_search(file)
+ char **file;
+{
+ int s;
+ int savelen;
+ char *vpath, *save;
+
+ save = save_variable_output(&savelen);
+ vpath = variable_expand ("$(VPATH)");
+ if (**file == '/' || *vpath == '\0') {
+ restore_variable_output(save, savelen);
+ return 0;
+ }
+ s = search_path(vpath, file);
+ restore_variable_output(save, savelen);
+ return s;
+}
+
+static int
+match_dep(filename, file)
+ char **filename;
+ struct file *file;
+{
+ struct dep *d;
+
+
+ if (!strcmp (*filename, ".") || !strcmp (*filename, ".."))
+ return 0;
+
+ for (d = file->deps; d != 0; d = d->next) {
+ if (d->file->old_name != 0) {
+ if (strcmp(*filename, d->file->old_name) == 0) {
+ *filename = dep_name(d);
+ return 1;
+ }
+ }
+ if (strcmp(*filename, dep_name(d)) == 0) {
+ if (general_vpath_search(filename))
+ return 1;
+ }
+ }
+ return 0;
+}
+
+
+
+static char *
+vpath_expand(line, file)
+ char *line;
+ struct file *file;
+{
+ struct variable *v;
+ char *p, *p1, *o;
+ static char *meta = 0;
+
+ if (meta == 0) {
+ static char buffer[256] = {0};
+ meta = buffer;
+ meta['\0'] = 1;
+ for (p = "=|^();&<>*?[]:$`'\"\\\n"; *p != 0; p++)
+ meta[*p] = 1;
+ }
+
+ p = line;
+ o = initialize_variable_output ();
+
+ while (1) {
+
+
+ for (p1 = p; *p1 != 0 && (isspace(*p1) || meta[*p1]); p1++)
+ ;
+ o = variable_buffer_output (o, p, p1 - p);
+ if (*p1 == 0)
+ break;
+ p = p1;
+ while (*p1 != 0 && !(isspace(*p1) || meta[*p1]))
+ p1++;
+ {
+ unsigned int n = p1 - p;
+ char *buffer = malloc(n + 1);
+ char *filename = buffer;
+ struct dep *dep;
+
+ strncpy(filename, p, n);
+ filename[n] = 0;
+
+ if (match_dep(&filename, file)) {
+ static struct file *last_file = 0;
+ if (last_file != file) {
+ last_file = file;
+ if (!(next_flag & NEXT_QUIET_FLAG)) {
+ error(&file->cmds->fileinfo,
+ "Using old-style VPATH substitution.");
+ error(&file->cmds->fileinfo,
+ "Consider using automatic variable substitution instead.");
+ }
+ }
+ o = variable_buffer_output (o, filename, strlen(filename));
+ } else {
+ o = variable_buffer_output (o, filename, n);
+ }
+ p = p1;
+ free(buffer);
+ }
+ if (*p == '\0')
+ break;
+ }
+ (void) variable_buffer_output (o, "", 1);
+ return initialize_variable_output ();
+}
+
+char *
+allocated_vpath_expand_for_file(line, file)
+ char *line;
+ struct file *file;
+{
+ char *save, *value;
+ struct variable_set_list *save_set_list;
+ int savelen;
+
+ if (file == 0)
+ fatal(NILF, "Can't do VPATH expansion on a null file.\n");
+
+ save = save_variable_output (&savelen);
+
+ save_set_list = current_variable_set_list;
+ current_variable_set_list = file->variables;
+ reading_file = &file->cmds->fileinfo;
+ value = vpath_expand (line, file);
+ current_variable_set_list = save_set_list;
+ reading_file = 0;
+
+ value = savestring (value, strlen (value));
+
+ restore_variable_output (save, savelen);
+
+ return value;
+}
+#endif