LCOV - code coverage report
Current view: top level - src - output.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 177 204 86.8 %
Date: 2015-04-20 Functions: 23 25 92.0 %

          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             : 

Generated by: LCOV version 1.10