1 /* This file is part of GNU cflow 2 Copyright (C) 1997-2019 Sergey Poznyakoff 3 4 GNU cflow is free software; you can redistribute it and/or modify 5 it under the terms of the GNU General Public License as published by 6 the Free Software Foundation; either version 3 of the License, or 7 (at your option) any later version. 8 9 GNU cflow is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU General Public License for more details. 13 14 You should have received a copy of the GNU General Public License 15 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 16 17 #ifdef HAVE_CONFIG_H 18 # include <config.h> 19 #endif 20 21 #include <stdio.h> 22 #include <stdlib.h> 23 #include <string.h> 24 #include <unistd.h> 25 #include <getopt.h> 26 #include <errno.h> 27 #define obstack_chunk_alloc xmalloc 28 #define obstack_chunk_free free 29 #include <obstack.h> 30 #include <error.h> 31 #include <xalloc.h> 32 #include <gettext.h> 33 34 #define _(c) gettext(c) 35 #define N_(c) c 36 37 #if HAVE_LOCALE_H 38 # include <locale.h> 39 #endif 40 #if !HAVE_SETLOCALE 41 # define setlocale(category, locale) /* empty */ 42 #endif 43 44 /* Exit codes */ 45 #define EX_OK 0 /* Success */ 46 #define EX_FATAL 1 /* Fatal error */ 47 #define EX_SOFT 2 /* Some input files cannot be read or parsed */ 48 #define EX_USAGE 3 /* Command line usage error */ 49 50 #define NUMITEMS(a) sizeof(a)/sizeof((a)[0]) 51 52 struct linked_list_entry { 53 struct linked_list_entry *next, *prev; 54 struct linked_list *list; 55 void *data; 56 }; 57 58 typedef void (*linked_list_free_data_fp) (void*); 59 60 struct linked_list { 61 linked_list_free_data_fp free_data; 62 struct linked_list_entry *head, *tail; 63 }; 64 65 #define linked_list_head(list) ((list) ? (list)->head : NULL) 66 67 enum symtype { 68 SymUndefined, /* Undefined or deleted symbol */ 69 SymToken, /* A token */ 70 SymIdentifier /* Function or variable */ 71 }; 72 73 enum storage { 74 ExternStorage, 75 ExplicitExternStorage, 76 StaticStorage, 77 AutoStorage, 78 AnyStorage 79 }; 80 81 typedef struct { 82 int line; 83 char *source; 84 } Ref; 85 86 enum symbol_flag { 87 symbol_none, 88 symbol_local, /* Unit-local symbol. Must be deleted after 89 processing current compilation unit */ 90 symbol_parm, /* Parameter */ 91 symbol_alias /* Alias to another symbol */ 92 }; 93 94 typedef struct symbol Symbol; 95 96 struct symbol { 97 struct table_entry *owner; 98 Symbol *next; /* Next symbol with the same hash */ 99 struct linked_list_entry *entry; 100 101 enum symtype type; /* Type of the symbol */ 102 char *name; /* Identifier */ 103 enum symbol_flag flag; /* Specific flag */ 104 struct symbol *alias; /* Points to the aliased symbol if 105 type==SymToken and flag==symbol_alias. 106 In this case, the rest of the structure 107 is ignored */ 108 109 int active; /* Set to 1 when the symbol's subtree is 110 being processed, prevent recursion */ 111 int expand_line; /* Output line when this symbol was first 112 expanded */ 113 114 int token_type; /* Type of the token */ 115 char *source; /* Source file */ 116 int def_line; /* Source line */ 117 struct linked_list *ref_line; /* Referenced in */ 118 119 int level; /* Block nesting level (for local vars), 120 Parameter nesting level (for params) */ 121 122 char *decl; /* Declaration */ 123 enum storage storage; /* Storage type */ 124 125 int arity; /* Number of parameters or -1 for 126 variables */ 127 128 int recursive; /* Is the function recursive */ 129 size_t ord; /* ordinal number */ 130 struct linked_list *caller; /* List of callers */ 131 struct linked_list *callee; /* List of callees */ 132 }; 133 134 /* Output flags */ 135 #define PRINT_XREF 0x01 136 #define PRINT_TREE 0x02 137 138 #ifndef CFLOW_PREPROC 139 # define CFLOW_PREPROC "/usr/bin/cpp" 140 #endif 141 142 #define MAX_OUTPUT_DRIVERS 8 143 144 extern unsigned char *level_mark; 145 extern FILE *outfile; 146 extern char *outname; 147 148 extern int verbose; 149 extern int print_option; 150 extern int use_indentation; 151 extern int assume_cplusplus; 152 extern int record_defines; 153 extern int strict_ansi; 154 extern char *level_indent[]; 155 extern char *level_end[]; 156 extern char *level_begin; 157 extern int print_levels; 158 extern int print_line_numbers; 159 extern int print_as_tree; 160 extern int brief_listing; 161 extern int reverse_tree; 162 extern int out_line; 163 extern char *start_name; 164 extern int all_functions; 165 extern int max_depth; 166 extern int emacs_option; 167 extern int debug; 168 extern int preprocess_option; 169 extern int omit_arguments_option; 170 extern int omit_symbol_names_option; 171 172 extern int token_stack_length; 173 extern int token_stack_increase; 174 175 extern int symbol_count; 176 extern unsigned input_file_count; 177 178 #define INSTALL_DEFAULT 0x00 179 #define INSTALL_OVERWRITE 0x01 180 #define INSTALL_CHECK_LOCAL 0x02 181 #define INSTALL_UNIT_LOCAL 0x04 182 183 Symbol *lookup(const char*); 184 Symbol *install(char*, int); 185 Symbol *install_ident(char *name, enum storage storage); 186 void ident_change_storage(Symbol *sp, enum storage storage); 187 void delete_autos(int level); 188 void delete_statics(void); 189 void delete_parms(int level); 190 void move_parms(int level); 191 size_t collect_symbols(Symbol ***, int (*sel)(), size_t rescnt); 192 size_t collect_functions(Symbol ***return_sym); 193 struct linked_list *linked_list_create(linked_list_free_data_fp fun); 194 void linked_list_destroy(struct linked_list **plist); 195 void linked_list_append(struct linked_list **plist, void *data); 196 void linked_list_prepend(struct linked_list **plist, void *data); 197 void linked_list_iterate(struct linked_list **plist, 198 int (*itr) (void *, void *), void *data); 199 void linked_list_unlink(struct linked_list *list, 200 struct linked_list_entry *ent); 201 size_t linked_list_size(struct linked_list *list); 202 203 int data_in_list(void *data, struct linked_list *list); 204 205 int get_token(void); 206 int source(char *name); 207 void init_lex(int debug_level); 208 void set_preprocessor(const char *arg); 209 void pp_option(const char *arg); 210 211 void init_parse(void); 212 int yyparse(void); 213 214 void output(void); 215 void newline(void); 216 void print_level(int lev, int last); 217 int globals_only(void); 218 int include_symbol(Symbol *sym); 219 int symbol_is_function(Symbol *sym); 220 221 void sourcerc(int *, char ***); 222 223 typedef enum { 224 cflow_output_init, 225 cflow_output_begin, 226 cflow_output_end, 227 cflow_output_newline, 228 cflow_output_separator, 229 cflow_output_symbol, 230 cflow_output_text 231 } cflow_output_command; 232 233 struct output_symbol { 234 int direct; 235 int level; 236 int last; 237 Symbol *sym; 238 }; 239 240 int register_output(const char *name, 241 int (*handler) (cflow_output_command cmd, 242 FILE *outfile, int line, 243 void *data, void *handler_data), 244 void *handler_data); 245 int select_output_driver (const char *name); 246 void output_init(void); 247 248 int gnu_output_handler(cflow_output_command cmd, 249 FILE *outfile, int line, 250 void *data, void *handler_data); 251 int posix_output_handler(cflow_output_command cmd, 252 FILE *outfile, int line, 253 void *data, void *handler_data); 254 255 256 typedef struct cflow_depmap *cflow_depmap_t; 257 cflow_depmap_t depmap_alloc(size_t count); 258 void depmap_set(cflow_depmap_t dmap, size_t row, size_t col); 259 int depmap_isset(cflow_depmap_t dmap, size_t row, size_t col); 260 void depmap_tc(cflow_depmap_t dmap); 261