Arves100
3af38fb06b
- Completely removed config.h generation file, as it was not used
anywere in the code
- Removed all the old build files and switched to CMake (3.0+)
- As tl-parser only uses zlib for crc32, removing the dependency makes
the CMake file easier to maintain and makes the code building
without third party code. The crc32 implementation was taken from
abb3e47a98
.
177 lines
4.1 KiB
C
177 lines
4.1 KiB
C
/*
|
|
This file is part of tl-parser
|
|
|
|
tl-parser is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
tl-parser is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this tl-parser. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
Copyright Vitaly Valtman 2014
|
|
|
|
It is derivative work of VK/KittenPHP-DB-Engine (https://github.com/vk-com/kphp-kdb/)
|
|
Copyright 2012-2013 Vkontakte Ltd
|
|
2012-2013 Vitaliy Valtman
|
|
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <assert.h>
|
|
|
|
#if defined(_MSC_VER)
|
|
#include <io.h>
|
|
#include <stdint.h>
|
|
#include <string.h>
|
|
#include "wingetopt.h"
|
|
#else
|
|
#include <unistd.h>
|
|
#endif
|
|
#include "tl-parser.h"
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <fcntl.h>
|
|
|
|
#include <signal.h>
|
|
|
|
#ifdef HAVE_EXECINFO_H
|
|
#include <execinfo.h>
|
|
#endif
|
|
#include <stdarg.h>
|
|
|
|
int verbosity;
|
|
int output_expressions;
|
|
void usage (void) {
|
|
printf ("usage: tl-parser [-v] [-h] <TL-schema-file>\n"
|
|
"\tTL compiler\n"
|
|
"\t-v\toutput statistical and debug information into stderr\n"
|
|
"\t-E\twhenever is possible output to stdout expressions\n"
|
|
"\t-e <file>\texport serialized schema to file\n"
|
|
);
|
|
exit (2);
|
|
}
|
|
|
|
int vkext_write (const char *filename) {
|
|
#if defined(_MSC_VER) && _MSC_VER >= 1400
|
|
int f = 0;
|
|
assert(_sopen_s(&f, filename, _O_CREAT | _O_WRONLY | _O_TRUNC | _O_BINARY, _SH_DENYNO, _S_IREAD | _S_IWRITE) == 0);
|
|
#elif defined(WIN32) || defined(_WIN32)
|
|
int f = open(filename, O_CREAT | O_WRONLY | O_TRUNC | O_BINARY, 0640);
|
|
assert(f >= 0);
|
|
#else
|
|
int f = open (filename, O_CREAT | O_WRONLY | O_TRUNC, 0640);
|
|
assert (f >= 0);
|
|
#endif
|
|
write_types (f);
|
|
close (f);
|
|
return 0;
|
|
}
|
|
|
|
void logprintf (const char *format, ...) __attribute__ ((format (printf, 1, 2)));
|
|
void logprintf (const char *format __attribute__ ((unused)), ...) {
|
|
va_list ap;
|
|
va_start (ap, format);
|
|
vfprintf (stderr, format, ap);
|
|
va_end (ap);
|
|
}
|
|
|
|
void hexdump (int *in_ptr, int *in_end) {
|
|
int *ptr = in_ptr;
|
|
while (ptr < in_end) { printf (" %08x", *(ptr ++)); }
|
|
printf ("\n");
|
|
}
|
|
|
|
#ifdef HAVE_EXECINFO_H
|
|
void print_backtrace (void) {
|
|
void *buffer[255];
|
|
const int calls = backtrace (buffer, sizeof (buffer) / sizeof (void *));
|
|
backtrace_symbols_fd (buffer, calls, 1);
|
|
}
|
|
#else
|
|
void print_backtrace (void) {
|
|
if (write (1, "No libexec. Backtrace disabled\n", 32) < 0) {
|
|
// Sad thing
|
|
}
|
|
}
|
|
#endif
|
|
|
|
void sig_segv_handler (int signum __attribute__ ((unused))) {
|
|
if (write (1, "SIGSEGV received\n", 18) < 0) {
|
|
// Sad thing
|
|
}
|
|
print_backtrace ();
|
|
exit (EXIT_FAILURE);
|
|
}
|
|
|
|
void sig_abrt_handler (int signum __attribute__ ((unused))) {
|
|
if (write (1, "SIGABRT received\n", 18) < 0) {
|
|
// Sad thing
|
|
}
|
|
print_backtrace ();
|
|
exit (EXIT_FAILURE);
|
|
}
|
|
|
|
int main (int argc, char **argv) {
|
|
signal (SIGSEGV, sig_segv_handler);
|
|
signal (SIGABRT, sig_abrt_handler);
|
|
int i;
|
|
char *vkext_file = 0;
|
|
while ((i = getopt (argc, argv, "Ehve:w:")) != -1) {
|
|
switch (i) {
|
|
case 'E':
|
|
output_expressions++;
|
|
break;
|
|
case 'h':
|
|
usage ();
|
|
return 2;
|
|
case 'e':
|
|
vkext_file = optarg;
|
|
break;
|
|
case 'v':
|
|
verbosity++;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (argc != optind + 1) {
|
|
usage ();
|
|
}
|
|
|
|
|
|
struct parse *P = tl_init_parse_file (argv[optind]);
|
|
if (!P) {
|
|
return 0;
|
|
}
|
|
struct tree *T;
|
|
if (!(T = tl_parse_lex (P))) {
|
|
fprintf (stderr, "Error in parse:\n");
|
|
tl_print_parse_error ();
|
|
return 0;
|
|
} else {
|
|
if (verbosity) {
|
|
fprintf (stderr, "Parse ok\n");
|
|
}
|
|
if (!tl_parse (T)) {
|
|
if (verbosity) {
|
|
fprintf (stderr, "Fail\n");
|
|
}
|
|
return 1;
|
|
} else {
|
|
if (verbosity) {
|
|
fprintf (stderr, "Ok\n");
|
|
}
|
|
}
|
|
}
|
|
if (vkext_file) {
|
|
vkext_write (vkext_file);
|
|
}
|
|
return 0;
|
|
}
|