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