summaryrefslogtreecommitdiffstats
path: root/soltools/mkdepend
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--soltools/mkdepend/collectdircontent.cxx91
-rw-r--r--soltools/mkdepend/collectdircontent.hxx60
-rw-r--r--soltools/mkdepend/cppsetup.c214
-rw-r--r--soltools/mkdepend/def.h193
-rw-r--r--soltools/mkdepend/ifparser.c426
-rw-r--r--soltools/mkdepend/ifparser.h75
-rw-r--r--soltools/mkdepend/imakemdep.h697
-rw-r--r--soltools/mkdepend/include.c347
-rw-r--r--soltools/mkdepend/main.c740
-rw-r--r--soltools/mkdepend/mkdepend.man368
-rw-r--r--soltools/mkdepend/parse.c402
-rw-r--r--soltools/mkdepend/pr.c146
12 files changed, 3759 insertions, 0 deletions
diff --git a/soltools/mkdepend/collectdircontent.cxx b/soltools/mkdepend/collectdircontent.cxx
new file mode 100644
index 000000000..c5e910c2e
--- /dev/null
+++ b/soltools/mkdepend/collectdircontent.cxx
@@ -0,0 +1,91 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+#include "collectdircontent.hxx"
+#include <rtl/character.hxx>
+
+PathFilePair IncludesCollection::split_path(const std::string& filePath) {
+ std::string sepU = "/";
+ std::string sepW = "\\";
+ std::string::size_type pos = filePath.rfind (sepU);
+ std::string::size_type posW = filePath.rfind (sepW);
+ if ((posW != std::string::npos) && ((posW > pos) || (pos == std::string::npos))) pos = posW;
+ if (pos != std::string::npos) {
+ std::string dirName = filePath.substr(0, pos);
+ return PathFilePair(dirName, filePath.substr(pos + 1, filePath.length()));
+ } else
+ return PathFilePair(".", filePath);
+}
+
+void IncludesCollection::add_to_collection(const std::string& dirPath) {
+ DirContent dirContent;
+#if defined(_WIN32)
+ WIN32_FIND_DATA FindFileData;
+ HANDLE hFind;
+ hFind = FindFirstFile((dirPath + "\\*").c_str(), &FindFileData);
+ if (hFind == INVALID_HANDLE_VALUE) {
+ // Invalid File Handle - no need to try it anymore
+ allIncludes.insert(EntriesPair(dirPath, DirContent()));
+ return;
+ }
+ do {
+ std::string winFileName(FindFileData.cFileName);
+ transform(
+ winFileName.begin(), winFileName.end(), winFileName.begin(),
+ [](char c) {
+ return rtl::toAsciiLowerCase(static_cast<unsigned char>(c));
+ });
+ dirContent.insert(winFileName);
+ } while (FindNextFile(hFind, &FindFileData));
+#else
+ DIR *pdir;
+ dirent *pent;
+ pdir = opendir(dirPath.c_str()); //"." refers to the current dir
+ if (!pdir) {
+ // Invalid File Handle - no need to try it anymore
+ allIncludes.insert(EntriesPair(dirPath, DirContent()));
+ return;
+ }
+ while ((pent = readdir(pdir))) {
+ dirContent.insert(pent->d_name);
+ }
+ closedir(pdir);
+#endif // defined( _WIN32 )
+ allIncludes.insert(EntriesPair(dirPath, dirContent));
+}
+
+bool IncludesCollection::exists(std::string filePath) {
+#if defined(_WIN32)
+ transform(
+ filePath.begin(), filePath.end(), filePath.begin(),
+ [](char c) {
+ return rtl::toAsciiLowerCase(static_cast<unsigned char>(c));
+ });
+#endif // defined( _WIN32 )
+ PathFilePair dirFile = split_path(filePath);
+ std::string dirPath = dirFile.first;
+ std::string fileName = dirFile.second;
+ DirMap::iterator mapIter = allIncludes.find(dirPath);
+ if (mapIter == allIncludes.end()) {
+ add_to_collection(dirPath);
+ mapIter = allIncludes.find(dirPath);
+ }
+ DirContent dirContent = (*mapIter).second;
+ DirContent::iterator dirIter = dirContent.find(fileName);
+ return dirIter != dirContent.end();
+}
+
+extern "C" {
+
+ IncludesCollection * create_IncludesCollection() {
+ return new IncludesCollection;
+ }
+
+ void delete_IncludesCollection(IncludesCollection *m) {
+ delete m;
+ }
+
+ int call_IncludesCollection_exists(IncludesCollection* m, const char * filePath) {
+ return m->exists(filePath);
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/soltools/mkdepend/collectdircontent.hxx b/soltools/mkdepend/collectdircontent.hxx
new file mode 100644
index 000000000..6821b7643
--- /dev/null
+++ b/soltools/mkdepend/collectdircontent.hxx
@@ -0,0 +1,60 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+#ifndef INCLUDED_SOLTOOLS_MKDEPEND_COLLECTDIRCONTENT_HXX
+#define INCLUDED_SOLTOOLS_MKDEPEND_COLLECTDIRCONTENT_HXX
+
+#if defined __cplusplus
+
+#include <set>
+#include <map>
+#include <string>
+
+#if defined(_WIN32)
+#if !defined WIN32_LEAN_AND_MEAN
+# define WIN32_LEAN_AND_MEAN
+#endif
+#include <windows.h>
+#include <algorithm>
+#else
+#include <dirent.h>
+#endif // defined( _WIN32 )
+
+#include <iostream>
+
+typedef std::set<std::string> DirContent;
+typedef std::map<std::string, DirContent> DirMap;
+typedef DirMap::value_type EntriesPair;
+typedef std::pair<std::string, std::string> PathFilePair;
+
+
+struct IncludesCollection {
+private:
+ DirMap allIncludes;
+ static PathFilePair split_path(const std::string& filePath);
+ void add_to_collection(const std::string& dirPath);
+
+public:
+ bool exists(std::string filePath);
+};
+
+#else
+
+struct IncludesCollection;
+
+#endif
+
+#if defined __cplusplus
+extern "C" {
+#endif
+
+struct IncludesCollection * create_IncludesCollection(void);
+void delete_IncludesCollection(struct IncludesCollection *);
+
+int call_IncludesCollection_exists(struct IncludesCollection* m, const char* filePath);
+
+#if defined __cplusplus
+}
+#endif
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/soltools/mkdepend/cppsetup.c b/soltools/mkdepend/cppsetup.c
new file mode 100644
index 000000000..e731e9fb4
--- /dev/null
+++ b/soltools/mkdepend/cppsetup.c
@@ -0,0 +1,214 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* $XConsortium: cppsetup.c,v 1.13 94/04/17 20:10:32 gildea Exp $ */
+/*
+
+Copyright (c) 1993, 1994 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+*/
+
+#include <ctype.h>
+
+#include "def.h"
+
+#ifdef CPP
+/*
+ * This file is strictly for the sake of cpy.y and yylex.c (if
+ * you indeed have the source for cpp).
+ */
+#define IB 1
+#define SB 2
+#define NB 4
+#define CB 8
+#define QB 16
+#define WB 32
+#define SALT '#'
+#if pdp11 | vax | ns16000 | mc68000 | ibm032
+#define COFF 128
+#else
+#define COFF 0
+#endif
+/*
+ * These variables used by cpy.y and yylex.c
+ */
+extern char *outp, *inp, *newp, *pend;
+extern char *ptrtab;
+extern char fastab[];
+extern char slotab[];
+
+/*
+ * cppsetup
+ */
+struct filepointer *currentfile;
+struct inclist *currentinc;
+
+cppsetup(line, filep, inc)
+ char *line;
+ struct filepointer *filep;
+ struct inclist *inc;
+{
+ char *p, savec;
+ static boolean setupdone = FALSE;
+ boolean value;
+
+ if (!setupdone) {
+ cpp_varsetup();
+ setupdone = TRUE;
+ }
+
+ currentfile = filep;
+ currentinc = inc;
+ inp = newp = line;
+ for (p=newp; *p; p++)
+ ;
+
+ /*
+ * put a newline back on the end, and set up pend, etc.
+ */
+ *p++ = '\n';
+ savec = *p;
+ *p = '\0';
+ pend = p;
+
+ ptrtab = slotab+COFF;
+ *--inp = SALT;
+ outp=inp;
+ value = yyparse();
+ *p = savec;
+ return value;
+}
+
+pperror(tag, x0,x1,x2,x3,x4)
+ int tag,x0,x1,x2,x3,x4;
+{
+ warning("\"%s\", line %d: ", currentinc->i_file, currentfile->f_line);
+ warning(x0,x1,x2,x3,x4);
+}
+
+
+yyerror(s)
+ char *s;
+{
+ fatalerr("Fatal error: %s\n", s);
+}
+#else /* not CPP */
+
+#include "ifparser.h"
+
+static const char *
+my_if_errors (IfParser *ip, const char *cp, const char *expecting)
+{
+#ifdef DEBUG_MKDEPEND
+ struct parse_data *pd = (struct parse_data *) ip->data;
+ int lineno = pd->filep->f_line;
+ char *filename = pd->inc->i_file;
+ char prefix[300];
+ int prefixlen;
+ int i;
+
+ sprintf (prefix, "\"%s\":%d", filename, lineno);
+ prefixlen = strlen(prefix);
+ fprintf (stderr, "%s: %s", prefix, pd->line);
+ i = cp - pd->line;
+ if (i > 0 && pd->line[i-1] != '\n') {
+ putc ('\n', stderr);
+ }
+ for (i += prefixlen + 3; i > 0; i--) {
+ putc (' ', stderr);
+ }
+ fprintf (stderr, "^--- expecting %s\n", expecting);
+#endif /* DEBUG_MKDEPEND */
+ (void)ip;
+ (void)cp;
+ (void)expecting;
+ return NULL;
+}
+
+
+#define MAXNAMELEN 256
+
+static char *
+lookup_variable (const char *var, size_t len)
+{
+ char tmpbuf[MAXNAMELEN + 1];
+
+ if (len > MAXNAMELEN)
+ return NULL;
+
+ strncpy (tmpbuf, var, len);
+ tmpbuf[len] = '\0';
+ return isdefined(tmpbuf);
+}
+
+
+static int
+my_eval_defined (IfParser *ip, const char *var, size_t len)
+{
+ (void)ip;
+ if (lookup_variable (var, len))
+ return 1;
+ else
+ return 0;
+}
+
+#define isvarfirstletter(ccc) (isalpha((unsigned char)(ccc)) || (ccc) == '_')
+
+static int
+my_eval_variable (IfParser *ip, const char *var, size_t len)
+{
+ char *s;
+
+ (void)ip;
+
+ s = lookup_variable (var, len);
+ if (!s)
+ return 0;
+ do {
+ var = s;
+ if (!isvarfirstletter(*var))
+ break;
+ s = lookup_variable (var, strlen(var));
+ } while (s);
+
+ return atoi(var);
+}
+
+
+int cppsetup(char const *line)
+{
+ IfParser ip;
+ int val = 0;
+
+ ip.funcs.handle_error = my_if_errors;
+ ip.funcs.eval_defined = my_eval_defined;
+ ip.funcs.eval_variable = my_eval_variable;
+
+ (void) ParseIfExpression (&ip, line, &val);
+ if (val)
+ return IF;
+ else
+ return IFFALSE;
+}
+#endif /* CPP */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/soltools/mkdepend/def.h b/soltools/mkdepend/def.h
new file mode 100644
index 000000000..bd06c5f01
--- /dev/null
+++ b/soltools/mkdepend/def.h
@@ -0,0 +1,193 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* $XConsortium: def.h,v 1.25 94/04/17 20:10:33 gildea Exp $ */
+/*
+
+Copyright (c) 1993, 1994 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+*/
+
+#ifndef NO_X11
+#include <X11/Xosdefs.h>
+#ifdef _WIN32
+#include <X11/Xw32defs.h>
+#endif
+#ifndef SUNOS4
+#include <X11/Xfuncproto.h>
+#endif /* SUNOS4 */
+#endif /* NO_X11 */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#ifndef _MSC_VER
+#include <unistd.h>
+#endif
+
+#ifndef X_NOT_POSIX
+#ifndef _POSIX_SOURCE
+#define _POSIX_SOURCE
+#endif
+#endif
+#include <sys/types.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+#ifndef S_IFDIR
+#define S_IFDIR 0040000
+#endif
+
+#ifndef S_IFREG
+#define S_IFREG 0100000
+#endif
+
+#define MAXFILES 65536
+
+#define MAXDIRS 64
+#define SYMHASHSEED 131 /* 131 1313 13131 ... */
+#define SYMHASHMEMBERS 64 /* must be 2^x to work right */
+#define TRUE 1
+#define FALSE 0
+
+/* the following must match the directives table in main.c */
+#define IF 0
+#define ERROR 10
+#define ELIF 13
+#define IFFALSE 15 /* pseudo value --- never matched */
+#define ELIFFALSE 16 /* pseudo value --- never matched */
+#define ELIFGUESSFALSE 19 /* pseudo value --- never matched */
+
+#ifdef DEBUG
+extern int _debugmask;
+/*
+ * debug levels are:
+ *
+ * 0 show ifn*(def)*,endif
+ * 1 trace defined/!defined
+ * 2 show #include
+ * 3 show #include SYMBOL
+ * 4-6 unused
+ */
+#define debug(level,arg) { if (_debugmask & (1 << level)) warning arg; }
+#else
+#define debug(level,arg) /**/
+#endif /* DEBUG */
+
+// VG: a C++ class for information about directories
+#include "collectdircontent.hxx"
+
+typedef unsigned char boolean;
+
+struct pair {
+ char *p_name;
+ char *p_value;
+ struct pair *p_next;
+};
+
+struct symhash {
+ struct pair *s_pairs[SYMHASHMEMBERS];
+};
+
+struct inclist {
+ char *i_incstring; /* string from #include line */
+ char *i_file; /* path name of the include file */
+ struct inclist **i_list; /* list of files it itself includes */
+ int i_listlen; /* length of i_list */
+ boolean i_notified; /* whether we have revealed includes */
+ boolean i_marked; /* whether it's in the makefile */
+ boolean i_searched; /* whether we have read this */
+};
+
+struct filepointer {
+ char *f_p;
+ char *f_base;
+ char *f_end;
+ int f_line;
+};
+
+#ifndef X_NOT_STDC_ENV
+#if defined(macII) && !defined(__STDC__) /* stdlib.h fails to define these */
+char *malloc(), *realloc();
+#endif /* macII */
+#else
+char *malloc();
+char *realloc();
+#endif
+
+char *copy(char const *);
+char *base_name(char *);
+char *get_line(struct filepointer *);
+char *isdefined(char *);
+struct filepointer *getfile(char *);
+struct inclist *newinclude(char const *newfile,
+ char const *incstring);
+struct inclist *inc_path(char *, char *, boolean,
+ struct IncludesCollection *);
+
+void define( char *def, struct symhash **symbols );
+void hash_define(char *name, char const * val, struct symhash **symbols);
+struct symhash *hash_copy( struct symhash *symbols );
+void hash_free( struct symhash *symbols );
+void freefile( struct filepointer * fp );
+int find_includes(struct filepointer *filep, struct inclist *file,
+ struct inclist *file_red, int recursion, boolean failOK,
+ struct IncludesCollection* incCollection, struct symhash *symbols);
+void included_by(struct inclist *ip,
+ struct inclist * newfile);
+int cppsetup(char const *line);
+void add_include(struct filepointer *filep, struct inclist *file,
+ struct inclist *file_red, char *include, boolean dot, boolean failOK,
+ struct IncludesCollection* incCollection, struct symhash *symbols);
+int match(char const *str, char **list);
+void recursive_pr_include(struct inclist *head, char *file,
+ char *base);
+void recursive_pr_dummy(struct inclist *head, char *file);
+void inc_clean(void);
+
+void fatalerr(char *, ...);
+void warning(char const *, ...);
+void warning1(char const *, ...);
+
+void convert_slashes(char *);
+char *append_slash(char *);
+
+extern char * directives[];
+
+extern struct inclist inclist[ MAXFILES ];
+extern struct inclist * inclistp;
+
+extern char *includedirs[ ];
+
+extern char * objprefix;
+
+extern char * objsuffix;
+
+extern boolean printed;
+
+extern boolean verbose;
+
+extern boolean show_where_not;
+
+extern boolean warn_multiple;
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/soltools/mkdepend/ifparser.c b/soltools/mkdepend/ifparser.c
new file mode 100644
index 000000000..52eb40d2e
--- /dev/null
+++ b/soltools/mkdepend/ifparser.c
@@ -0,0 +1,426 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * $XConsortium: ifparser.c,v 1.8 95/06/03 00:01:41 gildea Exp $
+ *
+ * Copyright 1992 Network Computing Devices, Inc.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Network Computing Devices may not be
+ * used in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. Network Computing Devices makes
+ * no representations about the suitability of this software for any purpose.
+ * It is provided ``as is'' without express or implied warranty.
+ *
+ * NETWORK COMPUTING DEVICES DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
+ * IN NO EVENT SHALL NETWORK COMPUTING DEVICES BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Jim Fulton
+ * Network Computing Devices, Inc.
+ *
+ * Simple if statement processor
+ *
+ * This module can be used to evaluate string representations of C language
+ * if constructs. It accepts the following grammar:
+ *
+ * EXPRESSION := VALUE
+ * | VALUE BINOP EXPRESSION
+ *
+ * VALUE := '(' EXPRESSION ')'
+ * | '!' VALUE
+ * | '-' VALUE
+ * | 'defined' '(' variable ')'
+ * | 'defined' variable
+ * | # variable '(' variable-list ')'
+ * | variable
+ * | number
+ *
+ * BINOP := '*' | '/' | '%'
+ * | '+' | '-'
+ * | '<<' | '>>'
+ * | '<' | '>' | '<=' | '>='
+ * | '==' | '!='
+ * | '&' | '|'
+ * | '&&' | '||'
+ *
+ * The normal C order of precedence is supported.
+ *
+ *
+ * External Entry Points:
+ *
+ * ParseIfExpression parse a string for #if
+ */
+
+#include "ifparser.h"
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+
+/****************************************************************************
+ Internal Macros and Utilities for Parser
+ ****************************************************************************/
+
+#define DO(val) if (!(val)) return NULL
+#define CALLFUNC(ggg,fff) (*((ggg)->funcs.fff))
+#define SKIPSPACE(ccc) while (isspace((unsigned char)*ccc)) ccc++
+#define isvarfirstletter(ccc) (isalpha((unsigned char)(ccc)) || (ccc) == '_')
+
+
+static const char *
+parse_variable (IfParser *g, const char *cp, const char **varp)
+{
+ SKIPSPACE (cp);
+
+ if (!isvarfirstletter (*cp))
+ return CALLFUNC(g, handle_error) (g, cp, "variable name");
+
+ *varp = cp;
+ /* EMPTY */
+ for (cp++; isalnum((unsigned char)*cp) || *cp == '_'; cp++) ;
+ return cp;
+}
+
+
+static const char *
+parse_number (IfParser *g, const char *cp, int *valp)
+{
+ SKIPSPACE (cp);
+
+ if (!isdigit((unsigned char)*cp))
+ return CALLFUNC(g, handle_error) (g, cp, "number");
+
+#ifdef _WIN32
+ {
+ char *cp2;
+ *valp = strtol(cp, &cp2, 0);
+ }
+#else
+ *valp = atoi (cp);
+ /* EMPTY */
+ for (cp++; isdigit((unsigned char)*cp); cp++) ;
+#endif
+ return cp;
+}
+
+
+static const char *
+parse_value (IfParser *g, const char *cp, int *valp)
+{
+ const char *var;
+
+ *valp = 0;
+
+ SKIPSPACE (cp);
+ if (!*cp)
+ return cp;
+
+ switch (*cp) {
+ case '(':
+ DO (cp = ParseIfExpression (g, cp + 1, valp));
+ SKIPSPACE (cp);
+ if (*cp != ')')
+ return CALLFUNC(g, handle_error) (g, cp, ")");
+
+ return cp + 1; /* skip the right paren */
+
+ case '!':
+ DO (cp = parse_value (g, cp + 1, valp));
+ *valp = !(*valp);
+ return cp;
+
+ case '-':
+ DO (cp = parse_value (g, cp + 1, valp));
+ *valp = -(*valp);
+ return cp;
+
+ case '#':
+ DO (cp = parse_variable (g, cp + 1, &var));
+ SKIPSPACE (cp);
+ if (*cp != '(')
+ return CALLFUNC(g, handle_error) (g, cp, "(");
+ do {
+ DO (cp = parse_variable (g, cp + 1, &var));
+ SKIPSPACE (cp);
+ } while (*cp && *cp != ')');
+ if (*cp != ')')
+ return CALLFUNC(g, handle_error) (g, cp, ")");
+ *valp = 1; /* XXX */
+ return cp + 1;
+
+ case 'd':
+ if (strncmp (cp, "defined", 7) == 0 && !isalnum((unsigned char)cp[7])) {
+ int paren = 0;
+ size_t len;
+
+ cp += 7;
+ SKIPSPACE (cp);
+ if (*cp == '(') {
+ paren = 1;
+ cp++;
+ }
+ DO (cp = parse_variable (g, cp, &var));
+ len = (size_t)(cp - var);
+ SKIPSPACE (cp);
+ if (paren && *cp != ')')
+ return CALLFUNC(g, handle_error) (g, cp, ")");
+ *valp = (*(g->funcs.eval_defined)) (g, var, len);
+ return cp + paren; /* skip the right paren */
+ }
+ /* fall out */
+ }
+
+ if (isdigit((unsigned char)*cp)) {
+ DO (cp = parse_number (g, cp, valp));
+ } else if (!isvarfirstletter(*cp))
+ return CALLFUNC(g, handle_error) (g, cp, "variable or number");
+ else {
+ DO (cp = parse_variable (g, cp, &var));
+ *valp = (*(g->funcs.eval_variable)) (g, var, (size_t)(cp - var));
+ }
+
+ return cp;
+}
+
+
+
+static const char *
+parse_product (IfParser *g, const char *cp, int *valp)
+{
+ int rightval;
+
+ DO (cp = parse_value (g, cp, valp));
+ SKIPSPACE (cp);
+
+ switch (*cp) {
+ case '*':
+ DO (cp = parse_product (g, cp + 1, &rightval));
+ *valp = (*valp * rightval);
+ break;
+
+ case '/':
+ DO (cp = parse_product (g, cp + 1, &rightval));
+
+ /* Do nothing in the divide-by-zero case. */
+ if (rightval) {
+ *valp = (*valp / rightval);
+ }
+ break;
+
+ case '%':
+ DO (cp = parse_product (g, cp + 1, &rightval));
+ *valp = (*valp % rightval);
+ break;
+ }
+ return cp;
+}
+
+
+static const char *
+parse_sum (IfParser *g, const char *cp, int *valp)
+{
+ int rightval;
+
+ DO (cp = parse_product (g, cp, valp));
+ SKIPSPACE (cp);
+
+ switch (*cp) {
+ case '+':
+ DO (cp = parse_sum (g, cp + 1, &rightval));
+ *valp = (*valp + rightval);
+ break;
+
+ case '-':
+ DO (cp = parse_sum (g, cp + 1, &rightval));
+ *valp = (*valp - rightval);
+ break;
+ }
+ return cp;
+}
+
+
+static const char *
+parse_shift (IfParser *g, const char *cp, int *valp)
+{
+ int rightval;
+
+ DO (cp = parse_sum (g, cp, valp));
+ SKIPSPACE (cp);
+
+ switch (*cp) {
+ case '<':
+ if (cp[1] == '<') {
+ DO (cp = parse_shift (g, cp + 2, &rightval));
+ *valp = (*valp << rightval);
+ }
+ break;
+
+ case '>':
+ if (cp[1] == '>') {
+ DO (cp = parse_shift (g, cp + 2, &rightval));
+ *valp = (*valp >> rightval);
+ }
+ break;
+ }
+ return cp;
+}
+
+
+static const char *
+parse_inequality (IfParser *g, const char *cp, int *valp)
+{
+ int rightval;
+
+ DO (cp = parse_shift (g, cp, valp));
+ SKIPSPACE (cp);
+
+ switch (*cp) {
+ case '<':
+ if (cp[1] == '=') {
+ DO (cp = parse_inequality (g, cp + 2, &rightval));
+ *valp = (*valp <= rightval);
+ } else {
+ DO (cp = parse_inequality (g, cp + 1, &rightval));
+ *valp = (*valp < rightval);
+ }
+ break;
+
+ case '>':
+ if (cp[1] == '=') {
+ DO (cp = parse_inequality (g, cp + 2, &rightval));
+ *valp = (*valp >= rightval);
+ } else {
+ DO (cp = parse_inequality (g, cp + 1, &rightval));
+ *valp = (*valp > rightval);
+ }
+ break;
+ }
+ return cp;
+}
+
+
+static const char *
+parse_equality (IfParser *g, const char *cp, int *valp)
+{
+ int rightval;
+
+ DO (cp = parse_inequality (g, cp, valp));
+ SKIPSPACE (cp);
+
+ switch (*cp) {
+ case '=':
+ if (cp[1] == '=')
+ cp++;
+ DO (cp = parse_equality (g, cp + 1, &rightval));
+ *valp = (*valp == rightval);
+ break;
+
+ case '!':
+ if (cp[1] != '=')
+ break;
+ DO (cp = parse_equality (g, cp + 2, &rightval));
+ *valp = (*valp != rightval);
+ break;
+ }
+ return cp;
+}
+
+
+static const char *
+parse_band (IfParser *g, const char *cp, int *valp)
+{
+ int rightval;
+
+ DO (cp = parse_equality (g, cp, valp));
+ SKIPSPACE (cp);
+
+ switch (*cp) {
+ case '&':
+ if (cp[1] != '&') {
+ DO (cp = parse_band (g, cp + 1, &rightval));
+ *valp = (*valp & rightval);
+ }
+ break;
+ }
+ return cp;
+}
+
+
+static const char *
+parse_bor (IfParser *g, const char *cp, int *valp)
+{
+ int rightval;
+
+ DO (cp = parse_band (g, cp, valp));
+ SKIPSPACE (cp);
+
+ switch (*cp) {
+ case '|':
+ if (cp[1] != '|') {
+ DO (cp = parse_bor (g, cp + 1, &rightval));
+ *valp = (*valp | rightval);
+ }
+ break;
+ }
+ return cp;
+}
+
+
+static const char *
+parse_land (IfParser *g, const char *cp, int *valp)
+{
+ int rightval;
+
+ DO (cp = parse_bor (g, cp, valp));
+ SKIPSPACE (cp);
+
+ switch (*cp) {
+ case '&':
+ if (cp[1] != '&')
+ return CALLFUNC(g, handle_error) (g, cp, "&&");
+ DO (cp = parse_land (g, cp + 2, &rightval));
+ *valp = (*valp && rightval);
+ break;
+ }
+ return cp;
+}
+
+
+static const char *
+parse_lor (IfParser *g, const char *cp, int *valp)
+{
+ int rightval;
+
+ DO (cp = parse_land (g, cp, valp));
+ SKIPSPACE (cp);
+
+ switch (*cp) {
+ case '|':
+ if (cp[1] != '|')
+ return CALLFUNC(g, handle_error) (g, cp, "||");
+ DO (cp = parse_lor (g, cp + 2, &rightval));
+ *valp = (*valp || rightval);
+ break;
+ }
+ return cp;
+}
+
+
+/****************************************************************************
+ External Entry Points
+ ****************************************************************************/
+
+const char *
+ParseIfExpression (IfParser *g, const char *cp, int *valp)
+{
+ return parse_lor (g, cp, valp);
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/soltools/mkdepend/ifparser.h b/soltools/mkdepend/ifparser.h
new file mode 100644
index 000000000..25da651c1
--- /dev/null
+++ b/soltools/mkdepend/ifparser.h
@@ -0,0 +1,75 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * $XConsortium: ifparser.h,v 1.1 92/08/22 13:05:39 rws Exp $
+ *
+ * Copyright 1992 Network Computing Devices, Inc.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Network Computing Devices may not be
+ * used in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. Network Computing Devices makes
+ * no representations about the suitability of this software for any purpose.
+ * It is provided ``as is'' without express or implied warranty.
+ *
+ * NETWORK COMPUTING DEVICES DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
+ * IN NO EVENT SHALL NETWORK COMPUTING DEVICES BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Jim Fulton
+ * Network Computing Devices, Inc.
+ *
+ * Simple if statement processor
+ *
+ * This module can be used to evaluate string representations of C language
+ * if constructs. It accepts the following grammar:
+ *
+ * EXPRESSION := VALUE
+ * | VALUE BINOP EXPRESSION
+ *
+ * VALUE := '(' EXPRESSION ')'
+ * | '!' VALUE
+ * | '-' VALUE
+ * | 'defined' '(' variable ')'
+ * | variable
+ * | number
+ *
+ * BINOP := '*' | '/' | '%'
+ * | '+' | '-'
+ * | '<<' | '>>'
+ * | '<' | '>' | '<=' | '>='
+ * | '==' | '!='
+ * | '&' | '|'
+ * | '&&' | '||'
+ *
+ * The normal C order of precedence is supported.
+ *
+ *
+ * External Entry Points:
+ *
+ * ParseIfExpression parse a string for #if
+ */
+
+#include <stdio.h>
+
+typedef int Bool;
+#define False 0
+#define True 1
+
+typedef struct if_parser {
+ struct { /* functions */
+ const char *(*handle_error) (struct if_parser *, const char *, const char *);
+ int (*eval_variable) (struct if_parser *, const char *, size_t);
+ int (*eval_defined) (struct if_parser *, const char *, size_t);
+ } funcs;
+} IfParser;
+
+const char *ParseIfExpression (IfParser *, const char *, int *);
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/soltools/mkdepend/imakemdep.h b/soltools/mkdepend/imakemdep.h
new file mode 100644
index 000000000..4a947ee44
--- /dev/null
+++ b/soltools/mkdepend/imakemdep.h
@@ -0,0 +1,697 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+
+/* $XConsortium: imakemdep.h,v 1.83 95/04/07 19:47:46 kaleb Exp $ */
+/* $XFree86: xc/config/imake/imakemdep.h,v 3.12 1995/07/08 10:22:17 dawes Exp $ */
+/*
+
+Copyright (c) 1993, 1994 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+*/
+
+
+/*
+ * This file contains machine-dependent constants for the imake utility.
+ * When porting imake, read each of the steps below and add in any necessary
+ * definitions. In general you should *not* edit ccimake.c or imake.c!
+ */
+
+#ifdef CCIMAKE
+/*
+ * Step 1: imake_ccflags
+ * Define any special flags that will be needed to get imake.c to compile.
+ * These will be passed to the compile along with the contents of the
+ * make variable BOOTSTRAPCFLAGS.
+ */
+#if defined(macII) || defined(_AUX_SOURCE)
+#define imake_ccflags "-DmacII -DSYSV"
+#endif
+
+#ifdef stellar
+#define imake_ccflags "-DSYSV"
+#endif
+
+#if defined(USL) || defined(Oki) || defined(NCR)
+#define imake_ccflags "-Xc -DSVR4"
+#endif
+
+#ifdef sony
+#if defined(SYSTYPE_SYSV) || defined(_SYSTYPE_SYSV)
+#define imake_ccflags "-DSVR4"
+#else
+#include <sys/param.h>
+#if NEWSOS < 41
+#define imake_ccflags "-Dbsd43 -DNOSTDHDRS"
+#else
+#if NEWSOS < 42
+#define imake_ccflags "-Dbsd43"
+#endif
+#endif
+#endif
+#endif
+
+#ifdef _CRAY
+#define imake_ccflags "-DSYSV -DUSG"
+#endif
+
+#if defined(_IBMR2) || defined(aix)
+#define imake_ccflags "-Daix -DSYSV"
+#endif
+
+#ifdef Mips
+# if defined(SYSTYPE_BSD) || defined(BSD) || defined(BSD43)
+# define imake_ccflags "-DBSD43"
+# else
+# define imake_ccflags "-DSYSV"
+# endif
+#endif
+
+#ifdef is68k
+#define imake_ccflags "-Dluna -Duniosb"
+#endif
+
+#ifdef SYSV386
+# ifdef SVR4
+# define imake_ccflags "-Xc -DSVR4"
+# else
+# define imake_ccflags "-DSYSV"
+# endif
+#endif
+
+#ifdef SVR4
+# ifdef i386
+# define imake_ccflags "-Xc -DSVR4"
+# endif
+#endif
+
+#ifdef SYSV
+# ifdef i386
+# define imake_ccflags "-DSYSV"
+# endif
+#endif
+
+#ifdef __convex__
+#define imake_ccflags "-fn -tm c1"
+#endif
+
+#ifdef apollo
+#define imake_ccflags "-DX_NOT_POSIX"
+#endif
+
+#ifdef _WIN32
+#define imake_ccflags "-nologo -batch -D__STDC__"
+#endif
+
+#ifdef __uxp__
+#define imake_ccflags "-DSVR4 -DANSICPP"
+#endif
+
+#ifdef __sxg__
+#define imake_ccflags "-DSYSV -DUSG -DNOSTDHDRS"
+#endif
+
+#if defined(SX) || defined(PC_UX)
+#define imake_ccflags "-DSYSV"
+#endif
+
+#ifdef nec_ews_svr2
+#define imake_ccflags "-DUSG"
+#endif
+
+#if defined(nec_ews_svr4) || defined(_nec_ews_svr4) || defined(_nec_up) || defined(_nec_ft)
+#define imake_ccflags "-DSVR4"
+#endif
+
+#ifdef MACH
+#define imake_ccflags "-DNOSTDHDRS"
+#endif
+
+/* this is for OS/2 under EMX. This won't work with DOS */
+#if defined(__EMX__)
+#define imake_ccflags "-DBSD43"
+#endif
+
+#else /* not CCIMAKE */
+#ifndef MAKEDEPEND
+/*
+ * Step 2: dup2
+ * If your OS doesn't have a dup2() system call to duplicate one file
+ * descriptor onto another, define such a mechanism here (if you don't
+ * already fall under the existing category(ies).
+ */
+#if defined(SYSV) && !defined(_CRAY) && !defined(Mips)
+#define dup2(fd1,fd2) ((fd1 == fd2) ? fd1 : (close(fd2), \
+ fcntl(fd1, F_DUPFD, fd2)))
+#endif
+
+
+/*
+ * Step 3: FIXUP_CPP_WHITESPACE
+ * If your cpp collapses tabs macro expansions into a single space and
+ * replaces escaped newlines with a space, define this symbol. This will
+ * cause imake to attempt to patch up the generated Makefile by looking
+ * for lines that have colons in them (this is why the rules file escapes
+ * all colons). One way to tell if you need this is to see whether or not
+ * your Makefiles have no tabs in them and lots of @@ strings.
+ */
+#if defined(sun) || defined(SYSV) || defined(SVR4) || defined(hcx) || defined(_WIN32) || (defined(AMOEBA) && defined(CROSS_COMPILE))
+#define FIXUP_CPP_WHITESPACE
+#endif
+#ifdef __minix_vmd
+#define FIXUP_CPP_WHITESPACE
+#endif
+
+/*
+ * Step 4: USE_CC_E, DEFAULT_CC, DEFAULT_CPP
+ * If you want to use cc -E instead of cpp, define USE_CC_E.
+ * If use cc -E but want a different compiler, define DEFAULT_CC.
+ * If the cpp you need is not in /lib/cpp, define DEFAULT_CPP.
+ */
+#ifdef _WIN32
+#define USE_CC_E
+#define DEFAULT_CC "cl"
+#endif
+#ifdef apollo
+#define DEFAULT_CPP "/usr/lib/cpp"
+#endif
+#if defined(_IBMR2) && !defined(DEFAULT_CPP)
+#define DEFAULT_CPP "/usr/lpp/X11/Xamples/util/cpp/cpp"
+#endif
+#if defined(sun) && defined(SVR4)
+#define DEFAULT_CPP "/usr/ccs/lib/cpp"
+#endif
+#ifdef __bsdi__
+#define DEFAULT_CPP "/usr/bin/cpp"
+#endif
+#ifdef __uxp__
+#define DEFAULT_CPP "/usr/ccs/lib/cpp"
+#endif
+#ifdef __sxg__
+#define DEFAULT_CPP "/usr/lib/cpp"
+#endif
+#ifdef _CRAY
+#define DEFAULT_CPP "/lib/pcpp"
+#endif
+#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
+#define DEFAULT_CPP "/usr/libexec/cpp"
+#endif
+#ifdef MACH
+#define USE_CC_E
+#endif
+#ifdef __minix_vmd
+#define DEFAULT_CPP "/usr/lib/cpp"
+#endif
+#if defined(__EMX__)
+/* expects cpp in PATH */
+#define DEFAULT_CPP "cpp"
+#endif
+
+/*
+ * Step 5: cpp_argv
+ * The following table contains the flags that should be passed
+ * whenever a Makefile is being generated. If your preprocessor
+ * doesn't predefine any unique symbols, choose one and add it to the
+ * end of this table. Then, do the following:
+ *
+ * a. Use this symbol in Imake.tmpl when setting MacroFile.
+ * b. Put this symbol in the definition of BootstrapCFlags in your
+ * <platform>.cf file.
+ * c. When doing a make World, always add "BOOTSTRAPCFLAGS=-Dsymbol"
+ * to the end of the command line.
+ *
+ * Note that you may define more than one symbol (useful for platforms
+ * that support multiple operating systems).
+ */
+
+#define ARGUMENTS 50 /* number of arguments in various arrays */
+char *cpp_argv[ARGUMENTS] = {
+ "cc", /* replaced by the actual program to exec */
+ "-I.", /* add current directory to include path */
+#ifdef unix
+ "-Uunix", /* remove unix symbol so that filename unix.c okay */
+#endif
+#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) || \
+ defined(MACH) || defined(DRAGONFLY)
+/* FIXME: strange list of obsolete systems */
+# ifdef __i386__
+ "-D__i386__",
+# endif
+# ifdef __GNUC__
+ "-traditional",
+# endif
+#endif
+#ifdef M4330
+ "-DM4330", /* Tektronix */
+#endif
+#ifdef M4310
+ "-DM4310", /* Tektronix */
+#endif
+#if defined(macII) || defined(_AUX_SOURCE)
+ "-DmacII", /* Apple A/UX */
+#endif
+#ifdef USL
+ "-DUSL", /* USL */
+#endif
+#ifdef sony
+ "-Dsony", /* Sony */
+#if !defined(SYSTYPE_SYSV) && !defined(_SYSTYPE_SYSV) && NEWSOS < 42
+ "-Dbsd43",
+#endif
+#endif
+#ifdef _IBMR2
+ "-D_IBMR2", /* IBM RS-6000 (we ensured that aix is defined above */
+#ifndef aix
+#define aix /* allow BOOTSTRAPCFLAGS="-D_IBMR2" */
+#endif
+#endif /* _IBMR2 */
+#ifdef aix
+ "-Daix", /* AIX instead of AOS */
+#ifndef ibm
+#define ibm /* allow BOOTSTRAPCFLAGS="-Daix" */
+#endif
+#endif /* aix */
+#ifdef ibm
+ "-Dibm", /* IBM PS/2 and RT under both AOS and AIX */
+#endif
+#ifdef luna
+ "-Dluna", /* OMRON luna 68K and 88K */
+#ifdef luna1
+ "-Dluna1",
+#endif
+#ifdef luna88k /* need not on UniOS-Mach Vers. 1.13 */
+ "-traditional", /* for some older version */
+#endif /* instead of "-DXCOMM=\\#" */
+#ifdef uniosb
+ "-Duniosb",
+#endif
+#ifdef uniosu
+ "-Duniosu",
+#endif
+#endif /* luna */
+#ifdef _CRAY /* Cray */
+ "-Ucray",
+#endif
+#ifdef Mips
+ "-DMips", /* Define and use Mips for Mips Co. OS/mach. */
+# if defined(SYSTYPE_BSD) || defined(BSD) || defined(BSD43)
+ "-DBSD43", /* Mips RISCOS supports two environments */
+# else
+ "-DSYSV", /* System V environment is the default */
+# endif
+#endif /* Mips */
+#ifdef MOTOROLA
+ "-DMOTOROLA", /* Motorola Delta Systems */
+# ifdef SYSV
+ "-DSYSV",
+# endif
+# ifdef SVR4
+ "-DSVR4",
+# endif
+#endif /* MOTOROLA */
+#ifdef i386
+ "-Di386",
+# ifdef SVR4
+ "-DSVR4",
+# endif
+# ifdef SYSV
+ "-DSYSV",
+# ifdef ISC
+ "-DISC",
+# ifdef ISC40
+ "-DISC40", /* ISC 4.0 */
+# else
+# ifdef ISC202
+ "-DISC202", /* ISC 2.0.2 */
+# else
+# ifdef ISC30
+ "-DISC30", /* ISC 3.0 */
+# else
+ "-DISC22", /* ISC 2.2.1 */
+# endif
+# endif
+# endif
+# endif
+# ifdef SCO
+ "-DSCO",
+# ifdef SCO324
+ "-DSCO324",
+# endif
+# endif
+# endif
+# ifdef ESIX
+ "-DESIX",
+# endif
+# ifdef ATT
+ "-DATT",
+# endif
+# ifdef DELL
+ "-DDELL",
+# endif
+#endif
+#ifdef SYSV386 /* System V/386 folks, obsolete */
+ "-Di386",
+# ifdef SVR4
+ "-DSVR4",
+# endif
+# ifdef ISC
+ "-DISC",
+# ifdef ISC40
+ "-DISC40", /* ISC 4.0 */
+# else
+# ifdef ISC202
+ "-DISC202", /* ISC 2.0.2 */
+# else
+# ifdef ISC30
+ "-DISC30", /* ISC 3.0 */
+# else
+ "-DISC22", /* ISC 2.2.1 */
+# endif
+# endif
+# endif
+# endif
+# ifdef SCO
+ "-DSCO",
+# ifdef SCO324
+ "-DSCO324",
+# endif
+# endif
+# ifdef ESIX
+ "-DESIX",
+# endif
+# ifdef ATT
+ "-DATT",
+# endif
+# ifdef DELL
+ "-DDELL",
+# endif
+#endif
+#ifdef __osf__
+ "-D__osf__",
+# ifdef __mips__
+ "-D__mips__",
+# endif
+# ifdef __alpha
+ "-D__alpha",
+# endif
+# ifdef __i386__
+ "-D__i386__",
+# endif
+# ifdef __GNUC__
+ "-traditional",
+# endif
+#endif
+#ifdef Oki
+ "-DOki",
+#endif
+#ifdef sun
+#ifdef SVR4
+ "-DSVR4",
+#endif
+#endif
+#ifdef _WIN32
+ "-DWIN32",
+ "-nologo",
+ "-batch",
+ "-D__STDC__",
+#endif
+#ifdef NCR
+ "-DNCR", /* NCR */
+#endif
+#ifdef linux
+ "-traditional",
+ "-Dlinux",
+#endif
+#ifdef __uxp__
+ "-D__uxp__",
+#endif
+#ifdef __sxg__
+ "-D__sxg__",
+#endif
+#ifdef nec_ews_svr2
+ "-Dnec_ews_svr2",
+#endif
+#ifdef AMOEBA
+ "-DAMOEBA",
+# ifdef CROSS_COMPILE
+ "-DCROSS_COMPILE",
+# ifdef CROSS_i80386
+ "-Di80386",
+# endif
+# ifdef CROSS_sparc
+ "-Dsparc",
+# endif
+# ifdef CROSS_mc68000
+ "-Dmc68000",
+# endif
+# else
+# ifdef i80386
+ "-Di80386",
+# endif
+# ifdef sparc
+ "-Dsparc",
+# endif
+# ifdef mc68000
+ "-Dmc68000",
+# endif
+# endif
+#endif
+#ifdef __minix_vmd
+ "-Dminix",
+#endif
+
+#if defined(__EMX__)
+ "-traditional",
+ "-Demxos2",
+#endif
+
+};
+#else /* else MAKEDEPEND */
+/*
+ * Step 6: predefs
+ * If your compiler and/or preprocessor define any specific symbols, add
+ * them to the following table. The definition of struct symtab is
+ * in util/makedepend/def.h.
+ */
+
+/* FIXME: strange list of obsolete systems */
+struct pair predefs[] = {
+#ifdef apollo
+ {"apollo", "1", NULL},
+#endif
+#ifdef ibm032
+ {"ibm032", "1", NULL},
+#endif
+#ifdef ibm
+ {"ibm", "1", NULL},
+#endif
+#ifdef aix
+ {"aix", "1", NULL},
+#endif
+#ifdef sun
+ {"sun", "1", NULL},
+#endif
+#ifdef sun2
+ {"sun2", "1", NULL},
+#endif
+#ifdef sun3
+ {"sun3", "1", NULL},
+#endif
+#ifdef sun4
+ {"sun4", "1", NULL},
+#endif
+#ifdef sparc
+ {"sparc", "1", NULL},
+#endif
+#ifdef __sparc__
+ {"__sparc__", "1", NULL},
+#endif
+#ifdef vax
+ {"vax", "1", NULL},
+#endif
+#ifdef VMS
+ {"VMS", "1", NULL},
+#endif
+#ifdef cray
+ {"cray", "1", NULL},
+#endif
+#ifdef CRAY
+ {"CRAY", "1", NULL},
+#endif
+#ifdef _CRAY
+ {"_CRAY", "1", NULL},
+#endif
+#ifdef att
+ {"att", "1", NULL},
+#endif
+#ifdef mips
+ {"mips", "1", NULL},
+#endif
+#ifdef __mips__
+ {"__mips__", "1", NULL},
+#endif
+#ifdef stellar
+ {"stellar", "1", NULL},
+#endif
+#ifdef mc68000
+ {"mc68000", "1", NULL},
+#endif
+#ifdef mc68020
+ {"mc68020", "1", NULL},
+#endif
+#ifdef __GNUC__
+ {"__GNUC__", "1", NULL},
+#endif
+#ifdef __STDC__
+ {"__STDC__", "1", NULL},
+#endif
+#ifdef __HIGHC__
+ {"__HIGHC__", "1", NULL},
+#endif
+#ifdef CMU
+ {"CMU", "1", NULL},
+#endif
+#ifdef luna
+ {"luna", "1", NULL},
+#ifdef luna1
+ {"luna1", "1", NULL},
+#endif
+#ifdef luna2
+ {"luna2", "1", NULL},
+#endif
+#ifdef luna88k
+ {"luna88k", "1", NULL},
+#endif
+#ifdef uniosb
+ {"uniosb", "1", NULL},
+#endif
+#ifdef uniosu
+ {"uniosu", "1", NULL},
+#endif
+#endif
+#ifdef ieeep754
+ {"ieeep754", "1", NULL},
+#endif
+#ifdef is68k
+ {"is68k", "1", NULL},
+#endif
+#ifdef m68k
+ {"m68k", "1", NULL},
+#endif
+#ifdef m88k
+ {"m88k", "1", NULL},
+#endif
+#ifdef __m88k__
+ {"__m88k__", "1", NULL},
+#endif
+#ifdef bsd43
+ {"bsd43", "1", NULL},
+#endif
+#ifdef hcx
+ {"hcx", "1", NULL},
+#endif
+#ifdef sony
+ {"sony", "1", NULL},
+#ifdef SYSTYPE_SYSV
+ {"SYSTYPE_SYSV", "1", NULL},
+#endif
+#ifdef _SYSTYPE_SYSV
+ {"_SYSTYPE_SYSV", "1", NULL},
+#endif
+#endif
+#ifdef __OSF__
+ {"__OSF__", "1", NULL},
+#endif
+#ifdef __osf__
+ {"__osf__", "1", NULL},
+#endif
+#ifdef __alpha
+ {"__alpha", "1", NULL},
+#endif
+#ifdef __DECC
+ {"__DECC", "1", NULL},
+#endif
+#ifdef __decc
+ {"__decc", "1", NULL},
+#endif
+#ifdef __uxp__
+ {"__uxp__", "1", NULL},
+#endif
+#ifdef __sxg__
+ {"__sxg__", "1", NULL},
+#endif
+#ifdef __bsdi__
+ {"__bsdi__", "1", NULL},
+#endif
+#ifdef nec_ews_svr2
+ {"nec_ews_svr2", "1", NULL},
+#endif
+#ifdef nec_ews_svr4
+ {"nec_ews_svr4", "1", NULL},
+#endif
+#ifdef _nec_ews_svr4
+ {"_nec_ews_svr4", "1", NULL},
+#endif
+#ifdef _nec_up
+ {"_nec_up", "1", NULL},
+#endif
+#ifdef SX
+ {"SX", "1", NULL},
+#endif
+#ifdef nec
+ {"nec", "1", NULL},
+#endif
+#ifdef _nec_ft
+ {"_nec_ft", "1", NULL},
+#endif
+#ifdef PC_UX
+ {"PC_UX", "1", NULL},
+#endif
+#ifdef sgi
+ {"sgi", "1", NULL},
+#endif
+#ifdef __sgi
+ {"__sgi", "1", NULL},
+#endif
+#ifdef __FreeBSD__
+ {"__FreeBSD__", "1", NULL},
+#endif
+#ifdef __NetBSD__
+ {"__NetBSD__", "1", NULL},
+#endif
+#ifdef __OpenBSD__
+ {"__OpenBSD__", "1", NULL},
+#endif
+#ifdef __DragonFly__
+ {"__DragonFly__", "1", NULL},
+#endif
+#ifdef __EMX__
+ {"__EMX__", "1", NULL},
+#endif
+ /* add any additional symbols before this line */
+ {NULL, NULL, NULL}
+};
+
+#endif /* MAKEDEPEND */
+#endif /* CCIMAKE */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/soltools/mkdepend/include.c b/soltools/mkdepend/include.c
new file mode 100644
index 000000000..d05a8fd75
--- /dev/null
+++ b/soltools/mkdepend/include.c
@@ -0,0 +1,347 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* $XConsortium: include.c,v 1.17 94/12/05 19:33:08 gildea Exp $ */
+/*
+
+Copyright (c) 1993, 1994 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+*/
+
+
+#include "def.h"
+#include <string.h>
+#include <assert.h>
+
+static void remove_dotdot( char * );
+static int isdot( char const * );
+static int isdotdot( char const * );
+static int issymbolic(char * dir, char * component);
+static int exists_path(struct IncludesCollection*, char*);
+
+#ifdef S_IFLNK
+static char *notdotdot[ MAXDIRS ];
+#endif
+
+struct inclist *inc_path(char *file, char *include, boolean dot, struct IncludesCollection *incCollection)
+{
+ static char path[ BUFSIZ ];
+ char **pp, *p;
+ struct inclist *ip;
+ struct stat st;
+ boolean found = FALSE;
+ (void)dot;
+
+ /*
+ * Check all previously found include files for a path that
+ * has already been expanded.
+ */
+ for (ip = inclist; ip->i_file; ip++)
+ if (strcmp(ip->i_incstring, include) == 0)
+ {
+ found = TRUE;
+ break;
+ }
+
+ /*
+ * If the path was surrounded by "" or is an absolute path,
+ * then check the exact path provided.
+ */
+// FIXME: creates duplicates in the dependency files if absolute paths are
+// given, which certainly is not the intended behavior. Also it slows down
+// makedepend performance considerably.
+// if (!found && (dot || *include == '/')) {
+//
+// if ((exists_path(incCollection, include)) && stat(include, &st) == 0 && !( st.st_mode & S_IFDIR)) {
+// ip = newinclude(include, include);
+// found = TRUE;
+// }
+// else if (show_where_not)
+// warning1("\tnot in %s\n", include);
+// }
+
+ /*
+ * See if this include file is in the directory of the
+ * file being compiled.
+ */
+ if (!found) {
+ for (p=file+strlen(file); p>file; p--)
+ if (*p == '/')
+ break;
+ if (p == file)
+ {
+ if(strlen(include) >= BUFSIZ )
+ {
+ fatalerr("include filename too long \"%s\"\n", include);
+ }
+ else
+ {
+ strcpy(path, include);
+ }
+ }
+ else
+ {
+ int partial = p - file;
+ size_t inc_len = strlen(include);
+ if(inc_len + partial >= BUFSIZ )
+ {
+ fatalerr("include filename too long \"%s\"\n", include);
+ }
+ else
+ {
+ memcpy(path, file, partial);
+ memcpy(path + partial, include, inc_len);
+ path[partial + inc_len] = 0;
+ }
+ }
+ remove_dotdot(path);
+ if ((exists_path(incCollection, path)) && stat(path, &st) == 0 && !( st.st_mode & S_IFDIR)) {
+ ip = newinclude(path, include);
+ found = TRUE;
+ }
+ else if (show_where_not)
+ warning1("\tnot in %s\n", path);
+ }
+
+ /*
+ * Check the include directories specified. (standard include dir
+ * should be at the end.)
+ */
+ if (!found)
+ for (pp = includedirs; *pp; pp++) {
+ sprintf(path, "%s/%s", *pp, include);
+ remove_dotdot(path);
+ if ((exists_path(incCollection, path)) && stat(path, &st) == 0 && !(st.st_mode & S_IFDIR)) {
+ ip = newinclude(path, include);
+ found = TRUE;
+ break;
+ }
+ else if (show_where_not)
+ warning1("\tnot in %s\n", path);
+ }
+
+ if (!found)
+ ip = NULL;
+ return ip;
+}
+
+int exists_path(struct IncludesCollection *incCollection, char *path)
+{
+ convert_slashes(path);
+ return call_IncludesCollection_exists(incCollection, path);
+}
+
+/*
+ * Occasionally, pathnames are created that look like .../x/../y
+ * Any of the 'x/..' sequences within the name can be eliminated.
+ * (but only if 'x' is not a symbolic link!!)
+ */
+void remove_dotdot(char *path)
+{
+ char *end, *from, *to, **cp;
+ char *components[ MAXFILES ],
+ newpath[ BUFSIZ ];
+ boolean component_copied;
+
+ /*
+ * slice path up into components.
+ */
+ to = newpath;
+ if (*path == '/')
+ *to++ = '/';
+ *to = '\0';
+ cp = components;
+ for (from=end=path; *end; end++)
+ if (*end == '/') {
+ while (*end == '/')
+ *end++ = '\0';
+ if (*from)
+ *cp++ = from;
+ from = end;
+ }
+ *cp++ = from;
+ *cp = NULL;
+
+ /*
+ * Recursively remove all 'x/..' component pairs.
+ */
+ cp = components;
+ while(*cp) {
+ if (!isdot(*cp) && !isdotdot(*cp) && isdotdot(*(cp+1))
+ && !issymbolic(newpath, *cp))
+ {
+ char **fp = cp + 2;
+ char **tp = cp;
+
+ do {
+ *tp++ = *fp; /* move all the pointers down */
+ } while (*fp++);
+ if (cp != components)
+ cp--; /* go back and check for nested ".." */
+ } else {
+ cp++;
+ }
+ }
+ /*
+ * Concatenate the remaining path elements.
+ */
+ cp = components;
+ component_copied = FALSE;
+ while(*cp) {
+ if (component_copied)
+ *to++ = '/';
+ component_copied = TRUE;
+ for (from = *cp; *from; )
+ *to++ = *from++;
+ *to = '\0';
+ cp++;
+ }
+ *to++ = '\0';
+
+ /*
+ * copy the reconstituted path back to our pointer.
+ */
+ strcpy(path, newpath);
+}
+
+int isdot(char const *p)
+{
+ if(p && p[0] == '.' && p[1] == '\0')
+ return TRUE;
+ return FALSE;
+}
+
+int isdotdot(char const *p)
+{
+ if(p && p[0] == '.' && p[1] == '.' && p[2] == '\0')
+ return TRUE;
+ return FALSE;
+}
+
+int issymbolic(char *dir, char *component)
+{
+#ifdef S_IFLNK
+ struct stat st;
+ char buf[ BUFSIZ ], **pp;
+
+#if defined __GNUC__ && !defined __clang__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wformat-truncation"
+ // silence "‘snprintf’ output may be truncated before the last format character", from gcc 8.3 to at least 9.2.1
+#endif
+ int n = snprintf(buf, BUFSIZ, "%s%s%s", dir, *dir ? "/" : "", component);
+#if defined __GNUC__ && !defined __clang__
+#pragma GCC diagnostic pop
+#endif
+ assert(n < BUFSIZ);
+ (void) n;
+ for (pp=notdotdot; *pp; pp++)
+ if (strcmp(*pp, buf) == 0)
+ return TRUE;
+ if (lstat(buf, &st) == 0
+ && (st.st_mode & S_IFMT) == S_IFLNK) {
+ *pp++ = copy(buf);
+ if (pp >= &notdotdot[ MAXDIRS ])
+ fatalerr("out of .. dirs, increase MAXDIRS\n");
+ return TRUE;
+ }
+#else
+ (void)dir; (void)component;
+#endif
+ return FALSE;
+}
+
+/*
+ * Add an include file to the list of those included by 'file'.
+ */
+struct inclist *newinclude(char const *newfile, char const *incstring)
+{
+ struct inclist *ip;
+
+ /*
+ * First, put this file on the global list of include files.
+ */
+ ip = inclistp++;
+ if (inclistp == inclist + MAXFILES - 1)
+ fatalerr("out of space: increase MAXFILES\n");
+ ip->i_file = copy(newfile);
+ if (incstring == NULL)
+ ip->i_incstring = ip->i_file;
+ else
+ ip->i_incstring = copy(incstring);
+
+ return ip;
+}
+
+void included_by(struct inclist *ip, struct inclist *newfile)
+{
+ int i;
+
+ if (ip == NULL)
+ return;
+ /*
+ * Put this include file (newfile) on the list of files included
+ * by 'file'. If 'file' is NULL, then it is not an include
+ * file itself (i.e. was probably mentioned on the command line).
+ * If it is already on the list, don't stick it on again.
+ */
+ if (ip->i_list == NULL)
+ ip->i_list = (struct inclist **)
+ malloc(sizeof(struct inclist *) * ++ip->i_listlen);
+ else {
+ for (i=0; i<ip->i_listlen; i++)
+ if (ip->i_list[ i ] == newfile) {
+ i = (int)strlen(newfile->i_file);
+ if (!(i > 2 &&
+ newfile->i_file[i-1] == 'c' &&
+ newfile->i_file[i-2] == '.'))
+ {
+ /* only complain if ip has */
+ /* no #include SYMBOL lines */
+ /* and is not a .c file */
+ if (warn_multiple)
+ {
+ warning("%s includes %s more than once!\n",
+ ip->i_file, newfile->i_file);
+ warning1("Already have\n");
+ for (i=0; i<ip->i_listlen; i++)
+ warning1("\t%s\n", ip->i_list[i]->i_file);
+ }
+ }
+ return;
+ }
+ ip->i_list = (struct inclist **) realloc(ip->i_list,
+ sizeof(struct inclist *) * ++ip->i_listlen);
+ }
+ ip->i_list[ ip->i_listlen-1 ] = newfile;
+}
+
+void inc_clean (void)
+{
+ struct inclist *ip;
+
+ for (ip = inclist; ip < inclistp; ip++) {
+ ip->i_marked = FALSE;
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/soltools/mkdepend/main.c b/soltools/mkdepend/main.c
new file mode 100644
index 000000000..b8b84b453
--- /dev/null
+++ b/soltools/mkdepend/main.c
@@ -0,0 +1,740 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* $XConsortium: main.c,v 1.84 94/11/30 16:10:44 kaleb Exp $ */
+/* $XFree86: xc/config/makedepend/main.c,v 3.4 1995/07/15 14:53:49 dawes Exp $ */
+/*
+
+Copyright (c) 1993, 1994 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+*/
+
+#if defined(FREEBSD) || defined(MACOSX)
+#include <sys/types.h>
+#include <sys/stat.h>
+#endif
+
+#ifdef _WIN32
+#include <io.h>
+#endif
+
+#ifdef _MSC_VER /* Define ssize_t */
+
+#if !defined(_W64)
+#if !defined(__midl) && (defined(_X86_) || defined(_M_IX86))
+#define _W64 __w64
+#else
+#define _W64
+#endif
+#endif
+
+#ifdef _WIN64
+typedef __int64 ssize_t;
+#else
+typedef _W64 int ssize_t;
+#endif
+
+#endif
+
+#include "def.h"
+#include <assert.h>
+#include <string.h>
+#ifdef hpux
+#define sigvec sigvector
+#endif /* hpux */
+
+#ifdef X_POSIX_C_SOURCE
+#define _POSIX_C_SOURCE X_POSIX_C_SOURCE
+#include <signal.h>
+#undef _POSIX_C_SOURCE
+#else
+#if defined(X_NOT_POSIX) || defined(_POSIX_SOURCE)
+#include <signal.h>
+#else
+#define _POSIX_SOURCE
+#include <signal.h>
+#undef _POSIX_SOURCE
+#endif
+#endif
+
+#include <stdarg.h>
+
+#ifdef MINIX
+#define USE_CHMOD 1
+#endif
+
+#ifdef DEBUG
+int _debugmask;
+#endif
+
+static char *ProgramName;
+
+#define OBJSUFFIX ".obj"
+#define INCLUDEDIR "."
+
+char *directives[] = {
+ "if",
+ "ifdef",
+ "ifndef",
+ "else",
+ "endif",
+ "define",
+ "undef",
+ "include",
+ "line",
+ "pragma",
+ "error",
+ "ident",
+ "sccs",
+ "elif",
+ "eject",
+ NULL
+};
+
+#define MAKEDEPEND
+#include "imakemdep.h" /* from config sources */
+#undef MAKEDEPEND
+
+/******* function declarations ********/
+/******* added by -Wall project *******/
+static void redirect(char * makefile);
+
+struct inclist inclist[ MAXFILES ];
+struct inclist *inclistp = inclist;
+
+static struct symhash *maininclist = NULL;
+
+static char *filelist[ MAXFILES ];
+char *includedirs[ MAXDIRS + 1 ];
+char *objprefix = "";
+char *objsuffix = OBJSUFFIX;
+static char *startat = "# DO NOT DELETE";
+boolean printed = FALSE;
+boolean verbose = FALSE;
+boolean show_where_not = FALSE;
+boolean warn_multiple = FALSE; /* Warn on multiple includes of same file */
+
+static
+#ifdef SIGNALRETURNSINT
+int
+#else
+void
+#endif
+catch (int sig)
+{
+ fflush (stdout);
+ fatalerr ("got signal %d\n", sig);
+}
+
+#if (defined(i386) && defined(SYSV)) || defined(_WIN32)
+#define USGISH
+#endif
+
+#ifndef USGISH
+#ifndef _POSIX_SOURCE
+#define sigaction sigvec
+#define sa_handler sv_handler
+#define sa_mask sv_mask
+#define sa_flags sv_flags
+#endif
+static struct sigaction sig_act;
+#endif /* USGISH */
+
+static boolean native_win_slashes = FALSE;
+
+int main(int argc, char **argv)
+{
+ char **fp = filelist;
+ char **incp = includedirs;
+ char *p;
+ struct inclist *ip;
+ char *makefile = NULL;
+ struct filepointer *filecontent;
+ struct pair *psymp = predefs;
+ char *endmarker = NULL;
+ char *defincdir = NULL;
+ struct IncludesCollection* incCollection;
+
+ ProgramName = argv[0];
+
+ while (psymp->p_name)
+ {
+ hash_define(psymp->p_name, psymp->p_value, &maininclist);
+ psymp++;
+ }
+ if (argc == 2 && argv[1][0] == '@') {
+ struct stat ast;
+ int afd;
+ char *args;
+ char **nargv;
+ int nargc;
+ char quotechar = '\0';
+
+ nargc = 1;
+ if ((afd = open(argv[1]+1, O_RDONLY)) < 0)
+ fatalerr("cannot open \"%s\"\n", argv[1]+1);
+ (void)fstat(afd, &ast);
+ args = (char *)malloc(ast.st_size + 1);
+ if ((ast.st_size = read(afd, args, (size_t) ast.st_size)) < 0)
+ fatalerr("failed to read %s\n", argv[1]+1);
+ args[ast.st_size] = '\0';
+ close(afd);
+ for (p = args; *p; p++) {
+ if (quotechar) {
+ if (quotechar == '\\'
+ || (*p == quotechar && p[-1] != '\\'))
+ quotechar = '\0';
+ continue;
+ }
+ switch (*p) {
+ case '\\':
+ case '"':
+ case '\'':
+ quotechar = *p;
+ break;
+ case ' ':
+ case '\n':
+ *p = '\0';
+ if (p > args && p[-1])
+ nargc++;
+ break;
+ }
+ }
+ if (p[-1])
+ nargc++;
+ nargv = (char **)malloc(nargc * sizeof(char *));
+ nargv[0] = argv[0];
+ argc = 1;
+ for (p = args; argc < nargc; p += strlen(p) + 1)
+ if (*p) nargv[argc++] = p;
+ argv = nargv;
+ }
+ for(argc--, argv++; argc; argc--, argv++) {
+ /* if looking for endmarker then check before parsing */
+ if (endmarker && strcmp (endmarker, *argv) == 0) {
+ endmarker = NULL;
+ continue;
+ }
+ if (**argv != '-') {
+ /* treat +thing as an option for C++ */
+ if (endmarker && **argv == '+')
+ continue;
+ *fp++ = argv[0];
+ continue;
+ }
+ switch(argv[0][1]) {
+ case '-':
+ endmarker = &argv[0][2];
+ if (endmarker[0] == '\0') endmarker = "--";
+ break;
+ case 'D':
+ if (argv[0][2] == '\0') {
+ argv++;
+ argc--;
+ }
+ for (p=argv[0] + 2; *p ; p++)
+ if (*p == '=') {
+ *p = ' ';
+ break;
+ }
+ define(argv[0] + 2, &maininclist);
+ break;
+ case 'I':
+ if (incp >= includedirs + MAXDIRS)
+ fatalerr("Too many -I flags.\n");
+ *incp++ = argv[0]+2;
+ if (**(incp-1) == '\0') {
+ *(incp-1) = *(++argv);
+ argc--;
+ }
+ break;
+ case 'Y':
+ defincdir = argv[0]+2;
+ break;
+ /* do not use if endmarker processing */
+ case 'a':
+ break;
+ case 'w':
+ if (endmarker) break;
+ if (argv[0][2] == '\0') {
+ argv++;
+ argc--;
+ }
+ break;
+ case 'n':
+ // Use "-n" switch to generate dependencies with windows-native slash style
+ native_win_slashes = TRUE;
+ break;
+ case 'o':
+ if (endmarker) break;
+ if (argv[0][2] == '\0') {
+ argv++;
+ argc--;
+ objsuffix = argv[0];
+ } else
+ objsuffix = argv[0]+2;
+ break;
+ case 'p':
+ if (endmarker) break;
+ if (argv[0][2] == '\0') {
+ argv++;
+ argc--;
+ objprefix = argv[0];
+ } else
+ objprefix = argv[0]+2;
+ break;
+ case 'v':
+ if (endmarker) break;
+ verbose = TRUE;
+#ifdef DEBUG
+ if (argv[0][2])
+ _debugmask = atoi(argv[0]+2);
+#endif
+ break;
+ case 's':
+ if (endmarker) break;
+ startat = argv[0]+2;
+ if (*startat == '\0') {
+ startat = *(++argv);
+ argc--;
+ }
+ if (*startat != '#')
+ fatalerr("-s flag's value should start %s\n",
+ "with '#'.");
+ break;
+ case 'f':
+ if (endmarker) break;
+ makefile = argv[0]+2;
+ if (*makefile == '\0') {
+ makefile = *(++argv);
+ argc--;
+ }
+ break;
+
+ case 'm':
+ warn_multiple = TRUE;
+ break;
+
+ /* Ignore -O, -g so we can just pass ${CFLAGS} to
+ makedepend
+ */
+ case 'O':
+ case 'g':
+ break;
+ default:
+ if (endmarker) break;
+ warning("ignoring option %s\n", argv[0]);
+ }
+ }
+
+ convert_slashes(objprefix);
+ objprefix = append_slash(objprefix);
+
+ if (!defincdir) {
+#ifdef PREINCDIR
+ if (incp >= includedirs + MAXDIRS)
+ fatalerr("Too many -I flags.\n");
+ *incp++ = PREINCDIR;
+#endif
+ if (incp >= includedirs + MAXDIRS)
+ fatalerr("Too many -I flags.\n");
+ *incp++ = INCLUDEDIR;
+#ifdef POSTINCDIR
+ if (incp >= includedirs + MAXDIRS)
+ fatalerr("Too many -I flags.\n");
+ *incp++ = POSTINCDIR;
+#endif
+ } else if (*defincdir) {
+ if (incp >= includedirs + MAXDIRS)
+ fatalerr("Too many -I flags.\n");
+ *incp++ = defincdir;
+ }
+
+ redirect(makefile);
+
+ /*
+ * catch signals.
+ */
+#ifdef USGISH
+/* should really reset SIGINT to SIG_IGN if it was. */
+#ifdef SIGHUP
+ signal (SIGHUP, catch);
+#endif
+ signal (SIGINT, catch);
+#ifdef SIGQUIT
+ signal (SIGQUIT, catch);
+#endif
+ signal (SIGILL, catch);
+#ifdef SIGBUS
+ signal (SIGBUS, catch);
+#endif
+ signal (SIGSEGV, catch);
+#ifdef SIGSYS
+ signal (SIGSYS, catch);
+#endif
+ signal (SIGFPE, catch);
+#else
+ sig_act.sa_handler = catch;
+#ifdef _POSIX_SOURCE
+ sigemptyset(&sig_act.sa_mask);
+ sigaddset(&sig_act.sa_mask, SIGINT);
+ sigaddset(&sig_act.sa_mask, SIGQUIT);
+#ifdef SIGBUS
+ sigaddset(&sig_act.sa_mask, SIGBUS);
+#endif
+ sigaddset(&sig_act.sa_mask, SIGILL);
+ sigaddset(&sig_act.sa_mask, SIGSEGV);
+ sigaddset(&sig_act.sa_mask, SIGHUP);
+ sigaddset(&sig_act.sa_mask, SIGPIPE);
+#ifdef SIGSYS
+ sigaddset(&sig_act.sa_mask, SIGSYS);
+#endif
+#else
+ sig_act.sa_mask = ((1<<(SIGINT -1))
+ |(1<<(SIGQUIT-1))
+#ifdef SIGBUS
+ |(1<<(SIGBUS-1))
+#endif
+ |(1<<(SIGILL-1))
+ |(1<<(SIGSEGV-1))
+ |(1<<(SIGHUP-1))
+ |(1<<(SIGPIPE-1))
+#ifdef SIGSYS
+ |(1<<(SIGSYS-1))
+#endif
+ );
+#endif /* _POSIX_SOURCE */
+ sig_act.sa_flags = 0;
+ sigaction(SIGHUP, &sig_act, (struct sigaction *)0);
+ sigaction(SIGINT, &sig_act, (struct sigaction *)0);
+ sigaction(SIGQUIT, &sig_act, (struct sigaction *)0);
+ sigaction(SIGILL, &sig_act, (struct sigaction *)0);
+#ifdef SIGBUS
+ sigaction(SIGBUS, &sig_act, (struct sigaction *)0);
+#endif
+ sigaction(SIGSEGV, &sig_act, (struct sigaction *)0);
+#ifdef SIGSYS
+ sigaction(SIGSYS, &sig_act, (struct sigaction *)0);
+#endif
+#endif /* USGISH */
+
+ /*
+ * now peruse through the list of files.
+ */
+ incCollection = create_IncludesCollection();
+
+ for(fp=filelist; *fp; fp++) {
+ struct symhash *includes;
+ filecontent = getfile(*fp);
+ ip = newinclude(*fp, (char *)NULL);
+
+ includes = hash_copy( maininclist );
+ find_includes(filecontent, ip, ip, 0, FALSE, incCollection, includes);
+ hash_free( includes );
+
+ freefile(filecontent);
+ recursive_pr_include(ip, ip->i_file, base_name(*fp));
+ if (printed)
+ fwrite("\n\n", 2, 1, stdout);
+ recursive_pr_dummy(ip, ip->i_file);
+ inc_clean();
+ }
+ if (printed)
+ printf("\n");
+
+ delete_IncludesCollection(incCollection);
+
+ exit(0);
+}
+
+struct filepointer *getfile(char *file)
+{
+ int fd;
+ struct filepointer *content;
+ struct stat st;
+ off_t size_backup;
+ ssize_t bytes_read;
+ unsigned malloc_size;
+
+ content = (struct filepointer *)malloc(sizeof(struct filepointer));
+ if ((fd = open(file, O_RDONLY)) < 0) {
+ warning("makedepend: Cannot open file \"%s\"\n", file);
+ content->f_p = content->f_base = content->f_end = (char *)malloc(1);
+ *content->f_p = '\0';
+ return content;
+ }
+ (void)fstat(fd, &st);
+
+ size_backup = st.st_size;
+ malloc_size = size_backup;
+ /* Since off_t usually is larger than unsigned, need to test for
+ * truncation.
+ */
+ if ( (off_t)malloc_size != size_backup )
+ {
+ close( fd );
+ warning("makedepend: File \"%s\" is too large.\n", file);
+ content->f_p = content->f_base = content->f_end = (char *)malloc(1);
+ *content->f_p = '\0';
+ return content;
+ }
+
+ content->f_base = (char *)malloc(malloc_size+1);
+ if (content->f_base == NULL)
+ fatalerr("makedepend: Cannot allocate memory to process file \"%s\"\n", file);
+ if ((bytes_read = read(fd, content->f_base, malloc_size)) < 0)
+ if ( st.st_mode & S_IFREG )
+ fatalerr("makedepend: Failed to read file \"%s\"\n", file);
+
+ close(fd);
+ content->f_p = content->f_base;
+ content->f_end = content->f_base + bytes_read;
+ *content->f_end = '\0';
+ content->f_line = 0;
+ return content;
+}
+
+void freefile(struct filepointer *fp)
+{
+ free(fp->f_base);
+ free(fp);
+}
+
+char *copy(char const *str)
+{
+ char *p = (char *)malloc(strlen(str) + 1);
+ assert(p); // Don't handle OOM conditions
+ strcpy(p, str);
+ return p;
+}
+
+int match(char const *str, char **list)
+{
+ int i;
+
+ for (i=0; *list; i++, list++)
+ if (strcmp(str, *list) == 0)
+ return i;
+ return -1;
+}
+
+/*
+ * Get the next line. We only return lines beginning with '#' since that
+ * is all this program is ever interested in.
+ */
+char *get_line(struct filepointer *filep)
+{
+ char *p, /* walking pointer */
+ *eof, /* end of file pointer */
+ *bol; /* beginning of line pointer */
+ int lineno; /* line number */
+
+ p = filep->f_p;
+ eof = filep->f_end;
+ if (p >= eof)
+ return (char *)NULL;
+ lineno = filep->f_line;
+
+ for(bol = p--; ++p < eof; ) {
+ if (*p == '/' && *(p+1) == '*') { /* consume comments */
+ *p++ = ' ';
+ *p++ = ' ';
+ while (*p) {
+ if (*p == '*' && *(p+1) == '/') {
+ *p++ = ' ';
+ *p = ' ';
+ break;
+ }
+ else if (*p == '\n')
+ lineno++;
+ *p++ = ' ';
+ }
+ continue;
+ }
+ else if (*p == '/' && *(p+1) == '/') { /* consume comments */
+ *p++ = ' ';
+ *p++ = ' ';
+ while (*p && *p != '\n')
+ *p++ = ' ';
+ if ( *p == '\n' )
+ p--;
+ lineno++;
+ continue;
+ }
+ else if (*p == '\\') {
+ if (*(p+1) == '\n') {
+ *p = ' ';
+ *(p+1) = ' ';
+ lineno++;
+ }
+ }
+ else if (*p == '\n') {
+ lineno++;
+ if (*bol == '#') {
+ char *cp;
+
+ *p++ = '\0';
+ /* punt lines with just # (yacc generated) */
+ for (cp = bol+1;
+ *cp && (*cp == ' ' || *cp == '\t'); cp++);
+ if (*cp) goto done;
+ }
+ bol = p+1;
+ }
+ }
+ if (*bol != '#')
+ bol = NULL;
+done:
+ filep->f_p = p;
+ filep->f_line = lineno;
+ return bol;
+}
+
+/*
+ * Strip the file name down to what we want to see in the Makefile.
+ * It will have objprefix and objsuffix around it.
+ */
+char *base_name(char *file)
+{
+ char *p;
+
+ file = copy(file);
+ for(p=file+strlen(file); p>file && *p != '.'; p--) ;
+
+ if (*p == '.')
+ *p = '\0';
+
+ while (p > file) {
+ if ( *p == '/' || *p == '\\') {
+ file = p + 1;
+ break;
+ }
+ p--;
+ }
+ return file;
+}
+
+#if defined(USG) && !defined(CRAY) && !defined(SVR4)
+int rename (char *from, char *to)
+{
+ (void) unlink (to);
+ if (link (from, to) == 0) {
+ unlink (from);
+ return 0;
+ } else {
+ return -1;
+ }
+}
+#endif /* USGISH */
+
+void redirect(char *makefile)
+{
+ FILE *fdout;
+ fdout = makefile ? freopen(makefile, "wb", stdout) : NULL; // binary mode please
+ if (fdout == NULL)
+ fatalerr("cannot open \"%s\"\n", makefile ? makefile : "<NULL>");
+}
+
+#if defined __GNUC__
+__attribute__ ((format (printf, 1, 2)))
+#endif
+void fatalerr(char *msg, ...)
+{
+ va_list args;
+ fprintf(stderr, "%s: error: ", ProgramName);
+ va_start(args, msg);
+ vfprintf(stderr, msg, args);
+ va_end(args);
+ exit (1);
+}
+
+#if defined __GNUC__
+__attribute__ ((format (printf, 1, 2)))
+#endif
+void warning(char const *msg, ...)
+{
+#ifdef DEBUG_MKDEPEND
+ va_list args;
+ fprintf(stderr, "%s: warning: ", ProgramName);
+ va_start(args, msg);
+ vfprintf(stderr, msg, args);
+ va_end(args);
+#else
+ (void)msg;
+#endif /* DEBUG_MKDEPEND */
+}
+
+#if defined __GNUC__
+__attribute__ ((format (printf, 1, 2)))
+#endif
+void warning1(char const *msg, ...)
+{
+#ifdef DEBUG_MKDEPEND
+ va_list args;
+ va_start(args, msg);
+ vfprintf(stderr, msg, args);
+ va_end(args);
+#else
+ (void)msg;
+#endif /* DEBUG_MKDEPEND */
+}
+
+void convert_slashes(char *path)
+{
+#if defined (_WIN32)
+ /*
+ * Convert backslashes to slashes
+ */
+ char *ptr;
+ if (native_win_slashes) {
+ for (ptr = (char*)path; *ptr; ++ptr)
+ if (*ptr == '/')
+ *ptr = '\\';
+ } else {
+ for (ptr = (char*)path; *ptr; ++ptr)
+ if (*ptr == '\\')
+ *ptr = '/';
+ }
+#else
+ (void)path;
+#endif
+}
+
+char* append_slash(char *path)
+{
+ char *new_string;
+ const char cLastChar = path[strlen(path) - 1];
+ if (cLastChar == '/' || cLastChar == '\\') {
+ new_string = path;
+ } else {
+ new_string = (char*)malloc(sizeof(char) * (strlen(path) + 2));
+ assert(new_string); // Don't handle OOM conditions
+ strcpy(new_string, path);
+ if (native_win_slashes)
+ strcat(new_string, "\\");
+ else
+ strcat(new_string, "/");
+ }
+ return new_string;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/soltools/mkdepend/mkdepend.man b/soltools/mkdepend/mkdepend.man
new file mode 100644
index 000000000..9c3cdccd9
--- /dev/null
+++ b/soltools/mkdepend/mkdepend.man
@@ -0,0 +1,368 @@
+.\" $XConsortium: mkdepend.man,v 1.15 94/04/17 20:10:37 gildea Exp $
+.\" Copyright (c) 1993, 1994 X Consortium
+.\"
+.\" Permission is hereby granted, free of charge, to any person obtaining a
+.\" copy of this software and associated documentation files (the "Software"),
+.\" to deal in the Software without restriction, including without limitation
+.\" the rights to use, copy, modify, merge, publish, distribute, sublicense,
+.\" and/or sell copies of the Software, and to permit persons to whom the
+.\" Software furnished to do so, subject to the following conditions:
+.\"
+.\" The above copyright notice and this permission notice shall be included in
+.\" all copies or substantial portions of the Software.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+.\" IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+.\" FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+.\" THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+.\" WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+.\" OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+.\" SOFTWARE.
+.\"
+.\" Except as contained in this notice, the name of the X Consortium shall not
+.\" be used in advertising or otherwise to promote the sale, use or other
+.\" dealing in this Software without prior written authorization from the
+.\" X Consortium.
+.TH MAKEDEPEND 1 "Release 6" "X Version 11"
+.UC 4
+.SH NAME
+makedepend \- create dependencies in makefiles
+.SH SYNOPSIS
+.B makedepend
+[
+.B \-Dname=def
+] [
+.B \-Dname
+] [
+.B \-Iincludedir
+] [
+.B \-Yincludedir
+] [
+.B \-a
+] [
+.B \-fmakefile
+] [
+.B \-oobjsuffix
+] [
+.B \-pobjprefix
+] [
+.B \-sstring
+] [
+.B \-wwidth
+] [
+.B \-v
+] [
+.B \-m
+] [
+\-\^\-
+.B otheroptions
+\-\^\-
+]
+sourcefile .\|.\|.
+.br
+.SH DESCRIPTION
+.B Makedepend
+reads each
+.I sourcefile
+in sequence and parses it like a C-preprocessor,
+processing all
+.I #include,
+.I #define,
+.I #undef,
+.I #ifdef,
+.I #ifndef,
+.I #endif,
+.I #if
+and
+.I #else
+directives so that it can correctly tell which
+.I #include,
+directives would be used in a compilation.
+Any
+.I #include,
+directives can reference files having other
+.I #include
+directives, and parsing will occur in these files as well.
+.PP
+Every file that a
+.I sourcefile
+includes,
+directly or indirectly,
+is what
+.B makedepend
+calls a "dependency".
+These dependencies are then written to a
+.I makefile
+in such a way that
+.B make(1)
+will know which object files must be recompiled when a dependency has changed.
+.PP
+By default,
+.B makedepend
+places its output in the file named
+.I makefile
+if it exists, otherwise
+.I Makefile.
+An alternate makefile may be specified with the
+.B \-f
+option.
+It first searches the makefile for
+the line
+.sp
+ # DO NOT DELETE THIS LINE \-\^\- make depend depends on it.
+.sp
+or one provided with the
+.B \-s
+option,
+as a delimiter for the dependency output.
+If it finds it, it will delete everything
+following this to the end of the makefile
+and put the output after this line.
+If it doesn't find it, the program
+will append the string to the end of the makefile
+and place the output following that.
+For each
+.I sourcefile
+appearing on the command line,
+.B makedepend
+puts lines in the makefile of the form
+.sp
+ sourcefile.o:\0dfile .\|.\|.
+.sp
+Where "sourcefile.o" is the name from the command
+line with its suffix replaced with ".o",
+and "dfile" is a dependency discovered in a
+.I #include
+directive while parsing
+.I sourcefile
+or one of the files it included.
+.SH EXAMPLE
+Normally,
+.B makedepend
+will be used in a makefile target so that typing "make depend" will
+bring the dependencies up to date for the makefile.
+For example,
+.nf
+ SRCS\0=\0file1.c\0file2.c\0.\|.\|.
+ CFLAGS\0=\0\-O\0\-DHACK\0\-I\^.\^.\^/foobar\0\-xyz
+ depend:
+ makedepend\0\-\^\-\0$(CFLAGS)\0\-\^\-\0$(SRCS)
+.fi
+.SH OPTIONS
+.B Makedepend
+will ignore any option that it does not understand so that you may use
+the same arguments that you would for
+.B cc(1).
+.TP 5
+.B \-Dname=def or \-Dname
+Define.
+This places a definition for
+.I name
+in
+.B makedepend's
+symbol table.
+Without
+.I =def
+the symbol becomes defined as "1".
+.TP 5
+.B \-Iincludedir
+Include directory.
+This option tells
+.B makedepend
+to prepend
+.I includedir
+to its list of directories to search when it encounters
+a
+.I #include
+directive.
+By default,
+.B makedepend
+only searches the standard include directories (usually /usr/include
+and possibly a compiler-dependent directory).
+.TP 5
+.B \-Yincludedir
+Replace all of the standard include directories with the single specified
+include directory; you can omit the
+.I includedir
+to simply prevent searching the standard include directories.
+.TP 5
+.B \-a
+Append the dependencies to the end of the file instead of replacing them.
+.TP 5
+.B \-fmakefile
+Filename.
+This allows you to specify an alternate makefile in which
+.B makedepend
+can place its output.
+.TP 5
+.B \-oobjsuffix
+Object file suffix.
+Some systems may have object files whose suffix is something other
+than ".o".
+This option allows you to specify another suffix, such as
+".b" with
+.I -o.b
+or ":obj"
+with
+.I -o:obj
+and so forth.
+.TP 5
+.B \-pobjprefix
+Object file prefix.
+The prefix is prepended to the name of the object file. This is
+usually used to designate a different directory for the object file.
+The default is the empty string.
+.TP 5
+.B \-sstring
+Starting string delimiter.
+This option permits you to specify
+a different string for
+.B makedepend
+to look for in the makefile.
+.TP 5
+.B \-wwidth
+Line width.
+Normally,
+.B makedepend
+will ensure that every output line that it writes will be no wider than
+78 characters for the sake of readability.
+This option enables you to change this width.
+.TP 5
+.B \-v
+Verbose operation.
+This option causes
+.B makedepend
+to emit the list of files included by each input file on standard output.
+.TP 5
+.B \-m
+Warn about multiple inclusion.
+This option causes
+.B makedepend
+to produce a warning if any input file includes another file more than
+once. In previous versions of
+.B makedepend
+this was the default behavior; the default has been changed to better
+match the behavior of the C compiler, which does not consider multiple
+inclusion to be an error. This option is provided for backward
+compatibility, and to aid in debugging problems related to multiple
+inclusion.
+.TP 5
+.B "\-\^\- options \-\^\-"
+If
+.B makedepend
+encounters a double hyphen (\-\^\-) in the argument list,
+then any unrecognized argument following it
+will be silently ignored; a second double hyphen terminates this
+special treatment.
+In this way,
+.B makedepend
+can be made to safely ignore esoteric compiler arguments that might
+normally be found in a CFLAGS
+.B make
+macro (see the
+.B EXAMPLE
+section above).
+All options that
+.B makedepend
+recognizes and appear between the pair of double hyphens
+are processed normally.
+.SH ALGORITHM
+The approach used in this program enables it to run an order of magnitude
+faster than any other "dependency generator" I have ever seen.
+Central to this performance are two assumptions:
+that all files compiled by a single
+makefile will be compiled with roughly the same
+.I -I
+and
+.I -D
+options;
+and that most files in a single directory will include largely the
+same files.
+.PP
+Given these assumptions,
+.B makedepend
+expects to be called once for each makefile, with
+all source files that are maintained by the
+makefile appearing on the command line.
+It parses each source and include
+file exactly once, maintaining an internal symbol table
+for each.
+Thus, the first file on the command line will take an amount of time
+proportional to the amount of time that a normal C preprocessor takes.
+But on subsequent files, if it encounter's an include file
+that it has already parsed, it does not parse it again.
+.PP
+For example,
+imagine you are compiling two files,
+.I file1.c
+and
+.I file2.c,
+they each include the header file
+.I header.h,
+and the file
+.I header.h
+in turn includes the files
+.I def1.h
+and
+.I def2.h.
+When you run the command
+.sp
+ makedepend\0file1.c\0file2.c
+.sp
+.B makedepend
+will parse
+.I file1.c
+and consequently,
+.I header.h
+and then
+.I def1.h
+and
+.I def2.h.
+It then decides that the dependencies for this file are
+.sp
+ file1.o:\0header.h\0def1.h\0def2.h
+.sp
+But when the program parses
+.I file2.c
+and discovers that it, too, includes
+.I header.h,
+it does not parse the file,
+but simply adds
+.I header.h,
+.I def1.h
+and
+.I def2.h
+to the list of dependencies for
+.I file2.o.
+.SH "SEE ALSO"
+cc(1), make(1)
+.SH BUGS
+.B makedepend
+parses, but does not currently evaluate, the SVR4
+#predicate(token-list) preprocessor expression;
+such expressions are simply assumed to be true.
+This may cause the wrong
+.I #include
+directives to be evaluated.
+.PP
+Imagine you are parsing two files,
+say
+.I file1.c
+and
+.I file2.c,
+each includes the file
+.I def.h.
+The list of files that
+.I def.h
+includes might truly be different when
+.I def.h
+is included by
+.I file1.c
+than when it is included by
+.I file2.c.
+But once
+.B makedepend
+arrives at a list of dependencies for a file,
+it is cast in concrete.
+.SH AUTHOR
+Todd Brunhoff, Tektronix, Inc. and MIT Project Athena
diff --git a/soltools/mkdepend/parse.c b/soltools/mkdepend/parse.c
new file mode 100644
index 000000000..a5c8273a2
--- /dev/null
+++ b/soltools/mkdepend/parse.c
@@ -0,0 +1,402 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* $XConsortium: parse.c,v 1.30 94/04/17 20:10:38 gildea Exp $ */
+/*
+
+Copyright (c) 1993, 1994 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+*/
+
+#include <ctype.h>
+
+#include "def.h"
+static char *hash_lookup( char *symbol, struct symhash *symbols );
+static int gobble( struct filepointer *filep, struct inclist *file,
+ struct inclist *file_red, struct symhash *symbols );
+static int deftype ( char *line, struct filepointer *filep, struct inclist *file,
+ int parse_it, struct symhash *symbols);
+static int zero_value(char const *exp, struct symhash *symbols);
+
+extern struct symhash *maininclist;
+
+int find_includes(struct filepointer *filep, struct inclist *file, struct inclist *file_red, int recursion, boolean failOK, struct IncludesCollection* incCollection, struct symhash *symbols)
+{
+ char *line;
+ int type;
+
+ while ((line = get_line(filep))) {
+ type = deftype(line, filep, file, TRUE, symbols);
+ switch(type) {
+ case IF:
+ doif:
+ type = find_includes(filep, file,
+ file_red, recursion+1, failOK, incCollection, symbols);
+ while ((type == ELIF) || (type == ELIFFALSE) ||
+ (type == ELIFGUESSFALSE))
+ type = gobble(filep, file, file_red, symbols);
+ break;
+ case IFFALSE:
+ doiffalse:
+ type = gobble(filep, file, file_red, symbols);
+ if (type == ELIF)
+ goto doif;
+ else if ((type == ELIFFALSE) || (type == ELIFGUESSFALSE))
+ goto doiffalse;
+ break;
+ case ELIFFALSE:
+ case ELIFGUESSFALSE:
+ case ELIF:
+ if (!recursion)
+ gobble(filep, file, file_red, symbols);
+ if (recursion)
+ return type;
+ define(line, &symbols);
+ break;
+ case ERROR:
+ warning("%s: %d: %s\n", file_red->i_file,
+ filep->f_line, line);
+ break;
+
+ case -1:
+ warning("%s", file_red->i_file);
+ if (file_red != file)
+ warning1(" (reading %s)", file->i_file);
+ warning1(", line %d: unknown directive == \"%s\"\n",
+ filep->f_line, line);
+ break;
+ case -2:
+ warning("%s", file_red->i_file);
+ if (file_red != file)
+ warning1(" (reading %s)", file->i_file);
+ warning1(", line %d: incomplete include == \"%s\"\n",
+ filep->f_line, line);
+ break;
+ }
+ }
+ // coverity[leaked_storage] - on purpose
+ return -1;
+}
+
+int gobble(struct filepointer *filep,
+ struct inclist *file,
+ struct inclist *file_red,
+ struct symhash *symbols)
+{
+ char *line;
+ int type;
+
+ while ((line = get_line(filep))) {
+ type = deftype(line, filep, file, FALSE, symbols);
+ switch(type) {
+ case IF:
+ case IFFALSE:
+ type = gobble(filep, file, file_red, symbols);
+ while ((type == ELIF) || (type == ELIFFALSE) ||
+ (type == ELIFGUESSFALSE))
+ type = gobble(filep, file, file_red, symbols);
+ break;
+ case ERROR:
+ break;
+ case ELIF:
+ case ELIFFALSE:
+ case ELIFGUESSFALSE:
+ return type;
+ case -1:
+ warning("%s, line %d: unknown directive == \"%s\"\n",
+ file_red->i_file, filep->f_line, line);
+ break;
+ }
+ }
+ return -1;
+}
+
+/*
+ * Decide what type of # directive this line is.
+ */
+int deftype (char *line, struct filepointer *filep, struct inclist * file,
+ int parse_it, struct symhash *symbols)
+{
+ char *p;
+ char *directive, savechar;
+ int ret;
+ (void)file; // used in DEBUG mode
+ (void)filep;
+ /*
+ * Parse the directive...
+ */
+ directive=line+1;
+ while (*directive == ' ' || *directive == '\t')
+ directive++;
+
+ p = directive;
+ while (*p >= 'a' && *p <= 'z')
+ p++;
+ savechar = *p;
+ *p = '\0';
+ ret = match(directive, directives);
+ *p = savechar;
+
+ /* If we don't recognize this compiler directive or we happen to just
+ * be gobbling up text while waiting for an #endif or #elif or #else
+ * in the case of an #elif we must check the zero_value and return an
+ * ELIF or an ELIFFALSE.
+ */
+
+ if (ret == ELIF && !parse_it)
+ {
+ while (*p == ' ' || *p == '\t')
+ p++;
+ /*
+ * parse an expression.
+ */
+ debug(0,("%s, line %d: #elif %s ",
+ file->i_file, filep->f_line, p));
+ ret = zero_value(p, symbols);
+ if (ret != IF)
+ {
+ debug(0,("false...\n"));
+ if (ret == IFFALSE)
+ return ELIFFALSE;
+ else
+ return ELIFGUESSFALSE;
+ }
+ else
+ {
+ debug(0,("true...\n"));
+ return ELIF;
+ }
+ }
+
+ if (ret < 0 || ! parse_it)
+ return ret;
+
+ /*
+ * now decide how to parse the directive, and do it.
+ */
+ while (*p == ' ' || *p == '\t')
+ p++;
+ switch (ret) {
+ case IF:
+ /*
+ * parse an expression.
+ */
+ ret = zero_value(p, symbols);
+ debug(0,("%s, line %d: %s #if %s\n",
+ file->i_file, filep->f_line, ret?"false":"true", p));
+ break;
+ case ELIF:
+ case ERROR:
+ debug(0,("%s, line %d: #%s\n",
+ file->i_file, filep->f_line, directives[ret]));
+ /*
+ * nothing to do.
+ */
+ break;
+ }
+ return ret;
+}
+
+/*
+ * HACK! - so that we do not have to introduce 'symbols' in each cppsetup.c
+ * function... It's safe, functions from cppsetup.c don't return here.
+ */
+static struct symhash *global_symbols = NULL;
+
+char * isdefined( char *symbol )
+{
+ return hash_lookup( symbol, global_symbols );
+}
+
+/*
+ * Return type based on if the #if expression evaluates to 0
+ */
+int zero_value(char const *exp, struct symhash *symbols)
+{
+ global_symbols = symbols; /* HACK! see above */
+ if (cppsetup(exp))
+ return IFFALSE;
+ else
+ return IF;
+}
+
+void define( char *def, struct symhash **symbols )
+{
+ char *val;
+
+ /* Separate symbol name and its value */
+ val = def;
+ while (isalnum((unsigned char)*val) || *val == '_')
+ val++;
+ if (*val)
+ *val++ = '\0';
+ while (*val == ' ' || *val == '\t')
+ val++;
+
+ if (!*val)
+ val = "1";
+ hash_define( def, val, symbols );
+}
+
+static int hash( char *str )
+{
+ /* Hash (Kernighan and Ritchie) */
+ unsigned int hashval = 0;
+
+ for ( ; *str; str++ )
+ {
+ hashval = ( hashval * SYMHASHSEED ) + ( *str );
+ }
+
+ return hashval & ( SYMHASHMEMBERS - 1 );
+}
+
+struct symhash *hash_copy( struct symhash *symbols )
+{
+ int i;
+ struct symhash *newsym;
+ if ( !symbols )
+ return NULL;
+
+ newsym = (struct symhash *) malloc( sizeof( struct symhash ) );
+
+ for ( i = 0; i < SYMHASHMEMBERS; ++i )
+ {
+ if ( !symbols->s_pairs[ i ] )
+ newsym->s_pairs[ i ] = NULL;
+ else
+ {
+ struct pair *it = symbols->s_pairs[ i ];
+ struct pair *nw = newsym->s_pairs[ i ] = (struct pair*) malloc( sizeof( struct pair ) );
+ nw->p_name = it->p_name;
+ nw->p_value = it->p_value;
+ nw->p_next = NULL;
+
+ while ( it->p_next )
+ {
+ nw->p_next = (struct pair*) malloc( sizeof( struct pair ) );
+ it = it->p_next;
+ nw = nw->p_next;
+ nw->p_name = it->p_name;
+ nw->p_value = it->p_value;
+ nw->p_next = NULL;
+ }
+ }
+ }
+ return newsym;
+}
+
+void hash_free( struct symhash *symbols )
+{
+ int i;
+
+ if ( !symbols )
+ return;
+
+ for ( i = 0; i < SYMHASHMEMBERS; ++i )
+ {
+ struct pair *it = symbols->s_pairs[ i ];
+ struct pair *next;
+ while ( it )
+ {
+ next = it->p_next;
+ free( it );
+ it = next;
+ }
+ }
+ free( symbols->s_pairs );
+}
+
+void hash_define( char *name, char const *val, struct symhash **symbols )
+{
+ int hashval;
+ struct pair *it;
+
+ if ( !symbols )
+ return;
+
+ /* Make space if it's needed */
+ if ( *symbols == NULL )
+ {
+ int i;
+
+ *symbols = (struct symhash *) malloc( sizeof( struct symhash ) );
+ if ( *symbols == NULL )
+ fatalerr( "malloc()/realloc() failure in insert_defn()\n" );
+
+ for ( i = 0; i < SYMHASHMEMBERS; ++i )
+ (*symbols)->s_pairs[i] = NULL;
+ }
+
+ hashval = hash( name );
+ it = (*symbols)->s_pairs[ hashval ];
+
+ /* Replace/insert the symbol */
+ if ( it == NULL )
+ {
+ it = (*symbols)->s_pairs[ hashval ] = (struct pair*) malloc( sizeof( struct pair ) );
+ it->p_name = copy( name );
+ it->p_value = copy( val );
+ it->p_next = NULL;
+ }
+ else if ( strcmp( it->p_name, name ) == 0 )
+ {
+ it->p_value = copy( val );
+ }
+ else
+ {
+ while ( it->p_next && ( strcmp( it->p_next->p_name, name ) != 0 ) )
+ {
+ it = it->p_next;
+ }
+ if ( it->p_next )
+ it->p_next->p_name = copy( name );
+ else
+ {
+ it->p_next = (struct pair*) malloc( sizeof( struct pair ) );
+ it->p_next->p_name = copy( name );
+ it->p_next->p_value = copy( val );
+ it->p_next->p_next = NULL;
+ }
+ }
+}
+
+char *hash_lookup( char *symbol, struct symhash *symbols )
+{
+ struct pair *it;
+
+ if ( !symbols )
+ return NULL;
+
+ it = symbols->s_pairs[ hash( symbol ) ];
+
+ while ( it && ( strcmp( it->p_name, symbol ) != 0 ) )
+ {
+ it = it->p_next;
+ }
+ if ( it )
+ return it->p_value;
+
+ return NULL;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/soltools/mkdepend/pr.c b/soltools/mkdepend/pr.c
new file mode 100644
index 000000000..7911502ed
--- /dev/null
+++ b/soltools/mkdepend/pr.c
@@ -0,0 +1,146 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* $XConsortium: pr.c,v 1.17 94/04/17 20:10:38 gildea Exp $ */
+/*
+
+Copyright (c) 1993, 1994 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+*/
+
+#include "def.h"
+#include <string.h>
+static size_t pr( struct inclist *ip, char *file,char *base);
+
+extern int width;
+
+void add_include(struct filepointer *filep, struct inclist *file, struct inclist *file_red, char *include, boolean dot, boolean failOK, struct IncludesCollection* incCollection, struct symhash *symbols)
+{
+ struct inclist *newfile;
+ struct filepointer *content;
+
+ /*
+ * First decide what the pathname of this include file really is.
+ */
+ newfile = inc_path(file->i_file, include, dot, incCollection);
+ if (newfile == NULL) {
+ if (failOK)
+ return;
+ if (file != file_red)
+ warning("%s (reading %s, line %d): ",
+ file_red->i_file, file->i_file, filep->f_line);
+ else
+ warning("%s, line %d: ", file->i_file, filep->f_line);
+ warning1("cannot find include file \"%s\"\n", include);
+ show_where_not = TRUE;
+ newfile = inc_path(file->i_file, include, dot, incCollection);
+ show_where_not = FALSE;
+ }
+
+ if (!newfile)
+ return;
+
+ /* Only add new dependency files if they don't have "/usr/include" in them. */
+ if (!(newfile->i_file && strstr(newfile->i_file, "/usr/"))) {
+ included_by(file, newfile);
+ }
+
+ if (!newfile->i_searched) {
+ newfile->i_searched = TRUE;
+ content = getfile(newfile->i_file);
+ // coverity[tainted_data] - this is a build time tool
+ find_includes(content, newfile, file_red, 0, failOK, incCollection, symbols);
+ freefile(content);
+ }
+}
+
+static void pr_dummy(struct inclist const *ip)
+{
+ fwrite(ip->i_file, strlen(ip->i_file), 1, stdout);
+ fwrite(" :\n\n", 4, 1, stdout);
+}
+
+void recursive_pr_dummy(struct inclist *head, char *file)
+{
+ int i;
+
+ if (head->i_marked == 2)
+ return;
+ head->i_marked = 2; // it's a large boolean...
+ if (head->i_file != file)
+ pr_dummy(head);
+ for (i=0; i<head->i_listlen; i++)
+ recursive_pr_dummy(head->i_list[ i ], file);
+}
+
+
+void recursive_pr_include(struct inclist *head, char *file, char *base)
+{
+ int i;
+
+ if (head->i_marked)
+ return;
+ head->i_marked = TRUE;
+ if (head->i_file != file)
+ pr(head, file, base);
+ for (i=0; i<head->i_listlen; i++)
+ recursive_pr_include(head->i_list[ i ], file, base);
+}
+
+size_t pr(struct inclist *ip, char *file, char *base)
+{
+ size_t ret;
+ static char *lastfile;
+ int len, i;
+ char buf[ BUFSIZ ];
+
+ printed = TRUE;
+ len = (int)strlen(ip->i_file)+4;
+ if (file != lastfile) {
+ lastfile = file;
+ sprintf(buf, "\n%s%s%s: \\\n %s", objprefix, base, objsuffix,
+ ip->i_file);
+ len = (int)strlen(buf);
+ }
+ else {
+ buf[0] = ' ';
+ buf[1] = '\\';
+ buf[2] = '\n';
+ buf[3] = ' ';
+ strcpy(buf+4, ip->i_file);
+ }
+ ret = fwrite(buf, len, 1, stdout);
+
+ /*
+ * If verbose is set, then print out what this file includes.
+ */
+ if (! verbose || ip->i_list == NULL || ip->i_notified)
+ return ret;
+ ip->i_notified = TRUE;
+ lastfile = NULL;
+ printf("\n# %s includes:", ip->i_file);
+ for (i=0; i<ip->i_listlen; i++)
+ printf("\n#\t%s", ip->i_list[ i ]->i_incstring);
+ return ret;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */