Age Owner 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
6752 neilc 10 CBC 2500 : output_line_number(void)
11 : {
6031 bruce 12 2500 : char *line = hashline_number();
13 :
2310 tgl 14 2500 : fprintf(base_yyout, "%s", line);
6269 meskes 15 2500 : free(line);
8451 16 2500 : }
17 :
18 : void
1530 19 140 : output_simple_statement(char *stmt, int whenever_mode)
20 : {
5717 21 140 : output_escaped_str(stmt, false);
1530 22 140 : if (whenever_mode)
23 11 : whenever_action(whenever_mode);
8451 24 140 : output_line_number();
6273 bruce 25 140 : free(stmt);
8451 meskes 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
2118 tgl 37 1008 : print_action(struct when *w)
38 : {
8451 meskes 39 1008 : switch (w->code)
40 : {
7836 bruce 41 531 : case W_SQLPRINT:
2310 tgl 42 531 : fprintf(base_yyout, "sqlprint();");
8397 bruce 43 531 : break;
44 2 : case W_GOTO:
2310 tgl 45 2 : fprintf(base_yyout, "goto %s;", w->command);
8397 bruce 46 2 : break;
47 171 : case W_DO:
2310 tgl 48 171 : fprintf(base_yyout, "%s;", w->command);
8397 bruce 49 171 : break;
50 291 : case W_STOP:
2310 tgl 51 291 : fprintf(base_yyout, "exit (1);");
8397 bruce 52 291 : break;
53 12 : case W_BREAK:
2310 tgl 54 12 : fprintf(base_yyout, "break;");
8397 bruce 55 12 : break;
2053 meskes 56 1 : case W_CONTINUE:
57 1 : fprintf(base_yyout, "continue;");
58 1 : break;
8397 bruce 59 UBC 0 : default:
2310 tgl 60 0 : fprintf(base_yyout, "{/* %d not implemented yet */}", w->code);
8397 bruce 61 0 : break;
62 : }
8451 meskes 63 CBC 1008 : }
64 :
65 : void
66 989 : whenever_action(int mode)
67 : {
8397 bruce 68 989 : if ((mode & 1) == 1 && when_nf.code != W_NOTHING)
69 : {
8451 meskes 70 28 : output_line_number();
2310 tgl 71 28 : fprintf(base_yyout, "\nif (sqlca.sqlcode == ECPG_NOT_FOUND) ");
8451 meskes 72 28 : print_action(&when_nf);
73 : }
74 989 : if (when_warn.code != W_NOTHING)
75 : {
76 143 : output_line_number();
2310 tgl 77 143 : fprintf(base_yyout, "\nif (sqlca.sqlwarn[0] == 'W') ");
8451 meskes 78 143 : print_action(&when_warn);
79 : }
80 989 : if (when_error.code != W_NOTHING)
81 : {
82 837 : output_line_number();
2310 tgl 83 837 : fprintf(base_yyout, "\nif (sqlca.sqlcode < 0) ");
8451 meskes 84 837 : print_action(&when_error);
85 : }
86 :
8397 bruce 87 989 : if ((mode & 2) == 2)
2310 tgl 88 944 : fputc('}', base_yyout);
89 :
8451 meskes 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 */
6268 tgl 97 2793 : if (input_filename
98 : #ifdef YYDEBUG
99 : && !base_yydebug
100 : #endif
101 : )
102 : {
103 : /* "* 2" here is for escaping '\' and '"' below */
2118 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 :
2310 108 2793 : sprintf(line, "\n#line %d \"", base_yylineno);
3565 meskes 109 2793 : src = input_filename;
110 2793 : dest = line + strlen(line);
111 203311 : while (*src)
112 : {
3564 113 200518 : if (*src == '\\' || *src == '"')
3565 meskes 114 UBC 0 : *dest++ = '\\';
3565 meskes 115 CBC 200518 : *dest++ = *src++;
116 : }
117 2793 : *dest = '\0';
118 2793 : strcat(dest, "\"\n");
119 :
8397 bruce 120 2793 : return line;
121 : }
122 :
8397 bruce 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
5717 meskes 136 CBC 525 : output_statement(char *stmt, int whenever_mode, enum ECPG_statement_type st)
137 : {
2310 tgl 138 525 : fprintf(base_yyout, "{ ECPGdo(__LINE__, %d, %d, %s, %d, ", compat, force_indicator, connection ? connection : "NULL", questionmarks);
139 :
1418 meskes 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]);
4862 149 525 : if (st == ECPGst_execute || st == ECPGst_exec_immediate)
1418 150 31 : fprintf(base_yyout, "%s, ", stmt);
151 : else
152 : {
153 494 : fputs("\"", base_yyout);
5717 154 494 : output_escaped_str(stmt, false);
2310 tgl 155 494 : fputs("\", ", base_yyout);
156 : }
157 :
158 : /* dump variables to C file */
7872 meskes 159 525 : dump_variables(argsinsert, 1);
2310 tgl 160 525 : fputs("ECPGt_EOIT, ", base_yyout);
7872 meskes 161 525 : dump_variables(argsresult, 1);
2310 tgl 162 525 : fputs("ECPGt_EORT);", base_yyout);
7872 meskes 163 525 : reset_variables();
164 :
5624 bruce 165 525 : whenever_action(whenever_mode | 2);
8451 meskes 166 525 : free(stmt);
167 525 : }
168 :
169 : void
5717 170 47 : output_prepare_statement(char *name, char *stmt)
171 : {
2310 tgl 172 47 : fprintf(base_yyout, "{ ECPGprepare(__LINE__, %s, %d, ", connection ? connection : "NULL", questionmarks);
5717 meskes 173 47 : output_escaped_str(name, true);
2310 tgl 174 47 : fputs(", ", base_yyout);
5717 meskes 175 47 : output_escaped_str(stmt, true);
2310 tgl 176 47 : fputs(");", base_yyout);
5717 meskes 177 47 : whenever_action(2);
178 47 : free(name);
179 47 : }
180 :
181 : void
182 38 : output_deallocate_prepare_statement(char *name)
183 : {
5624 bruce 184 38 : const char *con = connection ? connection : "NULL";
185 :
4121 peter_e 186 38 : if (strcmp(name, "all") != 0)
187 : {
2310 tgl 188 37 : fprintf(base_yyout, "{ ECPGdeallocate(__LINE__, %d, %s, ", compat, con);
5717 meskes 189 37 : output_escaped_str(name, true);
2310 tgl 190 37 : fputs(");", base_yyout);
191 : }
192 : else
193 1 : fprintf(base_yyout, "{ ECPGdeallocate_all(__LINE__, %d, %s);", compat, con);
194 :
5717 meskes 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 : {
5624 bruce 202 765 : int i = 0;
1297 tgl 203 765 : int len = strlen(str);
204 :
2495 rhaas 205 765 : if (quoted && str[0] == '"' && str[len - 1] == '"') /* do not escape quotes
206 : * at beginning and end
207 : * if quoted string */
208 : {
5717 meskes 209 83 : i = 1;
210 83 : len--;
2310 tgl 211 83 : fputs("\"", base_yyout);
212 : }
213 :
214 : /* output this char by char as we have to filter " and \n */
5717 meskes 215 28626 : for (; i < len; i++)
216 : {
6273 bruce 217 27861 : if (str[i] == '"')
2310 tgl 218 78 : fputs("\\\"", base_yyout);
6273 bruce 219 27783 : else if (str[i] == '\n')
2310 tgl 220 18 : fputs("\\\n", base_yyout);
5717 meskes 221 27765 : else if (str[i] == '\\')
222 : {
5050 bruce 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 :
2118 tgl 236 22 : if ((str[j] != '\n') && (str[j] != '\r' || str[j + 1] != '\n')) /* not followed by a
237 : * newline */
2310 238 22 : fputs("\\\\", base_yyout);
239 : }
6031 bruce 240 27743 : else if (str[i] == '\r' && str[i + 1] == '\n')
241 : {
2310 tgl 242 UBC 0 : fputs("\\\r\n", base_yyout);
6081 meskes 243 0 : i++;
244 : }
245 : else
2310 tgl 246 CBC 27743 : fputc(str[i], base_yyout);
247 : }
248 :
2665 peter_e 249 765 : if (quoted && str[0] == '"' && str[len] == '"')
2310 tgl 250 83 : fputs("\"", base_yyout);
6273 bruce 251 765 : }
|