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 11996 : static void set_level_mark (int lev, int mark) {
12 11996 : if (lev >= level_mark_size) {
13 21 : level_mark_size += level_mark_incr;
14 21 : level_mark = xrealloc (level_mark, level_mark_size);
15 : }
16 11996 : level_mark[lev] = mark;
17 11996 : }
18 :
19 3862 : void print_level (int lev, int last) {
20 : int i;
21 3862 : if (print_line_numbers)
22 718 : fprintf (outfile, "%5d ", out_line);
23 3862 : if (print_levels)
24 0 : fprintf (outfile, "{%4d} ", lev);
25 3862 : fprintf (outfile, "%s", level_begin);
26 36524 : for (i = 0; i < lev; i++)
27 32662 : fprintf (outfile, "%s", level_indent[level_mark[i]]);
28 3862 : fprintf (outfile, "%s", level_end [last]);
29 3862 : }
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 46 : 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 46 : if (driver_max == MAX_OUTPUT_DRIVERS - 1)
42 0 : abort ();
43 46 : output_driver[driver_max].name = strdup (name);
44 46 : output_driver[driver_max].handler = handler;
45 46 : output_driver[driver_max].handler_data = handler_data;
46 46 : 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 3863 : void newline () {
64 3863 : output_driver[driver_index].handler (cflow_output_newline, outfile, out_line, NULL, output_driver[driver_index].handler_data);
65 3863 : out_line++;
66 3863 : }
67 :
68 16 : static void begin () {
69 16 : output_driver[driver_index].handler (cflow_output_begin, outfile, out_line, NULL, output_driver[driver_index].handler_data);
70 16 : }
71 :
72 16 : static void end () {
73 16 : output_driver[driver_index].handler (cflow_output_end, outfile, out_line, NULL, output_driver[driver_index].handler_data);
74 16 : }
75 :
76 21 : static void separator () {
77 21 : output_driver[driver_index].handler (cflow_output_separator, outfile, out_line, NULL, output_driver[driver_index].handler_data);
78 21 : }
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 3862 : static int print_symbol (int direct, int level, int last, Symbol *sym) {
89 : struct output_symbol output_symbol;
90 3862 : output_symbol.direct = direct;
91 3862 : output_symbol.level = level;
92 3862 : output_symbol.last = last;
93 3862 : output_symbol.sym = sym;
94 3862 : return output_driver[driver_index].handler (cflow_output_symbol, outfile, out_line, &output_symbol, output_driver[driver_index].handler_data);
95 : }
96 :
97 47322 : static int compare (const void *ap, const void *bp) {
98 47322 : Symbol * const *a = ap;
99 47322 : Symbol * const *b = bp;
100 47322 : return strcmp ((*a)->name, (*b)->name);
101 : }
102 :
103 16090 : static int is_var (Symbol *symp) {
104 16090 : if (include_symbol (symp)) {
105 12778 : if (symp->type == SymIdentifier)
106 12778 : return symp->storage == ExternStorage || symp->storage == StaticStorage;
107 : else
108 0 : return 1;
109 : }
110 3312 : return 0;
111 : }
112 :
113 26764 : int symbol_is_function (Symbol *symp) {
114 26764 : return symp->type == SymIdentifier && symp->arity >= 0;
115 : }
116 :
117 3833 : static void clear_active (Symbol *sym) {
118 3833 : sym->active = 0;
119 3833 : }
120 :
121 2318 : void print_refs (char *name, struct linked_list *reflist) {
122 : Ref *refptr;
123 : struct linked_list_entry *p;
124 14754 : for (p = linked_list_head (reflist); p; p = p->next) {
125 12436 : refptr = (Ref *) p->data;
126 12436 : fprintf (outfile, "%s %s:%d\n", name, refptr -> source, refptr -> line);
127 : }
128 2318 : }
129 :
130 2318 : static void print_function (Symbol *symp) {
131 2318 : if (symp->source) {
132 881 : fprintf (outfile, "%s * %s:%d %s\n", symp -> name, symp -> source, symp -> def_line, symp -> decl);
133 : }
134 2318 : print_refs (symp -> name, symp -> ref_line);
135 2318 : }
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 2323 : for (i = 0; i < num; i++) {
148 2318 : symp = symbols[i];
149 2318 : switch (symp->type) {
150 : case SymIdentifier :
151 2318 : print_function (symp);
152 2318 : 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 3833 : static void set_active (Symbol *sym) {
164 3833 : sym->active = out_line;
165 3833 : }
166 :
167 47374 : static int is_printable (struct linked_list_entry *p) {
168 47374 : return p != NULL && include_symbol ((Symbol *) p->data);
169 : }
170 :
171 23950 : static int is_last (struct linked_list_entry *p) {
172 79674 : while ((p = p->next))
173 47374 : if (is_printable (p))
174 15600 : return 0;
175 8350 : return 1;
176 : }
177 :
178 11996 : static void direct_tree (int lev, int last, Symbol *sym) {
179 : struct linked_list_entry *p;
180 : int rc;
181 11996 : if (sym->type == SymUndefined || (max_depth && lev >= max_depth) || !include_symbol (sym))
182 8134 : return;
183 3862 : rc = print_symbol (1, lev, last, sym);
184 3862 : newline ();
185 3862 : if (rc || sym->active)
186 29 : return;
187 3833 : set_active (sym);
188 15808 : for (p = linked_list_head (sym->callee); p; p = p->next) {
189 11975 : set_level_mark (lev + 1, ! is_last (p));
190 11975 : direct_tree (lev + 1, is_last (p), (Symbol *) p -> data);
191 : }
192 3833 : 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 16 : 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 16 : num = collect_functions (&symbols);
221 2858 : for (i = 0; i < num; i++)
222 2842 : symbols[i]->ord = i;
223 16 : int *arrayOfDefLines = (int *) malloc ((num + 1) * sizeof (int));
224 16 : int length = 0;
225 : size_t jjj;
226 2858 : for (jjj = 0; jjj < num; jjj++) {
227 2842 : arrayOfDefLines[jjj] = symbols[jjj]->def_line;
228 2842 : length++;
229 : }
230 16 : fflush (stderr);
231 16 : fflush (stdout);
232 16 : stdout_bk = dup (fileno (stdout));
233 16 : stderr_bk = dup (fileno (stderr));
234 16 : fpEr = fopen ("tempEr.txt", "w");
235 16 : fp = fopen ("temp.txt", "w");
236 16 : dup2 (fileno (fpEr), fileno (stderr));
237 16 : dup2 (fileno (fp), fileno (stdout));
238 : short *TRANSPLANT_RESULT;
239 16 : TRANSPLANT_RESULT = GRAFT_INTERFACE (length, arrayOfDefLines, depmap, jjj, j, num, i, main_sym, symbols, stdout_bk, stderr_bk, fpEr, fp);
240 16 : fflush (stderr);
241 16 : fflush (stdout);
242 16 : fclose (fpEr);
243 16 : fclose (fp);
244 16 : dup2 (stderr_bk, fileno (stderr));
245 16 : dup2 (stdout_bk, fileno (stdout));
246 : FILE *outfileIDCT;
247 16 : char *outnameIDCT = (char *) malloc (1000 * sizeof (char));
248 16 : if (strcmp (outname, "-") == 0) {
249 1 : strcpy (outnameIDCT, "CFLOW_IDCTOUT_NOFILE.IDCT");
250 : }
251 : else {
252 15 : sprintf (outnameIDCT, "%sIDCT", outname);
253 : }
254 16 : outfileIDCT = fopen (outnameIDCT, "w");
255 : int jj;
256 2858 : for (jj = 0; jj < length; jj++) {
257 2842 : fprintf (outfileIDCT, "%d ", TRANSPLANT_RESULT [jj]);
258 : }
259 16 : fclose (outfileIDCT);
260 16 : depmap = depmap_alloc (num);
261 2858 : for (i = 0; i < num; i++) {
262 2842 : if (symbols[i]->callee) {
263 : struct linked_list_entry *p;
264 15995 : for (p = linked_list_head (symbols[i]->callee); p; p = p->next) {
265 14141 : Symbol *s = (Symbol *) p->data;
266 14141 : if (symbol_is_function (s))
267 5433 : depmap_set (depmap, i, ((Symbol *) p->data)->ord);
268 : }
269 : }
270 : }
271 16 : depmap_tc (depmap);
272 2858 : for (i = 0; i < num; i++)
273 2842 : if (depmap_isset (depmap, i, i))
274 143 : symbols[i]->recursive = 1;
275 16 : free (depmap);
276 16 : free (symbols);
277 16 : num = collect_symbols (&symbols, is_var, 0);
278 16 : qsort (symbols, num, sizeof (* symbols), compare);
279 16 : begin ();
280 16 : if (reverse_tree) {
281 0 : for (i = 0; i < num; i++) {
282 0 : inverted_tree (0, 0, symbols [i]);
283 0 : separator ();
284 : }
285 : }
286 : else {
287 16 : main_sym = lookup (start_name);
288 16 : if (main_sym) {
289 13 : direct_tree (0, 0, main_sym);
290 13 : separator ();
291 : }
292 : else {
293 25 : for (i = 0; i < num; i++) {
294 22 : if (symbols[i]->callee == NULL)
295 14 : continue;
296 8 : direct_tree (0, 0, symbols [i]);
297 8 : separator ();
298 : }
299 : }
300 : }
301 16 : end ();
302 16 : free (symbols);
303 16 : }
304 :
305 21 : void output () {
306 21 : if (strcmp (outname, "-") == 0) {
307 1 : outfile = stdout;
308 : }
309 : else {
310 20 : outfile = fopen (outname, "w");
311 20 : if (!outfile)
312 0 : error (2, errno, _ ("cannot open file `%s'"), outname);
313 : }
314 21 : set_level_mark (0, 0);
315 21 : if (print_option & PRINT_XREF) {
316 5 : xref_output ();
317 : }
318 21 : if (print_option & PRINT_TREE) {
319 16 : tree_output ();
320 : }
321 21 : fclose (outfile);
322 21 : }
323 :
|