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

Generated by: LCOV version 1.13