After discussion with Constantin reverted 2433, 2434, 2436, 2437 and 2438
(build automation and i18n changes). Latest server changes (2439 and 2440)
are OK.


git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/branches/1.5-xserver@2442 3789f03b-4d11-0410-bbf8-ca57d06f2519
diff --git a/unix/vncmkdepend/parse.c b/unix/vncmkdepend/parse.c
new file mode 100644
index 0000000..3f9b2fe
--- /dev/null
+++ b/unix/vncmkdepend/parse.c
@@ -0,0 +1,568 @@
+/* $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 "def.h"
+
+extern char	*directives[];
+extern struct inclist	maininclist;
+
+find_includes(filep, file, file_red, recursion, failOK)
+	struct filepointer	*filep;
+	struct inclist		*file, *file_red;
+	int			recursion;
+	boolean			failOK;
+{
+	register char	*line;
+	register int	type;
+	boolean recfailOK;
+
+	while (line = getline(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, line %d: incomplete undef == \"%s\"\n",
+				file_red->i_file, filep->f_line, line);
+			    break;
+			}
+			undefine(line, file_red);
+			break;
+		case INCLUDE:
+			add_include(filep, file, file_red, line, FALSE, failOK);
+			break;
+		case INCLUDEDOT:
+			add_include(filep, file, file_red, line, TRUE, failOK);
+			break;
+		case ERROR:
+		    	warning("(from %s) %s: %d: %s\n",
+				file_red->i_file, file->i_file,
+				 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;
+		}
+	}
+	return(-1);
+}
+
+gobble(filep, file, file_red)
+	register struct filepointer *filep;
+	struct inclist		*file, *file_red;
+{
+	register char	*line;
+	register int	type;
+
+	while (line = getline(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:
+			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 (line, filep, file_red, file, parse_it)
+	register char	*line;
+	register struct filepointer *filep;
+	register struct inclist *file_red, *file;
+	int	parse_it;
+{
+	register char	*p;
+	char	*directive, savechar;
+	register int	ret;
+
+	/*
+	 * 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, 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++;
+	switch (ret) {
+	case IF:
+		/*
+		 * parse an expression.
+		 */
+		ret = zero_value(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:
+		debug(2,("%s, line %d: #include %s\n",
+			file->i_file, filep->f_line, p));
+
+		/* Support ANSI macro substitution */
+		{
+		    struct symtab *sym = isdefined(p, file_red, NULL);
+		    while (sym) {
+			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_included_sym = TRUE; 
+			sym = isdefined(p, file_red, NULL);
+		    }
+		}
+
+		/*
+		 * Separate the name of the include file.
+		 */
+		while (*p && *p != '"' && *p != '<')
+			p++;
+		if (! *p)
+			return(-2);
+		if (*p++ == '"') {
+			ret = INCLUDEDOT;
+			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:
+		debug(0,("%s, line %d: #%s\n",
+			file->i_file, filep->f_line, directives[ret]));
+		/*
+		 * nothing to do.
+		 */
+		break;
+	}
+	return(ret);
+}
+
+struct symtab *isdefined(symbol, file, srcfile)
+	register char	*symbol;
+	struct inclist	*file;
+	struct inclist	**srcfile;
+{
+	register 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);
+}
+
+struct symtab *fdefined(symbol, file, srcfile)
+	register char	*symbol;
+	struct inclist	*file;
+	struct inclist	**srcfile;
+{
+	register struct inclist	**ip;
+	register struct symtab	*val;
+	register int	i;
+	static int	recurse_lvl = 0;
+
+	if (file->i_defchecked)
+		return(NULL);
+	file->i_defchecked = TRUE;
+	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 (val = fdefined(symbol, *ip, srcfile)) {
+				break;
+			}
+		}
+	else if (val != NULL && srcfile != NULL) *srcfile = file;
+	recurse_lvl--;
+	file->i_defchecked = FALSE;
+
+	return(val);
+}
+
+/*
+ * Return type based on if the #if expression evaluates to 0
+ */
+zero_value(exp, filep, file_red)
+	register char	*exp;
+	register struct filepointer *filep;
+	register struct inclist *file_red;
+{
+	if (cppsetup(exp, filep, file_red))
+	    return(IFFALSE);
+	else
+	    return(IF);
+}
+
+define(def, file)
+	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);
+}
+
+define2(name, val, file)
+	char	*name, *val;
+	struct inclist	*file;
+{
+    int first, last, below;
+    register struct symtab *sp = NULL, *dest;
+
+    /* Make space if it's needed */
+    if (file->i_defs == NULL)
+    {
+	file->i_defs = (struct symtab *)
+			malloc(sizeof (struct symtab) * SYMTABINC);
+	file->i_deflen = SYMTABINC;
+	file->i_ndefs = 0;
+    }
+    else if (file->i_ndefs == file->i_deflen)
+	file->i_defs = (struct symtab *)
+			realloc(file->i_defs,
+			    sizeof(struct symtab)*(file->i_deflen+=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)
+    {
+	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--;
+    }
+    sp->s_name = copy(name);
+    sp->s_value = copy(val);
+}
+
+struct symtab *slookup(symbol, file)
+	register char	*symbol;
+	register 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);
+}
+
+undefine(symbol, file)
+	char	*symbol;
+	register 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];
+	}
+}