LCOV - differential code coverage report
Current view: top level - src/interfaces/ecpg/preproc - output.c (source / functions) Coverage Total Hit UBC CBC
Current: Differential Code Coverage HEAD vs 15 Lines: 94.6 % 129 122 7 122
Current Date: 2023-04-08 15:15:32 Functions: 100.0 % 9 9 9
Baseline: 15
Baseline Date: 2023-04-08 15:09:40
Legend: Lines: hit not hit

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

Generated by: LCOV version v1.16-55-g56c0a2a