Age Owner Branch data 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
7123 neilc@samurai.com 10 :CBC 2580 : output_line_number(void)
11 : : {
6402 bruce@momjian.us 12 : 2580 : char *line = hashline_number();
13 : :
2681 tgl@sss.pgh.pa.us 14 : 2580 : fprintf(base_yyout, "%s", line);
6640 meskes@postgresql.or 15 : 2580 : free(line);
8822 16 : 2580 : }
17 : :
18 : : void
1901 19 : 144 : output_simple_statement(char *stmt, int whenever_mode)
20 : : {
6088 21 : 144 : output_escaped_str(stmt, false);
1901 22 [ + + ]: 144 : if (whenever_mode)
23 : 11 : whenever_action(whenever_mode);
8822 24 : 144 : output_line_number();
6644 bruce@momjian.us 25 : 144 : free(stmt);
8822 meskes@postgresql.or 26 : 144 : }
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
2489 tgl@sss.pgh.pa.us 37 : 1044 : print_action(struct when *w)
38 : : {
8822 meskes@postgresql.or 39 [ + + + + : 1044 : switch (w->code)
+ + - ]
40 : : {
8207 bruce@momjian.us 41 : 562 : case W_SQLPRINT:
2681 tgl@sss.pgh.pa.us 42 : 562 : fprintf(base_yyout, "sqlprint();");
8768 bruce@momjian.us 43 : 562 : break;
44 : 2 : case W_GOTO:
2681 tgl@sss.pgh.pa.us 45 : 2 : fprintf(base_yyout, "goto %s;", w->command);
8768 bruce@momjian.us 46 : 2 : break;
47 : 170 : case W_DO:
2681 tgl@sss.pgh.pa.us 48 : 170 : fprintf(base_yyout, "%s;", w->command);
8768 bruce@momjian.us 49 : 170 : break;
50 : 297 : case W_STOP:
2681 tgl@sss.pgh.pa.us 51 : 297 : fprintf(base_yyout, "exit (1);");
8768 bruce@momjian.us 52 : 297 : break;
53 : 12 : case W_BREAK:
2681 tgl@sss.pgh.pa.us 54 : 12 : fprintf(base_yyout, "break;");
8768 bruce@momjian.us 55 : 12 : break;
2424 meskes@postgresql.or 56 : 1 : case W_CONTINUE:
57 : 1 : fprintf(base_yyout, "continue;");
58 : 1 : break;
8768 bruce@momjian.us 59 :UBC 0 : default:
2681 tgl@sss.pgh.pa.us 60 : 0 : fprintf(base_yyout, "{/* %d not implemented yet */}", w->code);
8768 bruce@momjian.us 61 : 0 : break;
62 : : }
8822 meskes@postgresql.or 63 :CBC 1044 : }
64 : :
65 : : void
66 : 1019 : whenever_action(int mode)
67 : : {
8768 bruce@momjian.us 68 [ + + + + ]: 1019 : if ((mode & 1) == 1 && when_nf.code != W_NOTHING)
69 : : {
8822 meskes@postgresql.or 70 : 29 : output_line_number();
2681 tgl@sss.pgh.pa.us 71 : 29 : fprintf(base_yyout, "\nif (sqlca.sqlcode == ECPG_NOT_FOUND) ");
8822 meskes@postgresql.or 72 : 29 : print_action(&when_nf);
73 : : }
74 [ + + ]: 1019 : if (when_warn.code != W_NOTHING)
75 : : {
76 : 148 : output_line_number();
2681 tgl@sss.pgh.pa.us 77 : 148 : fprintf(base_yyout, "\nif (sqlca.sqlwarn[0] == 'W') ");
8822 meskes@postgresql.or 78 : 148 : print_action(&when_warn);
79 : : }
80 [ + + ]: 1019 : if (when_error.code != W_NOTHING)
81 : : {
82 : 867 : output_line_number();
2681 tgl@sss.pgh.pa.us 83 : 867 : fprintf(base_yyout, "\nif (sqlca.sqlcode < 0) ");
8822 meskes@postgresql.or 84 : 867 : print_action(&when_error);
85 : : }
86 : :
8768 bruce@momjian.us 87 [ + + ]: 1019 : if ((mode & 2) == 2)
2681 tgl@sss.pgh.pa.us 88 : 974 : fputc('}', base_yyout);
89 : :
8822 meskes@postgresql.or 90 : 1019 : output_line_number();
91 : 1019 : }
92 : :
93 : : char *
94 : 2876 : hashline_number(void)
95 : : {
96 : : /* do not print line numbers if we are in debug mode */
6639 tgl@sss.pgh.pa.us 97 [ + - ]: 2876 : if (input_filename
98 : : #ifdef YYDEBUG
99 : : && !base_yydebug
100 : : #endif
101 : : )
102 : : {
103 : : /* "* 2" here is for escaping '\' and '"' below */
2489 104 : 2876 : 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 : :
2681 108 : 2876 : sprintf(line, "\n#line %d \"", base_yylineno);
3936 meskes@postgresql.or 109 : 2876 : src = input_filename;
110 : 2876 : dest = line + strlen(line);
111 [ + + ]: 249379 : while (*src)
112 : : {
3935 113 [ + - - + ]: 246503 : if (*src == '\\' || *src == '"')
3936 meskes@postgresql.or 114 :UBC 0 : *dest++ = '\\';
3936 meskes@postgresql.or 115 :CBC 246503 : *dest++ = *src++;
116 : : }
117 : 2876 : *dest = '\0';
118 : 2876 : strcat(dest, "\"\n");
119 : :
8768 bruce@momjian.us 120 : 2876 : return line;
121 : : }
122 : :
8768 bruce@momjian.us 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
6088 meskes@postgresql.or 136 :CBC 550 : output_statement(char *stmt, int whenever_mode, enum ECPG_statement_type st)
137 : : {
2681 tgl@sss.pgh.pa.us 138 [ + + ]: 550 : fprintf(base_yyout, "{ ECPGdo(__LINE__, %d, %d, %s, %d, ", compat, force_indicator, connection ? connection : "NULL", questionmarks);
139 : :
1789 meskes@postgresql.or 140 [ + + + + ]: 550 : if (st == ECPGst_prepnormal && !auto_prepare)
141 : 213 : 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 : 550 : fprintf(base_yyout, "%s, ", ecpg_statement_type_name[st]);
5233 149 [ + + + + ]: 550 : if (st == ECPGst_execute || st == ECPGst_exec_immediate)
1789 150 : 31 : fprintf(base_yyout, "%s, ", stmt);
151 : : else
152 : : {
153 : 519 : fputs("\"", base_yyout);
6088 154 : 519 : output_escaped_str(stmt, false);
2681 tgl@sss.pgh.pa.us 155 : 519 : fputs("\", ", base_yyout);
156 : : }
157 : :
158 : : /* dump variables to C file */
8243 meskes@postgresql.or 159 : 550 : dump_variables(argsinsert, 1);
2681 tgl@sss.pgh.pa.us 160 : 550 : fputs("ECPGt_EOIT, ", base_yyout);
8243 meskes@postgresql.or 161 : 550 : dump_variables(argsresult, 1);
2681 tgl@sss.pgh.pa.us 162 : 550 : fputs("ECPGt_EORT);", base_yyout);
8243 meskes@postgresql.or 163 : 550 : reset_variables();
164 : :
5995 bruce@momjian.us 165 : 550 : whenever_action(whenever_mode | 2);
8822 meskes@postgresql.or 166 : 550 : free(stmt);
167 : 550 : }
168 : :
169 : : void
6088 170 : 48 : output_prepare_statement(char *name, char *stmt)
171 : : {
2681 tgl@sss.pgh.pa.us 172 [ + + ]: 48 : fprintf(base_yyout, "{ ECPGprepare(__LINE__, %s, %d, ", connection ? connection : "NULL", questionmarks);
6088 meskes@postgresql.or 173 : 48 : output_escaped_str(name, true);
2681 tgl@sss.pgh.pa.us 174 : 48 : fputs(", ", base_yyout);
6088 meskes@postgresql.or 175 : 48 : output_escaped_str(stmt, true);
2681 tgl@sss.pgh.pa.us 176 : 48 : fputs(");", base_yyout);
6088 meskes@postgresql.or 177 : 48 : whenever_action(2);
178 : 48 : free(name);
179 : 48 : }
180 : :
181 : : void
182 : 38 : output_deallocate_prepare_statement(char *name)
183 : : {
5995 bruce@momjian.us 184 [ + + ]: 38 : const char *con = connection ? connection : "NULL";
185 : :
4492 peter_e@gmx.net 186 [ + + ]: 38 : if (strcmp(name, "all") != 0)
187 : : {
2681 tgl@sss.pgh.pa.us 188 : 37 : fprintf(base_yyout, "{ ECPGdeallocate(__LINE__, %d, %s, ", compat, con);
6088 meskes@postgresql.or 189 : 37 : output_escaped_str(name, true);
2681 tgl@sss.pgh.pa.us 190 : 37 : fputs(");", base_yyout);
191 : : }
192 : : else
193 : 1 : fprintf(base_yyout, "{ ECPGdeallocate_all(__LINE__, %d, %s);", compat, con);
194 : :
6088 meskes@postgresql.or 195 : 38 : whenever_action(2);
196 : 38 : free(name);
197 : 38 : }
198 : :
199 : : static void
200 : 796 : output_escaped_str(char *str, bool quoted)
201 : : {
5995 bruce@momjian.us 202 : 796 : int i = 0;
1668 tgl@sss.pgh.pa.us 203 : 796 : int len = strlen(str);
204 : :
2866 rhaas@postgresql.org 205 [ + + + + : 796 : if (quoted && str[0] == '"' && str[len - 1] == '"') /* do not escape quotes
+ - ]
206 : : * at beginning and end
207 : : * if quoted string */
208 : : {
6088 meskes@postgresql.or 209 : 85 : i = 1;
210 : 85 : len--;
2681 tgl@sss.pgh.pa.us 211 : 85 : fputs("\"", base_yyout);
212 : : }
213 : :
214 : : /* output this char by char as we have to filter " and \n */
6088 meskes@postgresql.or 215 [ + + ]: 29994 : for (; i < len; i++)
216 : : {
6644 bruce@momjian.us 217 [ + + ]: 29198 : if (str[i] == '"')
2681 tgl@sss.pgh.pa.us 218 : 104 : fputs("\\\"", base_yyout);
6644 bruce@momjian.us 219 [ + + ]: 29094 : else if (str[i] == '\n')
2681 tgl@sss.pgh.pa.us 220 : 18 : fputs("\\\n", base_yyout);
6088 meskes@postgresql.or 221 [ + + ]: 29076 : else if (str[i] == '\\')
222 : : {
5421 bruce@momjian.us 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 : :
2489 tgl@sss.pgh.pa.us 236 [ + - - + : 22 : if ((str[j] != '\n') && (str[j] != '\r' || str[j + 1] != '\n')) /* not followed by a
- - ]
237 : : * newline */
2681 238 : 22 : fputs("\\\\", base_yyout);
239 : : }
6402 bruce@momjian.us 240 [ - + - - ]: 29054 : else if (str[i] == '\r' && str[i + 1] == '\n')
241 : : {
2681 tgl@sss.pgh.pa.us 242 :UBC 0 : fputs("\\\r\n", base_yyout);
6452 meskes@postgresql.or 243 : 0 : i++;
244 : : }
245 : : else
2681 tgl@sss.pgh.pa.us 246 :CBC 29054 : fputc(str[i], base_yyout);
247 : : }
248 : :
3036 peter_e@gmx.net 249 [ + + + + : 796 : if (quoted && str[0] == '"' && str[len] == '"')
+ - ]
2681 tgl@sss.pgh.pa.us 250 : 85 : fputs("\"", base_yyout);
6644 bruce@momjian.us 251 : 796 : }
|