Sync with 5.4.3
[deliverable/titan.core.git] / xsdconvert / converter.cc
CommitLineData
970ed795 1///////////////////////////////////////////////////////////////////////////////
3abe9331 2// Copyright (c) 2000-2015 Ericsson Telecom AB
970ed795
EL
3// All rights reserved. This program and the accompanying materials
4// are made available under the terms of the Eclipse Public License v1.0
5// which accompanies this distribution, and is available at
6// http://www.eclipse.org/legal/epl-v10.html
7///////////////////////////////////////////////////////////////////////////////
8#include "XMLParser.hh"
9#include "TTCN3Module.hh"
10#include "TTCN3ModuleInventory.hh"
11#include "SimpleType.hh"
12#include "ComplexType.hh"
13
14#include "../common/version_internal.h"
15#include "../common/license.h"
16
17#include <unistd.h> // for using "getopt" function
18#include <sys/stat.h>
19
20bool c_flag_used = false;
21int d_flag_used = 0;
22bool e_flag_used = false;
23bool f_flag_used = false;
3abe9331 24bool g_flag_used = true;
51fa56b9 25bool h_flag_used = false;
970ed795
EL
26bool p_flag_used = false;
27bool s_flag_used = false;
28bool t_flag_used = false;
29bool q_flag_used = false;
30bool w_flag_used = false;
31bool x_flag_used = false;
32bool z_flag_used = false;
33
34static void printProductinfo();
35static void printUsage(const char * argv0);
36static void printVersion();
3abe9331 37static void printErrorStatistics(const unsigned int errors, const unsigned int warnings);
970ed795
EL
38static bool generatePredefinedModules();
39static char **readModulesFromFile(const char *from_file, int *last_module);
3abe9331 40static int checkSyntax(const bool not_verbose, const int first_module, const int last_module,
41 const char * const * const module_names);
42static int validate(int const first_module, int const last_module,
43 const char * const * const module_names);
44static int generateCode(const bool quiet, const bool need_predefined,
45 const int first_module, const int last_module,
46 const char * const * const module_names);
47
48int main(int argc, char **argv) {
970ed795
EL
49 if (argc == 1) {
50 printProductinfo();
51 printUsage(argv[0]);
52 return EXIT_SUCCESS;
53 }
54
55 // The file holding a list of the XSD files.
56 const char *from_file = NULL;
57 char c;
58 opterr = 0;
59
51fa56b9 60 while ((c = getopt(argc, argv, "cdef:ghpqstvwxz")) != -1) {
3abe9331 61 switch (c) {
62 case 'c':
63 c_flag_used = true;
64 break;
65 case 'd':
66 ++d_flag_used;
67 break;
68 case 'e':
69 e_flag_used = true;
70 break;
71 case 'f':
72 f_flag_used = true;
73 from_file = optarg;
74 break;
75 case 'g':
76 g_flag_used = false;
77 break;
51fa56b9 78 case 'h':
79 h_flag_used = true;
80 break;
3abe9331 81 case 'p':
82 p_flag_used = true;
83 break;
84 case 's':
85 s_flag_used = true;
86 break;
87 case 't':
88 t_flag_used = true;
89 break;
90 case 'v':
91 printProductinfo();
92 printVersion();
970ed795 93#ifdef LICENSE
3abe9331 94 print_license_info();
970ed795 95#endif
3abe9331 96 return EXIT_SUCCESS;
97 case 'q':
98 q_flag_used = true;
99 break;
100 case 'w':
101 w_flag_used = true;
102 break;
103 case 'x':
104 x_flag_used = true;
105 break;
106 case 'z':
107 z_flag_used = true;
108 break;
109 default:
110 fprintf(stderr, "ERROR:\nInvalid option: -%c!\n", char(optopt));
111 printUsage(argv[0]);
112 return EXIT_FAILURE;
970ed795
EL
113 }
114 }
115
3abe9331 116 int first_module = f_flag_used ? 0 : optind;
117 int last_module = f_flag_used ? 0 : argc;
970ed795 118 char **module_names = f_flag_used ? NULL : argv;
3abe9331 119 try {
120 if (f_flag_used) {
121 // Idea from CR_TR00015706.
122 module_names = readModulesFromFile(from_file, &last_module);
123 if (!module_names) {
124 fprintf(stderr, "ERROR: The file `%s' holding the XSD files cannot be "
125 "processed!\n", from_file);
126 throw 1;
127 }
970ed795 128 }
970ed795 129
3abe9331 130 if (last_module - first_module <= 0) {
131 fprintf(stderr, "ERROR:\nNo module name was specified!\n");
132 printUsage(argv[0]);
133 throw 1;
134 }
970ed795
EL
135
136#ifdef LICENSE
3abe9331 137 {
138 init_openssl();
139 license_struct lstr;
140 load_license(&lstr);
141 int license_valid = verify_license(&lstr);
142 free_license(&lstr);
143 free_openssl();
144 if (!license_valid) {
145 exit(EXIT_FAILURE);
146 }
970ed795 147 }
970ed795
EL
148#endif
149
3abe9331 150 for (int i = first_module; i < last_module; ++i) {
151 if (!fopen(module_names[i], "r")) {
152 fprintf(stderr, "ERROR:\nInput file `%s' does not exist.\n",
153 module_names[i]);
154 throw 1;
155 }
970ed795 156 }
970ed795 157
3abe9331 158 if (checkSyntax(q_flag_used, first_module, last_module, module_names) == EXIT_FAILURE) {
159 throw 1;
160 }
970ed795 161
3abe9331 162 if (validate(first_module, last_module, module_names) == EXIT_FAILURE) {
163 throw 1;
164 }
970ed795 165
3abe9331 166 if (s_flag_used) {
167 printErrorStatistics(XMLParser::getNumErrors(),
168 XMLParser::getNumWarnings());
169 if (XMLParser::getNumErrors() > 0) {
170 throw 1;
171 }
172 return EXIT_SUCCESS;
173 }
970ed795 174
3abe9331 175 if (generateCode(q_flag_used, p_flag_used, first_module, last_module,
176 module_names) == EXIT_FAILURE) {
177 throw 1;
178 }
179 } catch (int) {
180 if (f_flag_used) {
181 for (int i = 0; i < last_module; ++i) {
182 Free(module_names[i]);
183 }
184 Free(module_names);
185 }
186 return EXIT_FAILURE;
187 }
970ed795
EL
188
189 if (XMLParser::getNumWarnings() > 0 ||
3abe9331 190 TTCN3ModuleInventory::getNumErrors() > 0 ||
191 TTCN3ModuleInventory::getNumWarnings() > 0) {
970ed795
EL
192 printErrorStatistics(TTCN3ModuleInventory::getNumErrors(),
193 XMLParser::getNumWarnings() + TTCN3ModuleInventory::getNumWarnings());
194 }
195
196 return EXIT_SUCCESS;
970ed795
EL
197}
198
3abe9331 199static void printProductinfo() {
970ed795
EL
200 fputs("XSD to TTCN-3 Converter for the TTCN-3 Test Executor, version "
201 PRODUCT_NUMBER "\n", stderr);
202}
203
3abe9331 204static void printUsage(const char * argv0) {
970ed795 205 fprintf(stderr, "\n"
3f84031e 206 "usage: %s [-ceghpstVwx] [-f file] schema.xsd ...\n"
970ed795
EL
207 " or %s -v\n"
208 "\n"
209 "OPTIONS:\n"
210 " -c: disable the generation of comments in TTCN-3 modules\n"
211 " -e: disable the generation of encoding instructions in TTCN-3 modules\n"
212 " -f file: the names of XSD files are taken from file instead of the command line\n"
3abe9331 213 " -g: generate TTCN-3 code disallowing element substitution\n"
51fa56b9 214 " -h: generate TTCN-3 code allowing type substitution\n"
970ed795
EL
215 " -p: do not generate the UsefulTtcn3Types and XSD predefined modules\n"
216 " -q: quiet mode - disable the issue of status messages\n"
217 " -s: parse and validate only - no TTCN-3 module generation\n"
218 " -t: disable the generation of timing information in TTCN-3 modules\n"
219 " -v: show version information\n"
220 " -w: suppress warnings\n"
221 " -x: disable schema validation but generate TTCN-3 modules\n"
222 " -z: zap URI scheme from module name\n"
223 , argv0, argv0);
224}
225
3abe9331 226static void printVersion() {
970ed795
EL
227 fputs("Product number: " PRODUCT_NUMBER "\n"
228 "Build date: " __DATE__ " " __TIME__ "\n"
229 "Compiled with: " C_COMPILER_VERSION "\n\n"
230 COPYRIGHT_STRING "\n\n", stderr);
231}
232
3abe9331 233static void printErrorStatistics(const unsigned int errors, const unsigned int warnings) {
970ed795 234 if (errors == 0) {
3abe9331 235 if (warnings == 0) {
970ed795
EL
236 fprintf(stderr,
237 "Notify: No errors or warnings were detected.\n");
3abe9331 238 } else {
970ed795
EL
239 fprintf(stderr,
240 "Notify: No errors and %u warning%s were detected.\n",
241 warnings,
242 warnings > 1 ? "s" : "");
3abe9331 243 }
244 } else {
245 if (warnings == 0) {
970ed795
EL
246 fprintf(stderr,
247 "Notify: %u error%s and no warnings were detected.\n",
248 errors,
249 errors > 1 ? "s" : "");
3abe9331 250 } else {
970ed795
EL
251 fprintf(stderr,
252 "Notify: %u error%s and %u warning%s were detected.\n",
253 errors,
254 errors > 1 ? "s" : "",
3abe9331 255 warnings,
256 warnings > 1 ? "s" : "");
257 }
970ed795
EL
258 }
259}
260
3abe9331 261static bool checkFailure() {
262 if (TTCN3ModuleInventory::getNumErrors() > 0) {
263 printErrorStatistics(TTCN3ModuleInventory::getNumErrors(),
264 XMLParser::getNumWarnings() + TTCN3ModuleInventory::getNumWarnings());
970ed795 265 return true;
3abe9331 266 } else {
970ed795
EL
267 return false;
268 }
3abe9331 269}
970ed795 270
3abe9331 271static bool generatePredefinedModules() {
feade998 272 //struct stat stFileInfo;
273 // Only generate the missing predefined modules.
274 // Generate, because the copyright is now generated into the modules.
275 //if (stat("UsefulTtcn3Types.ttcn", &stFileInfo) != 0) {
3abe9331 276 extern const char *moduleUsefulTtcn3Types;
277 FILE *fileUsefulTtcn3Types = fopen("UsefulTtcn3Types.ttcn", "w");
278 if (fileUsefulTtcn3Types == NULL) {
279 fprintf(stderr, "ERROR:\nCannot create file UsefulTtcn3Types.ttcn!\n");
280 return false;
281 }
feade998 282 generate_TTCN3_header(fileUsefulTtcn3Types, "UsefulTtcn3Types", false);
3abe9331 283 fprintf(fileUsefulTtcn3Types, "%s", moduleUsefulTtcn3Types);
284 if (!q_flag_used) {
285 fprintf(stderr, "Notify: File \'UsefulTtcn3Types.ttcn\' was generated.\n");
286 }
287 fclose(fileUsefulTtcn3Types);
feade998 288 //}
970ed795 289
3f84031e 290 //XSD.ttcn changed
291 //if (stat("XSD.ttcn", &stFileInfo) != 0) {
3abe9331 292 extern const char *moduleXSD;
293 FILE *fileXsd = fopen("XSD.ttcn", "w");
294 if (fileXsd == NULL) {
295 fprintf(stderr, "ERROR:\nCannot create file XSD.ttcn!\n");
296 return false;
297 }
feade998 298 generate_TTCN3_header(fileXsd, "XSD", false);
3abe9331 299 fprintf(fileXsd, "%s", moduleXSD);
300 if (!q_flag_used) {
301 fprintf(stderr, "Notify: File \'XSD.ttcn\' was generated.\n");
302 }
303 fclose(fileXsd);
3f84031e 304 //}
970ed795
EL
305 return true;
306}
307
3abe9331 308static char **readModulesFromFile(const char *from_file, int *last_module) {
970ed795
EL
309 FILE *input = fopen(from_file, "r");
310 if (!input) return NULL;
311 // It should be a relatively small file.
312 fseek(input, 0, SEEK_END);
313 size_t input_bytes = ftell(input);
314 rewind(input);
315 size_t buf_len = input_bytes + 1; // sizeof(char)==1 by definition
3abe9331 316 char *buf = (char *) Malloc(buf_len);
970ed795
EL
317 buf[buf_len - 1] = 0;
318 size_t bytes_read = fread(buf, 1, input_bytes, input);
319 fclose(input);
3abe9331 320 if ((size_t) input_bytes != bytes_read) {
970ed795
EL
321 Free(buf);
322 return NULL;
323 }
324 char **ret_val = NULL;
325 *last_module = 0;
326 const char *delim = " \f\n\r\t\v";
327 char *name = strtok(buf, delim);
328 while (name) {
329 if (!strlen(name))
330 continue;
3abe9331 331 ret_val = (char **) Realloc(ret_val, sizeof (char *) * ++(*last_module));
970ed795
EL
332 ret_val[*last_module - 1] = mcopystr(name);
333 name = strtok(NULL, delim);
334 }
335 Free(buf);
336 return ret_val;
337}
338
3abe9331 339static int checkSyntax(const bool not_verbose, const int first_module, const int last_module,
340 const char * const * const module_names) {
341 if (!not_verbose) {
970ed795 342 fprintf(stderr, "Notify: Checking documents...\n");
3abe9331 343 }
970ed795 344 for (int i = first_module; i < last_module; ++i) {
3abe9331 345 if (!not_verbose) {
970ed795 346 fprintf(stderr, "Notify: Parsing XML schema document `%s'...\n",
3abe9331 347 module_names[i]);
348 }
970ed795
EL
349 XMLParser syntaxchecker(module_names[i]);
350 syntaxchecker.checkSyntax();
351 }
352 if (XMLParser::getNumErrors() > 0) {
353 printErrorStatistics(XMLParser::getNumErrors(),
3abe9331 354 XMLParser::getNumWarnings());
970ed795
EL
355 return EXIT_FAILURE;
356 }
357 return EXIT_SUCCESS;
358}
359
3abe9331 360static int generateCode(const bool quiet, const bool need_predefined,
361 const int first_module, const int last_module,
362 const char * const * const module_names) {
970ed795
EL
363 TTCN3ModuleInventory& modules = TTCN3ModuleInventory::getInstance();
364 for (int i = first_module; i < last_module; ++i) {
365 XMLParser parser(module_names[i]);
366 TTCN3Module *module = modules.addModule(module_names[i], &parser);
367 parser.startConversion(module);
368 module->goodbyeParser(); // the parser is going away, don't use it
369 }
370
371 if (XMLParser::getNumErrors() > 0) {
372 printErrorStatistics(XMLParser::getNumErrors(),
3abe9331 373 XMLParser::getNumWarnings());
970ed795
EL
374 return EXIT_FAILURE;
375 }
376
377 if (d_flag_used > 1) {
378 modules.dump();
379 fputs("+++++++++++++++++++++++++++++\n", stderr);
380 }
381
382 modules.modulenameConversion();
383 modules.referenceResolving();
384 modules.nameConversion();
385 modules.finalModification();
386
3abe9331 387 if (d_flag_used > 0) {
388 modules.dump();
389 }
970ed795 390
3abe9331 391 if (checkFailure()) {
970ed795
EL
392 return EXIT_FAILURE;
393 }
394
3abe9331 395 if (!quiet) {
970ed795 396 fprintf(stderr, "Notify: Generating TTCN-3 modules...\n");
3abe9331 397 }
970ed795
EL
398
399 modules.moduleGeneration();
400
3abe9331 401 if (checkFailure()) {
970ed795
EL
402 return EXIT_FAILURE;
403 }
404
3abe9331 405 if (!need_predefined) {
406 if (!generatePredefinedModules()) {
970ed795 407 return EXIT_FAILURE;
3abe9331 408 }
409 }
970ed795
EL
410 return EXIT_SUCCESS;
411}
412
3abe9331 413static int validate(const int first_module, const int last_module,
414 const char * const * const module_names) {
970ed795
EL
415 for (int i = first_module; i < last_module; ++i) {
416 XMLParser validator(module_names[i]);
417 validator.validate();
418 }
419 if (XMLParser::getNumErrors() > 0) {
420 printErrorStatistics(XMLParser::getNumErrors(),
3abe9331 421 XMLParser::getNumWarnings());
970ed795
EL
422 return EXIT_FAILURE;
423 }
424 return EXIT_SUCCESS;
425}
426
3abe9331 427reffer::reffer(const char*) {
428}
This page took 0.117767 seconds and 5 git commands to generate.