LCOV - code coverage report
Current view: top level - src/interfaces/ecpg/preproc - util.c (source / functions) Coverage Total Hit
Test: Code coverage Lines: 0.0 % 106 0
Test Date: 2026-01-26 10:56:24 Functions: 0.0 % 12 0
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* src/interfaces/ecpg/preproc/util.c */
       2              : 
       3              : #include "postgres_fe.h"
       4              : 
       5              : #include <unistd.h>
       6              : 
       7              : #include "preproc_extern.h"
       8              : 
       9              : static void vmmerror(int error_code, enum errortype type, const char *error, va_list ap) pg_attribute_printf(3, 0);
      10              : 
      11              : 
      12              : /*
      13              :  * Handle preprocessor errors and warnings
      14              :  */
      15              : static void
      16            0 : vmmerror(int error_code, enum errortype type, const char *error, va_list ap)
      17              : {
      18              :         /* localize the error message string */
      19            0 :         error = _(error);
      20              : 
      21            0 :         fprintf(stderr, "%s:%d: ", input_filename, base_yylineno);
      22              : 
      23            0 :         switch (type)
      24              :         {
      25              :                 case ET_WARNING:
      26            0 :                         fprintf(stderr, _("WARNING: "));
      27            0 :                         break;
      28              :                 case ET_ERROR:
      29            0 :                         fprintf(stderr, _("ERROR: "));
      30            0 :                         break;
      31              :         }
      32              : 
      33            0 :         vfprintf(stderr, error, ap);
      34              : 
      35            0 :         fprintf(stderr, "\n");
      36              : 
      37              :         /* If appropriate, set error code to be inspected by ecpg.c */
      38            0 :         switch (type)
      39              :         {
      40              :                 case ET_WARNING:
      41              :                         break;
      42              :                 case ET_ERROR:
      43            0 :                         ret_value = error_code;
      44            0 :                         break;
      45              :         }
      46            0 : }
      47              : 
      48              : /* Report an error or warning */
      49              : void
      50            0 : mmerror(int error_code, enum errortype type, const char *error,...)
      51              : {
      52            0 :         va_list         ap;
      53              : 
      54            0 :         va_start(ap, error);
      55            0 :         vmmerror(error_code, type, error, ap);
      56            0 :         va_end(ap);
      57            0 : }
      58              : 
      59              : /* Report an error and abandon execution */
      60              : void
      61            0 : mmfatal(int error_code, const char *error,...)
      62              : {
      63            0 :         va_list         ap;
      64              : 
      65            0 :         va_start(ap, error);
      66            0 :         vmmerror(error_code, ET_ERROR, error, ap);
      67            0 :         va_end(ap);
      68              : 
      69            0 :         if (base_yyin)
      70            0 :                 fclose(base_yyin);
      71            0 :         if (base_yyout)
      72            0 :                 fclose(base_yyout);
      73              : 
      74            0 :         if (strcmp(output_filename, "-") != 0 && unlink(output_filename) != 0)
      75            0 :                 fprintf(stderr, _("could not remove output file \"%s\"\n"), output_filename);
      76            0 :         exit(error_code);
      77              : }
      78              : 
      79              : /*
      80              :  * Basic memory management support
      81              :  */
      82              : 
      83              : /* malloc + error check */
      84              : void *
      85            0 : mm_alloc(size_t size)
      86              : {
      87            0 :         void       *ptr = malloc(size);
      88              : 
      89            0 :         if (ptr == NULL)
      90            0 :                 mmfatal(OUT_OF_MEMORY, "out of memory");
      91              : 
      92            0 :         return ptr;
      93            0 : }
      94              : 
      95              : /* strdup + error check */
      96              : char *
      97            0 : mm_strdup(const char *string)
      98              : {
      99            0 :         char       *new = strdup(string);
     100              : 
     101            0 :         if (new == NULL)
     102            0 :                 mmfatal(OUT_OF_MEMORY, "out of memory");
     103              : 
     104            0 :         return new;
     105            0 : }
     106              : 
     107              : 
     108              : /*
     109              :  * "Local" memory management support
     110              :  *
     111              :  * These functions manage memory that is only needed for a short time
     112              :  * (processing of one input statement) within the ecpg grammar.
     113              :  * Data allocated with these is not meant to be freed separately;
     114              :  * rather it's freed by calling reclaim_local_storage() at the end
     115              :  * of each statement cycle.
     116              :  */
     117              : 
     118              : typedef struct loc_chunk
     119              : {
     120              :         struct loc_chunk *next;         /* list link */
     121              :         unsigned int chunk_used;        /* index of first unused byte in data[] */
     122              :         unsigned int chunk_avail;       /* # bytes still available in data[] */
     123              :         char            data[FLEXIBLE_ARRAY_MEMBER];    /* actual storage */
     124              : } loc_chunk;
     125              : 
     126              : #define LOC_CHUNK_OVERHEAD      MAXALIGN(offsetof(loc_chunk, data))
     127              : #define LOC_CHUNK_MIN_SIZE      8192
     128              : 
     129              : /* Head of list of loc_chunks */
     130              : static loc_chunk *loc_chunks = NULL;
     131              : 
     132              : /*
     133              :  * Allocate local space of the requested size.
     134              :  *
     135              :  * Exits on OOM.
     136              :  */
     137              : void *
     138            0 : loc_alloc(size_t size)
     139              : {
     140            0 :         void       *result;
     141            0 :         loc_chunk  *cur_chunk = loc_chunks;
     142              : 
     143              :         /* Ensure all allocations are adequately aligned */
     144            0 :         size = MAXALIGN(size);
     145              : 
     146              :         /* Need a new chunk? */
     147            0 :         if (cur_chunk == NULL || size > cur_chunk->chunk_avail)
     148              :         {
     149            0 :                 size_t          chunk_size = Max(size, LOC_CHUNK_MIN_SIZE);
     150              : 
     151            0 :                 cur_chunk = mm_alloc(chunk_size + LOC_CHUNK_OVERHEAD);
     152              :                 /* Depending on alignment rules, we could waste a bit here */
     153            0 :                 cur_chunk->chunk_used = LOC_CHUNK_OVERHEAD - offsetof(loc_chunk, data);
     154            0 :                 cur_chunk->chunk_avail = chunk_size;
     155              :                 /* New chunk becomes the head of the list */
     156            0 :                 cur_chunk->next = loc_chunks;
     157            0 :                 loc_chunks = cur_chunk;
     158            0 :         }
     159              : 
     160            0 :         result = cur_chunk->data + cur_chunk->chunk_used;
     161            0 :         cur_chunk->chunk_used += size;
     162            0 :         cur_chunk->chunk_avail -= size;
     163            0 :         return result;
     164            0 : }
     165              : 
     166              : /*
     167              :  * Copy given string into local storage
     168              :  */
     169              : char *
     170            0 : loc_strdup(const char *string)
     171              : {
     172            0 :         char       *result = loc_alloc(strlen(string) + 1);
     173              : 
     174            0 :         strcpy(result, string);
     175            0 :         return result;
     176            0 : }
     177              : 
     178              : /*
     179              :  * Reclaim local storage when appropriate
     180              :  */
     181              : void
     182            0 : reclaim_local_storage(void)
     183              : {
     184            0 :         loc_chunk  *cur_chunk,
     185              :                            *next_chunk;
     186              : 
     187            0 :         for (cur_chunk = loc_chunks; cur_chunk; cur_chunk = next_chunk)
     188              :         {
     189            0 :                 next_chunk = cur_chunk->next;
     190            0 :                 free(cur_chunk);
     191            0 :         }
     192            0 :         loc_chunks = NULL;
     193            0 : }
     194              : 
     195              : 
     196              : /*
     197              :  * String concatenation support routines.  These return "local" (transient)
     198              :  * storage.
     199              :  */
     200              : 
     201              : /*
     202              :  * Concatenate 2 strings, inserting a space between them unless either is empty
     203              :  */
     204              : char *
     205            0 : cat2_str(const char *str1, const char *str2)
     206              : {
     207            0 :         char       *res_str = (char *) loc_alloc(strlen(str1) + strlen(str2) + 2);
     208              : 
     209            0 :         strcpy(res_str, str1);
     210            0 :         if (strlen(str1) != 0 && strlen(str2) != 0)
     211            0 :                 strcat(res_str, " ");
     212            0 :         strcat(res_str, str2);
     213            0 :         return res_str;
     214            0 : }
     215              : 
     216              : /*
     217              :  * Concatenate N strings, inserting spaces between them unless they are empty
     218              :  */
     219              : char *
     220            0 : cat_str(int count,...)
     221              : {
     222            0 :         va_list         args;
     223            0 :         int                     i;
     224            0 :         char       *res_str;
     225              : 
     226            0 :         va_start(args, count);
     227              : 
     228            0 :         res_str = va_arg(args, char *);
     229              : 
     230              :         /* now add all other strings */
     231            0 :         for (i = 1; i < count; i++)
     232            0 :                 res_str = cat2_str(res_str, va_arg(args, char *));
     233              : 
     234            0 :         va_end(args);
     235              : 
     236            0 :         return res_str;
     237            0 : }
     238              : 
     239              : /*
     240              :  * Concatenate 2 strings, with no space between
     241              :  */
     242              : char *
     243            0 : make2_str(const char *str1, const char *str2)
     244              : {
     245            0 :         char       *res_str = (char *) loc_alloc(strlen(str1) + strlen(str2) + 1);
     246              : 
     247            0 :         strcpy(res_str, str1);
     248            0 :         strcat(res_str, str2);
     249            0 :         return res_str;
     250            0 : }
     251              : 
     252              : /*
     253              :  * Concatenate 3 strings, with no space between
     254              :  */
     255              : char *
     256            0 : make3_str(const char *str1, const char *str2, const char *str3)
     257              : {
     258            0 :         char       *res_str = (char *) loc_alloc(strlen(str1) + strlen(str2) + strlen(str3) + 1);
     259              : 
     260            0 :         strcpy(res_str, str1);
     261            0 :         strcat(res_str, str2);
     262            0 :         strcat(res_str, str3);
     263            0 :         return res_str;
     264            0 : }
        

Generated by: LCOV version 2.3.2-1