Header And Logo

PostgreSQL
| The world's most advanced open source database.

output.c

Go to the documentation of this file.
00001 /* src/interfaces/ecpg/preproc/output.c */
00002 
00003 #include "postgres_fe.h"
00004 
00005 #include "extern.h"
00006 
00007 static void output_escaped_str(char *cmd, bool quoted);
00008 
00009 void
00010 output_line_number(void)
00011 {
00012     char       *line = hashline_number();
00013 
00014     fprintf(yyout, "%s", line);
00015     free(line);
00016 }
00017 
00018 void
00019 output_simple_statement(char *stmt)
00020 {
00021     output_escaped_str(stmt, false);
00022     output_line_number();
00023     free(stmt);
00024 }
00025 
00026 
00027 /*
00028  * store the whenever action here
00029  */
00030 struct when when_error,
00031             when_nf,
00032             when_warn;
00033 
00034 static void
00035 print_action(struct when * w)
00036 {
00037     switch (w->code)
00038     {
00039         case W_SQLPRINT:
00040             fprintf(yyout, "sqlprint();");
00041             break;
00042         case W_GOTO:
00043             fprintf(yyout, "goto %s;", w->command);
00044             break;
00045         case W_DO:
00046             fprintf(yyout, "%s;", w->command);
00047             break;
00048         case W_STOP:
00049             fprintf(yyout, "exit (1);");
00050             break;
00051         case W_BREAK:
00052             fprintf(yyout, "break;");
00053             break;
00054         default:
00055             fprintf(yyout, "{/* %d not implemented yet */}", w->code);
00056             break;
00057     }
00058 }
00059 
00060 void
00061 whenever_action(int mode)
00062 {
00063     if ((mode & 1) == 1 && when_nf.code != W_NOTHING)
00064     {
00065         output_line_number();
00066         fprintf(yyout, "\nif (sqlca.sqlcode == ECPG_NOT_FOUND) ");
00067         print_action(&when_nf);
00068     }
00069     if (when_warn.code != W_NOTHING)
00070     {
00071         output_line_number();
00072         fprintf(yyout, "\nif (sqlca.sqlwarn[0] == 'W') ");
00073         print_action(&when_warn);
00074     }
00075     if (when_error.code != W_NOTHING)
00076     {
00077         output_line_number();
00078         fprintf(yyout, "\nif (sqlca.sqlcode < 0) ");
00079         print_action(&when_error);
00080     }
00081 
00082     if ((mode & 2) == 2)
00083         fputc('}', yyout);
00084 
00085     output_line_number();
00086 }
00087 
00088 char *
00089 hashline_number(void)
00090 {
00091     /* do not print line numbers if we are in debug mode */
00092     if (input_filename
00093 #ifdef YYDEBUG
00094         && !yydebug
00095 #endif
00096         )
00097     {
00098         char       *line = mm_alloc(strlen("\n#line %d \"%s\"\n") + sizeof(int) * CHAR_BIT * 10 / 3 + strlen(input_filename));
00099 
00100         sprintf(line, "\n#line %d \"%s\"\n", yylineno, input_filename);
00101 
00102         return line;
00103     }
00104 
00105     return EMPTY;
00106 }
00107 
00108 static char *ecpg_statement_type_name[] = {
00109     "ECPGst_normal",
00110     "ECPGst_execute",
00111     "ECPGst_exec_immediate",
00112     "ECPGst_prepnormal"
00113 };
00114 
00115 void
00116 output_statement(char *stmt, int whenever_mode, enum ECPG_statement_type st)
00117 {
00118     fprintf(yyout, "{ ECPGdo(__LINE__, %d, %d, %s, %d, ", compat, force_indicator, connection ? connection : "NULL", questionmarks);
00119     if (st == ECPGst_execute || st == ECPGst_exec_immediate)
00120     {
00121         fprintf(yyout, "%s, %s, ", ecpg_statement_type_name[st], stmt);
00122     }
00123     else
00124     {
00125         if (st == ECPGst_prepnormal && auto_prepare)
00126             fputs("ECPGst_prepnormal, \"", yyout);
00127         else
00128             fputs("ECPGst_normal, \"", yyout);
00129 
00130         output_escaped_str(stmt, false);
00131         fputs("\", ", yyout);
00132     }
00133 
00134     /* dump variables to C file */
00135     dump_variables(argsinsert, 1);
00136     fputs("ECPGt_EOIT, ", yyout);
00137     dump_variables(argsresult, 1);
00138     fputs("ECPGt_EORT);", yyout);
00139     reset_variables();
00140 
00141     whenever_action(whenever_mode | 2);
00142     free(stmt);
00143     if (connection != NULL)
00144         free(connection);
00145 }
00146 
00147 void
00148 output_prepare_statement(char *name, char *stmt)
00149 {
00150     fprintf(yyout, "{ ECPGprepare(__LINE__, %s, %d, ", connection ? connection : "NULL", questionmarks);
00151     output_escaped_str(name, true);
00152     fputs(", ", yyout);
00153     output_escaped_str(stmt, true);
00154     fputs(");", yyout);
00155     whenever_action(2);
00156     free(name);
00157     if (connection != NULL)
00158         free(connection);
00159 }
00160 
00161 void
00162 output_deallocate_prepare_statement(char *name)
00163 {
00164     const char *con = connection ? connection : "NULL";
00165 
00166     if (strcmp(name, "all") != 0)
00167     {
00168         fprintf(yyout, "{ ECPGdeallocate(__LINE__, %d, %s, ", compat, con);
00169         output_escaped_str(name, true);
00170         fputs(");", yyout);
00171     }
00172     else
00173         fprintf(yyout, "{ ECPGdeallocate_all(__LINE__, %d, %s);", compat, con);
00174 
00175     whenever_action(2);
00176     free(name);
00177     if (connection != NULL)
00178         free(connection);
00179 }
00180 
00181 static void
00182 output_escaped_str(char *str, bool quoted)
00183 {
00184     int         i = 0;
00185     int         len = strlen(str);
00186 
00187     if (quoted && str[0] == '\"' && str[len - 1] == '\"')       /* do not escape quotes
00188                                                                  * at beginning and end
00189                                                                  * if quoted string */
00190     {
00191         i = 1;
00192         len--;
00193         fputs("\"", yyout);
00194     }
00195 
00196     /* output this char by char as we have to filter " and \n */
00197     for (; i < len; i++)
00198     {
00199         if (str[i] == '"')
00200             fputs("\\\"", yyout);
00201         else if (str[i] == '\n')
00202             fputs("\\\n", yyout);
00203         else if (str[i] == '\\')
00204         {
00205             int         j = i;
00206 
00207             /*
00208              * check whether this is a continuation line if it is, do not
00209              * output anything because newlines are escaped anyway
00210              */
00211 
00212             /* accept blanks after the '\' as some other compilers do too */
00213             do
00214             {
00215                 j++;
00216             } while (str[j] == ' ' || str[j] == '\t');
00217 
00218             if ((str[j] != '\n') && (str[j] != '\r' || str[j + 1] != '\n'))     /* not followed by a
00219                                                                                  * newline */
00220                 fputs("\\\\", yyout);
00221         }
00222         else if (str[i] == '\r' && str[i + 1] == '\n')
00223         {
00224             fputs("\\\r\n", yyout);
00225             i++;
00226         }
00227         else
00228             fputc(str[i], yyout);
00229     }
00230 
00231     if (quoted && str[0] == '\"' && str[len] == '\"')
00232         fputs("\"", yyout);
00233 }