10eb10989Smrg/*
20eb10989Smrg
30eb10989SmrgCopyright (c) 1993, 1994, 1998 The Open Group.
40eb10989Smrg
50eb10989SmrgPermission to use, copy, modify, distribute, and sell this software and its
60eb10989Smrgdocumentation for any purpose is hereby granted without fee, provided that
70eb10989Smrgthe above copyright notice appear in all copies and that both that
80eb10989Smrgcopyright notice and this permission notice appear in supporting
90eb10989Smrgdocumentation.
100eb10989Smrg
110eb10989SmrgThe above copyright notice and this permission notice shall be included in
120eb10989Smrgall copies or substantial portions of the Software.
130eb10989Smrg
140eb10989SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
150eb10989SmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
160eb10989SmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
170eb10989SmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
180eb10989SmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
190eb10989SmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
200eb10989Smrg
210eb10989SmrgExcept as contained in this notice, the name of The Open Group shall not be
220eb10989Smrgused in advertising or otherwise to promote the sale, use or other dealings
230eb10989Smrgin this Software without prior written authorization from The Open Group.
240eb10989Smrg
250eb10989Smrg*/
260eb10989Smrg
27079e7944Smrg#ifdef HAVE_CONFIG_H
280eb10989Smrg# include "makedepend-config.h"
290eb10989Smrg#endif
300eb10989Smrg
310eb10989Smrg#include <stdlib.h>
320eb10989Smrg#include <stdio.h>
330eb10989Smrg#include <string.h>
340eb10989Smrg#include <ctype.h>
350eb10989Smrg#include <sys/types.h>
360eb10989Smrg#include <fcntl.h>
370eb10989Smrg#include <sys/stat.h>
380eb10989Smrg
39121633d0Smrg/* http://clang.llvm.org/docs/LanguageExtensions.html#has-attribute */
40121633d0Smrg#ifndef __has_attribute
41121633d0Smrg# define __has_attribute(x) 0  /* Compatibility with non-clang compilers. */
42121633d0Smrg#endif
43121633d0Smrg
44121633d0Smrg#ifndef _X_ATTRIBUTE_PRINTF
45121633d0Smrg#if __has_attribute(__format__) \
46121633d0Smrg    || defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 203)
47121633d0Smrg# define _X_ATTRIBUTE_PRINTF(x,y) __attribute__((__format__(__printf__,x,y)))
48121633d0Smrg#else /* not gcc >= 2.3 */
49121633d0Smrg# define _X_ATTRIBUTE_PRINTF(x,y)
50121633d0Smrg#endif
51121633d0Smrg#endif
52121633d0Smrg
53121633d0Smrg#ifndef _X_NORETURN
54121633d0Smrg#if __has_attribute(noreturn) \
55121633d0Smrg    || (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 205)) \
56121633d0Smrg    || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590))
57121633d0Smrg# define _X_NORETURN __attribute((noreturn))
58121633d0Smrg#else
59121633d0Smrg# define _X_NORETURN
60121633d0Smrg#endif /* GNUC  */
61121633d0Smrg#endif
62121633d0Smrg
63121633d0Smrg#ifndef HAVE_REALLOCARRAY
64121633d0Smrg#define reallocarray(ptr, num, size)    realloc(ptr, (num) * (size))
65121633d0Smrg#endif
66121633d0Smrg#define mallocarray(num, size)          reallocarray(NULL, num, size)
67121633d0Smrg
680eb10989Smrg#define MAXDEFINES	512
693bea7804Smrg#define MAXFILES	2048
70121633d0Smrg#define MAXINCFILES	128     /* "-include" files */
71121633d0Smrg#define MAXDIRS		512     /* -I flags */
7274901992Smrg#define PATHMAX		4096    /* realpath */
73121633d0Smrg#define SYMTABINC	10      /* must be > 1 for define() to work right */
740eb10989Smrg#define	TRUE		1
750eb10989Smrg#define	FALSE		0
760eb10989Smrg
77121633d0Smrg/* the following must match the directives table in parse.c */
780eb10989Smrg#define	IF		0
790eb10989Smrg#define	IFDEF		1
800eb10989Smrg#define	IFNDEF		2
810eb10989Smrg#define	ELSE		3
820eb10989Smrg#define	ENDIF		4
830eb10989Smrg#define	DEFINE		5
840eb10989Smrg#define	UNDEF		6
850eb10989Smrg#define	INCLUDE		7
860eb10989Smrg#define	LINE		8
870eb10989Smrg#define	PRAGMA		9
880eb10989Smrg#define ERROR           10
890eb10989Smrg#define IDENT           11
900eb10989Smrg#define SCCS            12
910eb10989Smrg#define ELIF            13
920eb10989Smrg#define EJECT           14
930eb10989Smrg#define WARNING         15
940eb10989Smrg#define INCLUDENEXT     16
95121633d0Smrg#define IFFALSE         17      /* pseudo value --- never matched */
96121633d0Smrg#define ELIFFALSE       18      /* pseudo value --- never matched */
97121633d0Smrg#define INCLUDEDOT      19      /* pseudo value --- never matched */
98121633d0Smrg#define IFGUESSFALSE    20      /* pseudo value --- never matched */
99121633d0Smrg#define ELIFGUESSFALSE  21      /* pseudo value --- never matched */
100121633d0Smrg#define INCLUDENEXTDOT  22      /* pseudo value --- never matched */
1010eb10989Smrg
1020eb10989Smrg#ifdef DEBUG
103121633d0Smrgextern int _debugmask;
104121633d0Smrg
1050eb10989Smrg/*
1060eb10989Smrg * debug levels are:
107d43532a6Smrg *
1080eb10989Smrg *     0	show ifn*(def)*,endif
1090eb10989Smrg *     1	trace defined/!defined
1100eb10989Smrg *     2	show #include
1110eb10989Smrg *     3	show #include SYMBOL
1120eb10989Smrg *     4-6	unused
1130eb10989Smrg */
114b2f5b1dbSmrg#define debug(level,arg) do { if (_debugmask & (1 << level)) warning arg; } while(0)
1150eb10989Smrg#else
116b2f5b1dbSmrg#define	debug(level,arg) do { /**/ } while (0)
1170eb10989Smrg#endif /* DEBUG */
1180eb10989Smrg
119121633d0Smrgtypedef unsigned char boolean;
1200eb10989Smrg
1210eb10989Smrgstruct symtab {
122121633d0Smrg    char *s_name;
123121633d0Smrg    char *s_value;
1240eb10989Smrg};
1250eb10989Smrg
1260eb10989Smrg/* possible i_flag */
127121633d0Smrg#define DEFCHECKED	(1<<0)  /* whether defines have been checked */
128121633d0Smrg#define NOTIFIED	(1<<1)  /* whether we have revealed includes */
129121633d0Smrg#define MARKED		(1<<2)  /* whether it's in the makefile */
130121633d0Smrg#define SEARCHED	(1<<3)  /* whether we have read this */
131121633d0Smrg#define FINISHED	(1<<4)  /* whether we are done reading this */
132121633d0Smrg#define INCLUDED_SYM	(1<<5)  /* whether #include SYMBOL was found
133121633d0Smrg                                   Can't use i_list if TRUE */
134121633d0Smrgstruct inclist {
135121633d0Smrg    char                *i_incstring;   /* string from #include line */
136121633d0Smrg    char                *i_file;        /* path name of the include file */
137121633d0Smrg    char                *i_realpath;    /* path name processed by realpath() */
138121633d0Smrg    struct inclist      **i_list;       /* list of files it itself includes */
139121633d0Smrg    struct symtab       **i_defs;       /* symbol table for this file and its
140121633d0Smrg                                           children when merged */
141121633d0Smrg    unsigned int        i_listlen;      /* length of i_list */
142121633d0Smrg    int                 i_ndefs;        /* current # defines */
143121633d0Smrg    boolean             *i_merged;      /* whether we have merged child
144121633d0Smrg                                           defines */
145121633d0Smrg    unsigned char       i_flags;
1460eb10989Smrg};
1470eb10989Smrg
1480eb10989Smrgstruct filepointer {
149121633d0Smrg    const char  *f_name;
150121633d0Smrg    char        *f_p;
151121633d0Smrg    char        *f_base;
152121633d0Smrg    char        *f_end;
153121633d0Smrg    long        f_len;
154121633d0Smrg    long        f_line;
155121633d0Smrg    long        cmdinc_count;
156121633d0Smrg    char        **cmdinc_list;
157121633d0Smrg    long        cmdinc_line;
1580eb10989Smrg};
1590eb10989Smrg
1600eb10989Smrg#include <stdlib.h>
1610eb10989Smrg
162121633d0Smrg/* main.c */
163121633d0Smrgint match(const char *str, const char *const *list);
164121633d0Smrgchar *getnextline(struct filepointer *fp);
165121633d0Smrgstruct filepointer *getfile(const char *file);
166121633d0Smrgvoid freefile(struct filepointer *fp);
167121633d0Smrg
168121633d0Smrg/* include.c */
169121633d0Smrgvoid included_by(struct inclist *ip, struct inclist *newfile);
170121633d0Smrgstruct inclist *newinclude(const char *newfile, const char *incstring,
171121633d0Smrg                           const char *incpath);
172121633d0Smrgvoid inc_clean(void);
173121633d0Smrgstruct inclist *inc_path(const char *file, const char *include, int type);
174121633d0Smrg
175121633d0Smrg/* parse.c */
176121633d0Smrgstruct symtab **isdefined(const char *symbol, struct inclist *file,
177121633d0Smrg                          struct inclist **srcfile);
178121633d0Smrgvoid define2(const char *name, const char *val, struct inclist *file);
179121633d0Smrgvoid define(char *def, struct inclist *file);
180121633d0Smrgvoid undefine(const char *symbol, struct inclist *file);
181121633d0Smrgint find_includes(struct filepointer *filep,
182121633d0Smrg                  struct inclist *file, struct inclist *file_red,
183121633d0Smrg                  int recursion, boolean failOK);
184121633d0Smrg
185121633d0Smrg/* pr.c */
186121633d0Smrgvoid recursive_pr_include(struct inclist *head,
187121633d0Smrg                          const char *file, const char *base);
188121633d0Smrgvoid add_include(struct filepointer *filep,
189121633d0Smrg                 struct inclist *file, struct inclist *file_red,
190121633d0Smrg                 const char *include, int type, boolean failOK);
191121633d0Smrg
192121633d0Smrg/* cppsetup.c */
193121633d0Smrgint cppsetup(const char *filename, const char *line,
194121633d0Smrg             struct filepointer *filep, struct inclist *inc);
195121633d0Smrg
196121633d0Smrg/* main.c */
197079e7944Smrgextern void fatalerr(const char *, ...) _X_ATTRIBUTE_PRINTF(1, 2) _X_NORETURN;
198121633d0Smrgextern void warning(const char *, ...)  _X_ATTRIBUTE_PRINTF(1, 2);
19963165362Smrgextern void warning1(const char *, ...) _X_ATTRIBUTE_PRINTF(1, 2);
200d43532a6Smrg
201121633d0Smrgextern struct inclist   inclist[MAXFILES];
202121633d0Smrgextern struct inclist   *inclistp;
203121633d0Smrgextern struct inclist   *inclistnext;
204121633d0Smrgextern struct inclist   maininclist;
205121633d0Smrgextern const char       *includedirs[];
206d43532a6Smrgextern const char       **includedirsnext;
207121633d0Smrgextern char             *notdotdot[];
208121633d0Smrg
209121633d0Smrgextern const char       *objprefix;
210121633d0Smrgextern const char       *objsuffix;
211121633d0Smrgextern int              width;
212121633d0Smrgextern boolean          printed;
213121633d0Smrgextern boolean          verbose;
214121633d0Smrgextern boolean          show_where_not;
215121633d0Smrgextern boolean          warn_multiple;
216