LCOV - differential code coverage report
Current view: top level - src/interfaces/ecpg/preproc - variable.c (source / functions) Coverage Total Hit LBC UIC UBC GBC GIC GNC CBC EUB ECB DCB
Current: Differential Code Coverage HEAD vs 15 Lines: 71.2 % 285 203 5 5 72 6 23 6 168 4 28 2
Current Date: 2023-04-08 15:15:32 Functions: 100.0 % 15 15 1 1 13 1 1
Baseline: 15
Baseline Date: 2023-04-08 15:09:40
Legend: Lines: hit not hit

           TLA  Line data    Source code
       1                 : /* src/interfaces/ecpg/preproc/variable.c */
       2                 : 
       3                 : #include "postgres_fe.h"
       4                 : 
       5                 : #include "preproc_extern.h"
       6                 : 
       7                 : static struct variable *allvariables = NULL;
       8                 : 
       9                 : struct variable *
      10 CBC         479 : new_variable(const char *name, struct ECPGtype *type, int brace_level)
      11                 : {
      12             479 :     struct variable *p = (struct variable *) mm_alloc(sizeof(struct variable));
      13                 : 
      14             479 :     p->name = mm_strdup(name);
      15             479 :     p->type = type;
      16             479 :     p->brace_level = brace_level;
      17                 : 
      18             479 :     p->next = allvariables;
      19             479 :     allvariables = p;
      20                 : 
      21             479 :     return p;
      22                 : }
      23                 : 
      24                 : static struct variable *
      25              29 : find_struct_member(char *name, char *str, struct ECPGstruct_member *members, int brace_level)
      26                 : {
      27              29 :     char       *next = strpbrk(++str, ".-["),
      28                 :                *end,
      29              29 :                 c = '\0';
      30                 : 
      31              29 :     if (next != NULL)
      32                 :     {
      33 UBC           0 :         c = *next;
      34               0 :         *next = '\0';
      35                 :     }
      36                 : 
      37 CBC          56 :     for (; members; members = members->next)
      38                 :     {
      39              56 :         if (strcmp(members->name, str) == 0)
      40                 :         {
      41              29 :             if (next == NULL)
      42                 :             {
      43                 :                 /* found the end */
      44              29 :                 switch (members->type->type)
      45                 :                 {
      46 UBC           0 :                     case ECPGt_array:
      47               0 :                         return new_variable(name, ECPGmake_array_type(ECPGmake_simple_type(members->type->u.element->type, members->type->u.element->size, members->type->u.element->counter), members->type->size), brace_level);
      48               0 :                     case ECPGt_struct:
      49                 :                     case ECPGt_union:
      50               0 :                         return new_variable(name, ECPGmake_struct_type(members->type->u.members, members->type->type, members->type->type_name, members->type->struct_sizeof), brace_level);
      51 CBC          29 :                     default:
      52              29 :                         return new_variable(name, ECPGmake_simple_type(members->type->type, members->type->size, members->type->counter), brace_level);
      53                 :                 }
      54                 :             }
      55                 :             else
      56                 :             {
      57 UBC           0 :                 *next = c;
      58               0 :                 if (c == '[')
      59                 :                 {
      60                 :                     int         count;
      61                 : 
      62                 :                     /*
      63                 :                      * We don't care about what's inside the array braces so
      64                 :                      * just eat up the character
      65                 :                      */
      66               0 :                     for (count = 1, end = next + 1; count; end++)
      67                 :                     {
      68               0 :                         switch (*end)
      69                 :                         {
      70               0 :                             case '[':
      71               0 :                                 count++;
      72               0 :                                 break;
      73               0 :                             case ']':
      74               0 :                                 count--;
      75               0 :                                 break;
      76               0 :                             default:
      77               0 :                                 break;
      78                 :                         }
      79                 :                     }
      80                 :                 }
      81                 :                 else
      82               0 :                     end = next;
      83                 : 
      84               0 :                 switch (*end)
      85                 :                 {
      86               0 :                     case '\0':  /* found the end, but this time it has to be
      87                 :                                  * an array element */
      88               0 :                         if (members->type->type != ECPGt_array)
      89               0 :                             mmfatal(PARSE_ERROR, "incorrectly formed variable \"%s\"", name);
      90                 : 
      91               0 :                         switch (members->type->u.element->type)
      92                 :                         {
      93               0 :                             case ECPGt_array:
      94               0 :                                 return new_variable(name, ECPGmake_array_type(ECPGmake_simple_type(members->type->u.element->u.element->type, members->type->u.element->u.element->size, members->type->u.element->u.element->counter), members->type->u.element->size), brace_level);
      95               0 :                             case ECPGt_struct:
      96                 :                             case ECPGt_union:
      97               0 :                                 return new_variable(name, ECPGmake_struct_type(members->type->u.element->u.members, members->type->u.element->type, members->type->u.element->type_name, members->type->u.element->struct_sizeof), brace_level);
      98               0 :                             default:
      99               0 :                                 return new_variable(name, ECPGmake_simple_type(members->type->u.element->type, members->type->u.element->size, members->type->u.element->counter), brace_level);
     100                 :                         }
     101                 :                         break;
     102               0 :                     case '-':
     103               0 :                         if (members->type->type == ECPGt_array)
     104               0 :                             return find_struct_member(name, ++end, members->type->u.element->u.members, brace_level);
     105                 :                         else
     106               0 :                             return find_struct_member(name, ++end, members->type->u.members, brace_level);
     107                 :                         break;
     108                 :                         break;
     109               0 :                     case '.':
     110               0 :                         if (members->type->type == ECPGt_array)
     111               0 :                             return find_struct_member(name, end, members->type->u.element->u.members, brace_level);
     112                 :                         else
     113               0 :                             return find_struct_member(name, end, members->type->u.members, brace_level);
     114                 :                         break;
     115               0 :                     default:
     116               0 :                         mmfatal(PARSE_ERROR, "incorrectly formed variable \"%s\"", name);
     117                 :                         break;
     118                 :                 }
     119                 :             }
     120                 :         }
     121                 :     }
     122                 : 
     123               0 :     return NULL;
     124                 : }
     125                 : 
     126                 : static struct variable *
     127 CBC          29 : find_struct(char *name, char *next, char *end)
     128                 : {
     129                 :     struct variable *p;
     130              29 :     char        c = *next;
     131                 : 
     132                 :     /* first get the mother structure entry */
     133              29 :     *next = '\0';
     134              29 :     p = find_variable(name);
     135                 : 
     136              29 :     if (c == '-')
     137                 :     {
     138 UBC           0 :         if (p->type->type != ECPGt_array)
     139               0 :             mmfatal(PARSE_ERROR, "variable \"%s\" is not a pointer", name);
     140                 : 
     141               0 :         if (p->type->u.element->type != ECPGt_struct && p->type->u.element->type != ECPGt_union)
     142               0 :             mmfatal(PARSE_ERROR, "variable \"%s\" is not a pointer to a structure or a union", name);
     143                 : 
     144                 :         /* restore the name, we will need it later */
     145               0 :         *next = c;
     146                 : 
     147               0 :         return find_struct_member(name, ++end, p->type->u.element->u.members, p->brace_level);
     148                 :     }
     149                 :     else
     150                 :     {
     151 CBC          29 :         if (next == end)
     152                 :         {
     153              29 :             if (p->type->type != ECPGt_struct && p->type->type != ECPGt_union)
     154 UBC           0 :                 mmfatal(PARSE_ERROR, "variable \"%s\" is neither a structure nor a union", name);
     155                 : 
     156                 :             /* restore the name, we will need it later */
     157 CBC          29 :             *next = c;
     158                 : 
     159              29 :             return find_struct_member(name, end, p->type->u.members, p->brace_level);
     160                 :         }
     161                 :         else
     162                 :         {
     163 UBC           0 :             if (p->type->type != ECPGt_array)
     164               0 :                 mmfatal(PARSE_ERROR, "variable \"%s\" is not an array", name);
     165                 : 
     166               0 :             if (p->type->u.element->type != ECPGt_struct && p->type->u.element->type != ECPGt_union)
     167               0 :                 mmfatal(PARSE_ERROR, "variable \"%s\" is not a pointer to a structure or a union", name);
     168                 : 
     169                 :             /* restore the name, we will need it later */
     170               0 :             *next = c;
     171                 : 
     172               0 :             return find_struct_member(name, end, p->type->u.element->u.members, p->brace_level);
     173                 :         }
     174                 :     }
     175                 : }
     176                 : 
     177                 : static struct variable *
     178 CBC        1316 : find_simple(char *name)
     179                 : {
     180                 :     struct variable *p;
     181                 : 
     182           10572 :     for (p = allvariables; p; p = p->next)
     183                 :     {
     184           10572 :         if (strcmp(p->name, name) == 0)
     185            1316 :             return p;
     186                 :     }
     187                 : 
     188 UBC           0 :     return NULL;
     189                 : }
     190                 : 
     191                 : /* Note that this function will end the program in case of an unknown */
     192                 : /* variable */
     193                 : struct variable *
     194 CBC        1345 : find_variable(char *name)
     195                 : {
     196                 :     char       *next,
     197                 :                *end;
     198                 :     struct variable *p;
     199                 :     int         count;
     200                 : 
     201            1345 :     next = strpbrk(name, ".[-");
     202            1345 :     if (next)
     203                 :     {
     204             129 :         if (*next == '[')
     205                 :         {
     206                 :             /*
     207                 :              * We don't care about what's inside the array braces so just eat
     208                 :              * up the characters
     209                 :              */
     210             300 :             for (count = 1, end = next + 1; count; end++)
     211                 :             {
     212             200 :                 switch (*end)
     213                 :                 {
     214 UBC           0 :                     case '[':
     215               0 :                         count++;
     216               0 :                         break;
     217 CBC         100 :                     case ']':
     218             100 :                         count--;
     219             100 :                         break;
     220             100 :                     default:
     221             100 :                         break;
     222                 :                 }
     223                 :             }
     224             100 :             if (*end == '.')
     225 UBC           0 :                 p = find_struct(name, next, end);
     226                 :             else
     227                 :             {
     228 CBC         100 :                 char        c = *next;
     229                 : 
     230             100 :                 *next = '\0';
     231             100 :                 p = find_simple(name);
     232             100 :                 if (p == NULL)
     233 UBC           0 :                     mmfatal(PARSE_ERROR, "variable \"%s\" is not declared", name);
     234                 : 
     235 CBC         100 :                 *next = c;
     236             100 :                 switch (p->type->u.element->type)
     237                 :                 {
     238 UBC           0 :                     case ECPGt_array:
     239               0 :                         return new_variable(name, ECPGmake_array_type(ECPGmake_simple_type(p->type->u.element->u.element->type, p->type->u.element->u.element->size, p->type->u.element->u.element->counter), p->type->u.element->size), p->brace_level);
     240 CBC           3 :                     case ECPGt_struct:
     241                 :                     case ECPGt_union:
     242               3 :                         return new_variable(name, ECPGmake_struct_type(p->type->u.element->u.members, p->type->u.element->type, p->type->u.element->type_name, p->type->u.element->struct_sizeof), p->brace_level);
     243              97 :                     default:
     244              97 :                         return new_variable(name, ECPGmake_simple_type(p->type->u.element->type, p->type->u.element->size, p->type->u.element->counter), p->brace_level);
     245                 :                 }
     246                 :             }
     247                 :         }
     248                 :         else
     249              29 :             p = find_struct(name, next, next);
     250                 :     }
     251                 :     else
     252            1216 :         p = find_simple(name);
     253                 : 
     254            1245 :     if (p == NULL)
     255 UBC           0 :         mmfatal(PARSE_ERROR, "variable \"%s\" is not declared", name);
     256                 : 
     257 CBC        1245 :     return p;
     258                 : }
     259                 : 
     260                 : void
     261             326 : remove_typedefs(int brace_level)
     262                 : {
     263                 :     struct typedefs *p,
     264                 :                *prev;
     265                 : 
     266             479 :     for (p = prev = types; p;)
     267                 :     {
     268             153 :         if (p->brace_level >= brace_level)
     269                 :         {
     270                 :             /* remove it */
     271              13 :             if (p == types)
     272              13 :                 prev = types = p->next;
     273                 :             else
     274 UBC           0 :                 prev->next = p->next;
     275                 : 
     276 CBC          13 :             if (p->type->type_enum == ECPGt_struct || p->type->type_enum == ECPGt_union)
     277              12 :                 free(p->struct_member_list);
     278              13 :             free(p->type);
     279              13 :             free(p->name);
     280              13 :             free(p);
     281              13 :             if (prev == types)
     282              13 :                 p = types;
     283                 :             else
     284 UBC           0 :                 p = prev ? prev->next : NULL;
     285                 :         }
     286                 :         else
     287                 :         {
     288 CBC         140 :             prev = p;
     289             140 :             p = prev->next;
     290                 :         }
     291                 :     }
     292             326 : }
     293                 : 
     294                 : void
     295             326 : remove_variables(int brace_level)
     296                 : {
     297                 :     struct variable *p,
     298                 :                *prev;
     299                 : 
     300            1547 :     for (p = prev = allvariables; p;)
     301                 :     {
     302            1221 :         if (p->brace_level >= brace_level)
     303                 :         {
     304                 :             /* is it still referenced by a cursor? */
     305                 :             struct cursor *ptr;
     306                 : 
     307             748 :             for (ptr = cur; ptr != NULL; ptr = ptr->next)
     308                 :             {
     309                 :                 struct arguments *varptr,
     310                 :                            *prevvar;
     311                 : 
     312             610 :                 for (varptr = prevvar = ptr->argsinsert; varptr != NULL; varptr = varptr->next)
     313                 :                 {
     314             253 :                     if (p == varptr->variable)
     315                 :                     {
     316                 :                         /* remove from list */
     317              10 :                         if (varptr == ptr->argsinsert)
     318               7 :                             ptr->argsinsert = varptr->next;
     319                 :                         else
     320               3 :                             prevvar->next = varptr->next;
     321                 :                     }
     322                 :                 }
     323             362 :                 for (varptr = prevvar = ptr->argsresult; varptr != NULL; varptr = varptr->next)
     324                 :                 {
     325               5 :                     if (p == varptr->variable)
     326                 :                     {
     327                 :                         /* remove from list */
     328               3 :                         if (varptr == ptr->argsresult)
     329               3 :                             ptr->argsresult = varptr->next;
     330                 :                         else
     331 UBC           0 :                             prevvar->next = varptr->next;
     332                 :                     }
     333                 :                 }
     334                 :             }
     335                 : 
     336                 :             /* remove it */
     337 CBC         391 :             if (p == allvariables)
     338             230 :                 prev = allvariables = p->next;
     339                 :             else
     340             161 :                 prev->next = p->next;
     341                 : 
     342             391 :             ECPGfree_type(p->type);
     343             391 :             free(p->name);
     344             391 :             free(p);
     345             391 :             if (prev == allvariables)
     346             258 :                 p = allvariables;
     347                 :             else
     348             133 :                 p = prev ? prev->next : NULL;
     349                 :         }
     350                 :         else
     351                 :         {
     352             830 :             prev = p;
     353             830 :             p = prev->next;
     354                 :         }
     355                 :     }
     356             326 : }
     357                 : 
     358                 : 
     359                 : /*
     360                 :  * Here are the variables that need to be handled on every request.
     361                 :  * These are of two kinds: input and output.
     362                 :  * I will make two lists for them.
     363                 :  */
     364                 : 
     365                 : struct arguments *argsinsert = NULL;
     366                 : struct arguments *argsresult = NULL;
     367                 : 
     368                 : void
     369            1917 : reset_variables(void)
     370                 : {
     371            1917 :     argsinsert = NULL;
     372            1917 :     argsresult = NULL;
     373            1917 : }
     374                 : 
     375                 : /* Insert a new variable into our request list.
     376                 :  * Note: The list is dumped from the end,
     377                 :  * so we have to add new entries at the beginning */
     378                 : void
     379             480 : add_variable_to_head(struct arguments **list, struct variable *var, struct variable *ind)
     380                 : {
     381             480 :     struct arguments *p = (struct arguments *) mm_alloc(sizeof(struct arguments));
     382                 : 
     383             480 :     p->variable = var;
     384             480 :     p->indicator = ind;
     385             480 :     p->next = *list;
     386             480 :     *list = p;
     387             480 : }
     388                 : 
     389                 : /* Append a new variable to our request list. */
     390                 : void
     391              93 : add_variable_to_tail(struct arguments **list, struct variable *var, struct variable *ind)
     392                 : {
     393                 :     struct arguments *p,
     394              93 :                *new = (struct arguments *) mm_alloc(sizeof(struct arguments));
     395                 : 
     396             100 :     for (p = *list; p && p->next; p = p->next);
     397                 : 
     398              93 :     new->variable = var;
     399              93 :     new->indicator = ind;
     400              93 :     new->next = NULL;
     401                 : 
     402              93 :     if (p)
     403              26 :         p->next = new;
     404                 :     else
     405              67 :         *list = new;
     406              93 : }
     407                 : 
     408                 : void
     409              17 : remove_variable_from_list(struct arguments **list, struct variable *var)
     410                 : {
     411                 :     struct arguments *p,
     412              17 :                *prev = NULL;
     413              17 :     bool        found = false;
     414                 : 
     415              17 :     for (p = *list; p; p = p->next)
     416                 :     {
     417              17 :         if (p->variable == var)
     418                 :         {
     419              17 :             found = true;
     420              17 :             break;
     421                 :         }
     422 UBC           0 :         prev = p;
     423                 :     }
     424 CBC          17 :     if (found)
     425                 :     {
     426              17 :         if (prev)
     427 UBC           0 :             prev->next = p->next;
     428                 :         else
     429 CBC          17 :             *list = p->next;
     430                 :     }
     431              17 : }
     432                 : 
     433                 : /* Dump out a list of all the variable on this list.
     434                 :    This is a recursive function that works from the end of the list and
     435                 :    deletes the list as we go on.
     436                 :  */
     437                 : void
     438            1561 : dump_variables(struct arguments *list, int mode)
     439                 : {
     440                 :     char       *str_zero;
     441                 : 
     442            1561 :     if (list == NULL)
     443            1071 :         return;
     444                 : 
     445             490 :     str_zero = mm_strdup("0");
     446                 : 
     447                 :     /*
     448                 :      * The list is build up from the beginning so lets first dump the end of
     449                 :      * the list:
     450                 :      */
     451                 : 
     452             490 :     dump_variables(list->next, mode);
     453                 : 
     454                 :     /* Then the current element and its indicator */
     455             490 :     ECPGdump_a_type(base_yyout, list->variable->name, list->variable->type, list->variable->brace_level,
     456             490 :                     list->indicator->name, list->indicator->type, list->indicator->brace_level,
     457                 :                     NULL, NULL, str_zero, NULL, NULL);
     458                 : 
     459                 :     /* Then release the list element. */
     460             490 :     if (mode != 0)
     461             490 :         free(list);
     462                 : 
     463             490 :     free(str_zero);
     464                 : }
     465                 : 
     466                 : void
     467              67 : check_indicator(struct ECPGtype *var)
     468                 : {
     469                 :     /* make sure this is a valid indicator variable */
     470              67 :     switch (var->type)
     471                 :     {
     472                 :             struct ECPGstruct_member *p;
     473                 : 
     474              45 :         case ECPGt_short:
     475                 :         case ECPGt_int:
     476                 :         case ECPGt_long:
     477                 :         case ECPGt_long_long:
     478                 :         case ECPGt_unsigned_short:
     479                 :         case ECPGt_unsigned_int:
     480                 :         case ECPGt_unsigned_long:
     481                 :         case ECPGt_unsigned_long_long:
     482              45 :             break;
     483                 : 
     484              11 :         case ECPGt_struct:
     485                 :         case ECPGt_union:
     486              36 :             for (p = var->u.members; p; p = p->next)
     487              25 :                 check_indicator(p->type);
     488              11 :             break;
     489                 : 
     490              11 :         case ECPGt_array:
     491              11 :             check_indicator(var->u.element);
     492              11 :             break;
     493 UBC           0 :         default:
     494               0 :             mmerror(PARSE_ERROR, ET_ERROR, "indicator variable must have an integer type");
     495               0 :             break;
     496                 :     }
     497 CBC          67 : }
     498                 : 
     499                 : struct typedefs *
     500 GNC        5392 : get_typedef(const char *name, bool noerror)
     501                 : {
     502                 :     struct typedefs *this;
     503                 : 
     504            8789 :     for (this = types; this != NULL; this = this->next)
     505                 :     {
     506            3427 :         if (strcmp(this->name, name) == 0)
     507              30 :             return this;
     508                 :     }
     509                 : 
     510            5362 :     if (!noerror)
     511 LBC           0 :         mmfatal(PARSE_ERROR, "unrecognized data type name \"%s\"", name);
     512 ECB             : 
     513 GNC        5362 :     return NULL;
     514                 : }
     515 ECB             : 
     516 EUB             : void
     517 GIC         371 : adjust_array(enum ECPGttype type_enum, char **dimension, char **length, char *type_dimension, char *type_index, int pointer_len, bool type_definition)
     518 ECB             : {
     519 GIC         371 :     if (atoi(type_index) >= 0)
     520                 :     {
     521               6 :         if (atoi(*length) >= 0)
     522 LBC           0 :             mmfatal(PARSE_ERROR, "multidimensional arrays are not supported");
     523                 : 
     524 CBC           6 :         *length = type_index;
     525                 :     }
     526 ECB             : 
     527 GBC         371 :     if (atoi(type_dimension) >= 0)
     528                 :     {
     529 CBC           1 :         if (atoi(*dimension) >= 0 && atoi(*length) >= 0)
     530 UIC           0 :             mmfatal(PARSE_ERROR, "multidimensional arrays are not supported");
     531                 : 
     532 CBC           1 :         if (atoi(*dimension) >= 0)
     533 UIC           0 :             *length = *dimension;
     534 ECB             : 
     535 GBC           1 :         *dimension = type_dimension;
     536                 :     }
     537 ECB             : 
     538 GBC         371 :     if (pointer_len > 2)
     539 UIC           0 :         mmfatal(PARSE_ERROR, ngettext("multilevel pointers (more than 2 levels) are not supported; found %d level",
     540 ECB             :                                       "multilevel pointers (more than 2 levels) are not supported; found %d levels", pointer_len),
     541                 :                 pointer_len);
     542                 : 
     543 CBC         371 :     if (pointer_len > 1 && type_enum != ECPGt_char && type_enum != ECPGt_unsigned_char && type_enum != ECPGt_string)
     544 UBC           0 :         mmfatal(PARSE_ERROR, "pointer to pointer is not supported for this data type");
     545                 : 
     546 GIC         371 :     if (pointer_len > 1 && (atoi(*length) >= 0 || atoi(*dimension) >= 0))
     547 UIC           0 :         mmfatal(PARSE_ERROR, "multidimensional arrays are not supported");
     548 ECB             : 
     549 GBC         371 :     if (atoi(*length) >= 0 && atoi(*dimension) >= 0 && pointer_len)
     550 UIC           0 :         mmfatal(PARSE_ERROR, "multidimensional arrays are not supported");
     551 ECB             : 
     552 GBC         371 :     switch (type_enum)
     553                 :     {
     554 CBC          34 :         case ECPGt_struct:
     555 EUB             :         case ECPGt_union:
     556                 :             /* pointer has to get dimension 0 */
     557 CBC          34 :             if (pointer_len)
     558                 :             {
     559               9 :                 *length = *dimension;
     560 GIC           9 :                 *dimension = mm_strdup("0");
     561                 :             }
     562 ECB             : 
     563 GIC          34 :             if (atoi(*length) >= 0)
     564 LBC           0 :                 mmfatal(PARSE_ERROR, "multidimensional arrays for structures are not supported");
     565 ECB             : 
     566 GIC          34 :             break;
     567              23 :         case ECPGt_varchar:
     568 ECB             :         case ECPGt_bytea:
     569 EUB             :             /* pointer has to get dimension 0 */
     570 GIC          23 :             if (pointer_len)
     571 LBC           0 :                 *dimension = mm_strdup("0");
     572 ECB             : 
     573                 :             /* one index is the string length */
     574 GIC          23 :             if (atoi(*length) < 0)
     575 ECB             :             {
     576 GBC          15 :                 *length = *dimension;
     577 GIC          15 :                 *dimension = mm_strdup("-1");
     578                 :             }
     579 ECB             : 
     580 GIC          23 :             break;
     581 CBC         118 :         case ECPGt_char:
     582 ECB             :         case ECPGt_unsigned_char:
     583                 :         case ECPGt_string:
     584                 :             /* char ** */
     585 CBC         118 :             if (pointer_len == 2)
     586 ECB             :             {
     587 GIC           8 :                 *length = *dimension = mm_strdup("0");
     588               8 :                 break;
     589                 :             }
     590 ECB             : 
     591                 :             /* pointer has to get length 0 */
     592 CBC         110 :             if (pointer_len == 1)
     593              36 :                 *length = mm_strdup("0");
     594                 : 
     595                 :             /* one index is the string length */
     596 GIC         110 :             if (atoi(*length) < 0)
     597 ECB             :             {
     598                 :                 /*
     599                 :                  * make sure we return length = -1 for arrays without given
     600                 :                  * bounds
     601                 :                  */
     602 GIC          64 :                 if (atoi(*dimension) < 0 && !type_definition)
     603                 : 
     604                 :                     /*
     605                 :                      * do not change this for typedefs since it will be
     606                 :                      * changed later on when the variable is defined
     607 ECB             :                      */
     608 GIC           5 :                     *length = mm_strdup("1");
     609              59 :                 else if (strcmp(*dimension, "0") == 0)
     610               2 :                     *length = mm_strdup("-1");
     611                 :                 else
     612              57 :                     *length = *dimension;
     613 ECB             : 
     614 CBC          64 :                 *dimension = mm_strdup("-1");
     615 ECB             :             }
     616 GIC         110 :             break;
     617 CBC         196 :         default:
     618                 :             /* a pointer has dimension = 0 */
     619             196 :             if (pointer_len)
     620                 :             {
     621              19 :                 *length = *dimension;
     622              19 :                 *dimension = mm_strdup("0");
     623                 :             }
     624 ECB             : 
     625 GIC         196 :             if (atoi(*length) >= 0)
     626 LBC           0 :                 mmfatal(PARSE_ERROR, "multidimensional arrays for simple data types are not supported");
     627 ECB             : 
     628 GIC         196 :             break;
     629                 :     }
     630 CBC         371 : }
        

Generated by: LCOV version v1.16-55-g56c0a2a