LCOV - code coverage report
Current view: top level - src/interfaces/ecpg/preproc - output.c (source / functions) Hit Total Coverage
Test: PostgreSQL 18devel Lines: 117 124 94.4 %
Date: 2024-11-21 09:14:53 Functions: 9 9 100.0 %
Legend: Lines: hit not hit

          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        5174 : output_line_number(void)
      11             : {
      12        5174 :     char       *line = hashline_number();
      13             : 
      14        5174 :     fprintf(base_yyout, "%s", line);
      15        5174 : }
      16             : 
      17             : void
      18         288 : output_simple_statement(const char *stmt, int whenever_mode)
      19             : {
      20         288 :     output_escaped_str(stmt, false);
      21         288 :     if (whenever_mode)
      22          22 :         whenever_action(whenever_mode);
      23         288 :     output_line_number();
      24         288 : }
      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        2094 : print_action(struct when *w)
      36             : {
      37        2094 :     switch (w->code)
      38             :     {
      39        1124 :         case W_SQLPRINT:
      40        1124 :             fprintf(base_yyout, "sqlprint();");
      41        1124 :             break;
      42           4 :         case W_GOTO:
      43           4 :             fprintf(base_yyout, "goto %s;", w->command);
      44           4 :             break;
      45         346 :         case W_DO:
      46         346 :             fprintf(base_yyout, "%s;", w->command);
      47         346 :             break;
      48         594 :         case W_STOP:
      49         594 :             fprintf(base_yyout, "exit (1);");
      50         594 :             break;
      51          24 :         case W_BREAK:
      52          24 :             fprintf(base_yyout, "break;");
      53          24 :             break;
      54           2 :         case W_CONTINUE:
      55           2 :             fprintf(base_yyout, "continue;");
      56           2 :             break;
      57           0 :         default:
      58           0 :             fprintf(base_yyout, "{/* %d not implemented yet */}", w->code);
      59           0 :             break;
      60             :     }
      61        2094 : }
      62             : 
      63             : void
      64        2044 : whenever_action(int mode)
      65             : {
      66        2044 :     if ((mode & 1) == 1 && when_nf.code != W_NOTHING)
      67             :     {
      68          58 :         output_line_number();
      69          58 :         fprintf(base_yyout, "\nif (sqlca.sqlcode == ECPG_NOT_FOUND) ");
      70          58 :         print_action(&when_nf);
      71             :     }
      72        2044 :     if (when_warn.code != W_NOTHING)
      73             :     {
      74         296 :         output_line_number();
      75         296 :         fprintf(base_yyout, "\nif (sqlca.sqlwarn[0] == 'W') ");
      76         296 :         print_action(&when_warn);
      77             :     }
      78        2044 :     if (when_error.code != W_NOTHING)
      79             :     {
      80        1740 :         output_line_number();
      81        1740 :         fprintf(base_yyout, "\nif (sqlca.sqlcode < 0) ");
      82        1740 :         print_action(&when_error);
      83             :     }
      84             : 
      85        2044 :     if ((mode & 2) == 2)
      86        1954 :         fputc('}', base_yyout);
      87             : 
      88        2044 :     output_line_number();
      89        2044 : }
      90             : 
      91             : char *
      92        5766 : hashline_number(void)
      93             : {
      94             :     /* do not print line numbers if we are in debug mode */
      95        5766 :     if (input_filename
      96             : #ifdef YYDEBUG
      97             :         && !base_yydebug
      98             : #endif
      99             :         )
     100             :     {
     101             :         /* "* 2" here is for escaping '\' and '"' below */
     102        5766 :         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        5766 :         sprintf(line, "\n#line %d \"", base_yylineno);
     107        5766 :         src = input_filename;
     108        5766 :         dest = line + strlen(line);
     109       74342 :         while (*src)
     110             :         {
     111       68576 :             if (*src == '\\' || *src == '"')
     112           0 :                 *dest++ = '\\';
     113       68576 :             *dest++ = *src++;
     114             :         }
     115        5766 :         *dest = '\0';
     116        5766 :         strcat(dest, "\"\n");
     117             : 
     118        5766 :         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        1106 : output_statement(const char *stmt, int whenever_mode, enum ECPG_statement_type st)
     135             : {
     136        1106 :     fprintf(base_yyout, "{ ECPGdo(__LINE__, %d, %d, %s, %d, ", compat, force_indicator, connection ? connection : "NULL", questionmarks);
     137             : 
     138        1106 :     if (st == ECPGst_prepnormal && !auto_prepare)
     139         432 :         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        1106 :     fprintf(base_yyout, "%s, ", ecpg_statement_type_name[st]);
     147        1106 :     if (st == ECPGst_execute || st == ECPGst_exec_immediate)
     148          62 :         fprintf(base_yyout, "%s, ", stmt);
     149             :     else
     150             :     {
     151        1044 :         fputs("\"", base_yyout);
     152        1044 :         output_escaped_str(stmt, false);
     153        1044 :         fputs("\", ", base_yyout);
     154             :     }
     155             : 
     156             :     /* dump variables to C file */
     157        1106 :     dump_variables(argsinsert, 1);
     158        1106 :     fputs("ECPGt_EOIT, ", base_yyout);
     159        1106 :     dump_variables(argsresult, 1);
     160        1106 :     fputs("ECPGt_EORT);", base_yyout);
     161        1106 :     reset_variables();
     162             : 
     163        1106 :     whenever_action(whenever_mode | 2);
     164        1106 : }
     165             : 
     166             : void
     167          96 : output_prepare_statement(const char *name, const char *stmt)
     168             : {
     169          96 :     fprintf(base_yyout, "{ ECPGprepare(__LINE__, %s, %d, ", connection ? connection : "NULL", questionmarks);
     170          96 :     output_escaped_str(name, true);
     171          96 :     fputs(", ", base_yyout);
     172          96 :     output_escaped_str(stmt, true);
     173          96 :     fputs(");", base_yyout);
     174          96 :     whenever_action(2);
     175          96 : }
     176             : 
     177             : void
     178          76 : output_deallocate_prepare_statement(const char *name)
     179             : {
     180          76 :     const char *con = connection ? connection : "NULL";
     181             : 
     182          76 :     if (strcmp(name, "all") != 0)
     183             :     {
     184          74 :         fprintf(base_yyout, "{ ECPGdeallocate(__LINE__, %d, %s, ", compat, con);
     185          74 :         output_escaped_str(name, true);
     186          74 :         fputs(");", base_yyout);
     187             :     }
     188             :     else
     189           2 :         fprintf(base_yyout, "{ ECPGdeallocate_all(__LINE__, %d, %s);", compat, con);
     190             : 
     191          76 :     whenever_action(2);
     192          76 : }
     193             : 
     194             : static void
     195        1598 : output_escaped_str(const char *str, bool quoted)
     196             : {
     197        1598 :     int         i = 0;
     198        1598 :     int         len = strlen(str);
     199             : 
     200        1598 :     if (quoted && str[0] == '"' && str[len - 1] == '"') /* do not escape quotes
     201             :                                                          * at beginning and end
     202             :                                                          * if quoted string */
     203             :     {
     204         170 :         i = 1;
     205         170 :         len--;
     206         170 :         fputs("\"", base_yyout);
     207             :     }
     208             : 
     209             :     /* output this char by char as we have to filter " and \n */
     210       60050 :     for (; i < len; i++)
     211             :     {
     212       58452 :         if (str[i] == '"')
     213         208 :             fputs("\\\"", base_yyout);
     214       58244 :         else if (str[i] == '\n')
     215          36 :             fputs("\\\n", base_yyout);
     216       58208 :         else if (str[i] == '\\')
     217             :         {
     218          44 :             int         j = i;
     219             : 
     220             :             /*
     221             :              * check whether this is a continuation line if it is, do not
     222             :              * output anything because newlines are escaped anyway
     223             :              */
     224             : 
     225             :             /* accept blanks after the '\' as some other compilers do too */
     226             :             do
     227             :             {
     228          44 :                 j++;
     229          44 :             } while (str[j] == ' ' || str[j] == '\t');
     230             : 
     231          44 :             if ((str[j] != '\n') && (str[j] != '\r' || str[j + 1] != '\n')) /* not followed by a
     232             :                                                                              * newline */
     233          44 :                 fputs("\\\\", base_yyout);
     234             :         }
     235       58164 :         else if (str[i] == '\r' && str[i + 1] == '\n')
     236             :         {
     237           0 :             fputs("\\\r\n", base_yyout);
     238           0 :             i++;
     239             :         }
     240             :         else
     241       58164 :             fputc(str[i], base_yyout);
     242             :     }
     243             : 
     244        1598 :     if (quoted && str[0] == '"' && str[len] == '"')
     245         170 :         fputs("\"", base_yyout);
     246        1598 : }

Generated by: LCOV version 1.14