source: EcnlProtoTool/trunk/mruby-1.2.0/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c@ 321

Last change on this file since 321 was 321, checked in by coas-nagasima, 7 years ago

文字コードを設定

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 5.6 KB
Line 
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
11static void
12p(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
23struct _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 int argc;
31 char** argv;
32};
33
34static void
35usage(const char *name)
36{
37 static const char *const usage_msg[] = {
38 "switches:",
39 "-b load and execute RiteBinary (mrb) file",
40 "-c check syntax only",
41 "-e 'command' one line of script",
42 "-v print version number, then run in verbose mode",
43 "--verbose run in verbose mode",
44 "--version print the version",
45 "--copyright print the copyright",
46 NULL
47 };
48 const char *const *p = usage_msg;
49
50 printf("Usage: %s [switches] programfile\n", name);
51 while (*p)
52 printf(" %s\n", *p++);
53}
54
55static int
56parse_args(mrb_state *mrb, int argc, char **argv, struct _args *args)
57{
58 char **origargv = argv;
59 static const struct _args args_zero = { 0 };
60
61 *args = args_zero;
62
63 for (argc--,argv++; argc > 0; argc--,argv++) {
64 char *item;
65 if (argv[0][0] != '-') break;
66
67 if (strlen(*argv) <= 1) {
68 argc--; argv++;
69 args->rfp = stdin;
70 break;
71 }
72
73 item = argv[0] + 1;
74 switch (*item++) {
75 case 'b':
76 args->mrbfile = TRUE;
77 break;
78 case 'c':
79 args->check_syntax = TRUE;
80 break;
81 case 'e':
82 if (item[0]) {
83 goto append_cmdline;
84 }
85 else if (argc > 1) {
86 argc--; argv++;
87 item = argv[0];
88append_cmdline:
89 if (!args->cmdline) {
90 size_t buflen;
91 char *buf;
92
93 buflen = strlen(item) + 1;
94 buf = (char *)mrb_malloc(mrb, buflen);
95 memcpy(buf, item, buflen);
96 args->cmdline = buf;
97 }
98 else {
99 size_t cmdlinelen;
100 size_t itemlen;
101
102 cmdlinelen = strlen(args->cmdline);
103 itemlen = strlen(item);
104 args->cmdline =
105 (char *)mrb_realloc(mrb, args->cmdline, cmdlinelen + itemlen + 2);
106 args->cmdline[cmdlinelen] = '\n';
107 memcpy(args->cmdline + cmdlinelen + 1, item, itemlen + 1);
108 }
109 }
110 else {
111 printf("%s: No code specified for -e\n", *origargv);
112 return EXIT_SUCCESS;
113 }
114 break;
115 case 'v':
116 if (!args->verbose) mrb_show_version(mrb);
117 args->verbose = TRUE;
118 break;
119 case '-':
120 if (strcmp((*argv) + 2, "version") == 0) {
121 mrb_show_version(mrb);
122 exit(EXIT_SUCCESS);
123 }
124 else if (strcmp((*argv) + 2, "verbose") == 0) {
125 args->verbose = TRUE;
126 break;
127 }
128 else if (strcmp((*argv) + 2, "copyright") == 0) {
129 mrb_show_copyright(mrb);
130 exit(EXIT_SUCCESS);
131 }
132 default:
133 return EXIT_FAILURE;
134 }
135 }
136
137 if (args->rfp == NULL && args->cmdline == NULL) {
138 if (*argv == NULL) args->rfp = stdin;
139 else {
140 args->rfp = fopen(argv[0], args->mrbfile ? "rb" : "r");
141 if (args->rfp == NULL) {
142 printf("%s: Cannot open program file. (%s)\n", *origargv, *argv);
143 return EXIT_FAILURE;
144 }
145 args->fname = TRUE;
146 args->cmdline = argv[0];
147 argc--; argv++;
148 }
149 }
150 args->argv = (char **)mrb_realloc(mrb, args->argv, sizeof(char*) * (argc + 1));
151 memcpy(args->argv, argv, (argc+1) * sizeof(char*));
152 args->argc = argc;
153
154 return EXIT_SUCCESS;
155}
156
157static void
158cleanup(mrb_state *mrb, struct _args *args)
159{
160 if (args->rfp && args->rfp != stdin)
161 fclose(args->rfp);
162 if (!args->fname)
163 mrb_free(mrb, args->cmdline);
164 mrb_free(mrb, args->argv);
165 mrb_close(mrb);
166}
167
168int
169main(int argc, char **argv)
170{
171 mrb_state *mrb = mrb_open();
172 int n = -1;
173 int i;
174 struct _args args;
175 mrb_value ARGV;
176 mrbc_context *c;
177 mrb_value v;
178 mrb_sym zero_sym;
179
180 if (mrb == NULL) {
181 fputs("Invalid mrb_state, exiting mruby\n", stderr);
182 return EXIT_FAILURE;
183 }
184
185 n = parse_args(mrb, argc, argv, &args);
186 if (n == EXIT_FAILURE || (args.cmdline == NULL && args.rfp == NULL)) {
187 cleanup(mrb, &args);
188 usage(argv[0]);
189 return n;
190 }
191
192 ARGV = mrb_ary_new_capa(mrb, args.argc);
193 for (i = 0; i < args.argc; i++) {
194 char* utf8 = mrb_utf8_from_locale(args.argv[i], -1);
195 if (utf8) {
196 mrb_ary_push(mrb, ARGV, mrb_str_new_cstr(mrb, utf8));
197 mrb_utf8_free(utf8);
198 }
199 }
200 mrb_define_global_const(mrb, "ARGV", ARGV);
201
202 c = mrbc_context_new(mrb);
203 if (args.verbose)
204 c->dump_result = TRUE;
205 if (args.check_syntax)
206 c->no_exec = TRUE;
207
208 /* Set $0 */
209 zero_sym = mrb_intern_lit(mrb, "$0");
210 if (args.rfp) {
211 const char *cmdline;
212 cmdline = args.cmdline ? args.cmdline : "-";
213 mrbc_filename(mrb, c, cmdline);
214 mrb_gv_set(mrb, zero_sym, mrb_str_new_cstr(mrb, cmdline));
215 }
216 else {
217 mrbc_filename(mrb, c, "-e");
218 mrb_gv_set(mrb, zero_sym, mrb_str_new_lit(mrb, "-e"));
219 }
220
221 /* Load program */
222 if (args.mrbfile) {
223 v = mrb_load_irep_file_cxt(mrb, args.rfp, c);
224 }
225 else if (args.rfp) {
226 v = mrb_load_file_cxt(mrb, args.rfp, c);
227 }
228 else {
229 char* utf8 = mrb_utf8_from_locale(args.cmdline, -1);
230 if (!utf8) abort();
231 v = mrb_load_string_cxt(mrb, utf8, c);
232 mrb_utf8_free(utf8);
233 }
234
235 mrbc_context_free(mrb, c);
236 if (mrb->exc) {
237 if (!mrb_undef_p(v)) {
238 mrb_print_error(mrb);
239 }
240 n = -1;
241 }
242 else if (args.check_syntax) {
243 printf("Syntax OK\n");
244 }
245 cleanup(mrb, &args);
246
247 return n == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
248}
Note: See TracBrowser for help on using the repository browser.