aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/c.l20
-rw-r--r--src/cflow.h63
-rw-r--r--src/gnu.c20
-rw-r--r--src/main.c72
-rw-r--r--src/output.c64
-rw-r--r--src/parser.c80
-rw-r--r--src/posix.c10
-rw-r--r--src/symbol.c18
8 files changed, 179 insertions, 168 deletions
diff --git a/src/c.l b/src/c.l
index 93f30f5..8f25d3e 100644
--- a/src/c.l
+++ b/src/c.l
@@ -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 */
diff --git a/src/gnu.c b/src/gnu.c
index 329d516..d1c56d4 100644
--- a/src/gnu.c
+++ b/src/gnu.c
@@ -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;
diff --git a/src/main.c b/src/main.c
index be905c4..d312718 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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;

Return to:

Send suggestions and report system problems to the System administrator.