Apply PIE to nghttpx
[platform/upstream/nghttp2.git] / third-party / mruby / mrbgems / mruby-bin-mruby / tools / mruby / mruby.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <mruby.h>
5 #include <mruby/array.h>
6 #include <mruby/compile.h>
7 #include <mruby/dump.h>
8 #include <mruby/variable.h>
9
10 #ifdef MRB_DISABLE_STDIO
11 static void
12 p(mrb_state *mrb, mrb_value obj)
13 {
14   mrb_value val = mrb_inspect(mrb, obj);
15
16   fwrite(RSTRING_PTR(val), RSTRING_LEN(val), 1, stdout);
17   putc('\n', stdout);
18 }
19 #else
20 #define p(mrb,obj) mrb_p(mrb,obj)
21 #endif
22
23 struct _args {
24   FILE *rfp;
25   char* cmdline;
26   mrb_bool fname        : 1;
27   mrb_bool mrbfile      : 1;
28   mrb_bool check_syntax : 1;
29   mrb_bool verbose      : 1;
30   mrb_bool debug        : 1;
31   int argc;
32   char** argv;
33   int libc;
34   char **libv;
35 };
36
37 static void
38 usage(const char *name)
39 {
40   static const char *const usage_msg[] = {
41   "switches:",
42   "-b           load and execute RiteBinary (mrb) file",
43   "-c           check syntax only",
44   "-d           set debugging flags (set $DEBUG to true)",
45   "-e 'command' one line of script",
46   "-r library   load the library before executing your script",
47   "-v           print version number, then run in verbose mode",
48   "--verbose    run in verbose mode",
49   "--version    print the version",
50   "--copyright  print the copyright",
51   NULL
52   };
53   const char *const *p = usage_msg;
54
55   printf("Usage: %s [switches] programfile\n", name);
56   while (*p)
57     printf("  %s\n", *p++);
58 }
59
60 static char *
61 dup_arg_item(mrb_state *mrb, const char *item)
62 {
63   size_t buflen = strlen(item) + 1;
64   char *buf = (char*)mrb_malloc(mrb, buflen);
65   memcpy(buf, item, buflen);
66   return buf;
67 }
68
69 static int
70 parse_args(mrb_state *mrb, int argc, char **argv, struct _args *args)
71 {
72   char **origargv = argv;
73   static const struct _args args_zero = { 0 };
74
75   *args = args_zero;
76
77   for (argc--,argv++; argc > 0; argc--,argv++) {
78     char *item;
79     if (argv[0][0] != '-') break;
80
81     if (strlen(*argv) <= 1) {
82       argc--; argv++;
83       args->rfp = stdin;
84       break;
85     }
86
87     item = argv[0] + 1;
88     switch (*item++) {
89     case 'b':
90       args->mrbfile = TRUE;
91       break;
92     case 'c':
93       args->check_syntax = TRUE;
94       break;
95     case 'd':
96       args->debug = TRUE;
97       break;
98     case 'e':
99       if (item[0]) {
100         goto append_cmdline;
101       }
102       else if (argc > 1) {
103         argc--; argv++;
104         item = argv[0];
105 append_cmdline:
106         if (!args->cmdline) {
107           args->cmdline = dup_arg_item(mrb, item);
108         }
109         else {
110           size_t cmdlinelen;
111           size_t itemlen;
112
113           cmdlinelen = strlen(args->cmdline);
114           itemlen = strlen(item);
115           args->cmdline =
116             (char *)mrb_realloc(mrb, args->cmdline, cmdlinelen + itemlen + 2);
117           args->cmdline[cmdlinelen] = '\n';
118           memcpy(args->cmdline + cmdlinelen + 1, item, itemlen + 1);
119         }
120       }
121       else {
122         printf("%s: No code specified for -e\n", *origargv);
123         return EXIT_SUCCESS;
124       }
125       break;
126     case 'r':
127       if (!item[0]) {
128         if (argc <= 1) {
129           printf("%s: No library specified for -r\n", *origargv);
130           return EXIT_FAILURE;
131         }
132         argc--; argv++;
133         item = argv[0];
134       }
135       if (args->libc == 0) {
136         args->libv = (char**)mrb_malloc(mrb, sizeof(char*));
137       }
138       else {
139         args->libv = (char**)mrb_realloc(mrb, args->libv, sizeof(char*) * (args->libc + 1));
140       }
141       args->libv[args->libc++] = dup_arg_item(mrb, item);
142       break;
143     case 'v':
144       if (!args->verbose) mrb_show_version(mrb);
145       args->verbose = TRUE;
146       break;
147     case '-':
148       if (strcmp((*argv) + 2, "version") == 0) {
149         mrb_show_version(mrb);
150         exit(EXIT_SUCCESS);
151       }
152       else if (strcmp((*argv) + 2, "verbose") == 0) {
153         args->verbose = TRUE;
154         break;
155       }
156       else if (strcmp((*argv) + 2, "copyright") == 0) {
157         mrb_show_copyright(mrb);
158         exit(EXIT_SUCCESS);
159       }
160     default:
161       return EXIT_FAILURE;
162     }
163   }
164
165   if (args->rfp == NULL && args->cmdline == NULL) {
166     if (*argv == NULL) args->rfp = stdin;
167     else {
168       args->rfp = fopen(argv[0], args->mrbfile ? "rb" : "r");
169       if (args->rfp == NULL) {
170         printf("%s: Cannot open program file. (%s)\n", *origargv, *argv);
171         return EXIT_FAILURE;
172       }
173       args->fname = TRUE;
174       args->cmdline = argv[0];
175       argc--; argv++;
176     }
177   }
178   args->argv = (char **)mrb_realloc(mrb, args->argv, sizeof(char*) * (argc + 1));
179   memcpy(args->argv, argv, (argc+1) * sizeof(char*));
180   args->argc = argc;
181
182   return EXIT_SUCCESS;
183 }
184
185 static void
186 cleanup(mrb_state *mrb, struct _args *args)
187 {
188   if (args->rfp && args->rfp != stdin)
189     fclose(args->rfp);
190   if (!args->fname)
191     mrb_free(mrb, args->cmdline);
192   mrb_free(mrb, args->argv);
193   if (args->libc) {
194     while (args->libc--) {
195       mrb_free(mrb, args->libv[args->libc]);
196     }
197     mrb_free(mrb, args->libv);
198   }
199   mrb_close(mrb);
200 }
201
202 int
203 main(int argc, char **argv)
204 {
205   mrb_state *mrb = mrb_open();
206   int n = -1;
207   int i;
208   struct _args args;
209   mrb_value ARGV;
210   mrbc_context *c;
211   mrb_value v;
212   mrb_sym zero_sym;
213
214   if (mrb == NULL) {
215     fputs("Invalid mrb_state, exiting mruby\n", stderr);
216     return EXIT_FAILURE;
217   }
218
219   n = parse_args(mrb, argc, argv, &args);
220   if (n == EXIT_FAILURE || (args.cmdline == NULL && args.rfp == NULL)) {
221     cleanup(mrb, &args);
222     usage(argv[0]);
223     return n;
224   }
225   else {
226     int ai = mrb_gc_arena_save(mrb);
227     ARGV = mrb_ary_new_capa(mrb, args.argc);
228     for (i = 0; i < args.argc; i++) {
229       char* utf8 = mrb_utf8_from_locale(args.argv[i], -1);
230       if (utf8) {
231         mrb_ary_push(mrb, ARGV, mrb_str_new_cstr(mrb, utf8));
232         mrb_utf8_free(utf8);
233       }
234     }
235     mrb_define_global_const(mrb, "ARGV", ARGV);
236     mrb_gv_set(mrb, mrb_intern_lit(mrb, "$DEBUG"), mrb_bool_value(args.debug));
237
238     c = mrbc_context_new(mrb);
239     if (args.verbose)
240       c->dump_result = TRUE;
241     if (args.check_syntax)
242       c->no_exec = TRUE;
243
244     /* Set $0 */
245     zero_sym = mrb_intern_lit(mrb, "$0");
246     if (args.rfp) {
247       const char *cmdline;
248       cmdline = args.cmdline ? args.cmdline : "-";
249       mrbc_filename(mrb, c, cmdline);
250       mrb_gv_set(mrb, zero_sym, mrb_str_new_cstr(mrb, cmdline));
251     }
252     else {
253       mrbc_filename(mrb, c, "-e");
254       mrb_gv_set(mrb, zero_sym, mrb_str_new_lit(mrb, "-e"));
255     }
256
257     /* Load libraries */
258     for (i = 0; i < args.libc; i++) {
259       FILE *lfp = fopen(args.libv[i], args.mrbfile ? "rb" : "r");
260       if (lfp == NULL) {
261         printf("Cannot open library file: %s\n", args.libv[i]);
262         mrbc_context_free(mrb, c);
263         cleanup(mrb, &args);
264         return EXIT_FAILURE;
265       }
266       if (args.mrbfile) {
267         v = mrb_load_irep_file_cxt(mrb, lfp, c);
268       }
269       else {
270         v = mrb_load_file_cxt(mrb, lfp, c);
271       }
272       fclose(lfp);
273     }
274
275     /* Load program */
276     if (args.mrbfile) {
277       v = mrb_load_irep_file_cxt(mrb, args.rfp, c);
278     }
279     else if (args.rfp) {
280       v = mrb_load_file_cxt(mrb, args.rfp, c);
281     }
282     else {
283       char* utf8 = mrb_utf8_from_locale(args.cmdline, -1);
284       if (!utf8) abort();
285       v = mrb_load_string_cxt(mrb, utf8, c);
286       mrb_utf8_free(utf8);
287     }
288
289     mrb_gc_arena_restore(mrb, ai);
290     mrbc_context_free(mrb, c);
291     if (mrb->exc) {
292       if (mrb_undef_p(v)) {
293         mrb_p(mrb, mrb_obj_value(mrb->exc));
294       }
295       else {
296         mrb_print_error(mrb);
297       }
298       n = -1;
299     }
300     else if (args.check_syntax) {
301       printf("Syntax OK\n");
302     }
303   }
304   cleanup(mrb, &args);
305
306   return n == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
307 }