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(const char *str, bool quoted);
8 : :
9 : : void
7633 neilc@samurai.com 10 :CBC 2608 : output_line_number(void)
11 : : {
6912 bruce@momjian.us 12 : 2608 : char *line = hashline_number();
13 : :
3191 tgl@sss.pgh.pa.us 14 : 2608 : fprintf(base_yyout, "%s", line);
9332 meskes@postgresql.or 15 : 2608 : }
16 : :
17 : : void
327 tgl@sss.pgh.pa.us 18 : 150 : output_simple_statement(const char *stmt, int whenever_mode)
19 : : {
6598 meskes@postgresql.or 20 : 150 : output_escaped_str(stmt, false);
2411 21 [ + + ]: 150 : if (whenever_mode)
22 : 13 : whenever_action(whenever_mode);
9332 23 : 150 : output_line_number();
24 : 150 : }
25 : :
26 : :
27 : : /*
28 : : * store the whenever action here
29 : : */
30 : : struct when when_error,
31 : : when_nf,
32 : : when_warn;
33 : :
34 : : static void
2999 tgl@sss.pgh.pa.us 35 : 1047 : print_action(struct when *w)
36 : : {
9332 meskes@postgresql.or 37 [ + + + + : 1047 : switch (w->code)
+ + - ]
38 : : {
8717 bruce@momjian.us 39 : 562 : case W_SQLPRINT:
3191 tgl@sss.pgh.pa.us 40 : 562 : fprintf(base_yyout, "sqlprint();");
9278 bruce@momjian.us 41 : 562 : break;
42 : 2 : case W_GOTO:
3191 tgl@sss.pgh.pa.us 43 : 2 : fprintf(base_yyout, "goto %s;", w->command);
9278 bruce@momjian.us 44 : 2 : break;
45 : 173 : case W_DO:
3191 tgl@sss.pgh.pa.us 46 : 173 : fprintf(base_yyout, "%s;", w->command);
9278 bruce@momjian.us 47 : 173 : break;
48 : 297 : case W_STOP:
3191 tgl@sss.pgh.pa.us 49 : 297 : fprintf(base_yyout, "exit (1);");
9278 bruce@momjian.us 50 : 297 : break;
51 : 12 : case W_BREAK:
3191 tgl@sss.pgh.pa.us 52 : 12 : fprintf(base_yyout, "break;");
9278 bruce@momjian.us 53 : 12 : break;
2934 meskes@postgresql.or 54 : 1 : case W_CONTINUE:
55 : 1 : fprintf(base_yyout, "continue;");
56 : 1 : break;
9278 bruce@momjian.us 57 :UBC 0 : default:
3191 tgl@sss.pgh.pa.us 58 : 0 : fprintf(base_yyout, "{/* %d not implemented yet */}", w->code);
9278 bruce@momjian.us 59 : 0 : break;
60 : : }
9332 meskes@postgresql.or 61 :CBC 1047 : }
62 : :
63 : : void
64 : 1033 : whenever_action(int mode)
65 : : {
9278 bruce@momjian.us 66 [ + + + + ]: 1033 : if ((mode & 1) == 1 && when_nf.code != W_NOTHING)
67 : : {
9332 meskes@postgresql.or 68 : 29 : output_line_number();
3191 tgl@sss.pgh.pa.us 69 : 29 : fprintf(base_yyout, "\nif (sqlca.sqlcode == ECPG_NOT_FOUND) ");
9332 meskes@postgresql.or 70 : 29 : print_action(&when_nf);
71 : : }
72 [ + + ]: 1033 : if (when_warn.code != W_NOTHING)
73 : : {
74 : 148 : output_line_number();
3191 tgl@sss.pgh.pa.us 75 : 148 : fprintf(base_yyout, "\nif (sqlca.sqlwarn[0] == 'W') ");
9332 meskes@postgresql.or 76 : 148 : print_action(&when_warn);
77 : : }
78 [ + + ]: 1033 : if (when_error.code != W_NOTHING)
79 : : {
80 : 870 : output_line_number();
3191 tgl@sss.pgh.pa.us 81 : 870 : fprintf(base_yyout, "\nif (sqlca.sqlcode < 0) ");
9332 meskes@postgresql.or 82 : 870 : print_action(&when_error);
83 : : }
84 : :
9278 bruce@momjian.us 85 [ + + ]: 1033 : if ((mode & 2) == 2)
3191 tgl@sss.pgh.pa.us 86 : 986 : fputc('}', base_yyout);
87 : :
9332 meskes@postgresql.or 88 : 1033 : output_line_number();
89 : 1033 : }
90 : :
91 : : char *
92 : 2907 : hashline_number(void)
93 : : {
94 : : /* do not print line numbers if we are in debug mode */
7149 tgl@sss.pgh.pa.us 95 [ + - ]: 2907 : if (input_filename
96 : : #ifdef YYDEBUG
97 : : && !base_yydebug
98 : : #endif
99 : : )
100 : : {
101 : : /* "* 2" here is for escaping '\' and '"' below */
327 102 : 2907 : char *line = loc_alloc(strlen("\n#line %d \"%s\"\n") + sizeof(int) * CHAR_BIT * 10 / 3 + strlen(input_filename) * 2);
103 : : char *src,
104 : : *dest;
105 : :
3191 106 : 2907 : sprintf(line, "\n#line %d \"", base_yylineno);
4446 meskes@postgresql.or 107 : 2907 : src = input_filename;
108 : 2907 : dest = line + strlen(line);
109 [ + + ]: 187061 : while (*src)
110 : : {
4445 111 [ + - - + ]: 184154 : if (*src == '\\' || *src == '"')
4446 meskes@postgresql.or 112 :UBC 0 : *dest++ = '\\';
4446 meskes@postgresql.or 113 :CBC 184154 : *dest++ = *src++;
114 : : }
115 : 2907 : *dest = '\0';
116 : 2907 : strcat(dest, "\"\n");
117 : :
9278 bruce@momjian.us 118 : 2907 : return line;
119 : : }
120 : :
327 tgl@sss.pgh.pa.us 121 :UBC 0 : return "";
122 : : }
123 : :
124 : : static char *ecpg_statement_type_name[] = {
125 : : "ECPGst_normal",
126 : : "ECPGst_execute",
127 : : "ECPGst_exec_immediate",
128 : : "ECPGst_prepnormal",
129 : : "ECPGst_prepare",
130 : : "ECPGst_exec_with_exprlist"
131 : : };
132 : :
133 : : void
327 tgl@sss.pgh.pa.us 134 :CBC 556 : output_statement(const char *stmt, int whenever_mode, enum ECPG_statement_type st)
135 : : {
3191 136 [ + + ]: 556 : fprintf(base_yyout, "{ ECPGdo(__LINE__, %d, %d, %s, %d, ", compat, force_indicator, connection ? connection : "NULL", questionmarks);
137 : :
2299 meskes@postgresql.or 138 [ + + + + ]: 556 : if (st == ECPGst_prepnormal && !auto_prepare)
139 : 217 : st = ECPGst_normal;
140 : :
141 : : /*
142 : : * In following cases, stmt is CSTRING or char_variable. They must be
143 : : * output directly. - prepared_name of EXECUTE without exprlist -
144 : : * execstring of EXECUTE IMMEDIATE
145 : : */
146 : 556 : fprintf(base_yyout, "%s, ", ecpg_statement_type_name[st]);
5743 147 [ + + + + ]: 556 : if (st == ECPGst_execute || st == ECPGst_exec_immediate)
2299 148 : 31 : fprintf(base_yyout, "%s, ", stmt);
149 : : else
150 : : {
151 : 525 : fputs("\"", base_yyout);
6598 152 : 525 : output_escaped_str(stmt, false);
3191 tgl@sss.pgh.pa.us 153 : 525 : fputs("\", ", base_yyout);
154 : : }
155 : :
156 : : /* dump variables to C file */
8753 meskes@postgresql.or 157 : 556 : dump_variables(argsinsert, 1);
283 tgl@sss.pgh.pa.us 158 : 556 : argsinsert = NULL;
3191 159 : 556 : fputs("ECPGt_EOIT, ", base_yyout);
8753 meskes@postgresql.or 160 : 556 : dump_variables(argsresult, 1);
283 tgl@sss.pgh.pa.us 161 : 556 : argsresult = NULL;
3191 162 : 556 : fputs("ECPGt_EORT);", base_yyout);
163 : :
6505 bruce@momjian.us 164 : 556 : whenever_action(whenever_mode | 2);
9332 meskes@postgresql.or 165 : 556 : }
166 : :
167 : : void
327 tgl@sss.pgh.pa.us 168 : 48 : output_prepare_statement(const char *name, const char *stmt)
169 : : {
3191 170 [ + + ]: 48 : fprintf(base_yyout, "{ ECPGprepare(__LINE__, %s, %d, ", connection ? connection : "NULL", questionmarks);
6598 meskes@postgresql.or 171 : 48 : output_escaped_str(name, true);
3191 tgl@sss.pgh.pa.us 172 : 48 : fputs(", ", base_yyout);
6598 meskes@postgresql.or 173 : 48 : output_escaped_str(stmt, true);
3191 tgl@sss.pgh.pa.us 174 : 48 : fputs(");", base_yyout);
6598 meskes@postgresql.or 175 : 48 : whenever_action(2);
176 : 48 : }
177 : :
178 : : void
327 tgl@sss.pgh.pa.us 179 : 38 : output_deallocate_prepare_statement(const char *name)
180 : : {
6505 bruce@momjian.us 181 [ + + ]: 38 : const char *con = connection ? connection : "NULL";
182 : :
5002 peter_e@gmx.net 183 [ + + ]: 38 : if (strcmp(name, "all") != 0)
184 : : {
3191 tgl@sss.pgh.pa.us 185 : 37 : fprintf(base_yyout, "{ ECPGdeallocate(__LINE__, %d, %s, ", compat, con);
6598 meskes@postgresql.or 186 : 37 : output_escaped_str(name, true);
3191 tgl@sss.pgh.pa.us 187 : 37 : fputs(");", base_yyout);
188 : : }
189 : : else
190 : 1 : fprintf(base_yyout, "{ ECPGdeallocate_all(__LINE__, %d, %s);", compat, con);
191 : :
6598 meskes@postgresql.or 192 : 38 : whenever_action(2);
193 : 38 : }
194 : :
195 : : static void
327 tgl@sss.pgh.pa.us 196 : 808 : output_escaped_str(const char *str, bool quoted)
197 : : {
6505 bruce@momjian.us 198 : 808 : int i = 0;
2178 tgl@sss.pgh.pa.us 199 : 808 : int len = strlen(str);
200 : :
3376 rhaas@postgresql.org 201 [ + + + + : 808 : if (quoted && str[0] == '"' && str[len - 1] == '"') /* do not escape quotes
+ - ]
202 : : * at beginning and end
203 : : * if quoted string */
204 : : {
6598 meskes@postgresql.or 205 : 85 : i = 1;
206 : 85 : len--;
3191 tgl@sss.pgh.pa.us 207 : 85 : fputs("\"", base_yyout);
208 : : }
209 : :
210 : : /* output this char by char as we have to filter " and \n */
6598 meskes@postgresql.or 211 [ + + ]: 30467 : for (; i < len; i++)
212 : : {
7154 bruce@momjian.us 213 [ + + ]: 29659 : if (str[i] == '"')
3191 tgl@sss.pgh.pa.us 214 : 104 : fputs("\\\"", base_yyout);
7154 bruce@momjian.us 215 [ + + ]: 29555 : else if (str[i] == '\n')
3191 tgl@sss.pgh.pa.us 216 : 20 : fputs("\\\n", base_yyout);
6598 meskes@postgresql.or 217 [ + + ]: 29535 : else if (str[i] == '\\')
218 : : {
5931 bruce@momjian.us 219 : 22 : int j = i;
220 : :
221 : : /*
222 : : * check whether this is a continuation line if it is, do not
223 : : * output anything because newlines are escaped anyway
224 : : */
225 : :
226 : : /* accept blanks after the '\' as some other compilers do too */
227 : : do
228 : : {
229 : 22 : j++;
230 [ - + - + ]: 22 : } while (str[j] == ' ' || str[j] == '\t');
231 : :
2999 tgl@sss.pgh.pa.us 232 [ + - - + : 22 : if ((str[j] != '\n') && (str[j] != '\r' || str[j + 1] != '\n')) /* not followed by a
- - ]
233 : : * newline */
3191 234 : 22 : fputs("\\\\", base_yyout);
235 : : }
6912 bruce@momjian.us 236 [ - + - - ]: 29513 : else if (str[i] == '\r' && str[i + 1] == '\n')
237 : : {
3191 tgl@sss.pgh.pa.us 238 :UBC 0 : fputs("\\\r\n", base_yyout);
6962 meskes@postgresql.or 239 : 0 : i++;
240 : : }
241 : : else
3191 tgl@sss.pgh.pa.us 242 :CBC 29513 : fputc(str[i], base_yyout);
243 : : }
244 : :
3546 peter_e@gmx.net 245 [ + + + + : 808 : if (quoted && str[0] == '"' && str[len] == '"')
+ - ]
3191 tgl@sss.pgh.pa.us 246 : 85 : fputs("\"", base_yyout);
7154 bruce@momjian.us 247 : 808 : }
|