funky-cli 0.0.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/src/mirb.c ADDED
@@ -0,0 +1,415 @@
1
+ /*
2
+ ** mirb - Embeddable Interactive Ruby Shell
3
+ **
4
+ ** This program takes code from the user in
5
+ ** an interactive way and executes it
6
+ ** immediately. It's a REPL...
7
+ */
8
+
9
+ #include <stdlib.h>
10
+ #include <string.h>
11
+ #include <stdio.h>
12
+ #include <ctype.h>
13
+
14
+ #ifdef ENABLE_READLINE
15
+ #include <readline/readline.h>
16
+ #include <readline/history.h>
17
+ #define MIRB_ADD_HISTORY(line) add_history(line)
18
+ #define MIRB_READLINE(ch) readline(ch)
19
+ #define MIRB_WRITE_HISTORY(path) write_history(path)
20
+ #define MIRB_READ_HISTORY(path) read_history(path)
21
+ #define MIRB_USING_HISTORY() using_history()
22
+ #elif defined(ENABLE_LINENOISE)
23
+ #define ENABLE_READLINE
24
+ #include <linenoise.h>
25
+ #define MIRB_ADD_HISTORY(line) linenoiseHistoryAdd(line)
26
+ #define MIRB_READLINE(ch) linenoise(ch)
27
+ #define MIRB_WRITE_HISTORY(path) linenoiseHistorySave(path)
28
+ #define MIRB_READ_HISTORY(path) linenoiseHistoryLoad(history_path)
29
+ #define MIRB_USING_HISTORY()
30
+ #endif
31
+
32
+ #include "mruby.h"
33
+ #include "mruby/array.h"
34
+ #include "mruby/proc.h"
35
+ #include "mruby/compile.h"
36
+ #include "mruby/string.h"
37
+
38
+ #ifdef ENABLE_READLINE
39
+
40
+ static const char history_file_name[] = ".mirb_history";
41
+
42
+ static char *
43
+ get_history_path(mrb_state *mrb)
44
+ {
45
+ char *path = NULL;
46
+ const char *home = getenv("HOME");
47
+
48
+ #ifdef _WIN32
49
+ if (home != NULL) {
50
+ home = getenv("USERPROFILE");
51
+ }
52
+ #endif
53
+
54
+ if (home != NULL) {
55
+ int len = snprintf(NULL, 0, "%s/%s", home, history_file_name);
56
+ if (len >= 0) {
57
+ size_t size = len + 1;
58
+ path = (char *)mrb_malloc_simple(mrb, size);
59
+ if (path != NULL) {
60
+ int n = snprintf(path, size, "%s/%s", home, history_file_name);
61
+ if (n != len) {
62
+ mrb_free(mrb, path);
63
+ path = NULL;
64
+ }
65
+ }
66
+ }
67
+ }
68
+
69
+ return path;
70
+ }
71
+
72
+ #endif
73
+
74
+ static void
75
+ p(mrb_state *mrb, mrb_value obj, int prompt)
76
+ {
77
+ mrb_value val;
78
+
79
+ val = mrb_funcall(mrb, obj, "inspect", 0);
80
+ if (prompt) {
81
+ if (!mrb->exc) {
82
+ fputs(" => ", stdout);
83
+ }
84
+ else {
85
+ val = mrb_funcall(mrb, mrb_obj_value(mrb->exc), "inspect", 0);
86
+ }
87
+ }
88
+ if (!mrb_string_p(val)) {
89
+ val = mrb_obj_as_string(mrb, obj);
90
+ }
91
+ fwrite(RSTRING_PTR(val), RSTRING_LEN(val), 1, stdout);
92
+ putc('\n', stdout);
93
+ }
94
+
95
+ /* Guess if the user might want to enter more
96
+ * or if he wants an evaluation of his code now */
97
+ static mrb_bool
98
+ is_code_block_open(struct mrb_parser_state *parser)
99
+ {
100
+ mrb_bool code_block_open = FALSE;
101
+
102
+ /* check for heredoc */
103
+ if (parser->parsing_heredoc != NULL) return TRUE;
104
+ if (parser->heredoc_end_now) {
105
+ parser->heredoc_end_now = FALSE;
106
+ return FALSE;
107
+ }
108
+
109
+ /* check for unterminated string */
110
+ if (parser->lex_strterm) return TRUE;
111
+
112
+ /* check if parser error are available */
113
+ if (0 < parser->nerr) {
114
+ const char unexpected_end[] = "syntax error, unexpected $end";
115
+ const char *message = parser->error_buffer[0].message;
116
+
117
+ /* a parser error occur, we have to check if */
118
+ /* we need to read one more line or if there is */
119
+ /* a different issue which we have to show to */
120
+ /* the user */
121
+
122
+ if (strncmp(message, unexpected_end, sizeof(unexpected_end) - 1) == 0) {
123
+ code_block_open = TRUE;
124
+ }
125
+ else if (strcmp(message, "syntax error, unexpected keyword_end") == 0) {
126
+ code_block_open = FALSE;
127
+ }
128
+ else if (strcmp(message, "syntax error, unexpected tREGEXP_BEG") == 0) {
129
+ code_block_open = FALSE;
130
+ }
131
+ return code_block_open;
132
+ }
133
+
134
+ switch (parser->lstate) {
135
+
136
+ /* all states which need more code */
137
+
138
+ case EXPR_BEG:
139
+ /* beginning of a statement, */
140
+ /* that means previous line ended */
141
+ code_block_open = FALSE;
142
+ break;
143
+ case EXPR_DOT:
144
+ /* a message dot was the last token, */
145
+ /* there has to come more */
146
+ code_block_open = TRUE;
147
+ break;
148
+ case EXPR_CLASS:
149
+ /* a class keyword is not enough! */
150
+ /* we need also a name of the class */
151
+ code_block_open = TRUE;
152
+ break;
153
+ case EXPR_FNAME:
154
+ /* a method name is necessary */
155
+ code_block_open = TRUE;
156
+ break;
157
+ case EXPR_VALUE:
158
+ /* if, elsif, etc. without condition */
159
+ code_block_open = TRUE;
160
+ break;
161
+
162
+ /* now all the states which are closed */
163
+
164
+ case EXPR_ARG:
165
+ /* an argument is the last token */
166
+ code_block_open = FALSE;
167
+ break;
168
+
169
+ /* all states which are unsure */
170
+
171
+ case EXPR_CMDARG:
172
+ break;
173
+ case EXPR_END:
174
+ /* an expression was ended */
175
+ break;
176
+ case EXPR_ENDARG:
177
+ /* closing parenthese */
178
+ break;
179
+ case EXPR_ENDFN:
180
+ /* definition end */
181
+ break;
182
+ case EXPR_MID:
183
+ /* jump keyword like break, return, ... */
184
+ break;
185
+ case EXPR_MAX_STATE:
186
+ /* don't know what to do with this token */
187
+ break;
188
+ default:
189
+ /* this state is unexpected! */
190
+ break;
191
+ }
192
+
193
+ return code_block_open;
194
+ }
195
+
196
+ struct _args {
197
+ mrb_bool verbose : 1;
198
+ int argc;
199
+ char** argv;
200
+ };
201
+
202
+ /* Print a short remark for the user */
203
+ static void
204
+ print_hint(void)
205
+ {
206
+ printf("mirb - Embeddable Interactive Ruby Shell\n\n");
207
+ }
208
+
209
+ #ifndef ENABLE_READLINE
210
+ /* Print the command line prompt of the REPL */
211
+ static void
212
+ print_cmdline(int code_block_open)
213
+ {
214
+ if (code_block_open) {
215
+ printf("* ");
216
+ }
217
+ else {
218
+ printf("> ");
219
+ }
220
+ fflush(stdout);
221
+ }
222
+ #endif
223
+
224
+ void mrb_codedump_all(mrb_state*, struct RProc*);
225
+
226
+ static int
227
+ check_keyword(const char *buf, const char *word)
228
+ {
229
+ const char *p = buf;
230
+ size_t len = strlen(word);
231
+
232
+ /* skip preceding spaces */
233
+ while (*p && isspace((unsigned char)*p)) {
234
+ p++;
235
+ }
236
+ /* check keyword */
237
+ if (strncmp(p, word, len) != 0) {
238
+ return 0;
239
+ }
240
+ p += len;
241
+ /* skip trailing spaces */
242
+ while (*p) {
243
+ if (!isspace((unsigned char)*p)) return 0;
244
+ p++;
245
+ }
246
+ return 1;
247
+ }
248
+
249
+ /*static mrb_value*/
250
+ /*main(int argc, char **argv)*/
251
+ mrb_value
252
+ mrb_mruby_cli_mirb(mrb_state *mrb, mrb_value klass)
253
+ {
254
+ char ruby_code[1024] = { 0 };
255
+ char last_code_line[1024] = { 0 };
256
+ #ifndef ENABLE_READLINE
257
+ int last_char;
258
+ int char_index;
259
+ #else
260
+ char *history_path;
261
+ #endif
262
+ mrbc_context *cxt;
263
+ struct mrb_parser_state *parser;
264
+ /*mrb_state *mrb;*/
265
+ mrb_value result;
266
+ struct _args args;
267
+ mrb_bool code_block_open = FALSE;
268
+ int ai;
269
+ unsigned int stack_keep = 0;
270
+
271
+ #ifdef ENABLE_READLINE
272
+ history_path = get_history_path(mrb);
273
+ if (history_path == NULL) {
274
+ fputs("failed to get history path\n", stderr);
275
+ return mrb_fixnum_value(EXIT_FAILURE);
276
+ }
277
+
278
+ MIRB_USING_HISTORY();
279
+ MIRB_READ_HISTORY(history_path);
280
+ #endif
281
+
282
+ print_hint();
283
+
284
+ cxt = mrbc_context_new(mrb);
285
+ cxt->capture_errors = TRUE;
286
+ cxt->lineno = 1;
287
+ mrbc_filename(mrb, cxt, "(mirb)");
288
+ if (args.verbose) cxt->dump_result = TRUE;
289
+
290
+ ai = mrb_gc_arena_save(mrb);
291
+
292
+ while (TRUE) {
293
+ char *utf8;
294
+
295
+ #ifndef ENABLE_READLINE
296
+ print_cmdline(code_block_open);
297
+
298
+ char_index = 0;
299
+ while ((last_char = getchar()) != '\n') {
300
+ if (last_char == EOF) break;
301
+ if (char_index > sizeof(last_code_line)-2) {
302
+ fputs("input string too long\n", stderr);
303
+ continue;
304
+ }
305
+ last_code_line[char_index++] = last_char;
306
+ }
307
+ if (last_char == EOF) {
308
+ fputs("\n", stdout);
309
+ break;
310
+ }
311
+
312
+ last_code_line[char_index++] = '\n';
313
+ last_code_line[char_index] = '\0';
314
+ #else
315
+ char* line = MIRB_READLINE(code_block_open ? "* " : "> ");
316
+ if (line == NULL) {
317
+ printf("\n");
318
+ break;
319
+ }
320
+ if (strlen(line) > sizeof(last_code_line)-2) {
321
+ fputs("input string too long\n", stderr);
322
+ continue;
323
+ }
324
+ strcpy(last_code_line, line);
325
+ strcat(last_code_line, "\n");
326
+ MIRB_ADD_HISTORY(line);
327
+ free(line);
328
+ #endif
329
+
330
+ if (code_block_open) {
331
+ if (strlen(ruby_code)+strlen(last_code_line) > sizeof(ruby_code)-1) {
332
+ fputs("concatenated input string too long\n", stderr);
333
+ continue;
334
+ }
335
+ strcat(ruby_code, last_code_line);
336
+ }
337
+ else {
338
+ if (check_keyword(last_code_line, "quit") || check_keyword(last_code_line, "exit")) {
339
+ break;
340
+ }
341
+ strcpy(ruby_code, last_code_line);
342
+ }
343
+
344
+ utf8 = mrb_utf8_from_locale(ruby_code, -1);
345
+ if (!utf8) abort();
346
+
347
+ /* parse code */
348
+ parser = mrb_parser_new(mrb);
349
+ if (parser == NULL) {
350
+ fputs("create parser state error\n", stderr);
351
+ break;
352
+ }
353
+ parser->s = utf8;
354
+ parser->send = utf8 + strlen(utf8);
355
+ parser->lineno = cxt->lineno;
356
+ mrb_parser_parse(parser, cxt);
357
+ code_block_open = is_code_block_open(parser);
358
+ mrb_utf8_free(utf8);
359
+
360
+ if (code_block_open) {
361
+ /* no evaluation of code */
362
+ }
363
+ else {
364
+ if (0 < parser->nerr) {
365
+ /* syntax error */
366
+ printf("line %d: %s\n", parser->error_buffer[0].lineno, parser->error_buffer[0].message);
367
+ }
368
+ else {
369
+ /* generate bytecode */
370
+ struct RProc *proc = mrb_generate_code(mrb, parser);
371
+ if (proc == NULL) {
372
+ fputs("codegen error\n", stderr);
373
+ mrb_parser_free(parser);
374
+ break;
375
+ }
376
+
377
+ if (args.verbose) {
378
+ mrb_codedump_all(mrb, proc);
379
+ }
380
+ /* pass a proc for evaulation */
381
+ /* evaluate the bytecode */
382
+ result = mrb_context_run(mrb,
383
+ proc,
384
+ mrb_top_self(mrb),
385
+ stack_keep);
386
+ stack_keep = proc->body.irep->nlocals;
387
+ /* did an exception occur? */
388
+ if (mrb->exc) {
389
+ p(mrb, mrb_obj_value(mrb->exc), 0);
390
+ mrb->exc = 0;
391
+ }
392
+ else {
393
+ /* no */
394
+ if (!mrb_respond_to(mrb, result, mrb_intern_lit(mrb, "inspect"))){
395
+ result = mrb_any_to_s(mrb, result);
396
+ }
397
+ p(mrb, result, 1);
398
+ }
399
+ }
400
+ ruby_code[0] = '\0';
401
+ last_code_line[0] = '\0';
402
+ mrb_gc_arena_restore(mrb, ai);
403
+ }
404
+ mrb_parser_free(parser);
405
+ cxt->lineno++;
406
+ }
407
+
408
+ #ifdef ENABLE_READLINE
409
+ MIRB_WRITE_HISTORY(history_path);
410
+ #endif
411
+
412
+ mrbc_context_free(mrb, cxt);
413
+
414
+ return mrb_fixnum_value(0);
415
+ }
data/src/mruby.c ADDED
@@ -0,0 +1,244 @@
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
+ #include "mruby/compile.h"
10
+ #include "mruby/value.h"
11
+ #include "mruby/string.h"
12
+
13
+ #ifdef MRB_DISABLE_STDIO
14
+ static void
15
+ p(mrb_state *mrb, mrb_value obj)
16
+ {
17
+ mrb_value val = mrb_inspect(mrb, obj);
18
+
19
+ fwrite(RSTRING_PTR(val), RSTRING_LEN(val), 1, stdout);
20
+ putc('\n', stdout);
21
+ }
22
+ #else
23
+ #define p(mrb,obj) mrb_p(mrb,obj)
24
+ #endif
25
+
26
+ struct _args {
27
+ FILE *rfp;
28
+ char* cmdline;
29
+ mrb_bool fname : 1;
30
+ mrb_bool mrbfile : 1;
31
+ mrb_bool check_syntax : 1;
32
+ mrb_bool verbose : 1;
33
+ int argc;
34
+ char** argv;
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
+ "-e 'command' one line of script",
45
+ "-v print version number, then run in verbose mode",
46
+ "--verbose run in verbose mode",
47
+ "--version print the version",
48
+ "--copyright print the copyright",
49
+ NULL
50
+ };
51
+ const char *const *p = usage_msg;
52
+
53
+ printf("Usage: %s [switches] programfile\n", name);
54
+ while (*p)
55
+ printf(" %s\n", *p++);
56
+ }
57
+
58
+ static int
59
+ parse_args(mrb_state *mrb, int argc, char **argv, struct _args *args)
60
+ {
61
+ char **origargv = argv;
62
+ static const struct _args args_zero = { 0 };
63
+
64
+ *args = args_zero;
65
+
66
+ for (argc--,argv++; argc > 0; argc--,argv++) {
67
+ char *item;
68
+ if (argv[0][0] != '-') break;
69
+
70
+ if (strlen(*argv) <= 1) {
71
+ argc--; argv++;
72
+ args->rfp = stdin;
73
+ break;
74
+ }
75
+
76
+ item = argv[0] + 1;
77
+ switch (*item++) {
78
+ case 'b':
79
+ args->mrbfile = TRUE;
80
+ break;
81
+ case 'c':
82
+ args->check_syntax = TRUE;
83
+ break;
84
+ case 'e':
85
+ if (item[0]) {
86
+ goto append_cmdline;
87
+ }
88
+ else if (argc > 1) {
89
+ argc--; argv++;
90
+ item = argv[0];
91
+ append_cmdline:
92
+ if (!args->cmdline) {
93
+ size_t buflen;
94
+ char *buf;
95
+
96
+ buflen = strlen(item) + 1;
97
+ buf = (char *)mrb_malloc(mrb, buflen);
98
+ memcpy(buf, item, buflen);
99
+ args->cmdline = buf;
100
+ }
101
+ else {
102
+ size_t cmdlinelen;
103
+ size_t itemlen;
104
+
105
+ cmdlinelen = strlen(args->cmdline);
106
+ itemlen = strlen(item);
107
+ args->cmdline =
108
+ (char *)mrb_realloc(mrb, args->cmdline, cmdlinelen + itemlen + 2);
109
+ args->cmdline[cmdlinelen] = '\n';
110
+ memcpy(args->cmdline + cmdlinelen + 1, item, itemlen + 1);
111
+ }
112
+ }
113
+ else {
114
+ printf("%s: No code specified for -e\n", *origargv);
115
+ return EXIT_SUCCESS;
116
+ }
117
+ break;
118
+ case 'v':
119
+ if (!args->verbose) mrb_show_version(mrb);
120
+ args->verbose = TRUE;
121
+ break;
122
+ case '-':
123
+ if (strcmp((*argv) + 2, "version") == 0) {
124
+ mrb_show_version(mrb);
125
+ }
126
+ else if (strcmp((*argv) + 2, "verbose") == 0) {
127
+ args->verbose = TRUE;
128
+ break;
129
+ }
130
+ else if (strcmp((*argv) + 2, "copyright") == 0) {
131
+ mrb_show_copyright(mrb);
132
+ }
133
+ default:
134
+ return EXIT_FAILURE;
135
+ }
136
+ }
137
+
138
+ if (args->rfp == NULL && args->cmdline == NULL) {
139
+ if (*argv == NULL) args->rfp = stdin;
140
+ else {
141
+ args->rfp = fopen(argv[0], args->mrbfile ? "rb" : "r");
142
+ if (args->rfp == NULL) {
143
+ printf("%s: Cannot open program file. (%s)\n", *origargv, *argv);
144
+ return EXIT_FAILURE;
145
+ }
146
+ args->fname = TRUE;
147
+ args->cmdline = argv[0];
148
+ argc--; argv++;
149
+ }
150
+ }
151
+ args->argv = (char **)mrb_realloc(mrb, args->argv, sizeof(char*) * (argc + 1));
152
+ memcpy(args->argv, argv, (argc+1) * sizeof(char*));
153
+ args->argc = argc;
154
+
155
+ return EXIT_SUCCESS;
156
+ }
157
+
158
+ mrb_value
159
+ mrb_mruby_cli_mruby(mrb_state *mrb, mrb_value klass)
160
+ {
161
+ int n = -1;
162
+ int i;
163
+ char *argv[255];
164
+ struct _args args;
165
+ mrb_value ARGV;
166
+ mrbc_context *c;
167
+ mrb_value v, array, element;
168
+ mrb_sym zero_sym;
169
+ mrb_int argc;
170
+
171
+ mrb_get_args(mrb, "io", &argc, &array);
172
+
173
+ for (i = 0; i < argc; i++) {
174
+ element = mrb_ary_shift(mrb, array);
175
+ argv[i] = RSTRING_PTR(element);
176
+ }
177
+
178
+ if (mrb == NULL) {
179
+ fputs("Invalid mrb_state, exiting mruby\n", stderr);
180
+ return mrb_fixnum_value(EXIT_FAILURE);
181
+ }
182
+
183
+ n = parse_args(mrb, argc, argv, &args);
184
+ if (n == EXIT_FAILURE || (args.cmdline == NULL && args.rfp == NULL)) {
185
+ usage(argv[0]);
186
+ return mrb_fixnum_value(n);
187
+ }
188
+
189
+ ARGV = mrb_ary_new_capa(mrb, args.argc);
190
+ for (i = 0; i < args.argc; i++) {
191
+ char* utf8 = mrb_utf8_from_locale(args.argv[i], -1);
192
+ if (utf8) {
193
+ mrb_ary_push(mrb, ARGV, mrb_str_new_cstr(mrb, utf8));
194
+ mrb_utf8_free(utf8);
195
+ }
196
+ }
197
+ mrb_define_global_const(mrb, "ARGV", ARGV);
198
+
199
+ c = mrbc_context_new(mrb);
200
+ if (args.verbose)
201
+ c->dump_result = TRUE;
202
+ if (args.check_syntax)
203
+ c->no_exec = TRUE;
204
+
205
+ /* Set $0 */
206
+ zero_sym = mrb_intern_lit(mrb, "$0");
207
+ if (args.rfp) {
208
+ const char *cmdline;
209
+ cmdline = args.cmdline ? args.cmdline : "-";
210
+ mrbc_filename(mrb, c, cmdline);
211
+ mrb_gv_set(mrb, zero_sym, mrb_str_new_cstr(mrb, cmdline));
212
+ }
213
+ else {
214
+ mrbc_filename(mrb, c, "-e");
215
+ mrb_gv_set(mrb, zero_sym, mrb_str_new_lit(mrb, "-e"));
216
+ }
217
+
218
+ /* Load program */
219
+ if (args.mrbfile) {
220
+ v = mrb_load_irep_file_cxt(mrb, args.rfp, c);
221
+ }
222
+ else if (args.rfp) {
223
+ v = mrb_load_file_cxt(mrb, args.rfp, c);
224
+ }
225
+ else {
226
+ char* utf8 = mrb_utf8_from_locale(args.cmdline, -1);
227
+ if (!utf8) abort();
228
+ v = mrb_load_string_cxt(mrb, utf8, c);
229
+ mrb_utf8_free(utf8);
230
+ }
231
+
232
+ mrbc_context_free(mrb, c);
233
+ if (mrb->exc) {
234
+ if (!mrb_undef_p(v)) {
235
+ mrb_print_error(mrb);
236
+ }
237
+ n = -1;
238
+ }
239
+ else if (args.check_syntax) {
240
+ printf("Syntax OK\n");
241
+ }
242
+
243
+ return n == 0 ? mrb_fixnum_value(EXIT_SUCCESS) : mrb_fixnum_value(EXIT_FAILURE);
244
+ }
@@ -1,6 +1,12 @@
1
1
  // This file is generated by mruby-cli. Do not touch.
2
2
  #include <stdlib.h>
3
3
  #include <stdio.h>
4
+ #include <string.h>
5
+
6
+ #include "mruby.h"
7
+ #include "mruby/compile.h"
8
+ #include "mruby/dump.h"
9
+ #include "mruby/proc.h"
4
10
 
5
11
  /* Include the mruby header */
6
12
  #include <mruby.h>
@@ -31,3 +37,4 @@ int main(int argc, char *argv[])
31
37
 
32
38
  return return_value;
33
39
  }
40
+
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: funky-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Thiago Scalone
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-09-20 00:00:00.000000000 Z
11
+ date: 2016-09-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -64,7 +64,14 @@ files:
64
64
  - funky-cli.gemspec
65
65
  - mrbgem.rake
66
66
  - mrblib/funky-cli.rb
67
+ - mrblib/funky-cli/helper.rb
68
+ - mrblib/funky-cli/mruby.rb
69
+ - mrblib/funky-cli/setup.rb
67
70
  - mrblib/funky-cli/version.rb
71
+ - mrblib/util.rb
72
+ - src/funky_cli_gem.c
73
+ - src/mirb.c
74
+ - src/mruby.c
68
75
  - test/test_funky-cli.rb
69
76
  - tools/funky-cli/funky-cli.c
70
77
  homepage: http://github.com/da_funk/funky-cli