summaryrefslogtreecommitdiffabout
path: root/src/main.c
authorSergey Poznyakoff <gray@gnu.org.ua>2005-03-19 21:16:14 (GMT)
committer Sergey Poznyakoff <gray@gnu.org.ua>2005-03-19 21:16:14 (GMT)
commitc093cbe8fbce9b51045bda290ee1a2dc17baedff (patch) (unidiff)
tree9e42c305df9e725220561c4b6b794e4526cf6023 /src/main.c
parent1ec31cd5bda832c52483c9a3a513383d577fde50 (diff)
downloadcflow-c093cbe8fbce9b51045bda290ee1a2dc17baedff.tar.gz
cflow-c093cbe8fbce9b51045bda290ee1a2dc17baedff.tar.bz2
Implemented POSIX options (except -i x)
(options): Reordered. Removed -C, -t (in favor of -i t), and -g (in favor of -i ^s). --brief option takes an optional argument (enable/disable) (progname): Removed (globals_only,include_symbol): New functions
Diffstat (limited to 'src/main.c') (more/less context) (ignore whitespace changes)
-rw-r--r--src/main.c330
1 files changed, 194 insertions, 136 deletions
diff --git a/src/main.c b/src/main.c
index e13fdeb..be905c4 100644
--- a/src/main.c
+++ b/src/main.c
@@ -30,47 +30,63 @@ const char *argp_program_version = "cflow (" PACKAGE_NAME ") " VERSION;
30const char *argp_program_bug_address = "<" PACKAGE_BUGREPORT ">"; 30const char *argp_program_bug_address = "<" PACKAGE_BUGREPORT ">";
31static char doc[] = ""; 31static char doc[] = "";
32 32
33#define OPT_DEFINES 256
34#define OPT_LEVEL_INDENT 257
35#define OPT_DEBUG 258
36
33static struct argp_option options[] = { 37static struct argp_option options[] = {
34 { "verbose", 'v', NULL, 0, 38 { NULL, 0, NULL, 0,
35 "be verbose on output", 0 }, 39 "General options:", 0},
36 { "ignore-indentation", 'S', NULL, 0, 40 { "depth", 'd', "NUMBER", 0,
37 "do not rely on indentation", 0 }, 41 "set the depth at which the flowgraph is cut off.", 1 },
38 { "c++", 'C', NULL, 0, 42 { "include", 'i', "SPEC", 0,
39 "expect C++ input", 0 }, 43 "Increase the number of included symbols. SPEC is a string consisting of the following characters: x (include external and static data symbols), and _ (include names that begin with an underscore). If SPEC starts with ^, its meaning is reversed", 1 },
40 { "defines" , 'd', NULL, 0, 44 { "format", 'f', "NAME", 0,
41 "record defines", 0 }, 45 "use given output format NAME. Valid names are gnu (default) and posix",
46 1 },
47 { "reverse", 'r', NULL, 0,
48 "Print reverse call tree", 1 },
42 { "xref", 'x', NULL, 0, 49 { "xref", 'x', NULL, 0,
43 "produce cross-reference listing only" }, 50 "produce cross-reference listing only", 1 },
44 { "typedefs", 't', NULL, 0, 51 { "print", 'P', "OPT", 0,
45 "record typedefs" }, 52 "Set printing option to OPT. Valid OPT values are: xref (or cross-ref), tree. Any unambiguous abbreviation of the above is also accepted", 1 },
53 { "output", 'o', "FILE", 0,
54 "set output file name (default -, meaning stdout)", 1 },
55
56 { NULL, 0, NULL, 0,
57 "Parser control:", 10},
58 { "ignore-indentation", 'S', NULL, 0,
59 "do not rely on indentation", 11 },
60 { "defines" , OPT_DEFINES, NULL, 0,
61 "record defines", 11 },
62 { "ansi", 'a', NULL, 0,
63 "Assume input to be written in ANSI C", 11 },
46 { "pushdown", 'p', "VALUE", 0, 64 { "pushdown", 'p', "VALUE", 0,
47 "set initial token stack size to VALUE", 0 }, 65 "set initial token stack size to VALUE", 11 },
48 { "symbol", 's', "SYM:TYPE", 0, 66 { "symbol", 's', "SYM:TYPE", 0,
49 "make cflow believe the symbol SYM is of type TYPE. Valid types are: keyword (or kw), modifier, identifier, type, wrapper. Any unambiguous abbreviation of the above is also accepted", 0 }, 67 "make cflow believe the symbol SYM is of type TYPE. Valid types are: keyword (or kw), modifier, identifier, type, wrapper. Any unambiguous abbreviation of the above is also accepted", 11 },
50 { "ansi", 'a', NULL, 0, 68 { "main", 'm', "NAME", 0,
51 "Assume input to be written in ANSI C", 0 }, 69 "Assume main function to be called NAME", 11 },
52 { "globals-only", 'g', NULL, 0, 70
53 "Record only global symbols" }, 71 { NULL, 0, NULL, 0,
72 "Output control:", 20},
54 { "print-level", 'l', NULL, 0, 73 { "print-level", 'l', NULL, 0,
55 "Print nesting level along with the call tree", 0 }, 74 "Print nesting level along with the call tree", 21 },
75 { "level-indent", OPT_LEVEL_INDENT, "STRING", 0,
76 "Use STRING when indenting to each new level", 21 },
56 { "tree", 'T', NULL, 0, 77 { "tree", 'T', NULL, 0,
57 "Draw tree", 0 }, 78 "Draw tree", 21 },
58 { "level-indent", 'i', "STRING", 0, 79 { "brief", 'b', "BOOL", OPTION_ARG_OPTIONAL,
59 "Use STRING when indenting to each new level", 0 }, 80 "brief output", 21 },
60 { "print", 'P', "OPT", 0, 81
61 "Set printing option to OPT. Valid OPT values are: xref (or cross-ref), tree. Any unambiguous abbreviation of the above is also accepted" }, 82 { NULL, 0, NULL, 0,
62 { "output", 'o', "FILE", 0, 83 "Informational options:", 30},
63 "set output file name (default -, meaning stdout)" }, 84 { "verbose", 'v', NULL, 0,
64 { "main", 'm', "NAME", 0, 85 "be verbose on output", 31 },
65 "Assume main function to be called NAME", 0 },
66 { "brief", 'b', NULL, 0,
67 "brief output" },
68 { "reverse", 'r', NULL, 0,
69 "Print reverse call tree", 0 },
70 { "format", 'f', "NAME", 0,
71 "use given output format NAME. Valid names are gnu (default) and posix", 0},
72 { "license", 'L', 0, 0, 86 { "license", 'L', 0, 0,
73 "Print license and exit", 0 }, 87 "Print license and exit", 31 },
88 { "debug", OPT_DEBUG, "NUMBER", OPTION_ARG_OPTIONAL,
89 "set debugging level", 31 },
74 { 0, } 90 { 0, }
75}; 91};
76 92
@@ -89,6 +105,67 @@ char *cflow_license_text =
89" along with GNU cflow; if not, write to the Free Software\n" 105" along with GNU cflow; if not, write to the Free Software\n"
90" Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\n\n"; 106" Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\n\n";
91 107
108/* Structure representing various arguments of command line options */
109struct option_type {
110 char *str; /* optarg value */
111 int min_match; /* minimal number of characters to match */
112 int type; /* data associated with the arg */
113};
114
115static int find_option_type(struct option_type *, char *);
116
117/* Args for --print option */
118struct option_type print_optype[] = {
119 { "xref", 1, PRINT_XREF },
120 { "cross-ref", 1, PRINT_XREF },
121 { "tree", 1, PRINT_TREE },
122 { 0 },
123};
124/* Args for --symbol option */
125struct option_type symbol_optype[] = {
126 { "keyword", 2, WORD },
127 { "kw", 2, WORD },
128 { "modifier", 1, MODIFIER },
129 { "identifier", 1, IDENTIFIER },
130 { "type", 1, TYPE },
131 { "wrapper", 1, PARM_WRAPPER },
132 { 0 },
133};
134
135int debug; /* debug level */
136char *outname = "-"; /* default output file name */
137int print_option = 0; /* what to print. */
138int verbose; /* be verbose on output */
139int ignore_indentation; /* Don't rely on indentation,
140 * i.e. don't suppose the function body
141 * is necessarily surrounded by the curly braces
142 * in the first column
143 */
144int record_defines; /* Record macro definitions */
145int strict_ansi; /* Assume sources to be written in ANSI C */
146int print_levels; /* Print level number near every branch */
147int print_as_tree; /* Print as tree */
148int brief_listing; /* Produce short listing */
149int reverse_tree; /* Generate reverse tree */
150int max_depth; /* The depth at which the flowgraph is cut off */
151char *included_symbols = "s";
152 /* A list of symbols included in the graph.
153 Consists of the following letters:
154 x Include (external and static) data symbols;
155 _ Include names that begin with an underscore;
156 s Include static functions;
157 t Include typedefs (for cross-references only);
158 */
159char *excluded_symbols = "";
160 /* A list of symbols *not* included in the graph.
161 Overrides included_symbols */
162
163char *level_indent[] = { NULL, NULL };
164char *level_end[] = { "", "" };
165char *level_begin = "";
166
167char *start_name = "main"; /* Name of start symbol */
168
92static error_t 169static error_t
93parse_opt (int key, char *arg, struct argp_state *state) 170parse_opt (int key, char *arg, struct argp_state *state)
94{ 171{
@@ -98,11 +175,8 @@ parse_opt (int key, char *arg, struct argp_state *state)
98 case 'a': 175 case 'a':
99 strict_ansi = 1; 176 strict_ansi = 1;
100 break; 177 break;
101 case 'C': 178 case OPT_DEBUG:
102 assume_cplusplus = 1; 179 debug = arg ? atoi(arg) : 1;
103 break;
104 case 'D':
105 debug = 1;
106 break; 180 break;
107 case 'L': 181 case 'L':
108 printf("License for %s:\n\n", argp_program_version); 182 printf("License for %s:\n\n", argp_program_version);
@@ -122,20 +196,30 @@ parse_opt (int key, char *arg, struct argp_state *state)
122 level_end[1] = "\\-"; 196 level_end[1] = "\\-";
123 break; 197 break;
124 case 'b': 198 case 'b':
125 brief_listing = 1; 199 brief_listing = arg ? (arg[0] == 'y' || arg[0] == 'Y') : 1;
126 break; 200 break;
127 case 'd': 201 case 'd':
202 max_depth = atoi(arg);
203 if (max_depth < 0)
204 max_depth = 0;
205 break;
206 case OPT_DEFINES:
128 record_defines = 1; 207 record_defines = 1;
129 break; 208 break;
130 case 'f': 209 case 'f':
131 if (select_output_driver(arg)) 210 if (select_output_driver(arg))
132 argp_error(state, "%s: No such output driver", optarg); 211 argp_error(state, "%s: No such output driver", optarg);
212 else if (strcmp (arg, "posix") == 0)
213 brief_listing = 1;
133 break; 214 break;
134 case 'g': 215 case OPT_LEVEL_INDENT:
135 globals_only = 1; 216 set_level_indent(arg);
136 break; 217 break;
137 case 'i': 218 case 'i':
138 set_level_indent(arg); 219 if (arg[0] == '^')
220 excluded_symbols = arg+1;
221 else
222 included_symbols = arg;
139 break; 223 break;
140 case 'l': 224 case 'l':
141 print_levels = 1; 225 print_levels = 1;
@@ -157,9 +241,6 @@ parse_opt (int key, char *arg, struct argp_state *state)
157 case 's': 241 case 's':
158 symbol_override(arg); 242 symbol_override(arg);
159 break; 243 break;
160 case 't':
161 record_typedefs = 1;
162 break;
163 case 'v': 244 case 'v':
164 verbose = 1; 245 verbose = 1;
165 break; 246 break;
@@ -182,109 +263,55 @@ static struct argp argp = {
182 NULL 263 NULL
183}; 264};
184 265
185/* Structure representing various arguments of command line options */ 266int
186struct option_type { 267included_char(int c)
187 char *str; /* optarg value */
188 int min_match; /* minimal number of characters to match */
189 int type; /* data associated with the arg */
190};
191
192static int find_option_type(struct option_type *, char *);
193
194/* Args for --print option */
195struct option_type print_optype[] = {
196 "xref", 1, PRINT_XREF,
197 "cross-ref", 1, PRINT_XREF,
198 "tree", 1, PRINT_TREE,
199 0
200};
201/* Args for --symbol option */
202struct option_type symbol_optype[] = {
203 "keyword", 2, WORD,
204 "kw", 2, WORD,
205 "modifier", 1, MODIFIER,
206 "identifier", 1, IDENTIFIER,
207 "type", 1, TYPE,
208 "wrapper", 1, PARM_WRAPPER,
209 0
210};
211
212char *progname; /* program name */
213int debug; /* debug mode on */
214char *outname = "-"; /* default output file name */
215int print_option = 0; /* what to print. */
216int verbose; /* be verbose on output */
217int ignore_indentation; /* Don't rely on indentation,
218 * i.e. don't suppose the function body
219 * is necessarily surrounded by the curly braces
220 * in the first column
221 */
222int assume_cplusplus; /* Assume C++ input always */
223int record_defines; /* Record macro definitions */
224int record_typedefs; /* Record typedefs */
225int strict_ansi; /* Assume sources to be written in ANSI C */
226int globals_only; /* List only global symbols */
227int print_levels; /* Print level number near every branch */
228int print_as_tree; /* Print as tree */
229int brief_listing; /* Produce short listing */
230int reverse_tree; /* Generate reverse tree */
231
232char *level_indent[] = { NULL, NULL };
233char *level_end[] = { "", "" };
234char *level_begin = "";
235
236char *start_name = "main"; /* Name of start symbol */
237
238void
239xalloc_die(void)
240{ 268{
241 error(1, ENOMEM, ""); 269 return strchr (included_symbols, c)
270 && !strchr (excluded_symbols, c);
242} 271}
243 272
244int 273int
245main(int argc, char **argv) 274globals_only()
246{ 275{
247 int i; 276 return !included_char('s');
248 int index; 277}
249
250 progname = argv[0];
251 register_output("gnu", gnu_output_handler, NULL);
252 register_output("posix", posix_output_handler, NULL);
253 sourcerc(&argc, &argv);
254 278
255 if (argp_parse (&argp, argc, argv, 0, &index, NULL)) 279int
256 exit (1); 280include_symbol(Symbol *sym)
281{
282 int type;
257 283
258 if (argv[optind] == NULL) 284 if (sym->name[0] == '_')
259 error(1, 0, "No input files"); 285 type = '_';
260 if (print_option == 0) 286 else if (sym->type == SymFunction && sym->v.func.storage == StaticStorage)
261 print_option = PRINT_TREE; 287 type = 's';
262 288 else if (sym->type == SymToken
263 init(); 289 && sym->v.type.token_type == TYPE
264 290 && sym->v.type.source)
265 argc -= index; 291 type = 't';
266 argv += index; 292 else /* FIXME: 'x' is not used */
267 while (argc--) { 293 type = 0;
268 if (source(*argv++) == 0) 294
269 yyparse(); 295 if (type == 0)
270 } 296 return 1;
271 cleanup(); 297 return included_char(type);
298}
272 299
273 output(); 300void
274 return 0; 301xalloc_die(void)
302{
303 error(1, ENOMEM, "");
275} 304}
276 305
277void 306void
278init() 307init()
279{ 308{
280 int i;
281
282 if (level_indent[0] == NULL) { 309 if (level_indent[0] == NULL) {
283 level_indent[0] = level_indent[1] = " "; /* 4 spaces */ 310 level_indent[0] = level_indent[1] = " "; /* 4 spaces */
284 level_end[0] = level_end[1] = ""; 311 level_end[0] = level_end[1] = "";
285 } 312 }
286 313
287 init_lex(); 314 init_lex(debug > 1);
288 init_parse(); 315 init_parse();
289} 316}
290 317
@@ -399,11 +426,11 @@ number(char **str_ptr, int base, int count)
399#define LEVEL_END1 5 426#define LEVEL_END1 5
400 427
401struct option_type level_indent_optype[] = { 428struct option_type level_indent_optype[] = {
402 "begin", 1, LEVEL_BEGIN, 429 { "begin", 1, LEVEL_BEGIN },
403 "0", 1, LEVEL_INDENT0, 430 { "0", 1, LEVEL_INDENT0 },
404 "1", 1, LEVEL_INDENT1, 431 { "1", 1, LEVEL_INDENT1 },
405 "end0", 4, LEVEL_END0, 432 { "end0", 4, LEVEL_END0 },
406 "end1", 4, LEVEL_END1, 433 { "end1", 4, LEVEL_END1 },
407}; 434};
408 435
409void 436void
@@ -519,6 +546,37 @@ parse_level_string(char *str, char **return_ptr)
519 *return_ptr = strdup(text); 546 *return_ptr = strdup(text);
520} 547}
521 548
549int
550main(int argc, char **argv)
551{
552 int index;
553
554 register_output("gnu", gnu_output_handler, NULL);
555 register_output("posix", posix_output_handler, NULL);
556 sourcerc(&argc, &argv);
557
558 if (argp_parse (&argp, argc, argv, 0, &index, NULL))
559 exit (1);
560
561 if (argv[optind] == NULL)
562 error(1, 0, "No input files");
563 if (print_option == 0)
564 print_option = PRINT_TREE;
565
566 init();
567
568 argc -= index;
569 argv += index;
570 while (argc--) {
571 if (source(*argv++) == 0)
572 yyparse();
573 }
574 cleanup();
575
576 output();
577 return 0;
578}
579
522 580
523 581
524 582

Return to:

Send suggestions and report system problems to the System administrator.