LCOV - code coverage report
Current view: top level - src/interfaces/ecpg/preproc - output.c (source / functions) Coverage Total Hit
Test: PostgreSQL 20devel Lines: 94.4 % 125 118
Test Date: 2026-07-12 22:15:32 Functions: 100.0 % 9 9
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
Branches: 80.5 % 77 62

             Branch data     Line data    Source code
       1                 :             : /* src/interfaces/ecpg/preproc/output.c */
       2                 :             : 
       3                 :             : #include "postgres_fe.h"
       4                 :             : 
       5                 :             : #include "preproc_extern.h"
       6                 :             : 
       7                 :             : static void output_escaped_str(const char *str, bool quoted);
       8                 :             : 
       9                 :             : void
      10                 :        2682 : output_line_number(void)
      11                 :             : {
      12                 :        2682 :     char       *line = hashline_number();
      13                 :             : 
      14                 :        2682 :     fprintf(base_yyout, "%s", line);
      15                 :        2682 : }
      16                 :             : 
      17                 :             : void
      18                 :         155 : output_simple_statement(const char *stmt, int whenever_mode)
      19                 :             : {
      20                 :         155 :     output_escaped_str(stmt, false);
      21         [ +  + ]:         155 :     if (whenever_mode)
      22                 :          13 :         whenever_action(whenever_mode);
      23                 :         155 :     output_line_number();
      24                 :         155 : }
      25                 :             : 
      26                 :             : 
      27                 :             : /*
      28                 :             :  * store the whenever action here
      29                 :             :  */
      30                 :             : struct when when_error,
      31                 :             :             when_nf,
      32                 :             :             when_warn;
      33                 :             : 
      34                 :             : static void
      35                 :        1067 : print_action(struct when *w)
      36                 :             : {
      37   [ +  +  +  +  :        1067 :     switch (w->code)
                +  +  - ]
      38                 :             :     {
      39                 :         585 :         case W_SQLPRINT:
      40                 :         585 :             fprintf(base_yyout, "sqlprint();");
      41                 :         585 :             break;
      42                 :           2 :         case W_GOTO:
      43                 :           2 :             fprintf(base_yyout, "goto %s;", w->command);
      44                 :           2 :             break;
      45                 :         173 :         case W_DO:
      46                 :         173 :             fprintf(base_yyout, "%s;", w->command);
      47                 :         173 :             break;
      48                 :         293 :         case W_STOP:
      49                 :         293 :             fprintf(base_yyout, "exit (1);");
      50                 :         293 :             break;
      51                 :          13 :         case W_BREAK:
      52                 :          13 :             fprintf(base_yyout, "break;");
      53                 :          13 :             break;
      54                 :           1 :         case W_CONTINUE:
      55                 :           1 :             fprintf(base_yyout, "continue;");
      56                 :           1 :             break;
      57                 :           0 :         default:
      58                 :           0 :             fprintf(base_yyout, "{/* %d not implemented yet */}", w->code);
      59                 :           0 :             break;
      60                 :             :     }
      61                 :        1067 : }
      62                 :             : 
      63                 :             : void
      64                 :        1072 : whenever_action(int mode)
      65                 :             : {
      66   [ +  +  +  + ]:        1072 :     if ((mode & 1) == 1 && when_nf.code != W_NOTHING)
      67                 :             :     {
      68                 :          30 :         output_line_number();
      69                 :          30 :         fprintf(base_yyout, "\nif (sqlca.sqlcode == ECPG_NOT_FOUND) ");
      70                 :          30 :         print_action(&when_nf);
      71                 :             :     }
      72         [ +  + ]:        1072 :     if (when_warn.code != W_NOTHING)
      73                 :             :     {
      74                 :         144 :         output_line_number();
      75                 :         144 :         fprintf(base_yyout, "\nif (sqlca.sqlwarn[0] == 'W') ");
      76                 :         144 :         print_action(&when_warn);
      77                 :             :     }
      78         [ +  + ]:        1072 :     if (when_error.code != W_NOTHING)
      79                 :             :     {
      80                 :         893 :         output_line_number();
      81                 :         893 :         fprintf(base_yyout, "\nif (sqlca.sqlcode < 0) ");
      82                 :         893 :         print_action(&when_error);
      83                 :             :     }
      84                 :             : 
      85         [ +  + ]:        1072 :     if ((mode & 2) == 2)
      86                 :        1023 :         fputc('}', base_yyout);
      87                 :             : 
      88                 :        1072 :     output_line_number();
      89                 :        1072 : }
      90                 :             : 
      91                 :             : char *
      92                 :        2993 : hashline_number(void)
      93                 :             : {
      94                 :             :     /* do not print line numbers if we are in debug mode */
      95         [ +  - ]:        2993 :     if (input_filename
      96                 :             : #ifdef YYDEBUG
      97                 :             :         && !base_yydebug
      98                 :             : #endif
      99                 :             :         )
     100                 :             :     {
     101                 :             :         /* "* 2" here is for escaping '\' and '"' below */
     102                 :        2993 :         char       *line = loc_alloc(strlen("\n#line %d \"%s\"\n") + sizeof(int) * CHAR_BIT * 10 / 3 + strlen(input_filename) * 2);
     103                 :             :         char       *src,
     104                 :             :                    *dest;
     105                 :             : 
     106                 :        2993 :         sprintf(line, "\n#line %d \"", base_yylineno);
     107                 :        2993 :         src = input_filename;
     108                 :        2993 :         dest = line + strlen(line);
     109         [ +  + ]:       38655 :         while (*src)
     110                 :             :         {
     111   [ +  -  -  + ]:       35662 :             if (*src == '\\' || *src == '"')
     112                 :           0 :                 *dest++ = '\\';
     113                 :       35662 :             *dest++ = *src++;
     114                 :             :         }
     115                 :        2993 :         *dest = '\0';
     116                 :        2993 :         strcat(dest, "\"\n");
     117                 :             : 
     118                 :        2993 :         return line;
     119                 :             :     }
     120                 :             : 
     121                 :           0 :     return "";
     122                 :             : }
     123                 :             : 
     124                 :             : static char *ecpg_statement_type_name[] = {
     125                 :             :     "ECPGst_normal",
     126                 :             :     "ECPGst_execute",
     127                 :             :     "ECPGst_exec_immediate",
     128                 :             :     "ECPGst_prepnormal",
     129                 :             :     "ECPGst_prepare",
     130                 :             :     "ECPGst_exec_with_exprlist"
     131                 :             : };
     132                 :             : 
     133                 :             : void
     134                 :         577 : output_statement(const char *stmt, int whenever_mode, enum ECPG_statement_type st)
     135                 :             : {
     136         [ +  + ]:         577 :     fprintf(base_yyout, "{ ECPGdo(__LINE__, %d, %d, %s, %d, ", compat, force_indicator, connection ? connection : "NULL", questionmarks);
     137                 :             : 
     138   [ +  +  +  + ]:         577 :     if (st == ECPGst_prepnormal && !auto_prepare)
     139                 :         222 :         st = ECPGst_normal;
     140                 :             : 
     141                 :             :     /*
     142                 :             :      * In following cases, stmt is CSTRING or char_variable. They must be
     143                 :             :      * output directly. - prepared_name of EXECUTE without exprlist -
     144                 :             :      * execstring of EXECUTE IMMEDIATE
     145                 :             :      */
     146                 :         577 :     fprintf(base_yyout, "%s, ", ecpg_statement_type_name[st]);
     147   [ +  +  +  + ]:         577 :     if (st == ECPGst_execute || st == ECPGst_exec_immediate)
     148                 :          33 :         fprintf(base_yyout, "%s, ", stmt);
     149                 :             :     else
     150                 :             :     {
     151                 :         544 :         fputs("\"", base_yyout);
     152                 :         544 :         output_escaped_str(stmt, false);
     153                 :         544 :         fputs("\", ", base_yyout);
     154                 :             :     }
     155                 :             : 
     156                 :             :     /* dump variables to C file */
     157                 :         577 :     dump_variables(argsinsert, 1);
     158                 :         577 :     argsinsert = NULL;
     159                 :         577 :     fputs("ECPGt_EOIT, ", base_yyout);
     160                 :         577 :     dump_variables(argsresult, 1);
     161                 :         577 :     argsresult = NULL;
     162                 :         577 :     fputs("ECPGt_EORT);", base_yyout);
     163                 :             : 
     164                 :         577 :     whenever_action(whenever_mode | 2);
     165                 :         577 : }
     166                 :             : 
     167                 :             : void
     168                 :          51 : output_prepare_statement(const char *name, const char *stmt)
     169                 :             : {
     170         [ +  + ]:          51 :     fprintf(base_yyout, "{ ECPGprepare(__LINE__, %s, %d, ", connection ? connection : "NULL", questionmarks);
     171                 :          51 :     output_escaped_str(name, true);
     172                 :          51 :     fputs(", ", base_yyout);
     173                 :          51 :     output_escaped_str(stmt, true);
     174                 :          51 :     fputs(");", base_yyout);
     175                 :          51 :     whenever_action(2);
     176                 :          51 : }
     177                 :             : 
     178                 :             : void
     179                 :          41 : output_deallocate_prepare_statement(const char *name)
     180                 :             : {
     181         [ +  + ]:          41 :     const char *con = connection ? connection : "NULL";
     182                 :             : 
     183         [ +  + ]:          41 :     if (strcmp(name, "all") != 0)
     184                 :             :     {
     185                 :          38 :         fprintf(base_yyout, "{ ECPGdeallocate(__LINE__, %d, %s, ", compat, con);
     186                 :          38 :         output_escaped_str(name, true);
     187                 :          38 :         fputs(");", base_yyout);
     188                 :             :     }
     189                 :             :     else
     190                 :           3 :         fprintf(base_yyout, "{ ECPGdeallocate_all(__LINE__, %d, %s);", compat, con);
     191                 :             : 
     192                 :          41 :     whenever_action(2);
     193                 :          41 : }
     194                 :             : 
     195                 :             : static void
     196                 :         839 : output_escaped_str(const char *str, bool quoted)
     197                 :             : {
     198                 :         839 :     int         i = 0;
     199                 :         839 :     int         len = strlen(str);
     200                 :             : 
     201   [ +  +  +  +  :         839 :     if (quoted && str[0] == '"' && str[len - 1] == '"') /* do not escape quotes
                   +  - ]
     202                 :             :                                                          * at beginning and end
     203                 :             :                                                          * if quoted string */
     204                 :             :     {
     205                 :          90 :         i = 1;
     206                 :          90 :         len--;
     207                 :          90 :         fputs("\"", base_yyout);
     208                 :             :     }
     209                 :             : 
     210                 :             :     /* output this char by char as we have to filter " and \n */
     211         [ +  + ]:       32579 :     for (; i < len; i++)
     212                 :             :     {
     213         [ +  + ]:       31740 :         if (str[i] == '"')
     214                 :         100 :             fputs("\\\"", base_yyout);
     215         [ +  + ]:       31640 :         else if (str[i] == '\n')
     216                 :          20 :             fputs("\\\n", base_yyout);
     217         [ +  + ]:       31620 :         else if (str[i] == '\\')
     218                 :             :         {
     219                 :          14 :             int         j = i;
     220                 :             : 
     221                 :             :             /*
     222                 :             :              * check whether this is a continuation line if it is, do not
     223                 :             :              * output anything because newlines are escaped anyway
     224                 :             :              */
     225                 :             : 
     226                 :             :             /* accept blanks after the '\' as some other compilers do too */
     227                 :             :             do
     228                 :             :             {
     229                 :          14 :                 j++;
     230   [ -  +  -  + ]:          14 :             } while (str[j] == ' ' || str[j] == '\t');
     231                 :             : 
     232   [ +  -  -  +  :          14 :             if ((str[j] != '\n') && (str[j] != '\r' || str[j + 1] != '\n')) /* not followed by a
                   -  - ]
     233                 :             :                                                                              * newline */
     234                 :          14 :                 fputs("\\\\", base_yyout);
     235                 :             :         }
     236   [ -  +  -  - ]:       31606 :         else if (str[i] == '\r' && str[i + 1] == '\n')
     237                 :             :         {
     238                 :           0 :             fputs("\\\r\n", base_yyout);
     239                 :           0 :             i++;
     240                 :             :         }
     241                 :             :         else
     242                 :       31606 :             fputc(str[i], base_yyout);
     243                 :             :     }
     244                 :             : 
     245   [ +  +  +  +  :         839 :     if (quoted && str[0] == '"' && str[len] == '"')
                   +  - ]
     246                 :          90 :         fputs("\"", base_yyout);
     247                 :         839 : }
        

Generated by: LCOV version 2.0-1