From: Bruce Momjian Date: Sat, 4 Feb 2006 02:32:38 +0000 (+0000) Subject: In ecpg, automatically double single quotes in $$ strings because X-Git-Tag: REL8_2_BETA1~1507 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b3769066b8427eb19ee918187b457271f97950af;p=postgresql In ecpg, automatically double single quotes in $$ strings because 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. --- diff --git a/src/interfaces/ecpg/preproc/output.c b/src/interfaces/ecpg/preproc/output.c index 27212ab4bc..2af7fdcaeb 100644 --- a/src/interfaces/ecpg/preproc/output.c +++ b/src/interfaces/ecpg/preproc/output.c @@ -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); + } +} diff --git a/src/interfaces/ecpg/preproc/pgc.l b/src/interfaces/ecpg/preproc/pgc.l index 16525da7b5..b9a6cfa60b 100644 --- a/src/interfaces/ecpg/preproc/pgc.l +++ b/src/interfaces/ecpg/preproc/pgc.l @@ -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} {dolqinside} { addlit(yytext, yyleng); } {dolqfailed} { addlit(yytext, yyleng); } . { - /* 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]); } <> { yyerror("unterminated dollar-quoted string"); }