PostgreSQL Source Code  git master
output.c
Go to the documentation of this file.
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
11 {
12  char *line = hashline_number();
13 
14  fprintf(base_yyout, "%s", line);
15 }
16 
17 void
18 output_simple_statement(const char *stmt, int whenever_mode)
19 {
20  output_escaped_str(stmt, false);
21  if (whenever_mode)
22  whenever_action(whenever_mode);
24 }
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
35 print_action(struct when *w)
36 {
37  switch (w->code)
38  {
39  case W_SQLPRINT:
40  fprintf(base_yyout, "sqlprint();");
41  break;
42  case W_GOTO:
43  fprintf(base_yyout, "goto %s;", w->command);
44  break;
45  case W_DO:
46  fprintf(base_yyout, "%s;", w->command);
47  break;
48  case W_STOP:
49  fprintf(base_yyout, "exit (1);");
50  break;
51  case W_BREAK:
52  fprintf(base_yyout, "break;");
53  break;
54  case W_CONTINUE:
55  fprintf(base_yyout, "continue;");
56  break;
57  default:
58  fprintf(base_yyout, "{/* %d not implemented yet */}", w->code);
59  break;
60  }
61 }
62 
63 void
65 {
66  if ((mode & 1) == 1 && when_nf.code != W_NOTHING)
67  {
69  fprintf(base_yyout, "\nif (sqlca.sqlcode == ECPG_NOT_FOUND) ");
70  print_action(&when_nf);
71  }
72  if (when_warn.code != W_NOTHING)
73  {
75  fprintf(base_yyout, "\nif (sqlca.sqlwarn[0] == 'W') ");
77  }
78  if (when_error.code != W_NOTHING)
79  {
81  fprintf(base_yyout, "\nif (sqlca.sqlcode < 0) ");
82  print_action(&when_error);
83  }
84 
85  if ((mode & 2) == 2)
86  fputc('}', base_yyout);
87 
89 }
90 
91 char *
93 {
94  /* do not print line numbers if we are in debug mode */
95  if (input_filename
96 #ifdef YYDEBUG
97  && !base_yydebug
98 #endif
99  )
100  {
101  /* "* 2" here is for escaping '\' and '"' below */
102  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 
106  sprintf(line, "\n#line %d \"", base_yylineno);
107  src = input_filename;
108  dest = line + strlen(line);
109  while (*src)
110  {
111  if (*src == '\\' || *src == '"')
112  *dest++ = '\\';
113  *dest++ = *src++;
114  }
115  *dest = '\0';
116  strcat(dest, "\"\n");
117 
118  return line;
119  }
120 
121  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
134 output_statement(const char *stmt, int whenever_mode, enum ECPG_statement_type st)
135 {
136  fprintf(base_yyout, "{ ECPGdo(__LINE__, %d, %d, %s, %d, ", compat, force_indicator, connection ? connection : "NULL", questionmarks);
137 
138  if (st == ECPGst_prepnormal && !auto_prepare)
139  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  */
147  if (st == ECPGst_execute || st == ECPGst_exec_immediate)
148  fprintf(base_yyout, "%s, ", stmt);
149  else
150  {
151  fputs("\"", base_yyout);
152  output_escaped_str(stmt, false);
153  fputs("\", ", base_yyout);
154  }
155 
156  /* dump variables to C file */
158  argsinsert = NULL;
159  fputs("ECPGt_EOIT, ", base_yyout);
161  argsresult = NULL;
162  fputs("ECPGt_EORT);", base_yyout);
163 
164  whenever_action(whenever_mode | 2);
165 }
166 
167 void
168 output_prepare_statement(const char *name, const char *stmt)
169 {
170  fprintf(base_yyout, "{ ECPGprepare(__LINE__, %s, %d, ", connection ? connection : "NULL", questionmarks);
171  output_escaped_str(name, true);
172  fputs(", ", base_yyout);
173  output_escaped_str(stmt, true);
174  fputs(");", base_yyout);
175  whenever_action(2);
176 }
177 
178 void
180 {
181  const char *con = connection ? connection : "NULL";
182 
183  if (strcmp(name, "all") != 0)
184  {
185  fprintf(base_yyout, "{ ECPGdeallocate(__LINE__, %d, %s, ", compat, con);
186  output_escaped_str(name, true);
187  fputs(");", base_yyout);
188  }
189  else
190  fprintf(base_yyout, "{ ECPGdeallocate_all(__LINE__, %d, %s);", compat, con);
191 
192  whenever_action(2);
193 }
194 
195 static void
196 output_escaped_str(const char *str, bool quoted)
197 {
198  int i = 0;
199  int len = strlen(str);
200 
201  if (quoted && str[0] == '"' && str[len - 1] == '"') /* do not escape quotes
202  * at beginning and end
203  * if quoted string */
204  {
205  i = 1;
206  len--;
207  fputs("\"", base_yyout);
208  }
209 
210  /* output this char by char as we have to filter " and \n */
211  for (; i < len; i++)
212  {
213  if (str[i] == '"')
214  fputs("\\\"", base_yyout);
215  else if (str[i] == '\n')
216  fputs("\\\n", base_yyout);
217  else if (str[i] == '\\')
218  {
219  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  j++;
230  } while (str[j] == ' ' || str[j] == '\t');
231 
232  if ((str[j] != '\n') && (str[j] != '\r' || str[j + 1] != '\n')) /* not followed by a
233  * newline */
234  fputs("\\\\", base_yyout);
235  }
236  else if (str[i] == '\r' && str[i + 1] == '\n')
237  {
238  fputs("\\\r\n", base_yyout);
239  i++;
240  }
241  else
242  fputc(str[i], base_yyout);
243  }
244 
245  if (quoted && str[0] == '"' && str[len] == '"')
246  fputs("\"", base_yyout);
247 }
bool auto_prepare
Definition: ecpg.c:21
enum COMPAT_MODE compat
Definition: ecpg.c:26
bool force_indicator
Definition: ecpg.c:18
bool questionmarks
Definition: ecpg.c:19
ECPG_statement_type
Definition: ecpgtype.h:96
@ ECPGst_normal
Definition: ecpgtype.h:97
@ ECPGst_execute
Definition: ecpgtype.h:98
@ ECPGst_exec_immediate
Definition: ecpgtype.h:99
@ ECPGst_prepnormal
Definition: ecpgtype.h:100
const char * str
#define stmt
Definition: indent_codes.h:59
int j
Definition: isn.c:73
int i
Definition: isn.c:72
void output_line_number(void)
Definition: output.c:10
void output_simple_statement(const char *stmt, int whenever_mode)
Definition: output.c:18
void output_prepare_statement(const char *name, const char *stmt)
Definition: output.c:168
struct when when_error when_nf when_warn
Definition: output.c:30
void whenever_action(int mode)
Definition: output.c:64
static char * ecpg_statement_type_name[]
Definition: output.c:124
void output_statement(const char *stmt, int whenever_mode, enum ECPG_statement_type st)
Definition: output.c:134
static void print_action(struct when *w)
Definition: output.c:35
char * hashline_number(void)
Definition: output.c:92
static void output_escaped_str(const char *str, bool quoted)
Definition: output.c:196
void output_deallocate_prepare_statement(const char *name)
Definition: output.c:179
static PgChecksumMode mode
Definition: pg_checksums.c:55
const void size_t len
#define sprintf
Definition: port.h:240
#define fprintf
Definition: port.h:242
char * connection
void dump_variables(struct arguments *list, int mode)
Definition: variable.c:461
int base_yylineno
char * input_filename
struct arguments * argsresult
Definition: variable.c:375
struct arguments * argsinsert
Definition: variable.c:374
void * loc_alloc(size_t size)
Definition: util.c:138
FILE * base_yyout
Definition: type.h:89
char * command
Definition: type.h:91
enum WHEN_TYPE code
Definition: type.h:90
@ W_STOP
Definition: type.h:85
@ W_GOTO
Definition: type.h:83
@ W_SQLPRINT
Definition: type.h:82
@ W_BREAK
Definition: type.h:81
@ W_CONTINUE
Definition: type.h:80
@ W_DO
Definition: type.h:84
@ W_NOTHING
Definition: type.h:79
const char * name