Index: branches/XORG/src/makedep/Imakefile
===================================================================
--- branches/XORG/src/makedep/Imakefile	(revision 165)
+++ branches/XORG/src/makedep/Imakefile	(revision 165)
@@ -0,0 +1,101 @@
+XCOMM $Xorg: Imakefile,v 1.3 2000/08/17 19:41:50 cpqbld Exp $
+XCOMM
+XCOMM
+XCOMM
+XCOMM
+XCOMM $XFree86: xc/config/makedepend/Imakefile,v 3.12tsi Exp $
+
+    SRCS = include.c main.c parse.c pr.c cppsetup.c ifparser.c
+    OBJS = include.o main.o parse.o pr.o cppsetup.o ifparser.o
+
+XCOMM Some compilers generate fatal errors if an -L directory does
+XCOMM not exist.  Since BUILDLIBDIR may not exist yet suppress its use.
+         LDPRELIB =
+        LDPRELIBS =
+
+#if HasGcc && !defined(PreIncDir)
+#ifdef CrossCompileDir
+#else
+#define PreIncDir /usr/local/lib/gcc-include
+#endif
+#endif
+#ifdef PreIncDir
+PREINCDIR = PreIncDir
+PREINC_DEFINES = -DPREINCDIR=\"$(PREINCDIR)\"
+#endif
+#ifndef StdIncDir
+#ifdef CrossCompileDir
+#define StdIncDir Concat(CrossCompileDir,/../include)
+#else
+#define StdIncDir /usr/include
+#endif
+#endif
+STDINCDIR = StdIncDir
+STDINC_DEFINES = -DINCLUDEDIR=\"$(STDINCDIR)\"
+#ifdef PostIncDir
+POSTINCDIR = PostIncDir
+POSTINC_DEFINES = -DPOSTINCDIR=\"$(POSTINCDIR)\"
+#endif
+#ifdef ExtraIncDir
+EXTRAINCDIR = ExtraIncDir
+EXTRAINC_DEFINES = -DEXTRAINCDIR=\"$(EXTRAINCDIR)\"
+#endif
+INC_DEFINES = $(PREINC_DEFINES) $(STDINC_DEFINES) $(POSTINC_DEFINES) \
+	      $(EXTRAINC_DEFINES)
+OSUF = Concat(.,Osuf)
+OSUF_DEFINES = -DOBJSUFFIX=\"$(OSUF)\"
+MAIN_DEFINES = $(INC_DEFINES) $(SIGNAL_DEFINES) $(OSUF_DEFINES)
+INCLUDES = -I$(IMAKESRC) -I$(TOP)/include $(TOP_X_INCLUDES)/X11
+
+ DEPLIBS =
+
+#if defined(MacIIArchitecture) || defined(SequentArchitecture) || defined(i386ScoArchitecture)
+ XBSDLIB = /**/
+#endif
+
+AllTarget(HostProgramTargetName(makedepend))
+
+makedependonly:: HostProgramTargetName(makedepend)
+
+/*
+ * bootstrapping: want to build the real makedepend
+ * only after we've run "make depend" here.  That way
+ * the program has the right dependencies for clearmake.
+ * Save the bootstrap original files so they can be winked in
+ * to other views.
+ */
+
+#if HasClearmake
+bootstrap:
+	test -h X11 || $(LN) TOPDIR/include X11
+	$(MAKE) -f Makefile.proto TOP_INCLUDES=-I. makedepend
+
+depend::
+	$(MAKE) -f Makefile.proto depend
+	test -d bootstrap || mkdir bootstrap
+	$(MV) *.o makedepend bootstrap
+	$(MAKE) -f Makefile.proto makedepend
+
+clean::
+	$(RM) -r bootstrap
+	$(RM) X11
+#else
+bootstrap:
+#endif /* HasClearmake */
+
+clean::
+	$(RM) Makefile.proto
+
+#undef InstallManPage
+#define InstallManPage(file,dest) /* as nothing */
+#if CrossCompiling
+ComplexHostProgramTarget(makedepend)
+#else
+ComplexProgramTarget(makedepend)
+#endif
+
+SpecialCObjectRule(main,$(ICONFIGFILES),$(MAIN_DEFINES))
+
+InstallManPageLong(mkdepend,$(MANDIR),makedepend)
+
+InstallDriverSDKNamedProg(makedepend,makedepend,$(DRIVERSDKDIR)/config/makedepend)
Index: branches/XORG/src/makedep/cppsetup.c
===================================================================
--- branches/XORG/src/makedep/cppsetup.c	(revision 165)
+++ branches/XORG/src/makedep/cppsetup.c	(revision 165)
@@ -0,0 +1,233 @@
+/* $Xorg: cppsetup.c,v 1.5 2001/02/09 02:03:16 xorgcvs Exp $ */
+/*
+
+Copyright (c) 1993, 1994, 1998  The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+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
+OPEN GROUP 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 Open Group 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 Open Group.
+
+*/
+/* $XFree86: xc/config/makedepend/cppsetup.c,v 3.10 2001/12/14 19:53:20 dawes Exp $ */
+
+#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 defined(pdp11) || defined(vax) || defined(ns16000) || defined(mc68000) || defined(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;
+
+int
+cppsetup(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);
+}
+
+struct symtab **lookup(symbol)
+	char	*symbol;
+{
+	static struct symtab    *undefined;
+	struct symtab   **sp;
+
+	sp = isdefined(symbol, currentinc, NULL);
+	if (sp == NULL) {
+		sp = &undefined;
+		(*sp)->s_value = NULL;
+	}
+	return (sp);
+}
+
+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)
+	register char	*s;
+{
+	fatalerr("Fatal error: %s\n", s);
+}
+#else /* not CPP */
+
+#include "ifparser.h"
+struct _parse_data {
+    struct filepointer *filep;
+    struct inclist *inc;
+    char *filename;
+    const char *line;
+};
+
+static const char *
+my_if_errors (IfParser *ip, const char *cp, const char *expecting)
+{
+    struct _parse_data *pd = (struct _parse_data *) ip->data;
+    int lineno = pd->filep->f_line;
+    char *filename = pd->filename;
+    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);
+    return NULL;
+}
+
+
+#define MAXNAMELEN 256
+
+static struct symtab **
+lookup_variable (IfParser *ip, const char *var, int len)
+{
+    char tmpbuf[MAXNAMELEN + 1];
+    struct _parse_data *pd = (struct _parse_data *) ip->data;
+
+    if (len > MAXNAMELEN)
+	return 0;
+
+    strncpy (tmpbuf, var, len);
+    tmpbuf[len] = '\0';
+    return isdefined (tmpbuf, pd->inc, NULL);
+}
+
+
+static int
+my_eval_defined (IfParser *ip, const char *var, int len)
+{
+    if (lookup_variable (ip, var, len))
+	return 1;
+    else
+	return 0;
+}
+
+#define isvarfirstletter(ccc) (isalpha(ccc) || (ccc) == '_')
+
+static long
+my_eval_variable (IfParser *ip, const char *var, int len)
+{
+    long val;
+    struct symtab **s;
+
+    s = lookup_variable (ip, var, len);
+    if (!s)
+	return 0;
+    do {
+	var = (*s)->s_value;
+	if (!isvarfirstletter(*var) || !strcmp((*s)->s_name, var))
+	    break;
+	s = lookup_variable (ip, var, strlen(var));
+    } while (s);
+
+    var = ParseIfExpression(ip, var, &val);
+    if (var && *var) debug(4, ("extraneous: '%s'\n", var));
+    return val;
+}
+
+int
+cppsetup(char *filename,
+	 char *line,
+	 struct filepointer *filep,
+	 struct inclist *inc)
+{
+    IfParser ip;
+    struct _parse_data pd;
+    long val = 0;
+
+    pd.filep = filep;
+    pd.inc = inc;
+    pd.line = line;
+    pd.filename = filename;
+    ip.funcs.handle_error = my_if_errors;
+    ip.funcs.eval_defined = my_eval_defined;
+    ip.funcs.eval_variable = my_eval_variable;
+    ip.data = (char *) &pd;
+
+    (void) ParseIfExpression (&ip, line, &val);
+    if (val)
+	return IF;
+    else
+	return IFFALSE;
+}
+#endif /* CPP */
+
Index: branches/XORG/src/makedep/def.h
===================================================================
--- branches/XORG/src/makedep/def.h	(revision 165)
+++ branches/XORG/src/makedep/def.h	(revision 165)
@@ -0,0 +1,182 @@
+/* $Xorg: def.h,v 1.4 2001/02/09 02:03:16 xorgcvs Exp $ */
+/*
+
+Copyright (c) 1993, 1994, 1998 The Open Group.
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+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
+OPEN GROUP 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 Open Group 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 Open Group.
+
+*/
+/* $XFree86: xc/config/makedepend/def.h,v 3.13tsi Exp $ */
+
+#include "Xos.h"
+#include "Xfuncproto.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#if 0
+#ifndef X_NOT_POSIX
+#ifndef _POSIX_SOURCE
+#define _POSIX_SOURCE
+#endif
+#endif
+#endif
+#include <sys/types.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+#define MAXDEFINES	512
+#define MAXFILES	1024
+#define MAXINCFILES	128	/* "-include" files */
+#define MAXDIRS		64
+#define SYMTABINC	10	/* must be > 1 for define() to work right */
+#define	TRUE		1
+#define	FALSE		0
+
+/* the following must match the directives table in main.c */
+#define	IF		0
+#define	IFDEF		1
+#define	IFNDEF		2
+#define	ELSE		3
+#define	ENDIF		4
+#define	DEFINE		5
+#define	UNDEF		6
+#define	INCLUDE		7
+#define	LINE		8
+#define	PRAGMA		9
+#define ERROR           10
+#define IDENT           11
+#define SCCS            12
+#define ELIF            13
+#define EJECT           14
+#define WARNING         15
+#define INCLUDENEXT     16
+#define IFFALSE         17     /* pseudo value --- never matched */
+#define ELIFFALSE       18     /* pseudo value --- never matched */
+#define INCLUDEDOT      19     /* pseudo value --- never matched */
+#define IFGUESSFALSE    20     /* pseudo value --- never matched */
+#define ELIFGUESSFALSE  21     /* pseudo value --- never matched */
+#define INCLUDENEXTDOT  22     /* 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 */
+
+typedef	unsigned char boolean;
+
+struct symtab {
+	char	*s_name;
+	char	*s_value;
+};
+
+/* possible i_flag */
+#define DEFCHECKED	(1<<0)	/* whether defines have been checked */
+#define NOTIFIED	(1<<1)	/* whether we have revealed includes */
+#define MARKED		(1<<2)	/* whether it's in the makefile */
+#define SEARCHED	(1<<3)	/* whether we have read this */
+#define FINISHED	(1<<4)	/* whether we are done reading this */
+#define INCLUDED_SYM	(1<<5)	/* whether #include SYMBOL was found
+				   Can't use i_list if TRUE */
+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 */
+	struct symtab	**i_defs;	/* symbol table for this file and its
+					   children when merged */
+	int		i_ndefs;	/* current # defines */
+	boolean		*i_merged;      /* whether we have merged child
+					   defines */
+	unsigned char   i_flags;
+};
+
+struct filepointer {
+	char	*f_name;
+	char	*f_p;
+	char	*f_base;
+	char	*f_end;
+	long	f_len;
+	long	f_line;
+	long	cmdinc_count;
+	char	**cmdinc_list;
+	long	cmdinc_line;
+};
+
+#include <stdlib.h>
+#if defined(macII) && !defined(__STDC__)  /* stdlib.h fails to define these */
+char *malloc(), *realloc();
+#endif /* macII */
+
+char			*copy(char *str);
+int                     match(char *str, char **list);
+char			*base_name(char *file);
+char			*getnextline(struct filepointer *fp);
+struct symtab		**slookup(char *symbol, struct inclist *file);
+struct symtab		**isdefined(char *symbol, struct inclist *file,
+				    struct inclist **srcfile);
+struct symtab		**fdefined(char *symbol, struct inclist *file,
+				   struct inclist **srcfile);
+struct filepointer	*getfile(char *file);
+void                    included_by(struct inclist *ip, 
+				    struct inclist *newfile);
+struct inclist		*newinclude(char *newfile, char *incstring);
+void                    inc_clean (void);
+struct inclist		*inc_path(char *file, char *include, int type);
+
+void                    freefile(struct filepointer *fp);
+
+void                    define2(char *name, char *val, struct inclist *file);
+void                    define(char *def, struct inclist *file);
+void                    undefine(char *symbol, struct inclist *file);
+int                     find_includes(struct filepointer *filep, 
+				      struct inclist *file, 
+				      struct inclist *file_red, 
+				      int recursion, boolean failOK);
+
+void                    recursive_pr_include(struct inclist *head, 
+					     char *file, char *base);
+void                    add_include(struct filepointer *filep, 
+				    struct inclist *file, 
+				    struct inclist *file_red, 
+				    char *include, int type,
+				    boolean failOK);
+
+int                     cppsetup(char *filename,
+				 char *line,
+				 struct filepointer *filep,
+				 struct inclist *inc);
+
+
+extern void fatalerr(char *, ...);
+extern void warning(char *, ...);
+extern void warning1(char *, ...);
Index: branches/XORG/src/makedep/ifparser.c
===================================================================
--- branches/XORG/src/makedep/ifparser.c	(revision 165)
+++ branches/XORG/src/makedep/ifparser.c	(revision 165)
@@ -0,0 +1,549 @@
+/*
+ * $Xorg: ifparser.c,v 1.3 2000/08/17 19:41:50 cpqbld 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 ':'	EXPRESSION
+ * 
+ *     VALUE		:=	'('  EXPRESSION  ')'
+ * 			 |	'!'  VALUE
+ * 			 |	'-'  VALUE
+ * 			 |	'+'  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
+ */
+/* $XFree86: xc/config/makedepend/ifparser.c,v 3.10tsi Exp $ */
+
+#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(*ccc)) ccc++
+#define isvarfirstletter(ccc) (isalpha(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(*cp) || *cp == '_'; cp++) ;
+    return cp;
+}
+
+
+static const char *
+parse_number (IfParser *g, const char *cp, long *valp)
+{
+    long base = 10;
+    SKIPSPACE (cp);
+
+    if (!isdigit(*cp))
+	return CALLFUNC(g, handle_error) (g, cp, "number");
+
+    *valp = 0;
+
+    if (*cp == '0') {
+	cp++;
+	if ((*cp == 'x') || (*cp == 'X')) {
+	    base = 16;
+	    cp++;
+	} else {
+	    base = 8;
+	}
+    }
+
+    /* Ignore overflows and assume ASCII, what source is usually written in */
+    while (1) {
+	int increment = -1;
+	if (base == 8) {
+	    if ((*cp >= '0') && (*cp <= '7'))
+		increment = *cp++ - '0';
+	} else if (base == 16) {
+	    if ((*cp >= '0') && (*cp <= '9'))
+		increment = *cp++ - '0';
+	    else if ((*cp >= 'A') &&  (*cp <= 'F'))
+		increment = *cp++ - ('A' - 10);
+	    else if ((*cp >= 'a') && (*cp <= 'f'))
+		increment = *cp++ - ('a' - 10);
+	} else {	/* Decimal */
+	    if ((*cp >= '0') && (*cp <= '9'))
+		increment = *cp++ - '0';
+	}
+	if (increment < 0)
+	    break;
+	*valp = (*valp * base) + increment;
+    }
+
+    /* Skip trailing qualifiers */
+    while (*cp == 'U' || *cp == 'u' || *cp == 'L' || *cp == 'l') cp++;
+    return cp;
+}
+
+static const char *
+parse_character (IfParser *g, const char *cp, long *valp)
+{
+    char val;
+
+    SKIPSPACE (cp);
+    if (*cp == '\\')
+	switch (cp[1]) {
+	case 'n': val = '\n'; break;
+	case 't': val = '\t'; break;
+	case 'v': val = '\v'; break;
+	case 'b': val = '\b'; break;
+	case 'r': val = '\r'; break;
+	case 'f': val = '\f'; break;
+	case 'a': val = '\a'; break;
+	case '\\': val = '\\'; break;
+	case '?': val = '\?'; break;
+	case '\'': val = '\''; break;
+	case '\"': val = '\"'; break;
+	case 'x': val = (char) strtol (cp + 2, NULL, 16); break;
+	default: val = (char) strtol (cp + 1, NULL, 8); break;
+	}
+    else
+	val = *cp;
+    while (*cp != '\'') cp++;
+    *valp = (long) val;
+    return cp;
+}
+
+static const char *
+parse_value (IfParser *g, const char *cp, long *valp)
+{
+    const char *var, *varend;
+
+    *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_value (g, cp + 1, 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 '\'':
+	DO (cp = parse_character (g, cp + 1, valp));
+	if (*cp != '\'')
+	    return CALLFUNC(g, handle_error) (g, cp, "'");
+	return cp + 1;
+
+      case 'd':
+	if (strncmp (cp, "defined", 7) == 0 && !isalnum(cp[7])) {
+	    int paren = 0;
+	    int len;
+
+	    cp += 7;
+	    SKIPSPACE (cp);
+	    if (*cp == '(') {
+		paren = 1;
+		cp++;
+	    }
+	    DO (cp = parse_variable (g, cp, &var));
+	    len = 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(*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));
+	varend = cp;
+	SKIPSPACE(cp);
+	if (*cp != '(') {
+	    *valp = (*(g->funcs.eval_variable)) (g, var, varend - var);
+	} else {
+	    do {
+		long dummy;
+		DO (cp = ParseIfExpression (g, cp + 1, &dummy));
+		SKIPSPACE(cp);
+		if (*cp == ')')
+		    break;
+		if (*cp != ',')
+		    return CALLFUNC(g, handle_error) (g, cp, ",");
+	    } while (1);
+
+	    *valp = 1;	/* XXX */
+	    cp++;
+	}
+    }
+    
+    return cp;
+}
+
+
+
+static const char *
+parse_product (IfParser *g, const char *cp, long *valp)
+{
+    long 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));
+	*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, long *valp)
+{
+    long 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, long *valp)
+{
+    long 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, long *valp)
+{
+    long 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, long *valp)
+{
+    long 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, long *valp)
+{
+    long 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_bxor (IfParser *g, const char *cp, long *valp)
+{
+    long rightval;
+
+    DO (cp = parse_band (g, cp, valp));
+    SKIPSPACE (cp);
+
+    switch (*cp) {
+      case '^':
+	DO (cp = parse_bxor (g, cp + 1, &rightval));
+	*valp = (*valp ^ rightval);
+	break;
+    }
+    return cp;
+}
+
+
+static const char *
+parse_bor (IfParser *g, const char *cp, long *valp)
+{
+    long rightval;
+
+    DO (cp = parse_bxor (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, long *valp)
+{
+    long 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, long *valp)
+{
+    long 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;
+}
+
+
+static const char *
+parse_cond(IfParser *g, const char *cp, long *valp)
+{
+    long trueval, falseval;
+
+    DO (cp = parse_lor (g, cp, valp));
+    SKIPSPACE (cp);
+
+    switch (*cp) {
+      case '?':
+	DO (cp = parse_cond (g, cp + 1, &trueval));
+	SKIPSPACE (cp);
+	if (*cp != ':')
+	    return CALLFUNC(g, handle_error) (g, cp, ":");
+	DO (cp = parse_cond (g, cp + 1, &falseval));
+	*valp = (*valp ? trueval : falseval);
+	break;
+    }
+    return cp;
+}
+
+
+/****************************************************************************
+			     External Entry Points
+ ****************************************************************************/
+
+const char *
+ParseIfExpression (IfParser *g, const char *cp, long *valp)
+{
+    return parse_cond (g, cp, valp);
+}
Index: branches/XORG/src/makedep/ifparser.h
===================================================================
--- branches/XORG/src/makedep/ifparser.h	(revision 165)
+++ branches/XORG/src/makedep/ifparser.h	(revision 165)
@@ -0,0 +1,83 @@
+/*
+ * $Xorg: ifparser.h,v 1.3 2000/08/17 19:41:51 cpqbld 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 ':'	EXPRESSION
+ * 
+ *     VALUE		:=	'('  EXPRESSION  ')'
+ * 			 |	'!'  VALUE
+ * 			 |	'-'  VALUE
+ *			 |	'~'  VALUE
+ * 			 |	'defined'  '('  variable  ')'
+ * 			 |	variable
+ * 			 |	number
+ * 
+ *     BINOP		:=	'*'	|  '/'	|  '%'
+ * 			 |	'+'	|  '-'
+ * 			 |	'<<'	|  '>>'
+ * 			 |	'<'	|  '>'	|  '<='  |  '>='
+ * 			 |	'=='	|  '!='
+ * 			 |	'&'	|  '^'  |  '|'
+ * 			 |	'&&'	|  '||'
+ * 
+ * The normal C order of precedence is supported.
+ * 
+ * 
+ * External Entry Points:
+ * 
+ *     ParseIfExpression		parse a string for #if
+ */
+
+/* $XFree86: xc/config/makedepend/ifparser.h,v 3.4 2001/01/17 16:38:58 dawes Exp $ */
+
+#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 *);
+	long (*eval_variable) (struct _if_parser *, const char *, int);
+	int (*eval_defined) (struct _if_parser *, const char *, int);
+    } funcs;
+    char *data;
+} IfParser;
+
+const char *ParseIfExpression (
+    IfParser *, 
+    const char *, 
+    long *
+);
+
Index: branches/XORG/src/makedep/include.c
===================================================================
--- branches/XORG/src/makedep/include.c	(revision 165)
+++ branches/XORG/src/makedep/include.c	(revision 165)
@@ -0,0 +1,318 @@
+/* $Xorg: include.c,v 1.4 2001/02/09 02:03:16 xorgcvs Exp $ */
+/*
+
+Copyright (c) 1993, 1994, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+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
+OPEN GROUP 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 Open Group 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 Open Group.
+
+*/
+/* $XFree86: xc/config/makedepend/include.c,v 3.6 2001/04/29 23:25:02 tsi Exp $ */
+
+
+#include "def.h"
+
+extern struct	inclist	inclist[ MAXFILES ],
+			*inclistp, *inclistnext;
+extern char	*includedirs[ ],
+		**includedirsnext;
+extern char	*notdotdot[ ];
+extern boolean show_where_not;
+extern boolean warn_multiple;
+
+static boolean
+isdot(char *p)
+{
+	if(p && *p++ == '.' && *p++ == '\0')
+		return(TRUE);
+	return(FALSE);
+}
+
+static boolean
+isdotdot(char *p)
+{
+	if(p && *p++ == '.' && *p++ == '.' && *p++ == '\0')
+		return(TRUE);
+	return(FALSE);
+}
+
+static boolean
+issymbolic(char *dir, char *component)
+{
+#ifdef S_IFLNK
+	struct stat	st;
+	char	buf[ BUFSIZ ], **pp;
+
+	sprintf(buf, "%s%s%s", dir, *dir ? "/" : "", component);
+	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);
+	}
+#endif
+	return(FALSE);
+}
+
+/*
+ * 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!!)
+ */
+static void
+remove_dotdot(char *path)
+{
+	register 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);
+}
+
+/*
+ * Add an include file to the list of those included by 'file'.
+ */
+struct inclist *
+newinclude(char *newfile, char *incstring)
+{
+	register 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);
+
+	inclistnext = inclistp;
+	return(ip);
+}
+
+void
+included_by(struct inclist *ip, struct inclist *newfile)
+{
+	register 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);
+		ip->i_merged = (boolean *)
+		    malloc(sizeof(boolean) * ip->i_listlen);
+	} else {
+		for (i=0; i<ip->i_listlen; i++)
+			if (ip->i_list[ i ] == newfile) {
+			    i = strlen(newfile->i_file);
+			    if (!(ip->i_flags & INCLUDED_SYM) &&
+				!(i > 2 &&
+				  newfile->i_file[i-1] == 'c' &&
+				  newfile->i_file[i-2] == '.'))
+			    {
+				/* only bitch 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_merged = (boolean *)
+		    realloc(ip->i_merged, sizeof(boolean) * ip->i_listlen);
+	}
+	ip->i_list[ ip->i_listlen-1 ] = newfile;
+	ip->i_merged[ ip->i_listlen-1 ] = FALSE;
+}
+
+void
+inc_clean (void)
+{
+	register struct inclist *ip;
+
+	for (ip = inclist; ip < inclistp; ip++) {
+		ip->i_flags &= ~MARKED;
+	}
+}
+
+struct inclist *
+inc_path(char *file, char *include, int type)
+{
+	static char		path[ BUFSIZ ];
+	register char		**pp, *p;
+	register struct inclist	*ip;
+	struct stat		st;
+
+	/*
+	 * Check all previously found include files for a path that
+	 * has already been expanded.
+	 */
+	if ((type == INCLUDE) || (type == INCLUDEDOT))
+		inclistnext = inclist;
+	ip = inclistnext;
+
+	for (; ip->i_file; ip++) {
+		if ((strcmp(ip->i_incstring, include) == 0) &&
+		    !(ip->i_flags & INCLUDED_SYM)) {
+			inclistnext = ip + 1;
+			return ip;
+		}
+	}
+
+	if (inclistnext == inclist) {
+		/*
+		 * If the path was surrounded by "" or is an absolute path,
+		 * then check the exact path provided.
+		 */
+		if ((type == INCLUDEDOT) ||
+		    (type == INCLUDENEXTDOT) ||
+		    (*include == '/')) {
+			if (stat(include, &st) == 0)
+				return newinclude(include, include);
+			if (show_where_not)
+				warning1("\tnot in %s\n", include);
+		}
+
+		/*
+		 * If the path was surrounded by "" see if this include file is
+		 * in the directory of the file being parsed.
+		 */
+		if ((type == INCLUDEDOT) || (type == INCLUDENEXTDOT)) {
+			for (p=file+strlen(file); p>file; p--)
+				if (*p == '/')
+					break;
+			if (p == file) {
+				strcpy(path, include);
+			} else {
+				strncpy(path, file, (p-file) + 1);
+				path[ (p-file) + 1 ] = '\0';
+				strcpy(path + (p-file) + 1, include);
+			}
+			remove_dotdot(path);
+			if (stat(path, &st) == 0)
+				return newinclude(path, include);
+			if (show_where_not)
+				warning1("\tnot in %s\n", path);
+		}
+	}
+
+	/*
+	 * Check the include directories specified.  Standard include dirs
+	 * should be at the end.
+	 */
+	if ((type == INCLUDE) || (type == INCLUDEDOT))
+		includedirsnext = includedirs;
+	pp = includedirsnext;
+
+	for (; *pp; pp++) {
+		sprintf(path, "%s/%s", *pp, include);
+		remove_dotdot(path);
+		if (stat(path, &st) == 0) {
+			includedirsnext = pp + 1;
+			return newinclude(path, include);
+		}
+		if (show_where_not)
+			warning1("\tnot in %s\n", path);
+	}
+
+	return NULL;
+}
Index: branches/XORG/src/makedep/main.c
===================================================================
--- branches/XORG/src/makedep/main.c	(revision 165)
+++ branches/XORG/src/makedep/main.c	(revision 165)
@@ -0,0 +1,852 @@
+/* $Xorg: main.c,v 1.5 2001/02/09 02:03:16 xorgcvs Exp $ */
+/*
+
+Copyright (c) 1993, 1994, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+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
+THE OPEN GROUP 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 Open Group 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 Open Group.
+
+*/
+/* $XFree86: xc/config/makedepend/main.c,v 3.31tsi Exp $ */
+
+#include "def.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
+
+/* #define DEBUG_DUMP */
+#ifdef DEBUG_DUMP
+#define DBG_PRINT(file, fmt, args)   fprintf(file, fmt, args)
+#else
+#define DBG_PRINT(file, fmt, args)   /* empty */
+#endif
+
+#define DASH_INC_PRE    "#include \""
+#define DASH_INC_POST   "\""
+
+char *ProgramName;
+
+char	*directives[] = {
+	"if",
+	"ifdef",
+	"ifndef",
+	"else",
+	"endif",
+	"define",
+	"undef",
+	"include",
+	"line",
+	"pragma",
+	"error",
+	"ident",
+	"sccs",
+	"elif",
+	"eject",
+	"warning",
+	"include_next",
+	NULL
+};
+
+#define MAKEDEPEND
+#include "imakemdep.h"	/* from config sources */
+#undef MAKEDEPEND
+
+struct	inclist inclist[ MAXFILES ],
+		*inclistp = inclist,
+		*inclistnext = inclist,
+		maininclist;
+
+static char	*filelist[ MAXFILES ];
+char		*includedirs[ MAXDIRS + 1 ],
+		**includedirsnext = includedirs;
+char		*notdotdot[ MAXDIRS ];
+static int	cmdinc_count = 0;
+static char	*cmdinc_list[ 2 * MAXINCFILES ];
+char		*objprefix = "";
+char		*objsuffix = OBJSUFFIX;
+static char	*startat = "# DO NOT DELETE";
+int		width = 78;
+static boolean	append = FALSE;
+boolean		printed = FALSE;
+boolean		verbose = FALSE;
+boolean		show_where_not = FALSE;
+/* Warn on multiple includes of same file */
+boolean 	warn_multiple = FALSE;
+
+static void setfile_cmdinc(struct filepointer *filep, long count, char **list);
+static void redirect(char *line, char *makefile);
+
+static
+#ifdef SIGNALRETURNSINT
+int
+#else
+void
+#endif
+catch (int sig)
+{
+	fflush (stdout);
+	fatalerr ("got signal %d\n", sig);
+}
+
+#if defined(USG) || (defined(i386) && defined(SYSV)) || defined(WIN32) || defined(__UNIXOS2__) || defined(Lynx_22) || defined(__CYGWIN__)
+#define USGISH
+#endif
+
+#ifndef USGISH
+#ifdef X_NOT_POSIX
+#define sigaction sigvec
+#define sa_handler sv_handler
+#define sa_mask sv_mask
+#define sa_flags sv_flags
+#endif
+struct sigaction sig_act;
+#endif /* USGISH */
+
+int
+main(int argc, char *argv[])
+{
+	char	**fp = filelist;
+	char	**incp = includedirs;
+	char	*p;
+	struct inclist	*ip;
+	char	*makefile = NULL;
+	struct filepointer	*filecontent;
+	struct symtab *psymp = predefs;
+	char *endmarker = NULL;
+	char *defincdir = NULL;
+	char **undeflist = NULL;
+	int numundefs = 0, i;
+
+	ProgramName = argv[0];
+
+	while (psymp->s_name)
+	{
+	    define2(psymp->s_name, psymp->s_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);
+	    fstat(afd, &ast);
+	    args = (char *)malloc(ast.st_size + 1);
+	    if ((ast.st_size = read(afd, args, 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 'U':
+			/* Undef's override all -D's so save them up */
+			numundefs++;
+			if (numundefs == 1)
+			    undeflist = malloc(sizeof(char *));
+			else
+			    undeflist = realloc(undeflist,
+						numundefs * sizeof(char *));
+			if (argv[0][2] == '\0') {
+				argv++;
+				argc--;
+			}
+			undeflist[numundefs - 1] = argv[0] + 2;
+			break;
+		case 'Y':
+			defincdir = argv[0]+2;
+			break;
+		/* do not use if endmarker processing */
+		case 'a':
+			if (endmarker) break;
+			append = TRUE;
+			break;
+		case 'w':
+			if (endmarker) break;
+			if (argv[0][2] == '\0') {
+				argv++;
+				argc--;
+				width = atoi(argv[0]);
+			} else
+				width = atoi(argv[0]+2);
+			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;
+		case 'i':
+			if (strcmp(&argv[0][1],"include") == 0) {
+				char *buf;
+				if (argc<2)
+					fatalerr("option -include is a "
+						 "missing its parameter\n");
+				if (cmdinc_count >= MAXINCFILES)
+					fatalerr("Too many -include flags.\n");
+				argc--;
+				argv++;
+				buf = malloc(strlen(DASH_INC_PRE) +
+					     strlen(argv[0]) +
+					     strlen(DASH_INC_POST) + 1);
+                		if(!buf)
+					fatalerr("out of memory at "
+						 "-include string\n");
+				cmdinc_list[2 * cmdinc_count + 0] = argv[0];
+				cmdinc_list[2 * cmdinc_count + 1] = buf;
+				cmdinc_count++;
+				break;
+			}
+			/* intentional fall through */
+		default:
+			if (endmarker) break;
+	/*		fatalerr("unknown opt = %s\n", argv[0]); */
+			warning("ignoring option %s\n", argv[0]);
+		}
+	}
+	/* Now do the undefs from the command line */
+	for (i = 0; i < numundefs; i++)
+	    undefine(undeflist[i], &maininclist);
+	if (numundefs > 0)
+	    free(undeflist);
+
+	if (!defincdir) {
+#ifdef PREINCDIR
+	    if (incp >= includedirs + MAXDIRS)
+		fatalerr("Too many -I flags.\n");
+	    *incp++ = PREINCDIR;
+#endif
+#ifdef __UNIXOS2__
+	    {
+		char *emxinc = getenv("C_INCLUDE_PATH");
+		/* can have more than one component */
+		if (emxinc) {
+		    char *beg, *end;
+		    beg= (char*)strdup(emxinc);
+		    for (;;) {
+			end = (char*)strchr(beg,';');
+			if (end) *end = 0;
+		    	if (incp >= includedirs + MAXDIRS)
+				fatalerr("Too many include dirs\n");
+			*incp++ = beg;
+			if (!end) break;
+			beg = end+1;
+		    }
+		}
+	    }
+#else /* !__UNIXOS2__, does not use INCLUDEDIR at all */
+	    if (incp >= includedirs + MAXDIRS)
+		fatalerr("Too many -I flags.\n");
+	    *incp++ = INCLUDEDIR;
+#endif
+
+#ifdef EXTRAINCDIR
+	    if (incp >= includedirs + MAXDIRS)
+		fatalerr("Too many -I flags.\n");
+	    *incp++ = EXTRAINCDIR;
+#endif
+
+#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(startat, 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
+#else
+	sig_act.sa_handler = catch;
+#if defined(_POSIX_SOURCE) || !defined(X_NOT_POSIX)
+	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.
+	 */
+	for(fp=filelist; *fp; fp++) {
+		DBG_PRINT(stderr,"file: %s\n",*fp);
+		filecontent = getfile(*fp);
+		setfile_cmdinc(filecontent, cmdinc_count, cmdinc_list);
+		ip = newinclude(*fp, (char *)NULL);
+
+		find_includes(filecontent, ip, ip, 0, FALSE);
+		freefile(filecontent);
+		recursive_pr_include(ip, ip->i_file, base_name(*fp));
+		inc_clean();
+	}
+	if (printed)
+		printf("\n");
+	return 0;
+}
+
+#ifdef __UNIXOS2__
+/*
+ * eliminate \r chars from file
+ */
+static int 
+elim_cr(char *buf, int sz)
+{
+	int i,wp;
+	for (i= wp = 0; i<sz; i++) {
+		if (buf[i] != '\r')
+			buf[wp++] = buf[i];
+	}
+	return wp;
+}
+#endif
+
+struct filepointer *
+getfile(char *file)
+{
+	int	fd;
+	struct filepointer	*content;
+	struct stat	st;
+
+	content = (struct filepointer *)malloc(sizeof(struct filepointer));
+	content->f_name = file;
+	if ((fd = open(file, O_RDONLY)) < 0) {
+		warning("cannot open \"%s\"\n", file);
+		content->f_p = content->f_base = content->f_end = (char *)malloc(1);
+		*content->f_p = '\0';
+		return(content);
+	}
+	fstat(fd, &st);
+	content->f_base = (char *)malloc(st.st_size+1);
+	if (content->f_base == NULL)
+		fatalerr("cannot allocate mem\n");
+	if ((st.st_size = read(fd, content->f_base, st.st_size)) < 0)
+		fatalerr("failed to read %s\n", file);
+#ifdef __UNIXOS2__
+	st.st_size = elim_cr(content->f_base,st.st_size);
+#endif
+	close(fd);
+	content->f_len = st.st_size+1;
+	content->f_p = content->f_base;
+	content->f_end = content->f_base + st.st_size;
+	*content->f_end = '\0';
+	content->f_line = 0;
+	content->cmdinc_count = 0;
+	content->cmdinc_list = NULL;
+	content->cmdinc_line = 0;
+	return(content);
+}
+
+void
+setfile_cmdinc(struct filepointer* filep, long count, char** list)
+{
+	filep->cmdinc_count = count;
+	filep->cmdinc_list = list;
+	filep->cmdinc_line = 0;
+}
+
+void
+freefile(struct filepointer *fp)
+{
+	free(fp->f_base);
+	free(fp);
+}
+
+char *copy(char *str)
+{
+	char	*p = (char *)malloc(strlen(str) + 1);
+
+	strcpy(p, str);
+	return(p);
+}
+
+int
+match(char *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 *getnextline(struct filepointer *filep)
+{
+	char	*p,	/* walking pointer */
+		*eof,	/* end of file pointer */
+		*bol;	/* beginning of line pointer */
+	int	lineno;	/* line number */
+	boolean whitespace = FALSE;
+
+	/*
+	 * Fake the "-include" line files in form of #include to the
+	 * start of each file.
+	 */
+	if (filep->cmdinc_line < filep->cmdinc_count) {
+		char *inc = filep->cmdinc_list[2 * filep->cmdinc_line + 0];
+		char *buf = filep->cmdinc_list[2 * filep->cmdinc_line + 1];
+		filep->cmdinc_line++;
+		sprintf(buf,"%s%s%s",DASH_INC_PRE,inc,DASH_INC_POST);
+		DBG_PRINT(stderr,"%s\n",buf);
+		return(buf);
+	}
+
+	p = filep->f_p;
+	eof = filep->f_end;
+	if (p >= eof)
+		return((char *)NULL);
+	lineno = filep->f_line;
+
+	for (bol = p--; ++p < eof; ) {
+		if ((bol == p) && ((*p == ' ') || (*p == '\t')))
+		{
+			/* Consume leading white-spaces for this line */
+			while (((p+1) < eof) && ((*p == ' ') || (*p == '\t')))
+			{
+				p++;
+				bol++;
+			}
+			whitespace = TRUE;
+		}
+        
+		if (*p == '/' && (p+1) < eof && *(p+1) == '*') {
+			/* Consume C comments */
+			*(p++) = ' ';
+			*(p++) = ' ';
+			while (p < eof && *p) {
+				if (*p == '*' && (p+1) < eof && *(p+1) == '/') {
+					*(p++) = ' ';
+					*(p++) = ' ';
+					break;
+				}
+				if (*p == '\n')
+					lineno++;
+				*(p++) = ' ';
+			}
+			--p;
+		}
+		else if (*p == '/' && (p+1) < eof && *(p+1) == '/') {
+			/* Consume C++ comments */
+			*(p++) = ' ';
+			*(p++) = ' ';
+			while (p < eof && *p) {
+				if (*p == '\\' && (p+1) < eof &&
+				    *(p+1) == '\n') {
+					*(p++) = ' ';
+					lineno++;
+				}
+				else if (*p == '?' && (p+3) < eof &&
+					 *(p+1) == '?' && 
+					 *(p+2) == '/' &&
+					 *(p+3) == '\n') {
+					*(p++) = ' ';
+					*(p++) = ' ';
+					*(p++) = ' ';
+					lineno++;
+				}
+				else if (*p == '\n')
+					break;	/* to process end of line */
+				*(p++) = ' ';
+			}
+			--p;
+		}
+		else if (*p == '\\' && (p+1) < eof && *(p+1) == '\n') {
+			/* Consume backslash line terminations */
+			*(p++) = ' ';
+			*p = ' ';
+			lineno++;
+		}
+		else if (*p == '?' && (p+3) < eof &&
+			 *(p+1) == '?' && *(p+2) == '/' && *(p+3) == '\n') {
+			/* Consume trigraph'ed backslash line terminations */
+			*(p++) = ' ';
+			*(p++) = ' ';
+			*(p++) = ' ';
+			*p = ' ';
+			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;
+				--p;
+			}
+			bol = p+1;
+			whitespace = FALSE;
+		}
+	}
+	if (*bol != '#')
+		bol = NULL;
+done:
+	if (bol && whitespace) {
+		warning("%s:  non-portable whitespace encountered at line %d\n",
+			filep->f_name, lineno);
+	}
+	filep->f_p = p;
+	filep->f_line = lineno;
+#ifdef DEBUG_DUMP
+	if (bol)
+		DBG_PRINT(stderr,"%s\n",bol);
+#endif
+	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';
+	return(file);
+}
+
+#if defined(USG) && !defined(CRAY) && !defined(SVR4) && !defined(__UNIXOS2__) && !defined(clipper) && !defined(__clipper__)
+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 *line, char *makefile)
+{
+	struct stat	st;
+	FILE	*fdin, *fdout;
+	char	backup[ BUFSIZ ],
+		buf[ BUFSIZ ];
+	boolean	found = FALSE;
+	int	len;
+
+	/*
+	 * if makefile is "-" then let it pour onto stdout.
+	 */
+	if (makefile && *makefile == '-' && *(makefile+1) == '\0') {
+		puts(line);
+		return;
+	}
+
+	/*
+	 * use a default makefile is not specified.
+	 */
+	if (!makefile) {
+		if (stat("Makefile", &st) == 0)
+			makefile = "Makefile";
+		else if (stat("makefile", &st) == 0)
+			makefile = "makefile";
+		else
+			fatalerr("[mM]akefile is not present\n");
+	}
+	else
+	    stat(makefile, &st);
+	if ((fdin = fopen(makefile, "r")) == NULL)
+		fatalerr("cannot open \"%s\"\n", makefile);
+	sprintf(backup, "%s.bak", makefile);
+	unlink(backup);
+#if defined(WIN32) || defined(__UNIXOS2__) || defined(__CYGWIN__)
+	fclose(fdin);
+#endif
+	if (rename(makefile, backup) < 0)
+		fatalerr("cannot rename %s to %s\n", makefile, backup);
+#if defined(WIN32) || defined(__UNIXOS2__) || defined(__CYGWIN__)
+	if ((fdin = fopen(backup, "r")) == NULL)
+		fatalerr("cannot open \"%s\"\n", backup);
+#endif
+	if ((fdout = freopen(makefile, "w", stdout)) == NULL)
+		fatalerr("cannot open \"%s\"\n", backup);
+	len = strlen(line);
+	while (!found && fgets(buf, BUFSIZ, fdin)) {
+		if (*buf == '#' && strncmp(line, buf, len) == 0)
+			found = TRUE;
+		fputs(buf, fdout);
+	}
+	if (!found) {
+		if (verbose)
+		warning("Adding new delimiting line \"%s\" and dependencies...\n",
+			line);
+		puts(line); /* same as fputs(fdout); but with newline */
+	} else if (append) {
+	    while (fgets(buf, BUFSIZ, fdin)) {
+		fputs(buf, fdout);
+	    }
+	}
+	fflush(fdout);
+#if defined(USGISH) || defined(_SEQUENT_) || defined(USE_CHMOD)
+	chmod(makefile, st.st_mode);
+#else
+        fchmod(fileno(fdout), st.st_mode);
+#endif /* USGISH */
+}
+
+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);
+}
+
+void
+warning(char *msg, ...)
+{
+	va_list args;
+	fprintf(stderr, "%s: warning:  ", ProgramName);
+	va_start(args, msg);
+	vfprintf(stderr, msg, args);
+	va_end(args);
+}
+
+void
+warning1(char *msg, ...)
+{
+	va_list args;
+	va_start(args, msg);
+	vfprintf(stderr, msg, args);
+	va_end(args);
+}
Index: branches/XORG/src/makedep/mkdepend.man
===================================================================
--- branches/XORG/src/makedep/mkdepend.man	(revision 165)
+++ branches/XORG/src/makedep/mkdepend.man	(revision 165)
@@ -0,0 +1,382 @@
+.\" $Xorg: mkdepend.man,v 1.5 2001/02/09 02:03:16 xorgcvs Exp $
+.\" Copyright (c) 1993, 1994, 1998 The Open Group
+.\" 
+.\" Permission to use, copy, modify, distribute, and sell this software and its
+.\" documentation for any purpose is hereby granted without fee, provided that
+.\" the above copyright notice appear in all copies and that both that
+.\" copyright notice and this permission notice appear in supporting
+.\" documentation.
+.\" 
+.\" 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 OPEN GROUP 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 Open Group 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
+.\" Open Group.
+.\"
+.\" $XFree86: xc/config/makedepend/mkdepend.man,v 1.6 2001/12/17 20:52:22 dawes Exp $
+.\"
+.TH MAKEDEPEND 1 __xorgversion__
+.UC 4
+.SH NAME
+makedepend \- create dependencies in makefiles
+.SH SYNOPSIS
+.B makedepend
+[
+.BI \-D name\fB=\fPdef
+] [
+.BI \-D name
+] [
+.BI \-I includedir
+] [
+.BI \-Y includedir
+] [
+.B \-a
+] [
+.BI \-f makefile
+] [
+.BI \-include \ file
+] [
+.BI \-o objsuffix
+] [
+.BI \-p objprefix
+] [
+.BI \-s string
+] [
+.BI \-w width
+] [
+.B \-v
+] [
+.B \-m
+] [
+\-\^\-
+.I otheroptions
+\-\^\-
+]
+.I sourcefile
+\&.\|.\|.
+.br
+.SH DESCRIPTION
+The
+.B makedepend
+program 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,
+.I #elif
+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 \fIdependency.\fP
+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 \fIsourcefile.o\fP is the name from the command
+line with its suffix replaced with ``.o'',
+and \fIdfile\fP 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
+The program
+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 \-D\fIname\fP=\fIdef\fP \fRor\fP \-D\fIname\fP
+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 \-I\fIincludedir\fP
+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 \-Y\fIincludedir\fP
+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 \-f\fImakefile\fP
+Filename.
+This allows you to specify an alternate makefile in which
+.B makedepend
+can place its output.
+Specifying ``\-'' as the file name (i.e., \fB\-f\-\fP) sends the
+output to standard output instead of modifying an existing file.
+.TP 5
+.B \-include \fIfile\fP
+Process file as input, and include all the resulting output
+before processing the regular input file. This has the same
+affect as if the specified file is an include statement that
+appears before the very first line of the regular input file.
+.TP 5
+.B \-o\fIobjsuffix\fP
+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 \-p\fIobjprefix\fP
+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 \-s\fIstring\fP
+Starting string delimiter.
+This option permits you to specify
+a different string for
+.B makedepend
+to look for in the makefile.
+.TP 5
+.B \-w\fIwidth\fP
+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.
+.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 "\-\^\- \fIoptions\fP \-\^\-"
+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 encounters 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
Index: branches/XORG/src/makedep/parse.c
===================================================================
--- branches/XORG/src/makedep/parse.c	(revision 165)
+++ branches/XORG/src/makedep/parse.c	(revision 165)
@@ -0,0 +1,686 @@
+/* $Xorg: parse.c,v 1.6 2001/02/09 02:03:16 xorgcvs Exp $ */
+/*
+
+Copyright (c) 1993, 1994, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+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
+OPEN GROUP 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 Open Group 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 Open Group.
+
+*/
+/* $XFree86: xc/config/makedepend/parse.c,v 1.11 2001/12/17 20:52:22 dawes Exp $ */
+
+#include "def.h"
+
+extern char	*directives[];
+extern struct inclist	inclist[ MAXFILES ],
+			*inclistnext,
+			maininclist;
+extern char	*includedirs[ ],
+		**includedirsnext;
+
+static int deftype (char *line, struct filepointer *filep,
+		    struct inclist *file_red, struct inclist *file,
+		    int parse_it);
+static int zero_value(char *filename, char *exp, struct filepointer *filep,
+		    struct inclist *file_red);
+static int merge2defines(struct inclist *file1, struct inclist *file2);
+
+static int
+gobble(struct filepointer *filep, struct inclist *file,
+       struct inclist *file_red)
+{
+	char	*line;
+	int	type;
+
+	while ((line = getnextline(filep))) {
+		switch(type = deftype(line, filep, file_red, file, FALSE)) {
+		case IF:
+		case IFFALSE:
+		case IFGUESSFALSE:
+		case IFDEF:
+		case IFNDEF:
+			type = gobble(filep, file, file_red);
+			while ((type == ELIF) || (type == ELIFFALSE) ||
+			       (type == ELIFGUESSFALSE))
+			    type = gobble(filep, file, file_red);
+			if (type == ELSE)
+			        (void)gobble(filep, file, file_red);
+			break;
+		case ELSE:
+		case ENDIF:
+			debug(0,("%s, line %d: #%s\n",
+				file->i_file, filep->f_line,
+				directives[type]));
+			return(type);
+		case DEFINE:
+		case UNDEF:
+		case INCLUDE:
+		case INCLUDEDOT:
+		case PRAGMA:
+		case ERROR:
+		case IDENT:
+		case SCCS:
+		case EJECT:
+		case WARNING:
+		case INCLUDENEXT:
+		case INCLUDENEXTDOT:
+			break;
+		case ELIF:
+		case ELIFFALSE:
+		case ELIFGUESSFALSE:
+			return(type);
+		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;
+		}
+	}
+	return(-1);
+}
+
+/*
+ * Decide what type of # directive this line is.
+ */
+static int 
+deftype (char *line, struct filepointer *filep, 
+	     struct inclist *file_red, struct inclist *file, int parse_it)
+{
+	register char	*p;
+	char	*directive, savechar, *q;
+	register int	ret;
+
+	/*
+	 * Parse the directive...
+	 */
+	directive=line+1;
+	while (*directive == ' ' || *directive == '\t')
+		directive++;
+
+	p = directive;
+	while ((*p == '_') || (*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(file->i_file, p, filep, file_red);
+	    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++;
+	q = p + strlen(p);
+	do {
+		q--;
+	} while (*q == ' ' || *q == '\t');
+	q[1] = '\0';
+	switch (ret) {
+	case IF:
+		/*
+		 * parse an expression.
+		 */
+		ret = zero_value(file->i_file, p, filep, file_red);
+		debug(0,("%s, line %d: %s #if %s\n",
+			 file->i_file, filep->f_line, ret?"false":"true", p));
+		break;
+	case IFDEF:
+	case IFNDEF:
+		debug(0,("%s, line %d: #%s %s\n",
+			file->i_file, filep->f_line, directives[ret], p));
+	case UNDEF:
+		/*
+		 * separate the name of a single symbol.
+		 */
+		while (isalnum(*p) || *p == '_')
+			*line++ = *p++;
+		*line = '\0';
+		break;
+	case INCLUDE:
+	case INCLUDENEXT:
+		debug(2,("%s, line %d: #include%s %s\n",
+			file->i_file, filep->f_line,
+			(ret == INCLUDE) ? "" : "_next", p));
+
+		/* Support ANSI macro substitution */
+		while (1) {
+			struct symtab **sym;
+
+			if (!*p || *p == '"' || *p == '<')
+				break;
+
+		    	sym = isdefined(p, file_red, NULL);
+			if (!sym)
+				break;
+
+			p = (*sym)->s_value;
+			debug(3,("%s : #includes SYMBOL %s = %s\n",
+			       file->i_incstring,
+			       (*sym) -> s_name,
+			       (*sym) -> s_value));
+			/* mark file as having included a 'soft include' */
+			file->i_flags |= INCLUDED_SYM; 
+		}
+
+		/*
+		 * Separate the name of the include file.
+		 */
+		while (*p && *p != '"' && *p != '<')
+			p++;
+		if (! *p)
+			return(-2);
+		if (*p++ == '"') {
+			if (ret == INCLUDE)
+				ret = INCLUDEDOT;
+			else
+				ret = INCLUDENEXTDOT;
+			while (*p && *p != '"')
+				*line++ = *p++;
+		} else
+			while (*p && *p != '>')
+				*line++ = *p++;
+		*line = '\0';
+		break;
+	case DEFINE:
+		/*
+		 * copy the definition back to the beginning of the line.
+		 */
+		strcpy (line, p);
+		break;
+	case ELSE:
+	case ENDIF:
+	case ELIF:
+	case PRAGMA:
+	case ERROR:
+	case IDENT:
+	case SCCS:
+	case EJECT:
+	case WARNING:
+		debug(0,("%s, line %d: #%s\n",
+			file->i_file, filep->f_line, directives[ret]));
+		/*
+		 * nothing to do.
+		 */
+		break;
+	}
+	return(ret);
+}
+
+struct symtab **
+fdefined(char *symbol, struct inclist *file, struct inclist **srcfile)
+{
+	struct inclist	**ip;
+	struct symtab	**val;
+	int	i;
+	static int	recurse_lvl = 0;
+
+	if (file->i_flags & DEFCHECKED)
+		return(NULL);
+	debug(2,("Looking for %s in %s\n", symbol, file->i_file));
+	file->i_flags |= DEFCHECKED;
+	if ((val = slookup(symbol, file)))
+		debug(1,("%s defined in %s as %s\n",
+			 symbol, file->i_file, (*val)->s_value));
+	if (val == NULL && file->i_list)
+	{
+		for (ip = file->i_list, i=0; i < file->i_listlen; i++, ip++)
+			if (file->i_merged[i]==FALSE) {
+				val = fdefined(symbol, *ip, srcfile);
+				file->i_merged[i]=merge2defines(file,*ip);
+				if (val!=NULL) break;
+			}
+	}
+	else if (val != NULL && srcfile != NULL) *srcfile = file;
+	recurse_lvl--;
+	file->i_flags &= ~DEFCHECKED;
+
+	return(val);
+}
+
+struct symtab **
+isdefined(char *symbol, struct inclist *file, struct inclist **srcfile)
+{
+	struct symtab	**val;
+
+	if ((val = slookup(symbol, &maininclist))) {
+		debug(1,("%s defined on command line\n", symbol));
+		if (srcfile != NULL) *srcfile = &maininclist;
+		return(val);
+	}
+	if ((val = fdefined(symbol, file, srcfile)))
+		return(val);
+	debug(1,("%s not defined in %s\n", symbol, file->i_file));
+	return(NULL);
+}
+
+/*
+ * Return type based on if the #if expression evaluates to 0
+ */
+static int
+zero_value(char *filename,
+	   char *exp,
+	   struct filepointer *filep,
+	   struct inclist *file_red)
+{
+	if (cppsetup(filename, exp, filep, file_red))
+	    return(IFFALSE);
+	else
+	    return(IF);
+}
+
+void
+define2(char *name, char *val, struct inclist *file)
+{
+    int first, last, below;
+    register struct symtab **sp = NULL, **dest;
+    struct symtab *stab;
+
+    /* Make space if it's needed */
+    if (file->i_defs == NULL)
+    {
+	file->i_defs = (struct symtab **)
+			malloc(sizeof (struct symtab*) * SYMTABINC);
+	file->i_ndefs = 0;
+    }
+    else if (!(file->i_ndefs % SYMTABINC))
+	file->i_defs = (struct symtab **)
+			realloc(file->i_defs,
+			   sizeof(struct symtab*)*(file->i_ndefs+SYMTABINC));
+
+    if (file->i_defs == NULL)
+	fatalerr("malloc()/realloc() failure in insert_defn()\n");
+
+    below = first = 0;
+    last = file->i_ndefs - 1;
+    while (last >= first)
+    {
+	/* Fast inline binary search */
+	register char *s1;
+	register char *s2;
+	register int middle = (first + last) / 2;
+
+	/* Fast inline strchr() */
+	s1 = name;
+	s2 = file->i_defs[middle]->s_name;
+	while (*s1++ == *s2++)
+	    if (s2[-1] == '\0') break;
+
+	/* If exact match, set sp and break */
+	if (*--s1 == *--s2) 
+	{
+	    sp = file->i_defs + middle;
+	    break;
+	}
+
+	/* If name > i_defs[middle] ... */
+	if (*s1 > *s2) 
+	{
+	    below = first;
+	    first = middle + 1;
+	}
+	/* else ... */
+	else
+	{
+	    below = last = middle - 1;
+	}
+    }
+
+    /* Search is done.  If we found an exact match to the symbol name,
+       just replace its s_value */
+    if (sp != NULL)
+    {
+	debug(1,("redefining %s from %s to %s in file %s\n",
+		name, (*sp)->s_value, val, file->i_file));
+	free((*sp)->s_value);
+	(*sp)->s_value = copy(val);
+	return;
+    }
+
+    sp = file->i_defs + file->i_ndefs++;
+    dest = file->i_defs + below + 1;
+    while (sp > dest)
+    {
+	*sp = sp[-1];
+	sp--;
+    }
+    stab = (struct symtab *) malloc(sizeof (struct symtab));
+    if (stab == NULL)
+	fatalerr("malloc()/realloc() failure in insert_defn()\n");
+
+    debug(1,("defining %s to %s in file %s\n", name, val, file->i_file));
+    stab->s_name = copy(name);
+    stab->s_value = copy(val);
+    *sp = stab;
+}
+
+void
+define(char *def, struct inclist *file)
+{
+    char *val;
+
+    /* Separate symbol name and its value */
+    val = def;
+    while (isalnum(*val) || *val == '_')
+	val++;
+    if (*val)
+	*val++ = '\0';
+    while (*val == ' ' || *val == '\t')
+	val++;
+
+    if (!*val)
+	val = "1";
+    define2(def, val, file);
+}
+
+struct symtab **
+slookup(char *symbol, struct inclist *file)
+{
+	register int first = 0;
+	register int last = file->i_ndefs - 1;
+
+	if (file) while (last >= first)
+	{
+	    /* Fast inline binary search */
+	    register char *s1;
+	    register char *s2;
+	    register int middle = (first + last) / 2;
+
+	    /* Fast inline strchr() */
+	    s1 = symbol;
+	    s2 = file->i_defs[middle]->s_name;
+	    while (*s1++ == *s2++)
+	        if (s2[-1] == '\0') break;
+
+	    /* If exact match, we're done */
+	    if (*--s1 == *--s2) 
+	    {
+	        return file->i_defs + middle;
+	    }
+
+	    /* If symbol > i_defs[middle] ... */
+	    if (*s1 > *s2) 
+	    {
+	        first = middle + 1;
+	    }
+	    /* else ... */
+	    else
+	    {
+	        last = middle - 1;
+	    }
+	}
+	return(NULL);
+}
+
+static int 
+merge2defines(struct inclist *file1, struct inclist *file2)
+{
+	int i;
+
+	if ((file1==NULL) || (file2==NULL) ||
+	    !(file2->i_flags & FINISHED))
+		return 0;
+
+	for (i=0; i < file2->i_listlen; i++)
+		if (file2->i_merged[i]==FALSE)
+			return 0;
+
+	{
+		int first1 = 0;
+		int last1 = file1->i_ndefs - 1;
+
+		int first2 = 0;
+		int last2 = file2->i_ndefs - 1;
+
+                int first=0;
+                struct symtab** i_defs = NULL;
+		int deflen=file1->i_ndefs+file2->i_ndefs;
+
+		debug(2,("merging %s into %s\n",
+			file2->i_file, file1->i_file));
+
+                if (deflen>0)
+                { 
+                	/* make sure deflen % SYMTABINC == 0 is still true */
+                	deflen += (SYMTABINC - deflen % SYMTABINC) % SYMTABINC;
+                	i_defs=(struct symtab**)
+			    malloc(deflen*sizeof(struct symtab*));
+                	if (i_defs==NULL) return 0;
+        	}
+
+        	while ((last1 >= first1) && (last2 >= first2))
+        	{
+	    		char *s1=file1->i_defs[first1]->s_name;
+	    		char *s2=file2->i_defs[first2]->s_name;
+
+     			if (strcmp(s1,s2) < 0)
+                        	i_defs[first++]=file1->i_defs[first1++];
+     			else if (strcmp(s1,s2) > 0)
+                        	i_defs[first++]=file2->i_defs[first2++];
+                        else /* equal */
+                        {
+                        	i_defs[first++]=file2->i_defs[first2++];
+                                first1++;
+                        }
+        	}
+        	while (last1 >= first1)
+        	{
+                        i_defs[first++]=file1->i_defs[first1++];
+        	}
+        	while (last2 >= first2)
+        	{
+                        i_defs[first++]=file2->i_defs[first2++];
+        	}
+
+                if (file1->i_defs) free(file1->i_defs);
+                file1->i_defs=i_defs;
+                file1->i_ndefs=first;
+                
+		return 1;
+  	}
+}
+
+void
+undefine(char *symbol, struct inclist *file)
+{
+	register struct symtab **ptr;
+	struct inclist *srcfile;
+	while ((ptr = isdefined(symbol, file, &srcfile)) != NULL)
+	{
+	    srcfile->i_ndefs--;
+	    for (; ptr < srcfile->i_defs + srcfile->i_ndefs; ptr++)
+		*ptr = ptr[1];
+	}
+}
+
+int
+find_includes(struct filepointer *filep, struct inclist *file, 
+	      struct inclist *file_red, int recursion, boolean failOK)
+{
+	struct inclist	*inclistp;
+	char		**includedirsp;
+	register char	*line;
+	register int	type;
+	boolean recfailOK;
+
+	while ((line = getnextline(filep))) {
+		switch(type = deftype(line, filep, file_red, file, TRUE)) {
+		case IF:
+		doif:
+			type = find_includes(filep, file,
+				file_red, recursion+1, failOK);
+			while ((type == ELIF) || (type == ELIFFALSE) ||
+			       (type == ELIFGUESSFALSE))
+				type = gobble(filep, file, file_red);
+			if (type == ELSE)
+				gobble(filep, file, file_red);
+			break;
+		case IFFALSE:
+		case IFGUESSFALSE:
+		    doiffalse:
+			if (type == IFGUESSFALSE || type == ELIFGUESSFALSE)
+			    recfailOK = TRUE;
+			else
+			    recfailOK = failOK;
+			type = gobble(filep, file, file_red);
+			if (type == ELSE)
+			    find_includes(filep, file,
+					  file_red, recursion+1, recfailOK);
+			else
+			if (type == ELIF)
+			    goto doif;
+			else
+			if ((type == ELIFFALSE) || (type == ELIFGUESSFALSE))
+			    goto doiffalse;
+			break;
+		case IFDEF:
+		case IFNDEF:
+			if ((type == IFDEF && isdefined(line, file_red, NULL))
+			 || (type == IFNDEF && !isdefined(line, file_red, NULL))) {
+				debug(1,(type == IFNDEF ?
+				    "line %d: %s !def'd in %s via %s%s\n" : "",
+				    filep->f_line, line,
+				    file->i_file, file_red->i_file, ": doit"));
+				type = find_includes(filep, file,
+					file_red, recursion+1, failOK);
+				while (type == ELIF || type == ELIFFALSE || type == ELIFGUESSFALSE)
+					type = gobble(filep, file, file_red);
+				if (type == ELSE)
+					gobble(filep, file, file_red);
+			}
+			else {
+				debug(1,(type == IFDEF ?
+				    "line %d: %s !def'd in %s via %s%s\n" : "",
+				    filep->f_line, line,
+				    file->i_file, file_red->i_file, ": gobble"));
+				type = gobble(filep, file, file_red);
+				if (type == ELSE)
+					find_includes(filep, file,
+						file_red, recursion+1, failOK);
+				else if (type == ELIF)
+				    	goto doif;
+				else if (type == ELIFFALSE || type == ELIFGUESSFALSE)
+				    	goto doiffalse;
+			}
+			break;
+		case ELSE:
+		case ELIFFALSE:
+		case ELIFGUESSFALSE:
+		case ELIF:
+			if (!recursion)
+				gobble(filep, file, file_red);
+		case ENDIF:
+			if (recursion)
+				return(type);
+		case DEFINE:
+			define(line, file);
+			break;
+		case UNDEF:
+			if (!*line) {
+			    warning("%s", file_red->i_file);
+			    if (file_red != file)
+				warning1(" (reading %s)", file->i_file);
+			    warning1(", line %d: incomplete undef == \"%s\"\n",
+				filep->f_line, line);
+			    break;
+			}
+			undefine(line, file_red);
+			break;
+		case INCLUDE:
+		case INCLUDEDOT:
+		case INCLUDENEXT:
+		case INCLUDENEXTDOT:
+			inclistp = inclistnext;
+			includedirsp = includedirsnext;
+			debug(2,("%s, reading %s, includes %s\n",
+				file_red->i_file, file->i_file, line));
+			add_include(filep, file, file_red, line, type, failOK);
+			inclistnext = inclistp;
+			includedirsnext = includedirsp;
+			break;
+		case ERROR:
+		case WARNING:
+		    	warning("%s", file_red->i_file);
+			if (file_red != file)
+				warning1(" (reading %s)", file->i_file);
+			warning1(", line %d: %s\n",
+				 filep->f_line, line);
+		    	break;
+		    
+		case PRAGMA:
+		case IDENT:
+		case SCCS:
+		case EJECT:
+			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;
+		}
+	}
+	file->i_flags |= FINISHED;
+	debug(2,("finished with %s\n", file->i_file));
+	return(-1);
+}
Index: branches/XORG/src/makedep/pr.c
===================================================================
--- branches/XORG/src/makedep/pr.c	(revision 165)
+++ branches/XORG/src/makedep/pr.c	(revision 165)
@@ -0,0 +1,124 @@
+/* $Xorg: pr.c,v 1.4 2001/02/09 02:03:16 xorgcvs Exp $ */
+/*
+
+Copyright (c) 1993, 1994, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+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
+OPEN GROUP 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 Open Group 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 Open Group.
+
+*/
+/* $XFree86: xc/config/makedepend/pr.c,v 1.4 2001/04/29 23:25:02 tsi Exp $ */
+
+#include "def.h"
+
+extern struct	inclist	inclist[ MAXFILES ],
+			*inclistp;
+extern char	*objprefix;
+extern char	*objsuffix;
+extern int	width;
+extern boolean	printed;
+extern boolean	verbose;
+extern boolean	show_where_not;
+
+void
+add_include(struct filepointer *filep, struct inclist *file, 
+	    struct inclist *file_red, char *include, int type,
+	    boolean failOK)
+{
+	register struct inclist	*newfile;
+	register struct filepointer	*content;
+
+	/*
+	 * First decide what the pathname of this include file really is.
+	 */
+	newfile = inc_path(file->i_file, include, type);
+	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, type);
+		show_where_not = FALSE;
+	}
+
+	if (newfile) {
+		included_by(file, newfile);
+		if (!(newfile->i_flags & SEARCHED)) {
+			newfile->i_flags |= SEARCHED;
+			content = getfile(newfile->i_file);
+			find_includes(content, newfile, file_red, 0, failOK);
+			freefile(content);
+		}
+	}
+}
+
+static void
+pr(struct inclist *ip, char *file, char *base)
+{
+	static char	*lastfile;
+	static int	current_len;
+	register int	len, i;
+	char	buf[ BUFSIZ ];
+
+	printed = TRUE;
+	len = strlen(ip->i_file)+1;
+	if (current_len + len > width || file != lastfile) {
+		lastfile = file;
+		sprintf(buf, "\n%s%s%s: %s", objprefix, base, objsuffix,
+			ip->i_file);
+		len = current_len = strlen(buf);
+	}
+	else {
+		buf[0] = ' ';
+		strcpy(buf+1, ip->i_file);
+		current_len += len;
+	}
+	fwrite(buf, len, 1, stdout);
+
+	/*
+	 * If verbose is set, then print out what this file includes.
+	 */
+	if (! verbose || ip->i_list == NULL || ip->i_flags & NOTIFIED)
+		return;
+	ip->i_flags |= NOTIFIED;
+	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);
+}
+
+void
+recursive_pr_include(struct inclist *head, char *file, char *base)
+{
+	int	i;
+
+	if (head->i_flags & MARKED)
+		return;
+	head->i_flags |= MARKED;
+	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);
+}
