]> granicus.if.org Git - postgresql/commitdiff
In ecpg, automatically double single quotes in $$ strings because
authorBruce Momjian <bruce@momjian.us>
Sat, 4 Feb 2006 02:32:38 +0000 (02:32 +0000)
committerBruce Momjian <bruce@momjian.us>
Sat, 4 Feb 2006 02:32:38 +0000 (02:32 +0000)
internally $$ strings are converted to single-quote strings.

In ecpg, output newlines in commands using standard C escapes, rather
than using literal newlines, which is not portable.

src/interfaces/ecpg/preproc/output.c
src/interfaces/ecpg/preproc/pgc.l

index 27212ab4bc9d813db978761af8d90e2c0c43006c..2af7fdcaeb94050ad5a6e29067eb2f89ea780973 100644 (file)
@@ -2,6 +2,8 @@
 
 #include "extern.h"
 
+static void ouput_escaped_str(char *cmd);
+
 void
 output_line_number(void)
 {
@@ -10,21 +12,11 @@ output_line_number(void)
 }
 
 void
-output_simple_statement(char *cmd)
+output_simple_statement(char *stmt)
 {
-       int                     i,
-                               j = strlen(cmd);;
-
-       /* output this char by char as we have to filter '\"' */
-       for (i = 0; i < j; i++)
-       {
-               if (cmd[i] != '"')
-                       fputc(cmd[i], yyout);
-               else
-                       fputs("\\\"", yyout);
-       }
+       ouput_escaped_str(stmt);
        output_line_number();
-       free(cmd);
+       free(stmt);
 }
 
 /*
@@ -106,20 +98,8 @@ hashline_number(void)
 void
 output_statement(char *stmt, int mode, char *con)
 {
-       int                     i,
-                               j = strlen(stmt);
-
        fprintf(yyout, "{ ECPGdo(__LINE__, %d, %d, %s, \"", compat, force_indicator, con ? con : "NULL");
-
-       /* output this char by char as we have to filter '\"' */
-       for (i = 0; i < j; i++)
-       {
-               if (stmt[i] != '"')
-                       fputc(stmt[i], yyout);
-               else
-                       fputs("\\\"", yyout);
-       }
-
+       ouput_escaped_str(stmt);
        fputs("\", ", yyout);
 
        /* dump variables to C file */
@@ -135,3 +115,21 @@ output_statement(char *stmt, int mode, char *con)
        if (connection != NULL)
                free(connection);
 }
+
+
+static void
+ouput_escaped_str(char *str)
+{
+       int                     i, len = strlen(str);
+
+       /* output this char by char as we have to filter " and \n */
+       for (i = 0; i < len; i++)
+       {
+               if (str[i] == '"')
+                       fputs("\\\"", yyout);
+               else if (str[i] == '\n')
+                       fputs("\\n\\\n", yyout);
+               else
+                       fputc(str[i], yyout);
+       }
+}
index 16525da7b588f95b53b1d59a276e487491587a91..b9a6cfa60b1572ea577061958cfde71b0ab2311d 100644 (file)
@@ -12,7 +12,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/pgc.l,v 1.140 2006/02/02 03:51:41 momjian Exp $
+ *       $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/pgc.l,v 1.141 2006/02/04 02:32:38 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -152,7 +152,7 @@ dolq_start          [A-Za-z\200-\377_]
 dolq_cont              [A-Za-z\200-\377_0-9]
 dolqdelim              \$({dolq_start}{dolq_cont}*)?\$
 dolqfailed             \${dolq_start}{dolq_cont}*
-dolqinside             [^$]+
+dolqinside             [^$']+
 
 /* Double quote
  * Allows embedded spaces and other special characters into identifiers.
@@ -476,7 +476,10 @@ cppline                    {space}*#(.*\\{space})*.*{newline}
 <xdolq>{dolqinside}    { addlit(yytext, yyleng); }
 <xdolq>{dolqfailed}    { addlit(yytext, yyleng); }
 <xdolq>.       {
-                               /* This is only needed for $ inside the quoted text */
+                               /* $$ is implemented as a single-quoted string, so double it? */
+                               if (yytext[0] == '\'')
+                                       addlitchar(yytext[0]);
+                               /* single quote or dollar sign */
                                addlitchar(yytext[0]);
                        }
 <xdolq><<EOF>> { yyerror("unterminated dollar-quoted string"); }