1/* Copyright (c) 2004, 2010, Oracle and/or its affiliates.
2 Copyright (c) 2012, 2014, Monty Program Ab
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; version 2 of the License.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program; if not, write to the Free Software
15 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
16
17/*
18 Originally written by Magnus Svensson
19*/
20
21/*
22 Converts a SQL file into a C file that can be compiled and linked
23 into other programs
24*/
25
26#include <my_config.h>
27#include <stdarg.h>
28#include <stdlib.h>
29#include <stdio.h>
30
31/*
32 This is an internal tool used during the build process only,
33 - do not make a library just for this,
34 which would make the Makefiles and the server link
35 more complex than necessary,
36 - do not duplicate the code either.
37 so just add the sql_bootstrap.cc code as is.
38*/
39#include "../sql/sql_bootstrap.cc"
40
41FILE *in, *out;
42
43static void die(const char *fmt, ...)
44{
45 va_list args;
46
47 /* Print the error message */
48 fprintf(stderr, "FATAL ERROR: ");
49 if (fmt)
50 {
51 va_start(args, fmt);
52 vfprintf(stderr, fmt, args);
53 va_end(args);
54 }
55 else
56 fprintf(stderr, "unknown error");
57 fprintf(stderr, "\n");
58 fflush(stderr);
59
60 /* Close any open files */
61 if (in)
62 fclose(in);
63 if (out)
64 fclose(out);
65
66 exit(1);
67}
68
69char *fgets_fn(char *buffer, size_t size, fgets_input_t input, int *error)
70{
71 char *line= fgets(buffer, (int)size, (FILE*) input);
72 if (error)
73 *error= (line == NULL) ? ferror((FILE*)input) : 0;
74 return line;
75}
76
77static void print_query(FILE *out, const char *query)
78{
79 const char *ptr= query;
80 int column= 0;
81
82 fprintf(out, "\"");
83 while (*ptr)
84 {
85 switch(*ptr)
86 {
87 case '\n':
88 /*
89 Preserve the \n character in the query text,
90 and wrap to the next line, tabulated.
91 */
92 fprintf(out, "\\n\"\n \"");
93 column= 2;
94 break;
95 case '\r':
96 /* Skipped */
97 break;
98 case '\"':
99 fprintf(out, "\\\"");
100 column++;
101 break;
102 case '\\':
103 fprintf(out, "\\\\");
104 break;
105 default:
106 putc(*ptr, out);
107 column++;
108 break;
109 }
110 ptr++;
111 }
112 fprintf(out, "\\n\",\n");
113}
114
115int main(int argc, char *argv[])
116{
117 char query[MAX_BOOTSTRAP_QUERY_SIZE];
118 char* struct_name= argv[1];
119 char* infile_name= argv[2];
120 char* outfile_name= argv[3];
121 int rc;
122 int query_length;
123 int error= 0;
124 char *err_ptr;
125
126 if (argc != 4)
127 die("Usage: comp_sql <struct_name> <sql_filename> <c_filename>");
128
129 /* Open input and output file */
130 if (!(in= fopen(infile_name, "r")))
131 die("Failed to open SQL file '%s'", infile_name);
132 if (!(out= fopen(outfile_name, "w")))
133 die("Failed to open output file '%s'", outfile_name);
134
135 fprintf(out, "/*\n");
136 fprintf(out, " Do not edit this file, it is automatically generated from:\n");
137 fprintf(out, " <%s>\n", infile_name);
138 fprintf(out, "*/\n");
139 fprintf(out, "#include <stdlib.h>\n"); /* NULL */
140 fprintf(out, "const char* %s[]={\n", struct_name);
141
142 for ( ; ; )
143 {
144 rc= read_bootstrap_query(query, &query_length,
145 (fgets_input_t) in, fgets_fn, &error);
146
147 if (rc == READ_BOOTSTRAP_EOF)
148 break;
149
150 if (rc != READ_BOOTSTRAP_SUCCESS)
151 {
152 /* Get the most recent query text for reference. */
153 err_ptr= query + (query_length <= MAX_BOOTSTRAP_ERROR_LEN ?
154 0 : (query_length - MAX_BOOTSTRAP_ERROR_LEN));
155 switch (rc)
156 {
157 case READ_BOOTSTRAP_ERROR:
158 die("Failed to read the bootstrap input file. Return code (%d).\n"
159 "Last query: '%s'\n", error, err_ptr);
160 break;
161
162 case READ_BOOTSTRAP_QUERY_SIZE:
163 die("Failed to read the boostrap input file. Query size exceeded %d bytes.\n"
164 "Last query: '%s'.\n", MAX_BOOTSTRAP_LINE_SIZE, err_ptr);
165 break;
166
167 default:
168 die("Failed to read the boostrap input file. Unknown error.\n");
169 break;
170 }
171 }
172
173 print_query(out, query);
174 }
175
176 fprintf(out, "NULL\n};\n");
177
178 fclose(in);
179 fclose(out);
180
181 exit(0);
182
183}
184
185