LCOV - code coverage report
Current view: top level - src/compiler - catalog.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 78 81 96.3 %
Date: 2016-11-30 13:12:14 Functions: 8 8 100.0 %
Branches: 22 38 57.9 %

           Branch data     Line data    Source code
       1                 :            : #ifndef CATALOG_H
       2                 :            : #define CATALOG_H
       3                 :            : 
       4                 :            : #include <stdlib.h>
       5                 :            : #include "symbols.h"
       6                 :            : 
       7                 :            : /* Helper to build more intuitive schema data with fully qualified names. */
       8                 :            : 
       9                 :            : 
      10                 :            : typedef struct entry entry_t;
      11                 :            : typedef entry_t object_entry_t;
      12                 :            : typedef entry_t enum_entry_t;
      13                 :            : typedef struct scope_entry scope_entry_t;
      14                 :            : 
      15                 :            : struct entry {
      16                 :            :     fb_compound_type_t *ct;
      17                 :            :     char *name;
      18                 :            : };
      19                 :            : 
      20                 :            : struct scope_entry {
      21                 :            :     fb_scope_t *scope;
      22                 :            :     char *name;
      23                 :            : };
      24                 :            : 
      25                 :            : typedef struct catalog catalog_t;
      26                 :            : 
      27                 :            : struct catalog {
      28                 :            :     int qualify_names;
      29                 :            :     int nobjects;
      30                 :            :     int nenums;
      31                 :            :     size_t name_table_size;
      32                 :            :     object_entry_t *objects;
      33                 :            :     enum_entry_t *enums;
      34                 :            :     char *name_table;
      35                 :            :     object_entry_t *next_object;
      36                 :            :     enum_entry_t *next_enum;
      37                 :            :     char *next_name;
      38                 :            :     fb_schema_t *schema;
      39                 :            : };
      40                 :            : 
      41                 :         69 : static void count_symbol(void *context, fb_symbol_t *sym)
      42                 :            : {
      43                 :            :     catalog_t *catalog = context;
      44                 :            :     fb_ref_t *scope_name;
      45                 :            :     size_t n = 0;
      46                 :            :     fb_compound_type_t *ct;
      47                 :            :     
      48         [ +  + ]:         69 :     if (!(ct = get_compound_if_visible(catalog->schema, sym))) {
      49                 :            :         return;
      50                 :            :     }
      51                 :            : 
      52                 :            :     /*
      53                 :            :      * Find out how much space the name requires. We must store each
      54                 :            :      * name in full for sorting because comparing a variable number of
      55                 :            :      * parent scope names is otherwise tricky.
      56                 :            :      */
      57         [ +  - ]:         41 :     if (catalog->qualify_names) {
      58                 :         41 :         scope_name = ct->scope->name;
      59         [ +  + ]:        119 :         while (scope_name) {
      60                 :            :             /* + 1 for '.'. */
      61                 :         78 :             n += (size_t)scope_name->ident->len + 1;
      62                 :         78 :             scope_name = scope_name->link;
      63                 :            :         }
      64                 :            :     }
      65                 :            :     /* + 1 for '\0'. */
      66                 :         41 :     n += (size_t)sym->ident->len + 1;
      67                 :         41 :     catalog->name_table_size += n;
      68                 :            : 
      69      [ +  +  - ]:         41 :     switch (sym->kind) {
      70                 :            :     case fb_is_struct:
      71                 :            :     case fb_is_table:
      72                 :         29 :         ++catalog->nobjects;
      73                 :         29 :         break;
      74                 :            :     case fb_is_union:
      75                 :            :     case fb_is_enum:
      76                 :         12 :         ++catalog->nenums;
      77                 :         12 :         break;
      78                 :            :     default: return;
      79                 :            :     }
      80                 :            : }
      81                 :            : 
      82                 :         69 : static void install_symbol(void *context, fb_symbol_t *sym)
      83                 :            : {
      84                 :            :     catalog_t *catalog = context;
      85                 :            :     fb_ref_t *scope_name;
      86                 :            :     int n = 0;
      87                 :            :     char *s, *name;
      88                 :            :     fb_compound_type_t *ct;
      89                 :            :     
      90         [ +  + ]:         69 :     if (!(ct = get_compound_if_visible(catalog->schema, sym))) {
      91                 :            :         return;
      92                 :            :     }
      93                 :            : 
      94                 :         41 :     s = catalog->next_name;
      95                 :            :     name = s;
      96         [ +  - ]:         41 :     if (catalog->qualify_names) {
      97                 :         41 :         scope_name = ct->scope->name;
      98         [ +  + ]:        119 :         while (scope_name) {
      99                 :         78 :             n = scope_name->ident->len;
     100                 :         78 :             memcpy(s, scope_name->ident->text, n);
     101                 :         78 :             s += n;
     102                 :         78 :             *s++ = '.';
     103                 :         78 :             scope_name = scope_name->link;
     104                 :            :         }
     105                 :            :     }
     106                 :         41 :     n = sym->ident->len;
     107                 :         41 :     memcpy(s, sym->ident->text, n);
     108                 :         41 :     s += n;
     109                 :         41 :     *s++ = '\0';
     110                 :         41 :     catalog->next_name = s;
     111                 :            : 
     112      [ +  +  - ]:         41 :     switch (sym->kind) {
     113                 :            :     case fb_is_struct:
     114                 :            :     case fb_is_table:
     115                 :         29 :         catalog->next_object->ct = (fb_compound_type_t *)sym;
     116                 :         29 :         catalog->next_object->name = name;
     117                 :         29 :         catalog->next_object++;
     118                 :         29 :         break;
     119                 :            :     case fb_is_union:
     120                 :            :     case fb_is_enum:
     121                 :         12 :         catalog->next_enum->ct = (fb_compound_type_t *)sym;
     122                 :         12 :         catalog->next_enum->name = name;
     123                 :         12 :         catalog->next_enum++;
     124                 :         12 :         break;
     125                 :            :     default: break;
     126                 :            :     }
     127                 :            : }
     128                 :            : 
     129                 :         14 : static void count_symbols(void *context, fb_scope_t *scope)
     130                 :            : {
     131                 :         14 :     fb_symbol_table_visit(&scope->symbol_index, count_symbol, context);
     132                 :         14 : }
     133                 :            : 
     134                 :         14 : static void install_symbols(void *context, fb_scope_t *scope)
     135                 :            : {
     136                 :         14 :     fb_symbol_table_visit(&scope->symbol_index, install_symbol, context);
     137                 :         14 : }
     138                 :            : 
     139                 :         72 : static int compare_entries(const void *x, const void *y)
     140                 :            : {
     141                 :         72 :     return strcmp(((const entry_t *)x)->name, ((const entry_t *)y)->name);
     142                 :            : }
     143                 :            : 
     144                 :         10 : static void sort_entries(entry_t *entries, int count)
     145                 :            : {
     146                 :            :     int i;
     147                 :            : 
     148                 :         10 :     qsort(entries, count, sizeof(entries[0]), compare_entries);
     149                 :            : 
     150         [ +  + ]:         51 :     for (i = 0; i < count; ++i) {
     151                 :         41 :         entries[i].ct->export_index = (size_t)i;
     152                 :            :     }
     153                 :         10 : }
     154                 :            : 
     155                 :          5 : static void clear_catalog(catalog_t *catalog)
     156                 :            : {
     157         [ +  - ]:          5 :     if (catalog->objects) {
     158                 :          5 :         free(catalog->objects);
     159                 :            :     }
     160         [ +  - ]:          5 :     if (catalog->enums) {
     161                 :          5 :         free(catalog->enums);
     162                 :            :     }
     163         [ +  - ]:          5 :     if (catalog->name_table) {
     164                 :          5 :         free(catalog->name_table);
     165                 :            :     }
     166                 :          5 :     memset(catalog, 0, sizeof(*catalog));
     167                 :          5 : }
     168                 :            : 
     169                 :          5 : static int build_catalog(catalog_t *catalog, fb_schema_t *schema, int qualify_names, fb_scope_table_t *index)
     170                 :            : {
     171                 :          5 :     memset(catalog, 0, sizeof(*catalog));
     172                 :          5 :     catalog->qualify_names = qualify_names;
     173                 :          5 :     catalog->schema = schema;
     174                 :            : 
     175                 :            :     /* Build support datastructures before export. */
     176                 :          5 :     fb_scope_table_visit(index, count_symbols, catalog);
     177                 :          5 :     catalog->objects = calloc(catalog->nobjects, sizeof(catalog->objects[0]));
     178                 :          5 :     catalog->enums = calloc(catalog->nenums, sizeof(catalog->enums[0]));
     179                 :          5 :     catalog->name_table = malloc(catalog->name_table_size);
     180                 :          5 :     catalog->next_object = catalog->objects;
     181                 :          5 :     catalog->next_enum = catalog->enums;
     182                 :          5 :     catalog->next_name = catalog->name_table;
     183 [ -  + ][ #  # ]:          5 :     if ((!catalog->objects && catalog->nobjects > 0) ||
                 [ -  + ]
     184 [ #  # ][ -  + ]:          5 :         (!catalog->enums && catalog->nenums > 0) ||
     185         [ #  # ]:          0 :         (!catalog->name_table && catalog->name_table_size > 0)) {
     186                 :          0 :         clear_catalog(catalog);
     187                 :          0 :         return -1;
     188                 :            :     }
     189                 :          5 :     fb_scope_table_visit(index, install_symbols, catalog);
     190                 :            :     /* Presort objects and enums because the sorted index is required in Type tables. */
     191                 :          5 :     sort_entries(catalog->objects, catalog->nobjects);
     192                 :          5 :     sort_entries(catalog->enums, catalog->nenums);
     193                 :          5 :     return 0;
     194                 :            : }
     195                 :            : 
     196                 :            : #endif /* CATALOG_H */

Generated by: LCOV version 1.12