/* src/interfaces/ecpg/preproc/output.c */ #include "postgres_fe.h" #include "preproc_extern.h" static void output_escaped_str(char *cmd, bool quoted); void output_line_number(void) { char *line = hashline_number(); fprintf(base_yyout, "%s", line); free(line); } void output_simple_statement(char *stmt, int whenever_mode) { output_escaped_str(stmt, false); if (whenever_mode) whenever_action(whenever_mode); output_line_number(); free(stmt); } /* * store the whenever action here */ struct when when_error, when_nf, when_warn; static void print_action(struct when *w) { switch (w->code) { case W_SQLPRINT: fprintf(base_yyout, "sqlprint();"); break; case W_GOTO: fprintf(base_yyout, "goto %s;", w->command); break; case W_DO: fprintf(base_yyout, "%s;", w->command); break; case W_STOP: fprintf(base_yyout, "exit (1);"); break; case W_BREAK: fprintf(base_yyout, "break;"); break; case W_CONTINUE: fprintf(base_yyout, "continue;"); break; default: fprintf(base_yyout, "{/* %d not implemented yet */}", w->code); break; } } void whenever_action(int mode) { if ((mode & 1) == 1 && when_nf.code != W_NOTHING) { output_line_number(); fprintf(base_yyout, "\nif (sqlca.sqlcode == ECPG_NOT_FOUND) "); print_action(&when_nf); } if (when_warn.code != W_NOTHING) { output_line_number(); fprintf(base_yyout, "\nif (sqlca.sqlwarn[0] == 'W') "); print_action(&when_warn); } if (when_error.code != W_NOTHING) { output_line_number(); fprintf(base_yyout, "\nif (sqlca.sqlcode < 0) "); print_action(&when_error); } if ((mode & 2) == 2) fputc('}', base_yyout); output_line_number(); } char * hashline_number(void) { /* do not print line numbers if we are in debug mode */ if (input_filename #ifdef YYDEBUG && !base_yydebug #endif ) { /* "* 2" here is for escaping '\' and '"' below */ char *line = mm_alloc(strlen("\n#line %d \"%s\"\n") + sizeof(int) * CHAR_BIT * 10 / 3 + strlen(input_filename) * 2); char *src, *dest; sprintf(line, "\n#line %d \"", base_yylineno); src = input_filename; dest = line + strlen(line); while (*src) { if (*src == '\\' || *src == '"') *dest++ = '\\'; *dest++ = *src++; } *dest = '\0'; strcat(dest, "\"\n"); return line; } return EMPTY; } static char *ecpg_statement_type_name[] = { "ECPGst_normal", "ECPGst_execute", "ECPGst_exec_immediate", "ECPGst_prepnormal", "ECPGst_prepare", "ECPGst_exec_with_exprlist" }; void output_statement(char *stmt, int whenever_mode, enum ECPG_statement_type st) { fprintf(base_yyout, "{ ECPGdo(__LINE__, %d, %d, %s, %d, ", compat, force_indicator, connection ? connection : "NULL", questionmarks); if (st == ECPGst_prepnormal && !auto_prepare) st = ECPGst_normal; /* * In following cases, stmt is CSTRING or char_variable. They must be * output directly. - prepared_name of EXECUTE without exprlist - * execstring of EXECUTE IMMEDIATE */ fprintf(base_yyout, "%s, ", ecpg_statement_type_name[st]); if (st == ECPGst_execute || st == ECPGst_exec_immediate) fprintf(base_yyout, "%s, ", stmt); else { fputs("\"", base_yyout); output_escaped_str(stmt, false); fputs("\", ", base_yyout); } /* dump variables to C file */ dump_variables(argsinsert, 1); fputs("ECPGt_EOIT, ", base_yyout); dump_variables(argsresult, 1); fputs("ECPGt_EORT);", base_yyout); reset_variables(); whenever_action(whenever_mode | 2); free(stmt); } void output_prepare_statement(char *name, char *stmt) { fprintf(base_yyout, "{ ECPGprepare(__LINE__, %s, %d, ", connection ? connection : "NULL", questionmarks); output_escaped_str(name, true); fputs(", ", base_yyout); output_escaped_str(stmt, true); fputs(");", base_yyout); whenever_action(2); free(name); } void output_deallocate_prepare_statement(char *name) { const char *con = connection ? connection : "NULL"; if (strcmp(name, "all") != 0) { fprintf(base_yyout, "{ ECPGdeallocate(__LINE__, %d, %s, ", compat, con); output_escaped_str(name, true); fputs(");", base_yyout); } else fprintf(base_yyout, "{ ECPGdeallocate_all(__LINE__, %d, %s);", compat, con); whenever_action(2); free(name); } static void output_escaped_str(char *str, bool quoted) { int i = 0; int len = strlen(str); if (quoted && str[0] == '"' && str[len - 1] == '"') /* do not escape quotes * at beginning and end * if quoted string */ { i = 1; len--; fputs("\"", base_yyout); } /* output this char by char as we have to filter " and \n */ for (; i < len; i++) { if (str[i] == '"') fputs("\\\"", base_yyout); else if (str[i] == '\n') fputs("\\\n", base_yyout); else if (str[i] == '\\') { int j = i; /* * check whether this is a continuation line if it is, do not * output anything because newlines are escaped anyway */ /* accept blanks after the '\' as some other compilers do too */ do { j++; } while (str[j] == ' ' || str[j] == '\t'); if ((str[j] != '\n') && (str[j] != '\r' || str[j + 1] != '\n')) /* not followed by a * newline */ fputs("\\\\", base_yyout); } else if (str[i] == '\r' && str[i + 1] == '\n') { fputs("\\\r\n", base_yyout); i++; } else fputc(str[i], base_yyout); } if (quoted && str[0] == '"' && str[len] == '"') fputs("\"", base_yyout); }