diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2005-03-20 11:44:20 +0000 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2005-03-20 11:44:20 +0000 |
commit | 331de292f4a8eb70919476f82c9666a7c96ab4c2 (patch) | |
tree | 14dc7ddaa437bd13a8aadbe8b211e1129f5a77ca /src | |
parent | ad1eed9ad145a4787dfd9ad4979d105806bdfe52 (diff) | |
download | cflow-331de292f4a8eb70919476f82c9666a7c96ab4c2.tar.gz cflow-331de292f4a8eb70919476f82c9666a7c96ab4c2.tar.bz2 |
(GNU_STYLE_OPTIONS,SYSTEM_ERROR)
(FATAL_ERROR): Removed
(SymFunction): Renamed to SymIdentifier. All callers updated
(struct symbol): Removed union, rearranged fields. All callers
updated
Implemented -ix
Diffstat (limited to 'src')
-rw-r--r-- | src/c.l | 20 | ||||
-rw-r--r-- | src/cflow.h | 63 | ||||
-rw-r--r-- | src/gnu.c | 20 | ||||
-rw-r--r-- | src/main.c | 72 | ||||
-rw-r--r-- | src/output.c | 64 | ||||
-rw-r--r-- | src/parser.c | 80 | ||||
-rw-r--r-- | src/posix.c | 10 | ||||
-rw-r--r-- | src/symbol.c | 18 |
8 files changed, 179 insertions, 168 deletions
@@ -192,23 +192,23 @@ init_lex(int debug_level) for (i = 0; i < NUMITEMS(keywords); i++) { sp = install(keywords[i]); sp->type = SymToken; - sp->v.type.token_type = WORD; + sp->token_type = WORD; } for (i = 0; i < NUMITEMS(types); i++) { sp = install(types[i]); sp->type = SymToken; - sp->v.type.token_type = TYPE; - sp->v.type.source = NULL; - sp->v.type.def_line = -1; - sp->v.type.ref_line = NULL; + sp->token_type = TYPE; + sp->source = NULL; + sp->def_line = -1; + sp->ref_line = NULL; } sp = install("..."); sp->type = SymToken; - sp->v.type.token_type = IDENTIFIER; - sp->v.type.source = NULL; - sp->v.type.def_line = -1; - sp->v.type.ref_line = NULL; + sp->token_type = IDENTIFIER; + sp->source = NULL; + sp->def_line = -1; + sp->ref_line = NULL; } int @@ -219,7 +219,7 @@ ident() sp = lookup(yytext); if (sp && sp->type == SymToken) { yylval.str = sp->name; - return sp->v.type.token_type; + return sp->token_type; } obstack_grow(&string_stk, yytext, yyleng); obstack_1grow(&string_stk, 0); diff --git a/src/cflow.h b/src/cflow.h index 06385ba..a79ad66 100644 --- a/src/cflow.h +++ b/src/cflow.h @@ -31,12 +31,6 @@ #include <error.h> #include <xalloc.h> -#define GNU_STYLE_OPTIONS 1 - -#define SYSTEM_ERROR 0x0100 -#define FATAL_ERROR 0x0200 -#define FATAL(n) FATAL_ERROR|(n) - #define NUMITEMS(a) sizeof(a)/sizeof((a)[0]) typedef struct cons *Consptr; @@ -50,9 +44,9 @@ struct cons { #define CDR(a) (a)->cdr enum symtype { - SymUndefined, - SymToken, - SymFunction + SymUndefined, /* Undefined or deleted symbol */ + SymToken, /* A token */ + SymIdentifier /* Function or variable */ }; enum storage { @@ -71,33 +65,30 @@ typedef struct { typedef struct symbol Symbol; struct symbol { - Symbol *next; - enum symtype type; - char *name; - int active; - int expand_line; - union { - struct { - int token_type; - char *source; - int def_line; - Consptr ref_line; - } type; - struct { - int token_type; - char *source; - int def_line; - Consptr ref_line; - char *type; - enum storage storage; - int argc; - char *args; - int recursive; /* for functions only */ - int level; /* for local vars only */ - Consptr caller; - Consptr callee; - } func; - } v; + Symbol *next; /* Next symbol with the same hash */ + enum symtype type; /* Type of the symbol */ + char *name; /* Identifier */ + int active; /* Set to 1 when the symbol's subtree is + being processed, prevent recursion */ + int expand_line; /* Output line when this symbol was first + expanded */ + + int token_type; /* Type of the token */ + char *source; /* Source file */ + int def_line; /* Source line */ + Consptr ref_line; /* Referenced in */ + + int level; /* Nesting level (for local vars only) */ + + char *decl; /* Declaration */ + enum storage storage; /* Storage type */ + + int arity; /* Number of parameters or -1 for + variables */ + + int recursive; /* Is the function recursive */ + Consptr caller; /* List of callers */ + Consptr callee; /* List of callees */ }; /* Output flags */ @@ -35,17 +35,19 @@ print_level(int lev, int last) void print_function_name(Symbol *sym, int has_subtree) { - fprintf(outfile, "%s()", sym->name); - if (sym->v.func.type) + fprintf(outfile, "%s", sym->name); + if (sym->arity >= 0) + fprintf(outfile, "()"); + if (sym->decl) fprintf(outfile, " <%s at %s:%d>", - sym->v.func.type, - sym->v.func.source, - sym->v.func.def_line); + sym->decl, + sym->source, + sym->def_line); if (sym->active) { fprintf(outfile, " (recursive: see %d)", sym->active-1); return; } - if (sym->v.func.recursive) + if (sym->recursive) fprintf(outfile, " (R)"); if (!print_as_tree && has_subtree) fprintf(outfile, ":"); @@ -56,8 +58,8 @@ static int print_symbol(FILE *outfile, int line, struct output_symbol *s) { int has_subtree = s->direct ? - s->sym->v.func.callee != NULL : - s->sym->v.func.caller != NULL; + s->sym->callee != NULL : + s->sym->caller != NULL; print_level(s->level, s->last); print_function_name(s->sym, has_subtree); @@ -66,7 +68,7 @@ print_symbol(FILE *outfile, int line, struct output_symbol *s) if (s->sym->expand_line) { fprintf(outfile, " [see %d]", s->sym->expand_line); return 1; - } else if (s->sym->v.func.callee) + } else if (s->sym->callee) s->sym->expand_line = line; } return 0; @@ -58,7 +58,7 @@ static struct argp_option options[] = { { "ignore-indentation", 'S', NULL, 0, "do not rely on indentation", 11 }, { "defines" , OPT_DEFINES, NULL, 0, - "record defines", 11 }, + "record defines (not implemented yet)", 11 }, { "ansi", 'a', NULL, 0, "Assume input to be written in ANSI C", 11 }, { "pushdown", 'p', "VALUE", 0, @@ -148,16 +148,14 @@ int print_as_tree; /* Print as tree */ int brief_listing; /* Produce short listing */ int reverse_tree; /* Generate reverse tree */ int max_depth; /* The depth at which the flowgraph is cut off */ -char *included_symbols = "s"; - /* A list of symbols included in the graph. +char *included_symbols; /* A list of symbols included in the graph. Consists of the following letters: x Include (external and static) data symbols; _ Include names that begin with an underscore; s Include static functions; t Include typedefs (for cross-references only); */ -char *excluded_symbols = ""; - /* A list of symbols *not* included in the graph. +char *excluded_symbols; /* A list of symbols *not* included in the graph. Overrides included_symbols */ char *level_indent[] = { NULL, NULL }; @@ -209,17 +207,24 @@ parse_opt (int key, char *arg, struct argp_state *state) case 'f': if (select_output_driver(arg)) argp_error(state, "%s: No such output driver", optarg); - else if (strcmp (arg, "posix") == 0) + else if (strcmp(arg, "posix") == 0) brief_listing = 1; break; case OPT_LEVEL_INDENT: set_level_indent(arg); break; case 'i': - if (arg[0] == '^') - excluded_symbols = arg+1; - else - included_symbols = arg; + if (arg[0] == '^') { + excluded_symbols = xrealloc(excluded_symbols, + strlen(excluded_symbols) + + strlen(arg+1) + 1); + strcat(excluded_symbols, arg+1); + } else { + included_symbols = xrealloc(included_symbols, + strlen(included_symbols) + + strlen(arg) + 1); + strcat(included_symbols, arg); + } break; case 'l': print_levels = 1; @@ -254,13 +259,13 @@ parse_opt (int key, char *arg, struct argp_state *state) } static struct argp argp = { - options, - parse_opt, - "[FILE]...", - doc, - NULL, - NULL, - NULL + options, + parse_opt, + "[FILE]...", + doc, + NULL, + NULL, + NULL }; int @@ -279,18 +284,20 @@ globals_only() int include_symbol(Symbol *sym) { - int type; + int type = 0; - if (sym->name[0] == '_') - type = '_'; - else if (sym->type == SymFunction && sym->v.func.storage == StaticStorage) - type = 's'; - else if (sym->type == SymToken - && sym->v.type.token_type == TYPE - && sym->v.type.source) + if (sym->name[0] == '_' && !included_char('_')) + return 0; + + if (sym->type == SymIdentifier) { + if (sym->arity == -1) + type = 'x'; + else if (sym->storage == StaticStorage) + type = 's'; + } else if (sym->type == SymToken + && sym->token_type == TYPE + && sym->source) type = 't'; - else /* FIXME: 'x' is not used */ - type = 0; if (type == 0) return 1; @@ -359,10 +366,10 @@ symbol_override(char *str) type = IDENTIFIER; sp = install(str); sp->type = SymToken; - sp->v.type.token_type = type; - sp->v.type.source = NULL; - sp->v.type.def_line = -1; - sp->v.type.ref_line = NULL; + sp->token_type = type; + sp->source = NULL; + sp->def_line = -1; + sp->ref_line = NULL; } void @@ -555,6 +562,9 @@ main(int argc, char **argv) register_output("posix", posix_output_handler, NULL); sourcerc(&argc, &argv); + included_symbols = xstrdup("s"); + excluded_symbols = xstrdup(""); + if (argp_parse (&argp, argc, argv, 0, &index, NULL)) exit (1); diff --git a/src/output.c b/src/output.c index 27732e1..95aee70 100644 --- a/src/output.c +++ b/src/output.c @@ -22,12 +22,22 @@ char *level_mark; /* Tree level information. level_mark[i] contains 1 if there are more * leafs on the level `i', otherwise it contains 0 */ -int level_mark_size=1000; -/* Arbitrary size of level mark. Seems to be more than enough */ +int level_mark_size = 0; /* Actual size of level_mark */ +int level_mark_incr = 128; /* level_mark is expanded by this number of bytes */ int out_line = 1; /* Current output line number */ FILE *outfile; /* Output file */ +static void +set_level_mark(int lev, int mark) +{ + if (lev > level_mark_size) { + level_mark_size += level_mark_incr; + level_mark = xrealloc(level_mark, level_mark_size); + } + level_mark[lev] = mark; +} + /* Low level output functions */ @@ -146,21 +156,15 @@ static int is_var(Symbol *symp) { if (include_symbol(symp)) { - if (symp->type == SymFunction) - return symp->v.func.storage == ExternStorage || - symp->v.func.storage == StaticStorage; + if (symp->type == SymIdentifier) + return symp->storage == ExternStorage || + symp->storage == StaticStorage; else return 1; } return 0; } -static int -is_fun(Symbol *symp) -{ - return symp->type == SymFunction && symp->v.func.argc >= 0; -} - static void clear_active(Symbol *sym) { @@ -186,24 +190,24 @@ print_refs(char *name, Consptr cons) static void print_function(Symbol *symp) { - if (symp->v.func.source) { + if (symp->source) { fprintf(outfile, "%s * %s:%d %s\n", symp->name, - symp->v.func.source, - symp->v.func.def_line, - symp->v.func.type); + symp->source, + symp->def_line, + symp->decl); } - print_refs(symp->name, symp->v.func.ref_line); + print_refs(symp->name, symp->ref_line); } static void print_type(Symbol *symp) { - if (symp->v.type.source) + if (symp->source) fprintf(outfile, "%s t %s:%d\n", symp->name, - symp->v.type.source, - symp->v.type.def_line); + symp->source, + symp->def_line); } void @@ -219,7 +223,7 @@ xref_output() for (i = 0; i < num; i++) { symp = symbols[i]; switch (symp->type) { - case SymFunction: + case SymIdentifier: print_function(symp); break; case SymToken: @@ -246,11 +250,11 @@ scan_tree(int lev, Symbol *sym) if (sym->type == SymUndefined) return; if (sym->active) { - sym->v.func.recursive = 1; + sym->recursive = 1; return; } sym->active = 1; - for (cons = sym->v.func.callee; cons; cons = CDR(cons)) { + for (cons = sym->callee; cons; cons = CDR(cons)) { scan_tree(lev+1, (Symbol*)CAR(cons)); } sym->active = 0; @@ -280,8 +284,8 @@ direct_tree(int lev, int last, Symbol *sym) if (rc || sym->active) return; set_active(sym); - for (cons = sym->v.func.callee; cons; cons = CDR(cons)) { - level_mark[lev+1] = CDR(cons) != NULL; + for (cons = sym->callee; cons; cons = CDR(cons)) { + set_level_mark(lev+1, CDR(cons) != NULL); direct_tree(lev+1, CDR(cons) == NULL, (Symbol*)CAR(cons)); } clear_active(sym); @@ -304,8 +308,8 @@ inverted_tree(int lev, int last, Symbol *sym) if (rc || sym->active) return; set_active(sym); - for (cons = sym->v.func.caller; cons; cons = CDR(cons)) { - level_mark[lev+1] = CDR(cons) != NULL; + for (cons = sym->caller; cons; cons = CDR(cons)) { + set_level_mark(lev+1, CDR(cons) != NULL); inverted_tree(lev+1, CDR(cons) == NULL, (Symbol*)CAR(cons)); } clear_active(sym); @@ -318,11 +322,11 @@ tree_output() int i, num; /* Collect and sort symbols */ - num = collect_symbols(&symbols, is_fun); + num = collect_symbols(&symbols, is_var); qsort(symbols, num, sizeof(*symbols), compare); /* Scan and mark the recursive ones */ for (i = 0; i < num; i++) { - if (symbols[i]->v.func.callee) + if (symbols[i]->callee) scan_tree(0, symbols[i]); } @@ -343,7 +347,7 @@ tree_output() separator(); } else { for (i = 0; i < num; i++) { - if (symbols[i]->v.func.callee == NULL) + if (symbols[i]->callee == NULL) continue; direct_tree(0, 0, symbols[i]); separator(); @@ -368,7 +372,7 @@ output() } level_mark = xmalloc(level_mark_size); - level_mark[0] = 0; + set_level_mark(0, 0); if (print_option & PRINT_XREF) { xref_output(); } diff --git a/src/parser.c b/src/parser.c index 8778b49..3761b10 100644 --- a/src/parser.c +++ b/src/parser.c @@ -860,9 +860,10 @@ declare(Ident *ident) if (ident->storage == AutoStorage) { obstack_free(&text_stk, declstr); sp = install(ident->name); - sp->type = SymFunction; - sp->v.func.storage = ident->storage; - sp->v.func.level = level; + sp->type = SymIdentifier; + sp->storage = ident->storage; + sp->level = level; + sp->arity = -1; return; } @@ -873,22 +874,22 @@ declare(Ident *ident) } sp = get_symbol(ident->name); - if (sp->v.func.source) { + if (sp->source) { error_at_line(0, 0, filename, ident->line, "%s() redefined", ident->name); - error_at_line(0, 0, sp->v.func.source, sp->v.func.def_line, + error_at_line(0, 0, sp->source, sp->def_line, "this is the place of previous definition"); } - - sp->type = SymFunction; - sp->v.func.argc = ident->parmcnt; - sp->v.func.storage = (ident->storage == ExplicitExternStorage) ? + + sp->type = SymIdentifier; + sp->arity = ident->parmcnt; + sp->storage = (ident->storage == ExplicitExternStorage) ? ExternStorage : ident->storage; - sp->v.func.type = declstr; - sp->v.func.source = filename; - sp->v.func.def_line = ident->line; - sp->v.func.level = level; + sp->decl = declstr; + sp->source = filename; + sp->def_line = ident->line; + sp->level = level; if (debug) printf("%s:%d: %s/%d defined to %s\n", filename, @@ -905,15 +906,15 @@ declare_type(Ident *ident) finish_save(); sp = lookup(ident->name); for ( ; sp; sp = sp->next) - if (sp->type == SymToken && sp->v.type.token_type == TYPE) + if (sp->type == SymToken && sp->token_type == TYPE) break; if (!sp) sp = install(ident->name); sp->type = SymToken; - sp->v.type.token_type = TYPE; - sp->v.type.source = filename; - sp->v.type.def_line = ident->line; - sp->v.type.ref_line = NULL; + sp->token_type = TYPE; + sp->source = filename; + sp->def_line = ident->line; + sp->ref_line = NULL; if (debug) printf("%s:%d: type %s\n", filename, @@ -928,22 +929,22 @@ get_symbol(char *name) if (sp = lookup(name)) { for (; sp; sp = sp->next) { - if (sp->type == SymFunction && strcmp(sp->name, name) == 0) + if (sp->type == SymIdentifier && strcmp(sp->name, name) == 0) break; } if (sp) return sp; } sp = install(name); - sp->type = SymFunction; - sp->v.func.argc = -1; - sp->v.func.storage = ExternStorage; - sp->v.func.type = NULL; - sp->v.func.source = NULL; - sp->v.func.def_line = -1; - sp->v.func.ref_line = NULL; - sp->v.func.caller = sp->v.func.callee = NULL; - sp->v.func.level = -1; + sp->type = SymIdentifier; + sp->arity = -1; + sp->storage = ExternStorage; + sp->decl = NULL; + sp->source = NULL; + sp->def_line = -1; + sp->ref_line = NULL; + sp->caller = sp->callee = NULL; + sp->level = -1; return sp; } @@ -953,12 +954,12 @@ add_reference(char *name, int line) Symbol *sp = get_symbol(name); Ref *refptr; - if (sp->v.func.storage == AutoStorage) + if (sp->storage == AutoStorage) return NULL; refptr = xmalloc(sizeof(*refptr)); refptr->source = filename; refptr->line = line; - append_to_list(&sp->v.func.ref_line, refptr); + append_to_list(&sp->ref_line, refptr); return sp; } @@ -971,20 +972,23 @@ call(char *name, int line) sp = add_reference(name, line); if (!sp) return; - if (sp->v.func.argc < 0) - sp->v.func.argc = 0; + if (sp->arity < 0) + sp->arity = 0; if (caller) { - if (!symbol_in_list(caller, sp->v.func.caller)) - append_to_list(&sp->v.func.caller, caller); - if (!symbol_in_list(sp, caller->v.func.callee)) - append_to_list(&caller->v.func.callee, sp); + if (!symbol_in_list(caller, sp->caller)) + append_to_list(&sp->caller, caller); + if (!symbol_in_list(sp, caller->callee)) + append_to_list(&caller->callee, sp); } } void reference(char *name, int line) { - add_reference(name, line); + Symbol *sp = add_reference(name, line); + if (!sp) + return; + if (caller && !symbol_in_list(sp, caller->callee)) + append_to_list(&caller->callee, sp); } - diff --git a/src/posix.c b/src/posix.c index d2b5726..ef8469a 100644 --- a/src/posix.c +++ b/src/posix.c @@ -21,8 +21,8 @@ static void print_symbol_type(FILE *outfile, Symbol *sym) { - if (sym->v.func.type) { - char *p = sym->v.func.type; + if (sym->decl) { + char *p = sym->decl; while (*p) { char *q = p; @@ -47,8 +47,8 @@ print_symbol_type(FILE *outfile, Symbol *sym) fprintf(outfile, "%s, <%s %d>", p, - sym->v.func.source, - sym->v.func.def_line); + sym->source, + sym->def_line); } else fprintf(outfile, "<>"); } @@ -65,7 +65,7 @@ print_symbol(FILE *outfile, int line, struct output_symbol *s) if (s->sym->expand_line) { fprintf(outfile, "%d", s->sym->expand_line); return 1; - } else if (s->sym->v.func.callee) + } else if (s->sym->callee) s->sym->expand_line = line; } print_symbol_type(outfile, s->sym); diff --git a/src/symbol.c b/src/symbol.c index 5c59204..7584883 100644 --- a/src/symbol.c +++ b/src/symbol.c @@ -100,7 +100,7 @@ static_processor(void *data, void *proc_data) { Symbol *s = data; - if (s->type == SymFunction && s->v.func.storage == StaticStorage) + if (s->type == SymIdentifier && s->storage == StaticStorage) delete_symbol(s); return true; } @@ -118,7 +118,7 @@ auto_processor(void *data, void *proc_data) { Symbol *s = data; int *level = proc_data; - if (s->type == SymFunction && s->v.func.level == *level) + if (s->type == SymIdentifier && s->level == *level) delete_symbol(s); return true; } @@ -145,13 +145,13 @@ cleanup_processor(void *data, void *proc_data) Symbol *sym; for (sym = data; sym; sym = sym->next) { - if (sym->type == SymFunction) { - if (sym->v.func.ref_line) - sym->v.func.ref_line = CAR(sym->v.func.ref_line); - if (sym->v.func.caller) - sym->v.func.caller = CAR(sym->v.func.caller); - if (sym->v.func.callee) - sym->v.func.callee = CAR(sym->v.func.callee); + if (sym->type == SymIdentifier) { + if (sym->ref_line) + sym->ref_line = CAR(sym->ref_line); + if (sym->caller) + sym->caller = CAR(sym->caller); + if (sym->callee) + sym->callee = CAR(sym->callee); } } return true; |