1 /*
2     This file is part of tl-parser
3 
4     tl-parser 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, either version 2 of the License, or
7     (at your option) any later version.
8 
9     tl-parser is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13 
14     You should have received a copy of the GNU General Public License
15     along with this tl-parser. If not, see <http://www.gnu.org/licenses/>.
16 
17     Copyright Vitaly Valtman 2014
18 
19     It is derivative work of VK/KittenPHP-DB-Engine (https://github.com/vk-com/kphp-kdb/)
20     Copyright 2012-2013 Vkontakte Ltd
21               2012-2013 Vitaliy Valtman
22 
23 */
24 
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <assert.h>
28 
29 #include "tl-parser.h"
30 
31 #ifndef _WIN32
32 #include <unistd.h>
33 #endif
34 
35 #include <sys/types.h>
36 #include <sys/stat.h>
37 #include <fcntl.h>
38 
39 #include <signal.h>
40 
41 #ifdef HAVE_EXECINFO_H
42 #include <execinfo.h>
43 #endif
44 #include <stdarg.h>
45 
46 int verbosity;
47 int output_expressions;
usage(void)48 void usage (void) {
49   printf ("usage: tl-parser [-v] [-h] <TL-schema-file>\n"
50       "\tTL compiler\n"
51       "\t-v\toutput statistical and debug information into stderr\n"
52       "\t-E\twhenever is possible output to stdout expressions\n"
53       "\t-e <file>\texport serialized schema to file\n"
54        );
55   exit (2);
56 }
57 
vkext_write(const char * filename)58 int vkext_write (const char *filename) {
59   FILE *f = fopen(filename, "wb");
60   assert (f != NULL);
61   write_types (f);
62   fclose (f);
63   return 0;
64 }
65 
66 void logprintf (const char *format, ...) __attribute__ ((format (printf, 1, 2)));
logprintf(const char * format,...)67 void logprintf (const char *format __attribute__ ((unused)), ...) {
68   va_list ap;
69   va_start (ap, format);
70   vfprintf (stderr, format, ap);
71   va_end (ap);
72 }
73 
hexdump(int * in_ptr,int * in_end)74 void hexdump (int *in_ptr, int *in_end) {
75   int *ptr = in_ptr;
76   while (ptr < in_end) { printf (" %08x", *(ptr ++)); }
77   printf ("\n");
78 }
79 
80 #ifdef HAVE_EXECINFO_H
print_backtrace(void)81 void print_backtrace (void) {
82   void *buffer[255];
83   const int calls = backtrace (buffer, sizeof (buffer) / sizeof (void *));
84   backtrace_symbols_fd (buffer, calls, 1);
85 }
86 #else
print_backtrace(void)87 void print_backtrace (void) {
88   if (fwrite ("No libexec. Backtrace disabled\n", 32, 1, stderr) < 0) {
89     // Sad thing
90   }
91 }
92 #endif
93 
sig_segv_handler(int signum)94 void sig_segv_handler (int signum __attribute__ ((unused))) {
95   if (fwrite ("SIGSEGV received\n", 18, 1, stderr) < 0) {
96     // Sad thing
97   }
98   print_backtrace ();
99   exit (EXIT_FAILURE);
100 }
101 
sig_abrt_handler(int signum)102 void sig_abrt_handler (int signum __attribute__ ((unused))) {
103   if (fwrite ("SIGABRT received\n", 18, 1, stderr) < 0) {
104     // Sad thing
105   }
106   print_backtrace ();
107   exit (EXIT_FAILURE);
108 }
109 
main(int argc,char ** argv)110 int main (int argc, char **argv) {
111   signal (SIGSEGV, sig_segv_handler);
112   signal (SIGABRT, sig_abrt_handler);
113   int i;
114   char *vkext_file = 0;
115   while ((i = getopt (argc, argv, "Ehve:w:")) != -1) {
116     switch (i) {
117     case 'E':
118       output_expressions++;
119       break;
120     case 'h':
121       usage ();
122       return 2;
123     case 'e':
124       vkext_file = optarg;
125       break;
126     case 'v':
127       verbosity++;
128       break;
129     }
130   }
131 
132   if (argc != optind + 1) {
133     usage ();
134   }
135 
136 
137   struct parse *P = tl_init_parse_file (argv[optind]);
138   if (!P) {
139     return 1;
140   }
141   struct tree *T;
142   if (!(T = tl_parse_lex (P))) {
143     fprintf (stderr, "Error in parse:\n");
144     tl_print_parse_error ();
145     return 1;
146   } else {
147     if (verbosity) {
148       fprintf (stderr, "Parse ok\n");
149     }
150     if (!tl_parse (T)) {
151       if (verbosity) {
152         fprintf (stderr, "Fail\n");
153       }
154       return 1;
155     } else {
156       if (verbosity) {
157         fprintf (stderr, "Ok\n");
158       }
159     }
160   }
161   if (vkext_file) {
162     vkext_write (vkext_file);
163   }
164   return 0;
165 }
166