Line data Source code
1 :
2 : #include <cflow.h>
3 :
4 : #include <parser.h>
5 : unsigned char *level_mark;
6 : int level_mark_size = 0;
7 : int level_mark_incr = 128;
8 : int out_line = 1;
9 : FILE *outfile;
10 :
11 12112 : static void set_level_mark (int lev, int mark) {
12 12112 : if (lev >= level_mark_size) {
13 19 : level_mark_size += level_mark_incr;
14 19 : level_mark = xrealloc (level_mark, level_mark_size);
15 : }
16 12112 : level_mark[lev] = mark;
17 12112 : }
18 :
19 3943 : void print_level (int lev, int last) {
20 : int i;
21 3943 : if (print_line_numbers)
22 780 : fprintf (outfile, "%5d ", out_line);
23 3943 : if (print_levels)
24 0 : fprintf (outfile, "{%4d} ", lev);
25 3943 : fprintf (outfile, "%s", level_begin);
26 36816 : for (i = 0; i < lev; i++)
27 32873 : fprintf (outfile, "%s", level_indent[level_mark[i]]);
28 3943 : fprintf (outfile, "%s", level_end [last]);
29 3943 : }
30 :
31 : struct output_driver {
32 : char *name;
33 : int (*handler) (cflow_output_command cmd, FILE *outfile, int line, void *data, void *handler_data);
34 : void *handler_data;
35 : };
36 : static int driver_index;
37 : static int driver_max = 0;
38 : struct output_driver output_driver [MAX_OUTPUT_DRIVERS];
39 :
40 42 : int register_output (const char *name, int (*handler) (cflow_output_command cmd, FILE *outfile, int line, void *data, void *handler_data), void *handler_data) {
41 42 : if (driver_max == MAX_OUTPUT_DRIVERS - 1)
42 0 : abort ();
43 42 : output_driver[driver_max].name = strdup (name);
44 42 : output_driver[driver_max].handler = handler;
45 42 : output_driver[driver_max].handler_data = handler_data;
46 42 : return driver_max++;
47 : }
48 :
49 15 : int select_output_driver (const char *name) {
50 : int i;
51 29 : for (i = 0; i < driver_max; i++)
52 29 : if (strcmp (output_driver[i].name, name) == 0) {
53 15 : driver_index = i;
54 15 : return 0;
55 : }
56 0 : return -1;
57 : }
58 :
59 15 : void output_init () {
60 15 : output_driver[driver_index].handler (cflow_output_init, NULL, 0, NULL, output_driver[driver_index].handler_data);
61 15 : }
62 :
63 3944 : void newline () {
64 3944 : output_driver[driver_index].handler (cflow_output_newline, outfile, out_line, NULL, output_driver[driver_index].handler_data);
65 3944 : out_line++;
66 3944 : }
67 :
68 14 : static void begin () {
69 14 : output_driver[driver_index].handler (cflow_output_begin, outfile, out_line, NULL, output_driver[driver_index].handler_data);
70 14 : }
71 :
72 14 : static void end () {
73 14 : output_driver[driver_index].handler (cflow_output_end, outfile, out_line, NULL, output_driver[driver_index].handler_data);
74 14 : }
75 :
76 20 : static void separator () {
77 20 : output_driver[driver_index].handler (cflow_output_separator, outfile, out_line, NULL, output_driver[driver_index].handler_data);
78 20 : }
79 :
80 : #if 0
81 :
82 : static void print_text (char *buf) {
83 : output_driver[driver_index].handler (cflow_output_text, outfile, out_line, buf, output_driver[driver_index].handler_data);
84 : }
85 :
86 : #endif
87 :
88 3943 : static int print_symbol (int direct, int level, int last, Symbol *sym) {
89 : struct output_symbol output_symbol;
90 3943 : output_symbol.direct = direct;
91 3943 : output_symbol.level = level;
92 3943 : output_symbol.last = last;
93 3943 : output_symbol.sym = sym;
94 3943 : return output_driver[driver_index].handler (cflow_output_symbol, outfile, out_line, &output_symbol, output_driver[driver_index].handler_data);
95 : }
96 :
97 49217 : static int compare (const void *ap, const void *bp) {
98 49217 : Symbol * const *a = ap;
99 49217 : Symbol * const *b = bp;
100 49217 : return strcmp ((*a)->name, (*b)->name);
101 : }
102 :
103 16422 : static int is_var (Symbol *symp) {
104 16422 : if (include_symbol (symp)) {
105 13182 : if (symp->type == SymIdentifier)
106 13182 : return symp->storage == ExternStorage || symp->storage == StaticStorage;
107 : else
108 0 : return 1;
109 : }
110 3240 : return 0;
111 : }
112 :
113 27175 : int symbol_is_function (Symbol *symp) {
114 27175 : return symp->type == SymIdentifier && symp->arity >= 0;
115 : }
116 :
117 3914 : static void clear_active (Symbol *sym) {
118 3914 : sym->active = 0;
119 3914 : }
120 :
121 2388 : void print_refs (char *name, struct linked_list *reflist) {
122 : Ref *refptr;
123 : struct linked_list_entry *p;
124 14804 : for (p = linked_list_head (reflist); p; p = p->next) {
125 12416 : refptr = (Ref *) p->data;
126 12416 : fprintf (outfile, "%s %s:%d\n", name, refptr -> source, refptr -> line);
127 : }
128 2388 : }
129 :
130 2388 : static void print_function (Symbol *symp) {
131 2388 : if (symp->source) {
132 911 : fprintf (outfile, "%s * %s:%d %s\n", symp -> name, symp -> source, symp -> def_line, symp -> decl);
133 : }
134 2388 : print_refs (symp -> name, symp -> ref_line);
135 2388 : }
136 :
137 0 : static void print_type (Symbol *symp) {
138 0 : if (symp->source)
139 0 : fprintf (outfile, "%s t %s:%d\n", symp->name, symp->source, symp->def_line);
140 0 : }
141 :
142 5 : void xref_output () {
143 : Symbol **symbols, *symp;
144 : size_t i, num;
145 5 : num = collect_symbols (&symbols, is_var, 0);
146 5 : qsort (symbols, num, sizeof (* symbols), compare);
147 2393 : for (i = 0; i < num; i++) {
148 2388 : symp = symbols[i];
149 2388 : switch (symp->type) {
150 : case SymIdentifier :
151 2388 : print_function (symp);
152 2388 : break;
153 : case SymToken :
154 0 : print_type (symp);
155 0 : break;
156 : case SymUndefined :
157 0 : break;
158 : }
159 : }
160 5 : free (symbols);
161 5 : }
162 :
163 3914 : static void set_active (Symbol *sym) {
164 3914 : sym->active = out_line;
165 3914 : }
166 :
167 48098 : static int is_printable (struct linked_list_entry *p) {
168 48098 : return p != NULL && include_symbol ((Symbol *) p->data);
169 : }
170 :
171 24186 : static int is_last (struct linked_list_entry *p) {
172 80652 : while ((p = p->next))
173 48098 : if (is_printable (p))
174 15818 : return 0;
175 8368 : return 1;
176 : }
177 :
178 12113 : static void direct_tree (int lev, int last, Symbol *sym) {
179 : struct linked_list_entry *p;
180 : int rc;
181 12113 : if (sym->type == SymUndefined || (max_depth && lev >= max_depth) || !include_symbol (sym))
182 8170 : return;
183 3943 : rc = print_symbol (1, lev, last, sym);
184 3943 : newline ();
185 3943 : if (rc || sym->active)
186 29 : return;
187 3914 : set_active (sym);
188 16007 : for (p = linked_list_head (sym->callee); p; p = p->next) {
189 12093 : set_level_mark (lev + 1, ! is_last (p));
190 12093 : direct_tree (lev + 1, is_last (p), (Symbol *) p -> data);
191 : }
192 3914 : clear_active (sym);
193 : }
194 :
195 0 : static void inverted_tree (int lev, int last, Symbol *sym) {
196 : struct linked_list_entry *p;
197 : int rc;
198 0 : if (sym->type == SymUndefined || (max_depth && lev >= max_depth) || !include_symbol (sym))
199 0 : return;
200 0 : rc = print_symbol (0, lev, last, sym);
201 0 : newline ();
202 0 : if (rc || sym->active)
203 0 : return;
204 0 : set_active (sym);
205 0 : for (p = linked_list_head (sym->caller); p; p = p->next) {
206 0 : set_level_mark (lev + 1, ! is_last (p));
207 0 : inverted_tree (lev + 1, is_last (p), (Symbol *) p -> data);
208 : }
209 0 : clear_active (sym);
210 : }
211 :
212 14 : static void tree_output () {
213 : RedirectFile *fp;
214 : RedirectFile *fpEr;
215 : RedirectInt stderr_bk;
216 : RedirectInt stdout_bk;
217 : Symbol **symbols, *main_sym;
218 : size_t i, num, j;
219 : cflow_depmap_t depmap;
220 14 : num = collect_functions (&symbols);
221 2953 : for (i = 0; i < num; i++)
222 2939 : symbols[i]->ord = i;
223 14 : depmap = depmap_alloc (num);
224 2953 : for (i = 0; i < num; i++) {
225 2939 : if (symbols[i]->callee) {
226 : struct linked_list_entry *p;
227 16257 : for (p = linked_list_head (symbols[i]->callee); p; p = p->next) {
228 14360 : Symbol *s = (Symbol *) p->data;
229 14360 : if (symbol_is_function (s))
230 5575 : depmap_set (depmap, i, ((Symbol *) p->data)->ord);
231 : }
232 : }
233 : }
234 14 : depmap_tc (depmap);
235 2953 : for (i = 0; i < num; i++)
236 2939 : if (depmap_isset (depmap, i, i))
237 143 : symbols[i]->recursive = 1;
238 14 : free (depmap);
239 14 : free (symbols);
240 14 : num = collect_symbols (&symbols, is_var, 0);
241 14 : qsort (symbols, num, sizeof (* symbols), compare);
242 14 : begin ();
243 14 : if (reverse_tree) {
244 0 : for (i = 0; i < num; i++) {
245 0 : inverted_tree (0, 0, symbols [i]);
246 0 : separator ();
247 : }
248 : }
249 : else {
250 14 : main_sym = lookup (start_name);
251 14 : if (main_sym) {
252 12 : direct_tree (0, 0, main_sym);
253 12 : separator ();
254 : }
255 : else {
256 24 : for (i = 0; i < num; i++) {
257 22 : if (symbols[i]->callee == NULL)
258 14 : continue;
259 8 : direct_tree (0, 0, symbols [i]);
260 8 : separator ();
261 : }
262 : }
263 : }
264 14 : end ();
265 14 : free (symbols);
266 14 : }
267 :
268 : RedirectFile *fp;
269 : RedirectFile *fpEr;
270 : RedirectInt stderr_bk;
271 : RedirectInt stdout_bk;
272 :
273 19 : void output () {
274 19 : if (strcmp (outname, "-") == 0) {
275 1 : outfile = stdout;
276 : }
277 : else {
278 18 : outfile = fopen (outname, "w");
279 18 : if (!outfile)
280 0 : error (2, errno, _ ("cannot open file `%s'"), outname);
281 : }
282 19 : set_level_mark (0, 0);
283 19 : if (print_option & PRINT_XREF) {
284 5 : xref_output ();
285 : }
286 19 : if (print_option & PRINT_TREE) {
287 14 : tree_output ();
288 : }
289 19 : fclose (outfile);
290 19 : fflush (stderr);
291 19 : fflush (stdout);
292 19 : stdout_bk = dup (fileno (stdout));
293 19 : stderr_bk = dup (fileno (stderr));
294 19 : fpEr = fopen ("tempEr.txt", "w");
295 19 : fp = fopen ("temp.txt", "w");
296 19 : dup2 (fileno (fpEr), fileno (stderr));
297 19 : dup2 (fileno (fp), fileno (stdout));
298 19 : char *tarArchive = (char *) malloc (1000 * sizeof (char));
299 19 : char *outputFileName = outname;
300 19 : sprintf (tarArchive, "%sMYTAR", outname);
301 : int TRANSPLANT_RESULT;
302 19 : TRANSPLANT_RESULT = GRAFT_INTERFACE (outputFileName, tarArchive);
303 1 : fflush (stderr);
304 1 : fflush (stdout);
305 1 : fclose (fpEr);
306 1 : fclose (fp);
307 1 : dup2 (stderr_bk, fileno (stderr));
308 1 : dup2 (stdout_bk, fileno (stdout));
309 1 : }
310 :
|