--- /dev/null
+XCOMM $XConsortium: Imakefile,v 1.22 94/03/29 15:54:05 gildea 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
+
+#if HasGcc && !defined(PreIncDir)
+#define PreIncDir /usr/local/lib/gcc-include
+#endif
+#ifdef PreIncDir
+PREINCDIR = PreIncDir
+PREINC_DEFINES = -DPREINCDIR=\"$(PREINCDIR)\"
+#endif
+#ifndef StdIncDir
+#define StdIncDir /usr/include
+#endif
+STDINCDIR = StdIncDir
+STDINC_DEFINES = -DINCLUDEDIR=\"$(STDINCDIR)\"
+#ifdef PostIncDir
+POSTINCDIR = PostIncDir
+POSTINC_DEFINES = -DPOSTINCDIR=\"$(POSTINCDIR)\"
+#endif
+INC_DEFINES = $(PREINC_DEFINES) $(STDINC_DEFINES) $(POSTINC_DEFINES)
+OSUF = .Osuf
+OSUF_DEFINES = -DOBJSUFFIX=\"$(OSUF)\"
+MAIN_DEFINES = $(INC_DEFINES) $(SIGNAL_DEFINES) $(OSUF_DEFINES)
+INCLUDES = -I$(IMAKESRC)
+ DEPLIBS =
+
+#if defined(MacIIArchitecture) || defined(SequentArchitecture)
+ XBSDLIB = /**/
+#endif
+
+all:: makedepend
+
+#undef InstallManPage
+#define InstallManPage(file,dest) /* as nothing */
+#if CrossCompiling
+ComplexHostProgramTarget(makedepend)
+#else
+ComplexProgramTarget(makedepend)
+#endif
+
+SpecialObjectRule(main.o,$(ICONFIGFILES),$(MAIN_DEFINES))
+
+InstallManPageLong(mkdepend,$(MANDIR),makedepend)
--- /dev/null
+#
+# $XConsortium: cpp.ed,v 1.3 89/12/12 12:44:18 jim Exp $
+#
+# $Locker $
+#
+/struct symtab stab/d
+/struct symtab \*defloc;/d
+/struct symtab \*udfloc;/d
+/struct symtab \*incloc;/d
+/struct symtab \*ifloc;/d
+/struct symtab \*elsloc;/d
+/struct symtab \*eifloc;/d
+/struct symtab \*ifdloc;/d
+/struct symtab \*ifnloc;/d
+/struct symtab \*ysysloc;/d
+/struct symtab \*varloc;/d
+/struct symtab \*lneloc;/d
+/struct symtab \*ulnloc;/d
+/struct symtab \*uflloc;/d
+/^sayline(/s/$/ DELETED/p
+.,/^}/d
+/^unfill(/s/$/ DELETED/p
+.-1,/^}/d
+/^doincl(/s/$/ DELETED/p
+.-1,/^}/d
+/^equfrm(/s/$/ DELETED/p
+.,/^}/d
+/^dodef(/s/$/ DELETED/p
+.-1,/^}/d
+/^control(/s/$/ DELETED/p
+.-1,/^}/d
+/^savestring(/s/$/ DELETED/p
+.-1,/^}/d
+/^stsym(/s/$/ DELETED/p
+.-1,/^}/d
+/^ppsym(/s/$/ DELETED/p
+.-1,/^}/d
+/^yyerror(/s/$/ DELETED/p
+.,/^}/d
+/^ppwarn(/s/$/ DELETED/p
+.,/^}/d
+/^lookup(/s/$/ DELETED/p
+.-1,/^}/d
+/^subst(/s/$/ DELETED/p
+.-1,/^}/d
+/^trmdir(/s/$/ DELETED/p
+.-1,/^}/d
+/^copy(/s/$/ DELETED/p
+.-1,/^}/d
+/^pperror(/s/$/ DELETED/p
+.,/^}/d
+/^main(/s/$/ CHANGED to cpp_varsetup(argc,argv)/p
+.c
+cpp_varsetup(argc,argv)
+.
+/^strdex(/s/$/ DELETED/p
+.-1,/^}/d
+/^ for(i=1; i<argc; i++)/s/$/ To the end DELETED/p
+.,$c
+}
+.
+/^dump(/s/$/ DELETED/p
+.,/^}/c
+dump() { fatal("dump\n"); }
+.
+/^refill(/s/$/ DELETED/p
+.,/^}/c
+refill() { fatal("refill\n"); }
+.
+/^slookup(/s/$/ DELETED/p
+.-1,/^}/c
+static struct symtab *slookup() { fatal("slookup\n"); }
+.
+w
+q
--- /dev/null
+/* $XConsortium: cppsetup.c,v 1.13 94/04/17 20:10:32 gildea Exp $ */
+/*
+
+Copyright (c) 1993, 1994 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+*/
+
+#include "def.h"
+
+#ifdef CPP
+/*
+ * This file is strictly for the sake of cpy.y and yylex.c (if
+ * you indeed have the source for cpp).
+ */
+#define IB 1
+#define SB 2
+#define NB 4
+#define CB 8
+#define QB 16
+#define WB 32
+#define SALT '#'
+#if pdp11 | vax | ns16000 | mc68000 | ibm032
+#define COFF 128
+#else
+#define COFF 0
+#endif
+/*
+ * These variables used by cpy.y and yylex.c
+ */
+extern char *outp, *inp, *newp, *pend;
+extern char *ptrtab;
+extern char fastab[];
+extern char slotab[];
+
+/*
+ * cppsetup
+ */
+struct filepointer *currentfile;
+struct inclist *currentinc;
+
+cppsetup(line, filep, inc)
+ register char *line;
+ register struct filepointer *filep;
+ register struct inclist *inc;
+{
+ register 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;
+ const char *line;
+};
+
+static const char *
+_my_if_errors (ip, cp, expecting)
+ 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->inc->i_file;
+ char prefix[300];
+ int prefixlen;
+ int i;
+
+ sprintf (prefix, "\"%s\":%d", filename, lineno);
+ prefixlen = strlen(prefix);
+ fprintf (stderr, "%s: %s", prefix, pd->line);
+ i = cp - pd->line;
+ if (i > 0 && pd->line[i-1] != '\n') {
+ putc ('\n', stderr);
+ }
+ for (i += prefixlen + 3; i > 0; i--) {
+ putc (' ', stderr);
+ }
+ fprintf (stderr, "^--- expecting %s\n", expecting);
+ return NULL;
+}
+
+
+#define MAXNAMELEN 256
+
+static struct symtab *
+_lookup_variable (ip, var, len)
+ 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 (ip, var, len)
+ 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 int
+_my_eval_variable (ip, var, len)
+ IfParser *ip;
+ const char *var;
+ int len;
+{
+ struct symtab *s;
+
+ s = _lookup_variable (ip, var, len);
+ if (!s)
+ return 0;
+ do {
+ var = s->s_value;
+ if (!isvarfirstletter(*var))
+ break;
+ s = _lookup_variable (ip, var, strlen(var));
+ } while (s);
+
+ return atoi(var);
+}
+
+
+cppsetup(line, filep, inc)
+ register char *line;
+ register struct filepointer *filep;
+ register struct inclist *inc;
+{
+ IfParser ip;
+ struct _parse_data pd;
+ int val = 0;
+
+ pd.filep = filep;
+ pd.inc = inc;
+ pd.line = line;
+ 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 */
+
--- /dev/null
+/* $XConsortium: def.h,v 1.25 94/04/17 20:10:33 gildea Exp $ */
+/*
+
+Copyright (c) 1993, 1994 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+*/
+
+#include <X11/Xosdefs.h>
+#ifdef WIN32
+#include <X11/Xw32defs.h>
+#endif
+#include <X11/Xfuncproto.h>
+#include <stdio.h>
+#include <ctype.h>
+#ifndef X_NOT_POSIX
+#ifndef _POSIX_SOURCE
+#define _POSIX_SOURCE
+#endif
+#endif
+#include <sys/types.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+#define MAXDEFINES 512
+#define MAXFILES 512
+#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 IFFALSE 15 /* pseudo value --- never matched */
+#define ELIFFALSE 16 /* pseudo value --- never matched */
+#define INCLUDEDOT 17 /* pseudo value --- never matched */
+#define IFGUESSFALSE 18 /* pseudo value --- never matched */
+#define ELIFGUESSFALSE 19 /* pseudo value --- never matched */
+
+#ifdef DEBUG
+extern int _debugmask;
+/*
+ * debug levels are:
+ *
+ * 0 show ifn*(def)*,endif
+ * 1 trace defined/!defined
+ * 2 show #include
+ * 3 show #include SYMBOL
+ * 4-6 unused
+ */
+#define debug(level,arg) { if (_debugmask & (1 << level)) warning arg; }
+#else
+#define debug(level,arg) /**/
+#endif /* DEBUG */
+
+typedef unsigned char boolean;
+
+struct symtab {
+ char *s_name;
+ char *s_value;
+};
+
+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 */
+ int i_ndefs; /* current # defines */
+ int i_deflen; /* amount of space in table */
+ boolean i_defchecked; /* whether defines have been checked */
+ boolean i_notified; /* whether we have revealed includes */
+ boolean i_marked; /* whether it's in the makefile */
+ boolean i_searched; /* whether we have read this */
+ boolean i_included_sym; /* whether #include SYMBOL was found */
+ /* Can't use i_list if TRUE */
+};
+
+struct filepointer {
+ char *f_p;
+ char *f_base;
+ char *f_end;
+ long f_len;
+ long f_line;
+};
+
+#ifndef X_NOT_STDC_ENV
+#include <stdlib.h>
+#if defined(macII) && !defined(__STDC__) /* stdlib.h fails to define these */
+char *malloc(), *realloc();
+#endif /* macII */
+#else
+char *malloc();
+char *realloc();
+#endif
+
+char *copy();
+char *base_name();
+char *getline();
+struct symtab *slookup();
+struct symtab *isdefined();
+struct symtab *fdefined();
+struct filepointer *getfile();
+struct inclist *newinclude();
+struct inclist *inc_path();
+
+#if NeedVarargsPrototypes
+extern fatalerr(char *, ...);
+extern warning(char *, ...);
+extern warning1(char *, ...);
+#endif
--- /dev/null
+/*
+ * $XConsortium: ifparser.c,v 1.7 94/01/18 21:30:50 rws Exp $
+ *
+ * Copyright 1992 Network Computing Devices, Inc.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Network Computing Devices may not be
+ * used in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. Network Computing Devices makes
+ * no representations about the suitability of this software for any purpose.
+ * It is provided ``as is'' without express or implied warranty.
+ *
+ * NETWORK COMPUTING DEVICES DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
+ * IN NO EVENT SHALL NETWORK COMPUTING DEVICES BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Jim Fulton
+ * Network Computing Devices, Inc.
+ *
+ * Simple if statement processor
+ *
+ * This module can be used to evaluate string representations of C language
+ * if constructs. It accepts the following grammar:
+ *
+ * EXPRESSION := VALUE
+ * | VALUE BINOP EXPRESSION
+ *
+ * VALUE := '(' EXPRESSION ')'
+ * | '!' VALUE
+ * | '-' VALUE
+ * | 'defined' '(' variable ')'
+ * | 'defined' variable
+ * | # variable '(' variable-list ')'
+ * | variable
+ * | number
+ *
+ * BINOP := '*' | '/' | '%'
+ * | '+' | '-'
+ * | '<<' | '>>'
+ * | '<' | '>' | '<=' | '>='
+ * | '==' | '!='
+ * | '&' | '|'
+ * | '&&' | '||'
+ *
+ * The normal C order of precidence is supported.
+ *
+ *
+ * External Entry Points:
+ *
+ * ParseIfExpression parse a string for #if
+ */
+
+#include "ifparser.h"
+#include <ctype.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 (g, cp, varp)
+ 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 (g, cp, valp)
+ IfParser *g;
+ const char *cp;
+ int *valp;
+{
+ SKIPSPACE (cp);
+
+ if (!isdigit(*cp))
+ return CALLFUNC(g, handle_error) (g, cp, "number");
+
+#ifdef WIN32
+ *valp = strtol(cp, &cp, 0);
+#else
+ *valp = atoi (cp);
+ /* EMPTY */
+ for (cp++; isdigit(*cp); cp++) ;
+#endif
+ return cp;
+}
+
+
+static const char *
+parse_value (g, cp, valp)
+ IfParser *g;
+ const char *cp;
+ int *valp;
+{
+ const char *var;
+
+ *valp = 0;
+
+ SKIPSPACE (cp);
+ if (!*cp)
+ return cp;
+
+ switch (*cp) {
+ case '(':
+ DO (cp = ParseIfExpression (g, cp + 1, valp));
+ SKIPSPACE (cp);
+ if (*cp != ')')
+ return CALLFUNC(g, handle_error) (g, cp, ")");
+
+ return cp + 1; /* skip the right paren */
+
+ case '!':
+ DO (cp = parse_value (g, cp + 1, valp));
+ *valp = !(*valp);
+ return cp;
+
+ case '-':
+ DO (cp = parse_value (g, cp + 1, valp));
+ *valp = -(*valp);
+ return cp;
+
+ case '#':
+ DO (cp = parse_variable (g, cp + 1, &var));
+ SKIPSPACE (cp);
+ if (*cp != '(')
+ return CALLFUNC(g, handle_error) (g, cp, "(");
+ do {
+ DO (cp = parse_variable (g, cp + 1, &var));
+ SKIPSPACE (cp);
+ } while (*cp && *cp != ')');
+ if (*cp != ')')
+ return CALLFUNC(g, handle_error) (g, cp, ")");
+ *valp = 1; /* XXX */
+ return cp + 1;
+
+ case 'd':
+ if (strncmp (cp, "defined", 7) == 0 && !isalnum(cp[7])) {
+ int paren = 0;
+ cp += 7;
+ SKIPSPACE (cp);
+ if (*cp == '(') {
+ paren = 1;
+ cp++;
+ }
+ DO (cp = parse_variable (g, cp, &var));
+ SKIPSPACE (cp);
+ if (paren && *cp != ')')
+ return CALLFUNC(g, handle_error) (g, cp, ")");
+ *valp = (*(g->funcs.eval_defined)) (g, var, cp - var);
+ 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));
+ *valp = (*(g->funcs.eval_variable)) (g, var, cp - var);
+ }
+
+ return cp;
+}
+
+
+
+static const char *
+parse_product (g, cp, valp)
+ IfParser *g;
+ const char *cp;
+ int *valp;
+{
+ int rightval;
+
+ DO (cp = parse_value (g, cp, valp));
+ SKIPSPACE (cp);
+
+ switch (*cp) {
+ case '*':
+ DO (cp = parse_product (g, cp + 1, &rightval));
+ *valp = (*valp * rightval);
+ break;
+
+ case '/':
+ DO (cp = parse_product (g, cp + 1, &rightval));
+ *valp = (*valp / rightval);
+ break;
+
+ case '%':
+ DO (cp = parse_product (g, cp + 1, &rightval));
+ *valp = (*valp % rightval);
+ break;
+ }
+ return cp;
+}
+
+
+static const char *
+parse_sum (g, cp, valp)
+ IfParser *g;
+ const char *cp;
+ int *valp;
+{
+ int rightval;
+
+ DO (cp = parse_product (g, cp, valp));
+ SKIPSPACE (cp);
+
+ switch (*cp) {
+ case '+':
+ DO (cp = parse_sum (g, cp + 1, &rightval));
+ *valp = (*valp + rightval);
+ break;
+
+ case '-':
+ DO (cp = parse_sum (g, cp + 1, &rightval));
+ *valp = (*valp - rightval);
+ break;
+ }
+ return cp;
+}
+
+
+static const char *
+parse_shift (g, cp, valp)
+ IfParser *g;
+ const char *cp;
+ int *valp;
+{
+ int rightval;
+
+ DO (cp = parse_sum (g, cp, valp));
+ SKIPSPACE (cp);
+
+ switch (*cp) {
+ case '<':
+ if (cp[1] == '<') {
+ DO (cp = parse_shift (g, cp + 2, &rightval));
+ *valp = (*valp << rightval);
+ }
+ break;
+
+ case '>':
+ if (cp[1] == '>') {
+ DO (cp = parse_shift (g, cp + 2, &rightval));
+ *valp = (*valp >> rightval);
+ }
+ break;
+ }
+ return cp;
+}
+
+
+static const char *
+parse_inequality (g, cp, valp)
+ IfParser *g;
+ const char *cp;
+ int *valp;
+{
+ int rightval;
+
+ DO (cp = parse_shift (g, cp, valp));
+ SKIPSPACE (cp);
+
+ switch (*cp) {
+ case '<':
+ if (cp[1] == '=') {
+ DO (cp = parse_inequality (g, cp + 2, &rightval));
+ *valp = (*valp <= rightval);
+ } else {
+ DO (cp = parse_inequality (g, cp + 1, &rightval));
+ *valp = (*valp < rightval);
+ }
+ break;
+
+ case '>':
+ if (cp[1] == '=') {
+ DO (cp = parse_inequality (g, cp + 2, &rightval));
+ *valp = (*valp >= rightval);
+ } else {
+ DO (cp = parse_inequality (g, cp + 1, &rightval));
+ *valp = (*valp > rightval);
+ }
+ break;
+ }
+ return cp;
+}
+
+
+static const char *
+parse_equality (g, cp, valp)
+ IfParser *g;
+ const char *cp;
+ int *valp;
+{
+ int rightval;
+
+ DO (cp = parse_inequality (g, cp, valp));
+ SKIPSPACE (cp);
+
+ switch (*cp) {
+ case '=':
+ if (cp[1] == '=')
+ cp++;
+ DO (cp = parse_equality (g, cp + 1, &rightval));
+ *valp = (*valp == rightval);
+ break;
+
+ case '!':
+ if (cp[1] != '=')
+ break;
+ DO (cp = parse_equality (g, cp + 2, &rightval));
+ *valp = (*valp != rightval);
+ break;
+ }
+ return cp;
+}
+
+
+static const char *
+parse_band (g, cp, valp)
+ IfParser *g;
+ const char *cp;
+ int *valp;
+{
+ int rightval;
+
+ DO (cp = parse_equality (g, cp, valp));
+ SKIPSPACE (cp);
+
+ switch (*cp) {
+ case '&':
+ if (cp[1] != '&') {
+ DO (cp = parse_band (g, cp + 1, &rightval));
+ *valp = (*valp & rightval);
+ }
+ break;
+ }
+ return cp;
+}
+
+
+static const char *
+parse_bor (g, cp, valp)
+ IfParser *g;
+ const char *cp;
+ int *valp;
+{
+ int rightval;
+
+ DO (cp = parse_band (g, cp, valp));
+ SKIPSPACE (cp);
+
+ switch (*cp) {
+ case '|':
+ if (cp[1] != '|') {
+ DO (cp = parse_bor (g, cp + 1, &rightval));
+ *valp = (*valp | rightval);
+ }
+ break;
+ }
+ return cp;
+}
+
+
+static const char *
+parse_land (g, cp, valp)
+ IfParser *g;
+ const char *cp;
+ int *valp;
+{
+ int rightval;
+
+ DO (cp = parse_bor (g, cp, valp));
+ SKIPSPACE (cp);
+
+ switch (*cp) {
+ case '&':
+ if (cp[1] != '&')
+ return CALLFUNC(g, handle_error) (g, cp, "&&");
+ DO (cp = parse_land (g, cp + 2, &rightval));
+ *valp = (*valp && rightval);
+ break;
+ }
+ return cp;
+}
+
+
+static const char *
+parse_lor (g, cp, valp)
+ IfParser *g;
+ const char *cp;
+ int *valp;
+{
+ int rightval;
+
+ DO (cp = parse_land (g, cp, valp));
+ SKIPSPACE (cp);
+
+ switch (*cp) {
+ case '|':
+ if (cp[1] != '|')
+ return CALLFUNC(g, handle_error) (g, cp, "||");
+ DO (cp = parse_lor (g, cp + 2, &rightval));
+ *valp = (*valp || rightval);
+ break;
+ }
+ return cp;
+}
+
+
+/****************************************************************************
+ External Entry Points
+ ****************************************************************************/
+
+const char *
+ParseIfExpression (g, cp, valp)
+ IfParser *g;
+ const char *cp;
+ int *valp;
+{
+ return parse_lor (g, cp, valp);
+}
+
+
--- /dev/null
+/*
+ * $XConsortium: ifparser.h,v 1.1 92/08/22 13:05:39 rws Exp $
+ *
+ * Copyright 1992 Network Computing Devices, Inc.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Network Computing Devices may not be
+ * used in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. Network Computing Devices makes
+ * no representations about the suitability of this software for any purpose.
+ * It is provided ``as is'' without express or implied warranty.
+ *
+ * NETWORK COMPUTING DEVICES DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
+ * IN NO EVENT SHALL NETWORK COMPUTING DEVICES BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Jim Fulton
+ * Network Computing Devices, Inc.
+ *
+ * Simple if statement processor
+ *
+ * This module can be used to evaluate string representations of C language
+ * if constructs. It accepts the following grammar:
+ *
+ * EXPRESSION := VALUE
+ * | VALUE BINOP EXPRESSION
+ *
+ * VALUE := '(' EXPRESSION ')'
+ * | '!' VALUE
+ * | '-' VALUE
+ * | 'defined' '(' variable ')'
+ * | variable
+ * | number
+ *
+ * BINOP := '*' | '/' | '%'
+ * | '+' | '-'
+ * | '<<' | '>>'
+ * | '<' | '>' | '<=' | '>='
+ * | '==' | '!='
+ * | '&' | '|'
+ * | '&&' | '||'
+ *
+ * The normal C order of precidence is supported.
+ *
+ *
+ * External Entry Points:
+ *
+ * ParseIfExpression parse a string for #if
+ */
+
+#include <stdio.h>
+
+#define const /**/
+typedef int Bool;
+#define False 0
+#define True 1
+
+typedef struct _if_parser {
+ struct { /* functions */
+ char *(*handle_error) (/* struct _if_parser *, const char *,
+ const char * */);
+ int (*eval_variable) (/* struct _if_parser *, const char *, int */);
+ int (*eval_defined) (/* struct _if_parser *, const char *, int */);
+ } funcs;
+ char *data;
+} IfParser;
+
+char *ParseIfExpression (/* IfParser *, const char *, int * */);
+
--- /dev/null
+/* $XConsortium: include.c,v 1.16 94/04/17 20:10:34 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 struct inclist inclist[ MAXFILES ],
+ *inclistp;
+extern char *includedirs[ ];
+extern char *notdotdot[ ];
+extern boolean show_where_not;
+extern boolean warn_multiple;
+
+struct inclist *inc_path(file, include, dot)
+ register char *file,
+ *include;
+ boolean dot;
+{
+ static char path[ BUFSIZ ];
+ register char **pp, *p;
+ register struct inclist *ip;
+ struct stat st;
+ boolean found = FALSE;
+
+ /*
+ * Check all previously found include files for a path that
+ * has already been expanded.
+ */
+ for (ip = inclist; ip->i_file; ip++)
+ if ((strcmp(ip->i_incstring, include) == 0) && !ip->i_included_sym)
+ {
+ found = TRUE;
+ break;
+ }
+
+ /*
+ * If the path was surrounded by "" or is an absolute path,
+ * then check the exact path provided.
+ */
+ if (!found && (dot || *include == '/')) {
+ if (stat(include, &st) == 0) {
+ ip = newinclude(include, include);
+ found = TRUE;
+ }
+ else if (show_where_not)
+ warning1("\tnot in %s\n", include);
+ }
+
+ /*
+ * See if this include file is in the directory of the
+ * file being compiled.
+ */
+ if (!found) {
+ for (p=file+strlen(file); p>file; p--)
+ if (*p == '/')
+ break;
+ if (p == file)
+ 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) {
+ ip = newinclude(path, include);
+ found = TRUE;
+ }
+ else if (show_where_not)
+ warning1("\tnot in %s\n", path);
+ }
+
+ /*
+ * Check the include directories specified. (standard include dir
+ * should be at the end.)
+ */
+ if (!found)
+ for (pp = includedirs; *pp; pp++) {
+ sprintf(path, "%s/%s", *pp, include);
+ remove_dotdot(path);
+ if (stat(path, &st) == 0) {
+ ip = newinclude(path, include);
+ found = TRUE;
+ break;
+ }
+ else if (show_where_not)
+ warning1("\tnot in %s\n", path);
+ }
+
+ if (!found)
+ ip = NULL;
+ return(ip);
+}
+
+/*
+ * Ocaisionally, 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!!)
+ */
+remove_dotdot(path)
+ 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;
+
+ /*
+ * Now copy the path, removing all 'x/..' components.
+ */
+ cp = components;
+ component_copied = FALSE;
+ while(*cp) {
+ if (!isdot(*cp) && !isdotdot(*cp) && isdotdot(*(cp+1))) {
+ if (issymbolic(newpath, *cp))
+ goto dont_remove;
+ cp++;
+ } else {
+ dont_remove:
+ 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);
+}
+
+isdot(p)
+ register char *p;
+{
+ if(p && *p++ == '.' && *p++ == '\0')
+ return(TRUE);
+ return(FALSE);
+}
+
+isdotdot(p)
+ register char *p;
+{
+ if(p && *p++ == '.' && *p++ == '.' && *p++ == '\0')
+ return(TRUE);
+ return(FALSE);
+}
+
+issymbolic(dir, component)
+ register char *dir, *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 >= ¬dotdot[ MAXDIRS ])
+ fatalerr("out of .. dirs, increase MAXDIRS\n");
+ return(TRUE);
+ }
+#endif
+ return(FALSE);
+}
+
+/*
+ * Add an include file to the list of those included by 'file'.
+ */
+struct inclist *newinclude(newfile, incstring)
+ register char *newfile, *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);
+ ip->i_included_sym = FALSE;
+ if (incstring == NULL)
+ ip->i_incstring = ip->i_file;
+ else
+ ip->i_incstring = copy(incstring);
+
+ return(ip);
+}
+
+included_by(ip, newfile)
+ register struct inclist *ip, *newfile;
+{
+ register i;
+
+ if (ip == NULL)
+ return;
+ /*
+ * Put this include file (newfile) on the list of files included
+ * by 'file'. If 'file' is NULL, then it is not an include
+ * file itself (i.e. was probably mentioned on the command line).
+ * If it is already on the list, don't stick it on again.
+ */
+ if (ip->i_list == NULL)
+ ip->i_list = (struct inclist **)
+ malloc(sizeof(struct inclist *) * ++ip->i_listlen);
+ else {
+ for (i=0; i<ip->i_listlen; i++)
+ if (ip->i_list[ i ] == newfile) {
+ i = strlen(newfile->i_file);
+ if (!ip->i_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_list[ ip->i_listlen-1 ] = newfile;
+}
+
+inc_clean ()
+{
+ register struct inclist *ip;
+
+ for (ip = inclist; ip < inclistp; ip++) {
+ ip->i_marked = FALSE;
+ }
+}
--- /dev/null
+/* $XConsortium: main.c,v 1.83 94/04/17 20:10:36 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"
+#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
+
+#if NeedVarargsPrototypes
+#include <stdarg.h>
+#endif
+
+#ifdef DEBUG
+int _debugmask;
+#endif
+
+char *ProgramName;
+
+char *directives[] = {
+ "if",
+ "ifdef",
+ "ifndef",
+ "else",
+ "endif",
+ "define",
+ "undef",
+ "include",
+ "line",
+ "pragma",
+ "error",
+ "ident",
+ "sccs",
+ "elif",
+ "eject",
+ NULL
+};
+
+#define MAKEDEPEND
+#include "imakemdep.h" /* from config sources */
+#undef MAKEDEPEND
+
+struct inclist inclist[ MAXFILES ],
+ *inclistp = inclist,
+ maininclist;
+
+char *filelist[ MAXFILES ];
+char *includedirs[ MAXDIRS + 1 ];
+char *notdotdot[ MAXDIRS ];
+char *objprefix = "";
+char *objsuffix = OBJSUFFIX;
+char *startat = "# DO NOT DELETE";
+int width = 78;
+boolean append = FALSE;
+boolean printed = FALSE;
+boolean verbose = FALSE;
+boolean show_where_not = FALSE;
+boolean warn_multiple = FALSE; /* Warn on multiple includes of same file */
+
+static
+#ifdef SIGNALRETURNSINT
+int
+#else
+void
+#endif
+catch (sig)
+ int sig;
+{
+ fflush (stdout);
+ fatalerr ("got signal %d\n", sig);
+}
+
+#if defined(USG) || (defined(SYSV386) && defined(SYSV)) || defined(WIN32)
+#define USGISH
+#endif
+
+#ifndef USGISH
+#ifndef _POSIX_SOURCE
+#define sigaction sigvec
+#define sa_handler sv_handler
+#define sa_mask sv_mask
+#define sa_flags sv_flags
+#endif
+struct sigaction sig_act;
+#endif /* USGISH */
+
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+ register char **fp = filelist;
+ register char **incp = includedirs;
+ register char *p;
+ register struct inclist *ip;
+ char *makefile = NULL;
+ struct filepointer *filecontent;
+ struct symtab *psymp = predefs;
+ char *endmarker = NULL;
+ char *defincdir = NULL;
+
+ 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 '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;
+ default:
+ if (endmarker) break;
+ /* fatalerr("unknown opt = %s\n", argv[0]); */
+ warning("ignoring option %s\n", argv[0]);
+ }
+ }
+ if (!defincdir) {
+#ifdef PREINCDIR
+ if (incp >= includedirs + MAXDIRS)
+ fatalerr("Too many -I flags.\n");
+ *incp++ = PREINCDIR;
+#endif
+ if (incp >= includedirs + MAXDIRS)
+ fatalerr("Too many -I flags.\n");
+ *incp++ = INCLUDEDIR;
+#ifdef POSTINCDIR
+ if (incp >= includedirs + MAXDIRS)
+ fatalerr("Too many -I flags.\n");
+ *incp++ = POSTINCDIR;
+#endif
+ } else if (*defincdir) {
+ if (incp >= includedirs + MAXDIRS)
+ fatalerr("Too many -I flags.\n");
+ *incp++ = defincdir;
+ }
+
+ redirect(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;
+#ifdef _POSIX_SOURCE
+ sigemptyset(&sig_act.sa_mask);
+ sigaddset(&sig_act.sa_mask, SIGINT);
+ sigaddset(&sig_act.sa_mask, SIGQUIT);
+#ifdef SIGBUS
+ sigaddset(&sig_act.sa_mask, SIGBUS);
+#endif
+ sigaddset(&sig_act.sa_mask, SIGILL);
+ sigaddset(&sig_act.sa_mask, SIGSEGV);
+ sigaddset(&sig_act.sa_mask, SIGHUP);
+ sigaddset(&sig_act.sa_mask, SIGPIPE);
+#ifdef SIGSYS
+ sigaddset(&sig_act.sa_mask, SIGSYS);
+#endif
+#else
+ sig_act.sa_mask = ((1<<(SIGINT -1))
+ |(1<<(SIGQUIT-1))
+#ifdef SIGBUS
+ |(1<<(SIGBUS-1))
+#endif
+ |(1<<(SIGILL-1))
+ |(1<<(SIGSEGV-1))
+ |(1<<(SIGHUP-1))
+ |(1<<(SIGPIPE-1))
+#ifdef SIGSYS
+ |(1<<(SIGSYS-1))
+#endif
+ );
+#endif /* _POSIX_SOURCE */
+ sig_act.sa_flags = 0;
+ sigaction(SIGHUP, &sig_act, (struct sigaction *)0);
+ sigaction(SIGINT, &sig_act, (struct sigaction *)0);
+ sigaction(SIGQUIT, &sig_act, (struct sigaction *)0);
+ sigaction(SIGILL, &sig_act, (struct sigaction *)0);
+#ifdef SIGBUS
+ sigaction(SIGBUS, &sig_act, (struct sigaction *)0);
+#endif
+ sigaction(SIGSEGV, &sig_act, (struct sigaction *)0);
+#ifdef SIGSYS
+ sigaction(SIGSYS, &sig_act, (struct sigaction *)0);
+#endif
+#endif /* USGISH */
+
+ /*
+ * now peruse through the list of files.
+ */
+ for(fp=filelist; *fp; fp++) {
+ filecontent = getfile(*fp);
+ 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");
+ exit(0);
+}
+
+struct filepointer *getfile(file)
+ char *file;
+{
+ register int fd;
+ struct filepointer *content;
+ struct stat st;
+
+ content = (struct filepointer *)malloc(sizeof(struct filepointer));
+ 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);
+ 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;
+ return(content);
+}
+
+freefile(fp)
+ struct filepointer *fp;
+{
+ free(fp->f_base);
+ free(fp);
+}
+
+char *copy(str)
+ register char *str;
+{
+ register char *p = (char *)malloc(strlen(str) + 1);
+
+ strcpy(p, str);
+ return(p);
+}
+
+match(str, list)
+ register char *str, **list;
+{
+ register 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 *getline(filep)
+ register struct filepointer *filep;
+{
+ register char *p, /* walking pointer */
+ *eof, /* end of file pointer */
+ *bol; /* beginning of line pointer */
+ register lineno; /* line number */
+
+ p = filep->f_p;
+ eof = filep->f_end;
+ if (p >= eof)
+ return((char *)NULL);
+ lineno = filep->f_line;
+
+ for(bol = p--; ++p < eof; ) {
+ if (*p == '/' && *(p+1) == '*') { /* consume comments */
+ *p++ = ' ', *p++ = ' ';
+ while (*p) {
+ if (*p == '*' && *(p+1) == '/') {
+ *p++ = ' ', *p = ' ';
+ break;
+ }
+ else if (*p == '\n')
+ lineno++;
+ *p++ = ' ';
+ }
+ continue;
+ }
+#ifdef WIN32
+ else if (*p == '/' && *(p+1) == '/') { /* consume comments */
+ *p++ = ' ', *p++ = ' ';
+ while (*p && *p != '\n')
+ *p++ = ' ';
+ lineno++;
+ continue;
+ }
+#endif
+ else if (*p == '\\') {
+ if (*(p+1) == '\n') {
+ *p = ' ';
+ *(p+1) = ' ';
+ lineno++;
+ }
+ }
+ else if (*p == '\n') {
+ lineno++;
+ if (*bol == '#') {
+ register char *cp;
+
+ *p++ = '\0';
+ /* punt lines with just # (yacc generated) */
+ for (cp = bol+1;
+ *cp && (*cp == ' ' || *cp == '\t'); cp++);
+ if (*cp) goto done;
+ }
+ bol = p+1;
+ }
+ }
+ if (*bol != '#')
+ bol = NULL;
+done:
+ filep->f_p = p;
+ filep->f_line = lineno;
+ return(bol);
+}
+
+/*
+ * Strip the file name down to what we want to see in the Makefile.
+ * It will have objprefix and objsuffix around it.
+ */
+char *base_name(file)
+ register char *file;
+{
+ register 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)
+int rename (from, to)
+ char *from, *to;
+{
+ (void) unlink (to);
+ if (link (from, to) == 0) {
+ unlink (from);
+ return 0;
+ } else {
+ return -1;
+ }
+}
+#endif /* USGISH */
+
+redirect(line, makefile)
+ char *line,
+ *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')
+ 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);
+#ifdef WIN32
+ fclose(fdin);
+#endif
+ if (rename(makefile, backup) < 0)
+ fatalerr("cannot rename %s to %s\n", makefile, backup);
+#ifdef WIN32
+ 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_)
+ chmod(makefile, st.st_mode);
+#else
+ fchmod(fileno(fdout), st.st_mode);
+#endif /* USGISH */
+}
+
+#if NeedVarargsPrototypes
+fatalerr(char *msg, ...)
+#else
+/*VARARGS*/
+fatalerr(msg,x1,x2,x3,x4,x5,x6,x7,x8,x9)
+ char *msg;
+#endif
+{
+#if NeedVarargsPrototypes
+ va_list args;
+#endif
+ fprintf(stderr, "%s: error: ", ProgramName);
+#if NeedVarargsPrototypes
+ va_start(args, msg);
+ vfprintf(stderr, msg, args);
+ va_end(args);
+#else
+ fprintf(stderr, msg,x1,x2,x3,x4,x5,x6,x7,x8,x9);
+#endif
+ exit (1);
+}
+
+#if NeedVarargsPrototypes
+warning(char *msg, ...)
+#else
+/*VARARGS0*/
+warning(msg,x1,x2,x3,x4,x5,x6,x7,x8,x9)
+ char *msg;
+#endif
+{
+#if NeedVarargsPrototypes
+ va_list args;
+#endif
+ fprintf(stderr, "%s: warning: ", ProgramName);
+#if NeedVarargsPrototypes
+ va_start(args, msg);
+ vfprintf(stderr, msg, args);
+ va_end(args);
+#else
+ fprintf(stderr, msg,x1,x2,x3,x4,x5,x6,x7,x8,x9);
+#endif
+}
+
+#if NeedVarargsPrototypes
+warning1(char *msg, ...)
+#else
+/*VARARGS0*/
+warning1(msg,x1,x2,x3,x4,x5,x6,x7,x8,x9)
+ char *msg;
+#endif
+{
+#if NeedVarargsPrototypes
+ va_list args;
+ va_start(args, msg);
+ vfprintf(stderr, msg, args);
+ va_end(args);
+#else
+ fprintf(stderr, msg,x1,x2,x3,x4,x5,x6,x7,x8,x9);
+#endif
+}
--- /dev/null
+.\" $XConsortium: mkdepend.man,v 1.15 94/04/17 20:10:37 gildea Exp $
+.\" Copyright (c) 1993, 1994 X Consortium
+.\"
+.\" Permission is hereby granted, free of charge, to any person obtaining a
+.\" copy of this software and associated documentation files (the "Software"),
+.\" to deal in the Software without restriction, including without limitation
+.\" the rights to use, copy, modify, merge, publish, distribute, sublicense,
+.\" and/or sell copies of the Software, and to permit persons to whom the
+.\" Software furnished to do so, subject to the following conditions:
+.\"
+.\" The above copyright notice and this permission notice shall be included in
+.\" all copies or substantial portions of the Software.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+.\" IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+.\" FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+.\" THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+.\" WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+.\" OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+.\" SOFTWARE.
+.\"
+.\" Except as contained in this notice, the name of the X Consortium shall not
+.\" be used in advertising or otherwise to promote the sale, use or other
+.\" dealing in this Software without prior written authorization from the
+.\" X Consortium.
+.TH MAKEDEPEND 1 "Release 6" "X Version 11"
+.UC 4
+.SH NAME
+makedepend \- create dependencies in makefiles
+.SH SYNOPSIS
+.B makedepend
+[
+.B \-Dname=def
+] [
+.B \-Dname
+] [
+.B \-Iincludedir
+] [
+.B \-Yincludedir
+] [
+.B \-a
+] [
+.B \-fmakefile
+] [
+.B \-oobjsuffix
+] [
+.B \-pobjprefix
+] [
+.B \-sstring
+] [
+.B \-wwidth
+] [
+.B \-v
+] [
+.B \-m
+] [
+\-\^\-
+.B otheroptions
+\-\^\-
+]
+sourcefile .\|.\|.
+.br
+.SH DESCRIPTION
+.B Makedepend
+reads each
+.I sourcefile
+in sequence and parses it like a C-preprocessor,
+processing all
+.I #include,
+.I #define,
+.I #undef,
+.I #ifdef,
+.I #ifndef,
+.I #endif,
+.I #if
+and
+.I #else
+directives so that it can correctly tell which
+.I #include,
+directives would be used in a compilation.
+Any
+.I #include,
+directives can reference files having other
+.I #include
+directives, and parsing will occur in these files as well.
+.PP
+Every file that a
+.I sourcefile
+includes,
+directly or indirectly,
+is what
+.B makedepend
+calls a "dependency".
+These dependencies are then written to a
+.I makefile
+in such a way that
+.B make(1)
+will know which object files must be recompiled when a dependency has changed.
+.PP
+By default,
+.B makedepend
+places its output in the file named
+.I makefile
+if it exists, otherwise
+.I Makefile.
+An alternate makefile may be specified with the
+.B \-f
+option.
+It first searches the makefile for
+the line
+.sp
+ # DO NOT DELETE THIS LINE \-\^\- make depend depends on it.
+.sp
+or one provided with the
+.B \-s
+option,
+as a delimiter for the dependency output.
+If it finds it, it will delete everything
+following this to the end of the makefile
+and put the output after this line.
+If it doesn't find it, the program
+will append the string to the end of the makefile
+and place the output following that.
+For each
+.I sourcefile
+appearing on the command line,
+.B makedepend
+puts lines in the makefile of the form
+.sp
+ sourcefile.o:\0dfile .\|.\|.
+.sp
+Where "sourcefile.o" is the name from the command
+line with its suffix replaced with ".o",
+and "dfile" is a dependency discovered in a
+.I #include
+directive while parsing
+.I sourcefile
+or one of the files it included.
+.SH EXAMPLE
+Normally,
+.B makedepend
+will be used in a makefile target so that typing "make depend" will
+bring the dependencies up to date for the makefile.
+For example,
+.nf
+ SRCS\0=\0file1.c\0file2.c\0.\|.\|.
+ CFLAGS\0=\0\-O\0\-DHACK\0\-I\^.\^.\^/foobar\0\-xyz
+ depend:
+ makedepend\0\-\^\-\0$(CFLAGS)\0\-\^\-\0$(SRCS)
+.fi
+.SH OPTIONS
+.B Makedepend
+will ignore any option that it does not understand so that you may use
+the same arguments that you would for
+.B cc(1).
+.TP 5
+.B \-Dname=def or \-Dname
+Define.
+This places a definition for
+.I name
+in
+.B makedepend's
+symbol table.
+Without
+.I =def
+the symbol becomes defined as "1".
+.TP 5
+.B \-Iincludedir
+Include directory.
+This option tells
+.B makedepend
+to prepend
+.I includedir
+to its list of directories to search when it encounters
+a
+.I #include
+directive.
+By default,
+.B makedepend
+only searches the standard include directories (usually /usr/include
+and possibly a compiler-dependent directory).
+.TP 5
+.B \-Yincludedir
+Replace all of the standard include directories with the single specified
+include directory; you can omit the
+.I includedir
+to simply prevent searching the standard include directories.
+.TP 5
+.B \-a
+Append the dependencies to the end of the file instead of replacing them.
+.TP 5
+.B \-fmakefile
+Filename.
+This allows you to specify an alternate makefile in which
+.B makedepend
+can place its output.
+.TP 5
+.B \-oobjsuffix
+Object file suffix.
+Some systems may have object files whose suffix is something other
+than ".o".
+This option allows you to specify another suffix, such as
+".b" with
+.I -o.b
+or ":obj"
+with
+.I -o:obj
+and so forth.
+.TP 5
+.B \-pobjprefix
+Object file prefix.
+The prefix is prepended to the name of the object file. This is
+usually used to designate a different directory for the object file.
+The default is the empty string.
+.TP 5
+.B \-sstring
+Starting string delimiter.
+This option permits you to specify
+a different string for
+.B makedepend
+to look for in the makefile.
+.TP 5
+.B \-wwidth
+Line width.
+Normally,
+.B makedepend
+will ensure that every output line that it writes will be no wider than
+78 characters for the sake of readability.
+This option enables you to change this width.
+.TP 5
+.B \-v
+Verbose operation.
+This option causes
+.B makedepend
+to emit the list of files included by each input file on standard output.
+.TP 5
+.B \-m
+Warn about multiple inclusion.
+This option causes
+.B makedepend
+to produce a warning if any input file includes another file more than
+once. In previous versions of
+.B makedepend
+this was the default behavior; the default has been changed to better
+match the behavior of the C compiler, which does not consider multiple
+inclusion to be an error. This option is provided for backward
+compatibility, and to aid in debugging problems related to multiple
+inclusion.
+.TP 5
+.B "\-\^\- options \-\^\-"
+If
+.B makedepend
+encounters a double hyphen (\-\^\-) in the argument list,
+then any unrecognized argument following it
+will be silently ignored; a second double hyphen terminates this
+special treatment.
+In this way,
+.B makedepend
+can be made to safely ignore esoteric compiler arguments that might
+normally be found in a CFLAGS
+.B make
+macro (see the
+.B EXAMPLE
+section above).
+All options that
+.B makedepend
+recognizes and appear between the pair of double hyphens
+are processed normally.
+.SH ALGORITHM
+The approach used in this program enables it to run an order of magnitude
+faster than any other "dependency generator" I have ever seen.
+Central to this performance are two assumptions:
+that all files compiled by a single
+makefile will be compiled with roughly the same
+.I -I
+and
+.I -D
+options;
+and that most files in a single directory will include largely the
+same files.
+.PP
+Given these assumptions,
+.B makedepend
+expects to be called once for each makefile, with
+all source files that are maintained by the
+makefile appearing on the command line.
+It parses each source and include
+file exactly once, maintaining an internal symbol table
+for each.
+Thus, the first file on the command line will take an amount of time
+proportional to the amount of time that a normal C preprocessor takes.
+But on subsequent files, if it encounter's an include file
+that it has already parsed, it does not parse it again.
+.PP
+For example,
+imagine you are compiling two files,
+.I file1.c
+and
+.I file2.c,
+they each include the header file
+.I header.h,
+and the file
+.I header.h
+in turn includes the files
+.I def1.h
+and
+.I def2.h.
+When you run the command
+.sp
+ makedepend\0file1.c\0file2.c
+.sp
+.B makedepend
+will parse
+.I file1.c
+and consequently,
+.I header.h
+and then
+.I def1.h
+and
+.I def2.h.
+It then decides that the dependencies for this file are
+.sp
+ file1.o:\0header.h\0def1.h\0def2.h
+.sp
+But when the program parses
+.I file2.c
+and discovers that it, too, includes
+.I header.h,
+it does not parse the file,
+but simply adds
+.I header.h,
+.I def1.h
+and
+.I def2.h
+to the list of dependencies for
+.I file2.o.
+.SH "SEE ALSO"
+cc(1), make(1)
+.SH BUGS
+.B makedepend
+parses, but does not currently evaluate, the SVR4
+#predicate(token-list) preprocessor expression;
+such expressions are simply assumed to be true.
+This may cause the wrong
+.I #include
+directives to be evaluated.
+.PP
+Imagine you are parsing two files,
+say
+.I file1.c
+and
+.I file2.c,
+each includes the file
+.I def.h.
+The list of files that
+.I def.h
+includes might truly be different when
+.I def.h
+is included by
+.I file1.c
+than when it is included by
+.I file2.c.
+But once
+.B makedepend
+arrives at a list of dependencies for a file,
+it is cast in concrete.
+.SH AUTHOR
+Todd Brunhoff, Tektronix, Inc. and MIT Project Athena
--- /dev/null
+/* $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("%s: %d: %s\n", file_red->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];
+ }
+}
--- /dev/null
+/* $XConsortium: pr.c,v 1.17 94/04/17 20:10:38 gildea Exp $ */
+/*
+
+Copyright (c) 1993, 1994 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+*/
+
+#include "def.h"
+
+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;
+
+add_include(filep, file, file_red, include, dot, failOK)
+ struct filepointer *filep;
+ struct inclist *file, *file_red;
+ char *include;
+ boolean dot;
+{
+ 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, dot);
+ if (newfile == NULL) {
+ if (failOK)
+ return;
+ if (file != file_red)
+ warning("%s (reading %s, line %d): ",
+ file_red->i_file, file->i_file, filep->f_line);
+ else
+ warning("%s, line %d: ", file->i_file, filep->f_line);
+ warning1("cannot find include file \"%s\"\n", include);
+ show_where_not = TRUE;
+ newfile = inc_path(file->i_file, include, dot);
+ show_where_not = FALSE;
+ }
+
+ if (newfile) {
+ included_by(file, newfile);
+ if (!newfile->i_searched) {
+ newfile->i_searched = TRUE;
+ content = getfile(newfile->i_file);
+ find_includes(content, newfile, file_red, 0, failOK);
+ freefile(content);
+ }
+ }
+}
+
+recursive_pr_include(head, file, base)
+ register struct inclist *head;
+ register char *file, *base;
+{
+ register int i;
+
+ if (head->i_marked)
+ return;
+ head->i_marked = TRUE;
+ if (head->i_file != file)
+ pr(head, file, base);
+ for (i=0; i<head->i_listlen; i++)
+ recursive_pr_include(head->i_list[ i ], file, base);
+}
+
+pr(ip, file, base)
+ register struct inclist *ip;
+ char *file, *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_notified)
+ return;
+ ip->i_notified = TRUE;
+ lastfile = NULL;
+ printf("\n# %s includes:", ip->i_file);
+ for (i=0; i<ip->i_listlen; i++)
+ printf("\n#\t%s", ip->i_list[ i ]->i_incstring);
+}