LCOV - differential code coverage report
Current view: top level - src/interfaces/ecpg/preproc - variable.c (source / functions) Coverage Total Hit UNC UBC GBC GNC CBC DUB DCB
Current: 7a15cff1f11193467898da1c1fabf06fd2caee04 vs 84a3778c79c2d28b4dc281d03ef2ab019b16483b Lines: 79.3 % 300 238 7 55 18 17 203 13 14
Current Date: 2025-12-15 18:36:29 -0500 Functions: 100.0 % 16 16 4 12 2
Baseline: lcov-20251216-010103-baseline Branches: 70.3 % 202 142 1 59 14 5 123
Baseline Date: 2025-12-15 13:30:48 -0800 Line coverage date bins:
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
(7,30] days: 70.8 % 24 17 7 17
(30,360] days: 0.0 % 1 0 1
(360..) days: 80.4 % 275 221 54 18 203
Function coverage date bins:
(7,30] days: 100.0 % 3 3 3
(360..) days: 100.0 % 13 13 1 12
Branch coverage date bins:
(7,30] days: 83.3 % 6 5 1 5
(360..) days: 69.9 % 196 137 59 14 123

 Age         Owner                    Branch data    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                 :                : /* this probably belongs in util.c, but for now it's only needed here */
                                 10                 :                : static char *
    9 tgl@sss.pgh.pa.us          11                 :GNC         165 : loc_nstrdup(const char *in, size_t len)
                                 12                 :                : {
                                 13                 :                :     char       *out;
                                 14                 :                : 
                                 15                 :            165 :     out = loc_alloc(len + 1);
                                 16                 :            165 :     memcpy(out, in, len);
                                 17                 :            165 :     out[len] = '\0';
                                 18                 :                : 
                                 19                 :            165 :     return out;
                                 20                 :                : }
                                 21                 :                : 
                                 22                 :                : struct variable *
 3100 tgl@sss.pgh.pa.us          23                 :CBC         520 : new_variable(const char *name, struct ECPGtype *type, int brace_level)
                                 24                 :                : {
 9379 bruce@momjian.us           25                 :            520 :     struct variable *p = (struct variable *) mm_alloc(sizeof(struct variable));
                                 26                 :                : 
                                 27                 :            520 :     p->name = mm_strdup(name);
                                 28                 :            520 :     p->type = type;
 8738 meskes@postgresql.or       29                 :            520 :     p->brace_level = brace_level;
                                 30                 :                : 
 9379 bruce@momjian.us           31                 :            520 :     p->next = allvariables;
                                 32                 :            520 :     allvariables = p;
                                 33                 :                : 
 3043 peter_e@gmx.net            34                 :            520 :     return p;
                                 35                 :                : }
                                 36                 :                : 
                                 37                 :                : /*
                                 38                 :                :  * Perform lookup of a field within a struct
                                 39                 :                :  *
                                 40                 :                :  * 'name' is the entire C variable name
                                 41                 :                :  * 'str' points just before the next field name to parse
                                 42                 :                :  * 'members' and 'brace_level' describe the struct we are looking into
                                 43                 :                :  *
                                 44                 :                :  * Returns NULL if field is not found.
                                 45                 :                :  *
                                 46                 :                :  * This recurses if needed to handle sub-fields.
                                 47                 :                :  */
                                 48                 :                : static struct variable *
    9 tgl@sss.pgh.pa.us          49                 :GNC          65 : find_struct_member(const char *name, const char *str,
                                 50                 :                :                    struct ECPGstruct_member *members, int brace_level)
                                 51                 :                : {
                                 52                 :                :     /* ++ here skips over the '.', or the '>' of '->' */
                                 53                 :             65 :     const char *next = strpbrk(++str, ".-["),
                                 54                 :                :                *end,
                                 55                 :                :                *field;
                                 56                 :                : 
 9379 bruce@momjian.us           57         [ +  + ]:CBC          65 :     if (next != NULL)
    9 tgl@sss.pgh.pa.us          58                 :GNC          12 :         field = loc_nstrdup(str, next - str);
                                 59                 :                :     else
                                 60                 :             53 :         field = str;
                                 61                 :                : 
 9379 bruce@momjian.us           62         [ +  - ]:CBC         104 :     for (; members; members = members->next)
                                 63                 :                :     {
    9 tgl@sss.pgh.pa.us          64         [ +  + ]:GNC         104 :         if (strcmp(members->name, field) == 0)
                                 65                 :                :         {
 8237 meskes@postgresql.or       66         [ +  + ]:CBC          65 :             if (next == NULL)
                                 67                 :                :             {
                                 68                 :                :                 /* found the end */
 8759                            69      [ -  -  + ]:             53 :                 switch (members->type->type)
                                 70                 :                :                 {
 9379 bruce@momjian.us           71                 :UBC           0 :                     case ECPGt_array:
 3043 peter_e@gmx.net            72                 :              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);
 9379 bruce@momjian.us           73                 :              0 :                     case ECPGt_struct:
                                 74                 :                :                     case ECPGt_union:
 3043 peter_e@gmx.net            75                 :              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);
 9379 bruce@momjian.us           76                 :CBC          53 :                     default:
 3043 peter_e@gmx.net            77                 :             53 :                         return new_variable(name, ECPGmake_simple_type(members->type->type, members->type->size, members->type->counter), brace_level);
                                 78                 :                :                 }
                                 79                 :                :             }
                                 80                 :                :             else
                                 81                 :                :             {
    9 tgl@sss.pgh.pa.us          82         [ +  - ]:GNC          12 :                 if (*next == '[')
                                 83                 :                :                 {
                                 84                 :                :                     int         count;
                                 85                 :                : 
                                 86                 :                :                     /*
                                 87                 :                :                      * We don't care about what's inside the array brackets so
                                 88                 :                :                      * just scan to find the matching right bracket.
                                 89                 :                :                      */
 8170 bruce@momjian.us           90         [ +  + ]:GBC          36 :                     for (count = 1, end = next + 1; count; end++)
                                 91                 :                :                     {
                                 92      [ -  +  + ]:             24 :                         switch (*end)
                                 93                 :                :                         {
 8170 bruce@momjian.us           94                 :UBC           0 :                             case '[':
                                 95                 :              0 :                                 count++;
                                 96                 :              0 :                                 break;
 8170 bruce@momjian.us           97                 :GBC          12 :                             case ']':
                                 98                 :             12 :                                 count--;
                                 99                 :             12 :                                 break;
                                100                 :             12 :                             default:
                                101                 :             12 :                                 break;
                                102                 :                :                         }
                                103                 :                :                     }
                                104                 :                :                 }
                                105                 :                :                 else
 8170 bruce@momjian.us          106                 :UBC           0 :                     end = next;
                                107                 :                : 
 8237 meskes@postgresql.or      108   [ -  -  +  - ]:GBC          12 :                 switch (*end)
                                109                 :                :                 {
 7367 bruce@momjian.us          110                 :UBC           0 :                     case '\0':  /* found the end, but this time it has to be
                                111                 :                :                                  * an array element */
 8170                           112         [ #  # ]:              0 :                         if (members->type->type != ECPGt_array)
 4417 peter_e@gmx.net           113                 :              0 :                             mmfatal(PARSE_ERROR, "incorrectly formed variable \"%s\"", name);
                                114                 :                : 
 8170 bruce@momjian.us          115      [ #  #  # ]:              0 :                         switch (members->type->u.element->type)
                                116                 :                :                         {
                                117                 :              0 :                             case ECPGt_array:
 3043 peter_e@gmx.net           118                 :              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);
 8170 bruce@momjian.us          119                 :              0 :                             case ECPGt_struct:
                                120                 :                :                             case ECPGt_union:
 3043 peter_e@gmx.net           121                 :              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);
 8170 bruce@momjian.us          122                 :              0 :                             default:
 3043 peter_e@gmx.net           123                 :              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);
                                124                 :                :                         }
                                125                 :                :                         break;
 8170 bruce@momjian.us          126                 :              0 :                     case '-':
 4765 meskes@postgresql.or      127         [ #  # ]:              0 :                         if (members->type->type == ECPGt_array)
 3043 peter_e@gmx.net           128                 :              0 :                             return find_struct_member(name, ++end, members->type->u.element->u.members, brace_level);
                                129                 :                :                         else
                                130                 :              0 :                             return find_struct_member(name, ++end, members->type->u.members, brace_level);
                                131                 :                :                         break;
 8170 bruce@momjian.us          132                 :GBC          12 :                     case '.':
 7993 meskes@postgresql.or      133         [ -  + ]:             12 :                         if (members->type->type == ECPGt_array)
 3043 peter_e@gmx.net           134                 :UBC           0 :                             return find_struct_member(name, end, members->type->u.element->u.members, brace_level);
                                135                 :                :                         else
 3043 peter_e@gmx.net           136                 :GBC          12 :                             return find_struct_member(name, end, members->type->u.members, brace_level);
                                137                 :                :                         break;
 8170 bruce@momjian.us          138                 :UBC           0 :                     default:
 4417 peter_e@gmx.net           139                 :              0 :                         mmfatal(PARSE_ERROR, "incorrectly formed variable \"%s\"", name);
                                140                 :                :                         break;
                                141                 :                :                 }
                                142                 :                :             }
                                143                 :                :         }
                                144                 :                :     }
                                145                 :                : 
 3043                           146                 :              0 :     return NULL;
                                147                 :                : }
                                148                 :                : 
                                149                 :                : /*
                                150                 :                :  * Do struct lookup when we have found var.field, var->field, or var[n].field
                                151                 :                :  *
                                152                 :                :  * 'name' is the entire C variable name
                                153                 :                :  * 'next' points at the character after the base name
                                154                 :                :  * 'end' points at the character after the subscript, if there was a
                                155                 :                :  * subscript, else it's the same as 'next'.
                                156                 :                :  *
                                157                 :                :  * This is used only at the first level of field reference; sub-fields will
                                158                 :                :  * be handled by internal recursion in find_struct_member.
                                159                 :                :  */
                                160                 :                : static struct variable *
    9 tgl@sss.pgh.pa.us         161                 :GNC          53 : find_struct(const char *name, const char *next, const char *end)
                                162                 :                : {
                                163                 :                :     char       *prefix;
                                164                 :                :     struct variable *p;
                                165                 :                : 
                                166                 :                :     /* first get the mother structure entry */
                                167                 :             53 :     prefix = loc_nstrdup(name, next - name);
                                168                 :             53 :     p = find_variable(prefix);
                                169                 :                : 
                                170         [ +  + ]:             53 :     if (*next == '-')
                                171                 :                :     {
                                172                 :                :         /* We have var->field */
 8759 meskes@postgresql.or      173         [ -  + ]:GBC           6 :         if (p->type->type != ECPGt_array)
    9 tgl@sss.pgh.pa.us         174                 :UNC           0 :             mmfatal(PARSE_ERROR, "variable \"%s\" is not a pointer", prefix);
                                175                 :                : 
 8759 meskes@postgresql.or      176   [ -  +  -  - ]:GBC           6 :         if (p->type->u.element->type != ECPGt_struct && p->type->u.element->type != ECPGt_union)
    9 tgl@sss.pgh.pa.us         177                 :UNC           0 :             mmfatal(PARSE_ERROR, "variable \"%s\" is not a pointer to a structure or a union", prefix);
                                178                 :                : 
 8224 meskes@postgresql.or      179                 :GBC           6 :         return find_struct_member(name, ++end, p->type->u.element->u.members, p->brace_level);
                                180                 :                :     }
                                181                 :                :     else
                                182                 :                :     {
 8237 meskes@postgresql.or      183         [ +  + ]:CBC          47 :         if (next == end)
                                184                 :                :         {
                                185                 :                :             /* We have var.field */
                                186   [ +  +  -  + ]:             41 :             if (p->type->type != ECPGt_struct && p->type->type != ECPGt_union)
    9 tgl@sss.pgh.pa.us         187                 :UNC           0 :                 mmfatal(PARSE_ERROR, "variable \"%s\" is neither a structure nor a union", prefix);
                                188                 :                : 
 8237 meskes@postgresql.or      189                 :CBC          41 :             return find_struct_member(name, end, p->type->u.members, p->brace_level);
                                190                 :                :         }
                                191                 :                :         else
                                192                 :                :         {
                                193                 :                :             /* We have var[n].field */
 8237 meskes@postgresql.or      194         [ -  + ]:GBC           6 :             if (p->type->type != ECPGt_array)
    9 tgl@sss.pgh.pa.us         195                 :UNC           0 :                 mmfatal(PARSE_ERROR, "variable \"%s\" is not an array", prefix);
                                196                 :                : 
 8237 meskes@postgresql.or      197   [ -  +  -  - ]:GBC           6 :             if (p->type->u.element->type != ECPGt_struct && p->type->u.element->type != ECPGt_union)
    9 tgl@sss.pgh.pa.us         198                 :UNC           0 :                 mmfatal(PARSE_ERROR, "variable \"%s\" is not a pointer to a structure or a union", prefix);
                                199                 :                : 
 8237 meskes@postgresql.or      200                 :GBC           6 :             return find_struct_member(name, end, p->type->u.element->u.members, p->brace_level);
                                201                 :                :         }
                                202                 :                :     }
                                203                 :                : }
                                204                 :                : 
                                205                 :                : /* Look up a variable given its base name */
                                206                 :                : static struct variable *
  428 tgl@sss.pgh.pa.us         207                 :CBC        1391 : find_simple(const char *name)
                                208                 :                : {
                                209                 :                :     struct variable *p;
                                210                 :                : 
 9379 bruce@momjian.us          211         [ +  - ]:          11503 :     for (p = allvariables; p; p = p->next)
                                212                 :                :     {
                                213         [ +  + ]:          11503 :         if (strcmp(p->name, name) == 0)
                                214                 :           1391 :             return p;
                                215                 :                :     }
                                216                 :                : 
 3043 peter_e@gmx.net           217                 :UBC           0 :     return NULL;
                                218                 :                : }
                                219                 :                : 
                                220                 :                : /*
                                221                 :                :  * Build a "struct variable" for a C variable reference.
                                222                 :                :  *
                                223                 :                :  * The given "name" string is a CVARIABLE per pgc.l, so it can include not
                                224                 :                :  * only a base variable name but also ".field", "->field", or "[subscript]"
                                225                 :                :  * decoration.  We don't need to understand that fully, because we always
                                226                 :                :  * duplicate the whole string into the name field of the result variable
                                227                 :                :  * and emit it literally to the output file; the C compiler will make sense
                                228                 :                :  * of it later.  What we do need to do here is identify the type of the
                                229                 :                :  * target field or array element so that we can attach a correct ECPGtype
                                230                 :                :  * struct to the result.
                                231                 :                :  *
                                232                 :                :  * Note that this function will end the program in case of an unknown variable.
                                233                 :                :  */
                                234                 :                : struct variable *
  428 tgl@sss.pgh.pa.us         235                 :CBC        1444 : find_variable(const char *name)
                                236                 :                : {
                                237                 :                :     const char *next,
                                238                 :                :                *end;
                                239                 :                :     struct variable *p;
                                240                 :                :     int         count;
                                241                 :                : 
 8237 meskes@postgresql.or      242                 :           1444 :     next = strpbrk(name, ".[-");
                                243         [ +  + ]:           1444 :     if (next)
                                244                 :                :     {
                                245                 :                :         /* Deal with field/subscript decoration */
                                246         [ +  + ]:            153 :         if (*next == '[')
                                247                 :                :         {
                                248                 :                :             /*
                                249                 :                :              * We don't care about what's inside the array brackets so just
                                250                 :                :              * scan to find the matching right bracket.
                                251                 :                :              */
 8170 bruce@momjian.us          252         [ +  + ]:            318 :             for (count = 1, end = next + 1; count; end++)
                                253                 :                :             {
                                254   [ -  +  -  + ]:            212 :                 switch (*end)
                                255                 :                :                 {
 8170 bruce@momjian.us          256                 :UBC           0 :                     case '[':
                                257                 :              0 :                         count++;
                                258                 :              0 :                         break;
 8170 bruce@momjian.us          259                 :CBC         106 :                     case ']':
                                260                 :            106 :                         count--;
                                261                 :            106 :                         break;
  426 tgl@sss.pgh.pa.us         262                 :UBC           0 :                     case '\0':
  235 peter@eisentraut.org      263                 :              0 :                         mmfatal(PARSE_ERROR, "unmatched bracket in variable \"%s\"", name);
                                264                 :                :                         break;
 8170 bruce@momjian.us          265                 :CBC         106 :                     default:
                                266                 :            106 :                         break;
                                267                 :                :                 }
                                268                 :                :             }
                                269         [ +  + ]:            106 :             if (*end == '.')
                                270                 :                :             {
                                271                 :                :                 /* We have var[n].field */
 8170 bruce@momjian.us          272                 :GBC           6 :                 p = find_struct(name, next, end);
                                273                 :                :             }
                                274                 :                :             else
                                275                 :                :             {
                                276                 :                :                 /*
                                277                 :                :                  * Note: this part assumes we must just have var[n] without
                                278                 :                :                  * any further decoration, which fails to handle cases such as
                                279                 :                :                  * var[n]->field.  For now, that's okay because
                                280                 :                :                  * pointer-to-pointer variables are rejected elsewhere.
                                281                 :                :                  */
    9 tgl@sss.pgh.pa.us         282                 :GNC         100 :                 char       *prefix = loc_nstrdup(name, next - name);
                                283                 :                : 
                                284                 :            100 :                 p = find_simple(prefix);
 7957 meskes@postgresql.or      285         [ -  + ]:CBC         100 :                 if (p == NULL)
    9 tgl@sss.pgh.pa.us         286                 :UNC           0 :                     mmfatal(PARSE_ERROR, "variable \"%s\" is not declared", prefix);
  425 tgl@sss.pgh.pa.us         287         [ -  + ]:CBC         100 :                 if (p->type->type != ECPGt_array)
    9 tgl@sss.pgh.pa.us         288                 :UNC           0 :                     mmfatal(PARSE_ERROR, "variable \"%s\" is not a pointer", prefix);
 8237 meskes@postgresql.or      289      [ -  +  + ]:CBC         100 :                 switch (p->type->u.element->type)
                                290                 :                :                 {
 8237 meskes@postgresql.or      291                 :UBC           0 :                     case ECPGt_array:
 3043 peter_e@gmx.net           292                 :              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);
 8237 meskes@postgresql.or      293                 :CBC           3 :                     case ECPGt_struct:
                                294                 :                :                     case ECPGt_union:
 3043 peter_e@gmx.net           295                 :              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);
 8237 meskes@postgresql.or      296                 :             97 :                     default:
 3043 peter_e@gmx.net           297                 :             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);
                                298                 :                :                 }
                                299                 :                :             }
                                300                 :                :         }
                                301                 :                :         else
                                302                 :                :         {
                                303                 :                :             /* Must be var.field or var->field */
 8170 bruce@momjian.us          304                 :             47 :             p = find_struct(name, next, next);
                                305                 :                :         }
                                306                 :                :     }
                                307                 :                :     else
                                308                 :           1291 :         p = find_simple(name);
                                309                 :                : 
 9379                           310         [ -  + ]:           1344 :     if (p == NULL)
 4417 peter_e@gmx.net           311                 :UBC           0 :         mmfatal(PARSE_ERROR, "variable \"%s\" is not declared", name);
                                312                 :                : 
 3043 peter_e@gmx.net           313                 :CBC        1344 :     return p;
                                314                 :                : }
                                315                 :                : 
                                316                 :                : void
 7842 meskes@postgresql.or      317                 :            331 : remove_typedefs(int brace_level)
                                318                 :                : {
                                319                 :                :     struct typedefs *p,
                                320                 :                :                *prev,
                                321                 :                :                *next;
                                322                 :                : 
  380 tgl@sss.pgh.pa.us         323         [ +  + ]:            495 :     for (p = types, prev = NULL; p; p = next)
                                324                 :                :     {
                                325                 :            164 :         next = p->next;
 7842 meskes@postgresql.or      326         [ +  + ]:            164 :         if (p->brace_level >= brace_level)
                                327                 :                :         {
                                328                 :                :             /* remove it */
  380 tgl@sss.pgh.pa.us         329         [ -  + ]:             14 :             if (prev)
  380 tgl@sss.pgh.pa.us         330                 :UBC           0 :                 prev->next = next;
                                331                 :                :             else
  380 tgl@sss.pgh.pa.us         332                 :CBC          14 :                 types = next;
                                333                 :                : 
 7779 bruce@momjian.us          334   [ +  +  -  + ]:             14 :             if (p->type->type_enum == ECPGt_struct || p->type->type_enum == ECPGt_union)
  384 tgl@sss.pgh.pa.us         335                 :             12 :                 ECPGfree_struct_member(p->struct_member_list);
                                336                 :             14 :             free(p->type->type_storage);
                                337                 :             14 :             free(p->type->type_str);
                                338                 :             14 :             free(p->type->type_dimension);
                                339                 :             14 :             free(p->type->type_index);
                                340                 :             14 :             free(p->type->type_sizeof);
 7842 meskes@postgresql.or      341                 :             14 :             free(p->type);
                                342                 :             14 :             free(p->name);
                                343                 :             14 :             free(p);
                                344                 :                :         }
                                345                 :                :         else
                                346                 :            150 :             prev = p;
                                347                 :                :     }
                                348                 :            331 : }
                                349                 :                : 
                                350                 :                : void
 9434                           351                 :            331 : remove_variables(int brace_level)
                                352                 :                : {
                                353                 :                :     struct variable *p,
                                354                 :                :                *prev,
                                355                 :                :                *next;
                                356                 :                : 
  380 tgl@sss.pgh.pa.us         357         [ +  + ]:           1673 :     for (p = allvariables, prev = NULL; p; p = next)
                                358                 :                :     {
                                359                 :           1342 :         next = p->next;
 9379 bruce@momjian.us          360         [ +  + ]:           1342 :         if (p->brace_level >= brace_level)
                                361                 :                :         {
                                362                 :                :             /* remove it, but first remove any references from cursors */
                                363                 :                :             struct cursor *ptr;
                                364                 :                : 
 8170                           365         [ +  + ]:            789 :             for (ptr = cur; ptr != NULL; ptr = ptr->next)
                                366                 :                :             {
                                367                 :                :                 struct arguments *varptr,
                                368                 :                :                            *prevvar,
                                369                 :                :                            *nextvar;
                                370                 :                : 
  380 tgl@sss.pgh.pa.us         371                 :            369 :                 for (varptr = ptr->argsinsert, prevvar = NULL;
                                372         [ +  + ]:            630 :                      varptr != NULL; varptr = nextvar)
                                373                 :                :                 {
  384                           374                 :            261 :                     nextvar = varptr->next;
 8224 meskes@postgresql.or      375         [ +  + ]:            261 :                     if (p == varptr->variable)
                                376                 :                :                     {
                                377                 :                :                         /* remove from list */
  380 tgl@sss.pgh.pa.us         378         [ +  + ]:             12 :                         if (prevvar)
                                379                 :              3 :                             prevvar->next = nextvar;
                                380                 :                :                         else
                                381                 :              9 :                             ptr->argsinsert = nextvar;
  384                           382                 :             12 :                         free(varptr);
                                383                 :                :                     }
                                384                 :                :                     else
  380                           385                 :            249 :                         prevvar = varptr;
                                386                 :                :                 }
                                387                 :            369 :                 for (varptr = ptr->argsresult, prevvar = NULL;
                                388         [ +  + ]:            374 :                      varptr != NULL; varptr = nextvar)
                                389                 :                :                 {
  384                           390                 :              5 :                     nextvar = varptr->next;
 8224 meskes@postgresql.or      391         [ +  + ]:              5 :                     if (p == varptr->variable)
                                392                 :                :                     {
                                393                 :                :                         /* remove from list */
  380 tgl@sss.pgh.pa.us         394         [ -  + ]:              3 :                         if (prevvar)
  380 tgl@sss.pgh.pa.us         395                 :UBC           0 :                             prevvar->next = nextvar;
                                396                 :                :                         else
  380 tgl@sss.pgh.pa.us         397                 :CBC           3 :                             ptr->argsresult = nextvar;
  384                           398                 :              3 :                         free(varptr);
                                399                 :                :                     }
                                400                 :                :                     else
  380                           401                 :              2 :                         prevvar = varptr;
                                402                 :                :                 }
                                403                 :                :             }
                                404                 :                : 
                                405                 :                :             /* remove it */
                                406         [ +  + ]:            420 :             if (prev)
                                407                 :            163 :                 prev->next = next;
                                408                 :                :             else
                                409                 :            257 :                 allvariables = next;
                                410                 :                : 
 9379 bruce@momjian.us          411                 :            420 :             ECPGfree_type(p->type);
                                412                 :            420 :             free(p->name);
                                413                 :            420 :             free(p);
                                414                 :                :         }
                                415                 :                :         else
                                416                 :            922 :             prev = p;
                                417                 :                :     }
 9434 meskes@postgresql.or      418                 :            331 : }
                                419                 :                : 
                                420                 :                : 
                                421                 :                : /*
                                422                 :                :  * Here are the variables that need to be handled on every request.
                                423                 :                :  * These are of two kinds: input and output.
                                424                 :                :  * I will make two lists for them.
                                425                 :                :  */
                                426                 :                : 
                                427                 :                : struct arguments *argsinsert = NULL;
                                428                 :                : struct arguments *argsresult = NULL;
                                429                 :                : 
                                430                 :                : void
                                431                 :           1458 : reset_variables(void)
                                432                 :                : {
                                433                 :                :     struct arguments *p,
                                434                 :                :                *next;
                                435                 :                : 
  384 tgl@sss.pgh.pa.us         436         [ +  + ]:           1460 :     for (p = argsinsert; p; p = next)
                                437                 :                :     {
                                438                 :              2 :         next = p->next;
                                439                 :              2 :         free(p);
                                440                 :                :     }
 9379 bruce@momjian.us          441                 :           1458 :     argsinsert = NULL;
  384 tgl@sss.pgh.pa.us         442         [ -  + ]:           1458 :     for (p = argsresult; p; p = next)
                                443                 :                :     {
  384 tgl@sss.pgh.pa.us         444                 :UBC           0 :         next = p->next;
                                445                 :              0 :         free(p);
                                446                 :                :     }
 9379 bruce@momjian.us          447                 :CBC        1458 :     argsresult = NULL;
 9434 meskes@postgresql.or      448                 :           1458 : }
                                449                 :                : 
                                450                 :                : /* Insert a new variable into our request list.
                                451                 :                :  * Note: The list is dumped from the end,
                                452                 :                :  * so we have to add new entries at the beginning */
                                453                 :                : void
 3100 tgl@sss.pgh.pa.us         454                 :            515 : add_variable_to_head(struct arguments **list, struct variable *var, struct variable *ind)
                                455                 :                : {
 9379 bruce@momjian.us          456                 :            515 :     struct arguments *p = (struct arguments *) mm_alloc(sizeof(struct arguments));
                                457                 :                : 
                                458                 :            515 :     p->variable = var;
                                459                 :            515 :     p->indicator = ind;
                                460                 :            515 :     p->next = *list;
                                461                 :            515 :     *list = p;
 9434 meskes@postgresql.or      462                 :            515 : }
                                463                 :                : 
                                464                 :                : /* Append a new variable to our request list. */
                                465                 :                : void
 3100 tgl@sss.pgh.pa.us         466                 :             97 : add_variable_to_tail(struct arguments **list, struct variable *var, struct variable *ind)
                                467                 :                : {
                                468                 :                :     struct arguments *p,
 9379 bruce@momjian.us          469                 :             97 :                *new = (struct arguments *) mm_alloc(sizeof(struct arguments));
                                470                 :                : 
                                471   [ +  +  +  + ]:            104 :     for (p = *list; p && p->next; p = p->next);
                                472                 :                : 
                                473                 :             97 :     new->variable = var;
                                474                 :             97 :     new->indicator = ind;
                                475                 :             97 :     new->next = NULL;
                                476                 :                : 
                                477         [ +  + ]:             97 :     if (p)
                                478                 :             26 :         p->next = new;
                                479                 :                :     else
                                480                 :             71 :         *list = new;
 9413 meskes@postgresql.or      481                 :             97 : }
                                482                 :                : 
                                483                 :                : void
 3100 tgl@sss.pgh.pa.us         484                 :             17 : remove_variable_from_list(struct arguments **list, struct variable *var)
                                485                 :                : {
                                486                 :                :     struct arguments *p,
 5772 bruce@momjian.us          487                 :             17 :                *prev = NULL;
                                488                 :             17 :     bool        found = false;
                                489                 :                : 
 5864 meskes@postgresql.or      490         [ +  - ]:             17 :     for (p = *list; p; p = p->next)
                                491                 :                :     {
                                492         [ +  - ]:             17 :         if (p->variable == var)
                                493                 :                :         {
                                494                 :             17 :             found = true;
                                495                 :             17 :             break;
                                496                 :                :         }
 5864 meskes@postgresql.or      497                 :UBC           0 :         prev = p;
                                498                 :                :     }
 5864 meskes@postgresql.or      499         [ +  - ]:CBC          17 :     if (found)
                                500                 :                :     {
                                501         [ -  + ]:             17 :         if (prev)
 5864 meskes@postgresql.or      502                 :UBC           0 :             prev->next = p->next;
                                503                 :                :         else
 5864 meskes@postgresql.or      504                 :CBC          17 :             *list = p->next;
  384 tgl@sss.pgh.pa.us         505                 :             17 :         free(p);
                                506                 :                :     }
 5864 meskes@postgresql.or      507                 :             17 : }
                                508                 :                : 
                                509                 :                : /* Dump out a list of all the variable on this list.
                                510                 :                :    This is a recursive function that works from the end of the list and
                                511                 :                :    deletes the list as we go on.
                                512                 :                :  */
                                513                 :                : void
 3100 tgl@sss.pgh.pa.us         514                 :           1656 : dump_variables(struct arguments *list, int mode)
                                515                 :                : {
                                516                 :                :     char       *str_zero;
                                517                 :                : 
 9379 bruce@momjian.us          518         [ +  + ]:           1656 :     if (list == NULL)
                                519                 :           1133 :         return;
                                520                 :                : 
 3840 meskes@postgresql.or      521                 :            523 :     str_zero = mm_strdup("0");
                                522                 :                : 
                                523                 :                :     /*
                                524                 :                :      * The list is build up from the beginning so lets first dump the end of
                                525                 :                :      * the list:
                                526                 :                :      */
                                527                 :                : 
 9379 bruce@momjian.us          528                 :            523 :     dump_variables(list->next, mode);
                                529                 :                : 
                                530                 :                :     /* Then the current element and its indicator */
 3292 tgl@sss.pgh.pa.us         531                 :            523 :     ECPGdump_a_type(base_yyout, list->variable->name, list->variable->type, list->variable->brace_level,
 5738 meskes@postgresql.or      532                 :            523 :                     list->indicator->name, list->indicator->type, list->indicator->brace_level,
                                533                 :                :                     NULL, NULL, str_zero, NULL, NULL);
                                534                 :                : 
                                535                 :                :     /* Then release the list element. */
 9379 bruce@momjian.us          536         [ +  - ]:            523 :     if (mode != 0)
                                537                 :            523 :         free(list);
                                538                 :                : 
 4308 sfrost@snowman.net        539                 :            523 :     free(str_zero);
                                540                 :                : }
                                541                 :                : 
                                542                 :                : void
 3100 tgl@sss.pgh.pa.us         543                 :             67 : check_indicator(struct ECPGtype *var)
                                544                 :                : {
                                545                 :                :     /* make sure this is a valid indicator variable */
 8759 meskes@postgresql.or      546   [ +  +  +  - ]:             67 :     switch (var->type)
                                547                 :                :     {
                                548                 :                :             struct ECPGstruct_member *p;
                                549                 :                : 
 9434                           550                 :             45 :         case ECPGt_short:
                                551                 :                :         case ECPGt_int:
                                552                 :                :         case ECPGt_long:
                                553                 :                :         case ECPGt_long_long:
                                554                 :                :         case ECPGt_unsigned_short:
                                555                 :                :         case ECPGt_unsigned_int:
                                556                 :                :         case ECPGt_unsigned_long:
                                557                 :                :         case ECPGt_unsigned_long_long:
                                558                 :             45 :             break;
                                559                 :                : 
                                560                 :             11 :         case ECPGt_struct:
                                561                 :                :         case ECPGt_union:
                                562         [ +  + ]:             36 :             for (p = var->u.members; p; p = p->next)
 8759                           563                 :             25 :                 check_indicator(p->type);
 9434                           564                 :             11 :             break;
                                565                 :                : 
                                566                 :             11 :         case ECPGt_array:
                                567                 :             11 :             check_indicator(var->u.element);
                                568                 :             11 :             break;
 9379 bruce@momjian.us          569                 :UBC           0 :         default:
 6171 peter_e@gmx.net           570                 :              0 :             mmerror(PARSE_ERROR, ET_ERROR, "indicator variable must have an integer type");
 9434 meskes@postgresql.or      571                 :              0 :             break;
                                572                 :                :     }
 9434 meskes@postgresql.or      573                 :CBC          67 : }
                                574                 :                : 
                                575                 :                : struct typedefs *
 1253 tgl@sss.pgh.pa.us         576                 :           5683 : get_typedef(const char *name, bool noerror)
                                577                 :                : {
                                578                 :                :     struct typedefs *this;
                                579                 :                : 
                                580         [ +  + ]:           9280 :     for (this = types; this != NULL; this = this->next)
                                581                 :                :     {
                                582         [ +  + ]:           3633 :         if (strcmp(this->name, name) == 0)
                                583                 :             36 :             return this;
                                584                 :                :     }
                                585                 :                : 
                                586         [ -  + ]:           5647 :     if (!noerror)
 4417 peter_e@gmx.net           587                 :UBC           0 :         mmfatal(PARSE_ERROR, "unrecognized data type name \"%s\"", name);
                                588                 :                : 
 1253 tgl@sss.pgh.pa.us         589                 :CBC        5647 :     return NULL;
                                590                 :                : }
                                591                 :                : 
                                592                 :                : void
  428                           593                 :            392 : adjust_array(enum ECPGttype type_enum,
                                594                 :                :              const char **dimension, const char **length,
                                595                 :                :              const char *type_dimension, const char *type_index,
                                596                 :                :              int pointer_len, bool type_definition)
                                597                 :                : {
 8252 meskes@postgresql.or      598         [ +  + ]:            392 :     if (atoi(type_index) >= 0)
                                599                 :                :     {
                                600         [ -  + ]:              6 :         if (atoi(*length) >= 0)
 4417 peter_e@gmx.net           601                 :UBC           0 :             mmfatal(PARSE_ERROR, "multidimensional arrays are not supported");
                                602                 :                : 
 9434 meskes@postgresql.or      603                 :CBC           6 :         *length = type_index;
                                604                 :                :     }
                                605                 :                : 
 8252                           606         [ +  + ]:            392 :     if (atoi(type_dimension) >= 0)
                                607                 :                :     {
                                608   [ -  +  -  - ]:              1 :         if (atoi(*dimension) >= 0 && atoi(*length) >= 0)
 4417 peter_e@gmx.net           609                 :UBC           0 :             mmfatal(PARSE_ERROR, "multidimensional arrays are not supported");
                                610                 :                : 
 8252 meskes@postgresql.or      611         [ -  + ]:CBC           1 :         if (atoi(*dimension) >= 0)
 9434 meskes@postgresql.or      612                 :UBC           0 :             *length = *dimension;
                                613                 :                : 
 9434 meskes@postgresql.or      614                 :CBC           1 :         *dimension = type_dimension;
                                615                 :                :     }
                                616                 :                : 
 8504 bruce@momjian.us          617         [ -  + ]:            392 :     if (pointer_len > 2)
 4417 peter_e@gmx.net           618                 :UBC           0 :         mmfatal(PARSE_ERROR, ngettext("multilevel pointers (more than 2 levels) are not supported; found %d level",
                                619                 :                :                                       "multilevel pointers (more than 2 levels) are not supported; found %d levels", pointer_len),
                                620                 :                :                 pointer_len);
                                621                 :                : 
 5975 meskes@postgresql.or      622   [ +  +  -  +  :CBC         392 :     if (pointer_len > 1 && type_enum != ECPGt_char && type_enum != ECPGt_unsigned_char && type_enum != ECPGt_string)
                                        -  -  -  - ]
 4417 peter_e@gmx.net           623                 :UBC           0 :         mmfatal(PARSE_ERROR, "pointer to pointer is not supported for this data type");
                                624                 :                : 
 8252 meskes@postgresql.or      625   [ +  +  +  -  :CBC         392 :     if (pointer_len > 1 && (atoi(*length) >= 0 || atoi(*dimension) >= 0))
                                              -  + ]
 4417 peter_e@gmx.net           626                 :UBC           0 :         mmfatal(PARSE_ERROR, "multidimensional arrays are not supported");
                                627                 :                : 
 8252 meskes@postgresql.or      628   [ +  +  +  +  :CBC         392 :     if (atoi(*length) >= 0 && atoi(*dimension) >= 0 && pointer_len)
                                              -  + ]
 4417 peter_e@gmx.net           629                 :UBC           0 :         mmfatal(PARSE_ERROR, "multidimensional arrays are not supported");
                                630                 :                : 
 9434 meskes@postgresql.or      631   [ +  +  +  + ]:CBC         392 :     switch (type_enum)
                                632                 :                :     {
 9379 bruce@momjian.us          633                 :             40 :         case ECPGt_struct:
                                634                 :                :         case ECPGt_union:
                                635                 :                :             /* pointer has to get dimension 0 */
 8796 meskes@postgresql.or      636         [ +  + ]:             40 :             if (pointer_len)
                                637                 :                :             {
 9379 bruce@momjian.us          638                 :             10 :                 *length = *dimension;
  428 tgl@sss.pgh.pa.us         639                 :             10 :                 *dimension = "0";
                                640                 :                :             }
                                641                 :                : 
 8252 meskes@postgresql.or      642         [ -  + ]:             40 :             if (atoi(*length) >= 0)
 4417 peter_e@gmx.net           643                 :UBC           0 :                 mmfatal(PARSE_ERROR, "multidimensional arrays for structures are not supported");
                                644                 :                : 
 9379 bruce@momjian.us          645                 :CBC          40 :             break;
                                646                 :             23 :         case ECPGt_varchar:
                                647                 :                :         case ECPGt_bytea:
                                648                 :                :             /* pointer has to get dimension 0 */
 8796 meskes@postgresql.or      649         [ -  + ]:             23 :             if (pointer_len)
  428 tgl@sss.pgh.pa.us         650                 :UBC           0 :                 *dimension = "0";
                                651                 :                : 
                                652                 :                :             /* one index is the string length */
 8252 meskes@postgresql.or      653         [ +  + ]:CBC          23 :             if (atoi(*length) < 0)
                                654                 :                :             {
 9379 bruce@momjian.us          655                 :             15 :                 *length = *dimension;
  428 tgl@sss.pgh.pa.us         656                 :             15 :                 *dimension = "-1";
                                657                 :                :             }
                                658                 :                : 
 9379 bruce@momjian.us          659                 :             23 :             break;
                                660                 :            129 :         case ECPGt_char:
                                661                 :                :         case ECPGt_unsigned_char:
                                662                 :                :         case ECPGt_string:
                                663                 :                :             /* char ** */
 8504                           664         [ +  + ]:            129 :             if (pointer_len == 2)
                                665                 :                :             {
  428 tgl@sss.pgh.pa.us         666                 :              8 :                 *length = *dimension = "0";
 8796 meskes@postgresql.or      667                 :              8 :                 break;
                                668                 :                :             }
                                669                 :                : 
                                670                 :                :             /* pointer has to get length 0 */
 8504 bruce@momjian.us          671         [ +  + ]:            121 :             if (pointer_len == 1)
  428 tgl@sss.pgh.pa.us         672                 :             45 :                 *length = "0";
                                673                 :                : 
                                674                 :                :             /* one index is the string length */
 8252 meskes@postgresql.or      675         [ +  + ]:            121 :             if (atoi(*length) < 0)
                                676                 :                :             {
                                677                 :                :                 /*
                                678                 :                :                  * make sure we return length = -1 for arrays without given
                                679                 :                :                  * bounds
                                680                 :                :                  */
 7893                           681   [ +  +  +  + ]:             66 :                 if (atoi(*dimension) < 0 && !type_definition)
                                682                 :                : 
                                683                 :                :                     /*
                                684                 :                :                      * do not change this for typedefs since it will be
                                685                 :                :                      * changed later on when the variable is defined
                                686                 :                :                      */
  428 tgl@sss.pgh.pa.us         687                 :              5 :                     *length = "1";
 7680 meskes@postgresql.or      688         [ +  + ]:             61 :                 else if (strcmp(*dimension, "0") == 0)
  428 tgl@sss.pgh.pa.us         689                 :              2 :                     *length = "-1";
                                690                 :                :                 else
 8198 meskes@postgresql.or      691                 :             59 :                     *length = *dimension;
                                692                 :                : 
  428 tgl@sss.pgh.pa.us         693                 :             66 :                 *dimension = "-1";
                                694                 :                :             }
 9379 bruce@momjian.us          695                 :            121 :             break;
                                696                 :            200 :         default:
                                697                 :                :             /* a pointer has dimension = 0 */
 8796 meskes@postgresql.or      698         [ +  + ]:            200 :             if (pointer_len)
                                699                 :                :             {
 9379 bruce@momjian.us          700                 :             20 :                 *length = *dimension;
  428 tgl@sss.pgh.pa.us         701                 :             20 :                 *dimension = "0";
                                702                 :                :             }
                                703                 :                : 
 8252 meskes@postgresql.or      704         [ -  + ]:            200 :             if (atoi(*length) >= 0)
 4417 peter_e@gmx.net           705                 :UBC           0 :                 mmfatal(PARSE_ERROR, "multidimensional arrays for simple data types are not supported");
                                706                 :                : 
 9379 bruce@momjian.us          707                 :CBC         200 :             break;
                                708                 :                :     }
 9434 meskes@postgresql.or      709                 :            392 : }
        

Generated by: LCOV version 2.4-beta