LCOV - code coverage report
Current view: top level - src - output.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 167 194 86.1 %
Date: 2015-04-21 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       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             : 

Generated by: LCOV version 1.10