1 /* 2 3 Copyright (c) 1993, 1994, 1998 The Open Group. 4 5 Permission to use, copy, modify, distribute, and sell this software and its 6 documentation for any purpose is hereby granted without fee, provided that 7 the above copyright notice appear in all copies and that both that 8 copyright notice and this permission notice appear in supporting 9 documentation. 10 11 The above copyright notice and this permission notice shall be included in 12 all copies or substantial portions of the Software. 13 14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 18 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 19 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20 21 Except as contained in this notice, the name of The Open Group shall not be 22 used in advertising or otherwise to promote the sale, use or other dealings 23 in this Software without prior written authorization from The Open Group. 24 25 */ 26 27 #ifdef HAVE_CONFIG_H 28 # include "makedepend-config.h" 29 #endif 30 31 #include <stdlib.h> 32 #include <stdio.h> 33 #include <string.h> 34 #include <ctype.h> 35 #include <sys/types.h> 36 #include <fcntl.h> 37 #include <sys/stat.h> 38 39 /* http://clang.llvm.org/docs/LanguageExtensions.html#has-attribute */ 40 #ifndef __has_attribute 41 # define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */ 42 #endif 43 44 #ifndef _X_ATTRIBUTE_PRINTF 45 #if __has_attribute(__format__) \ 46 || defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 203) 47 # define _X_ATTRIBUTE_PRINTF(x,y) __attribute__((__format__(__printf__,x,y))) 48 #else /* not gcc >= 2.3 */ 49 # define _X_ATTRIBUTE_PRINTF(x,y) 50 #endif 51 #endif 52 53 #ifndef _X_NORETURN 54 #if __has_attribute(noreturn) \ 55 || (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 205)) \ 56 || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)) 57 # define _X_NORETURN __attribute((noreturn)) 58 #else 59 # define _X_NORETURN 60 #endif /* GNUC */ 61 #endif 62 63 #ifndef HAVE_REALLOCARRAY 64 #define reallocarray(ptr, num, size) realloc(ptr, (num) * (size)) 65 #endif 66 #define mallocarray(num, size) reallocarray(NULL, num, size) 67 68 #define MAXDEFINES 512 69 #define MAXFILES 2048 70 #define MAXINCFILES 128 /* "-include" files */ 71 #define MAXDIRS 512 /* -I flags */ 72 #define PATHMAX 4096 /* realpath */ 73 #define SYMTABINC 10 /* must be > 1 for define() to work right */ 74 #define TRUE 1 75 #define FALSE 0 76 77 /* the following must match the directives table in parse.c */ 78 #define IF 0 79 #define IFDEF 1 80 #define IFNDEF 2 81 #define ELSE 3 82 #define ENDIF 4 83 #define DEFINE 5 84 #define UNDEF 6 85 #define INCLUDE 7 86 #define LINE 8 87 #define PRAGMA 9 88 #define ERROR 10 89 #define IDENT 11 90 #define SCCS 12 91 #define ELIF 13 92 #define EJECT 14 93 #define WARNING 15 94 #define INCLUDENEXT 16 95 #define IFFALSE 17 /* pseudo value --- never matched */ 96 #define ELIFFALSE 18 /* pseudo value --- never matched */ 97 #define INCLUDEDOT 19 /* pseudo value --- never matched */ 98 #define IFGUESSFALSE 20 /* pseudo value --- never matched */ 99 #define ELIFGUESSFALSE 21 /* pseudo value --- never matched */ 100 #define INCLUDENEXTDOT 22 /* pseudo value --- never matched */ 101 102 #ifdef DEBUG 103 extern int _debugmask; 104 105 /* 106 * debug levels are: 107 * 108 * 0 show ifn*(def)*,endif 109 * 1 trace defined/!defined 110 * 2 show #include 111 * 3 show #include SYMBOL 112 * 4-6 unused 113 */ 114 #define debug(level,arg) do { if (_debugmask & (1 << level)) warning arg; } while(0) 115 #else 116 #define debug(level,arg) do { /**/ } while (0) 117 #endif /* DEBUG */ 118 119 typedef unsigned char boolean; 120 121 struct symtab { 122 char *s_name; 123 char *s_value; 124 }; 125 126 /* possible i_flag */ 127 #define DEFCHECKED (1<<0) /* whether defines have been checked */ 128 #define NOTIFIED (1<<1) /* whether we have revealed includes */ 129 #define MARKED (1<<2) /* whether it's in the makefile */ 130 #define SEARCHED (1<<3) /* whether we have read this */ 131 #define FINISHED (1<<4) /* whether we are done reading this */ 132 #define INCLUDED_SYM (1<<5) /* whether #include SYMBOL was found 133 Can't use i_list if TRUE */ 134 struct inclist { 135 char *i_incstring; /* string from #include line */ 136 char *i_file; /* path name of the include file */ 137 char *i_realpath; /* path name processed by realpath() */ 138 struct inclist **i_list; /* list of files it itself includes */ 139 struct symtab **i_defs; /* symbol table for this file and its 140 children when merged */ 141 unsigned int i_listlen; /* length of i_list */ 142 int i_ndefs; /* current # defines */ 143 boolean *i_merged; /* whether we have merged child 144 defines */ 145 unsigned char i_flags; 146 }; 147 148 struct filepointer { 149 const char *f_name; 150 char *f_p; 151 char *f_base; 152 char *f_end; 153 long f_len; 154 long f_line; 155 long cmdinc_count; 156 char **cmdinc_list; 157 long cmdinc_line; 158 }; 159 160 #include <stdlib.h> 161 162 /* main.c */ 163 int match(const char *str, const char *const *list); 164 char *getnextline(struct filepointer *fp); 165 struct filepointer *getfile(const char *file); 166 void freefile(struct filepointer *fp); 167 168 /* include.c */ 169 void included_by(struct inclist *ip, struct inclist *newfile); 170 struct inclist *newinclude(const char *newfile, const char *incstring, 171 const char *incpath); 172 void inc_clean(void); 173 struct inclist *inc_path(const char *file, const char *include, int type); 174 175 /* parse.c */ 176 struct symtab **isdefined(const char *symbol, struct inclist *file, 177 struct inclist **srcfile); 178 void define2(const char *name, const char *val, struct inclist *file); 179 void define(char *def, struct inclist *file); 180 void undefine(const char *symbol, struct inclist *file); 181 int find_includes(struct filepointer *filep, 182 struct inclist *file, struct inclist *file_red, 183 int recursion, boolean failOK); 184 185 /* pr.c */ 186 void recursive_pr_include(struct inclist *head, 187 const char *file, const char *base); 188 void add_include(struct filepointer *filep, 189 struct inclist *file, struct inclist *file_red, 190 const char *include, int type, boolean failOK); 191 192 /* cppsetup.c */ 193 int cppsetup(const char *filename, const char *line, 194 struct filepointer *filep, struct inclist *inc); 195 196 /* main.c */ 197 extern void fatalerr(const char *, ...) _X_ATTRIBUTE_PRINTF(1, 2) _X_NORETURN; 198 extern void warning(const char *, ...) _X_ATTRIBUTE_PRINTF(1, 2); 199 extern void warning1(const char *, ...) _X_ATTRIBUTE_PRINTF(1, 2); 200 201 extern struct inclist inclist[MAXFILES]; 202 extern struct inclist *inclistp; 203 extern struct inclist *inclistnext; 204 extern struct inclist maininclist; 205 extern const char *includedirs[]; 206 extern const char **includedirsnext; 207 extern char *notdotdot[]; 208 209 extern const char *objprefix; 210 extern const char *objsuffix; 211 extern int width; 212 extern boolean printed; 213 extern boolean verbose; 214 extern boolean show_where_not; 215 extern boolean warn_multiple; 216