Home | History | Annotate | Line # | Download | only in dist
      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