Ruby  2.7.1p83(2020-03-31revisiona0c7c23c9cec0d0ffcba012279cd652d28ad5bf3)
ruby.c
Go to the documentation of this file.
1 /**********************************************************************
2 
3  ruby.c -
4 
5  $Author$
6  created at: Tue Aug 10 12:47:31 JST 1993
7 
8  Copyright (C) 1993-2007 Yukihiro Matsumoto
9  Copyright (C) 2000 Network Applied Communication Laboratory, Inc.
10  Copyright (C) 2000 Information-technology Promotion Agency, Japan
11 
12 **********************************************************************/
13 
14 #ifdef __CYGWIN__
15 #include <windows.h>
16 #include <sys/cygwin.h>
17 #endif
18 #include "ruby/encoding.h"
19 #include "ruby/thread.h"
20 #include "ruby/version.h"
21 #include "internal.h"
22 #include "eval_intern.h"
23 #include "dln.h"
24 #include <stdio.h>
25 #include <sys/types.h>
26 #include <ctype.h>
27 
28 #ifdef __hpux
29 #include <sys/pstat.h>
30 #endif
31 #if defined(LOAD_RELATIVE) && defined(HAVE_DLADDR)
32 #include <dlfcn.h>
33 #endif
34 
35 #ifdef HAVE_UNISTD_H
36 #include <unistd.h>
37 #endif
38 #if defined(HAVE_FCNTL_H)
39 #include <fcntl.h>
40 #elif defined(HAVE_SYS_FCNTL_H)
41 #include <sys/fcntl.h>
42 #endif
43 #ifdef HAVE_SYS_PARAM_H
44 # include <sys/param.h>
45 #endif
46 #ifndef MAXPATHLEN
47 # define MAXPATHLEN 1024
48 #endif
49 #ifndef O_ACCMODE
50 # define O_ACCMODE (O_RDONLY | O_WRONLY | O_RDWR)
51 #endif
52 
53 #include "ruby/util.h"
54 
55 #include "mjit.h"
56 
57 void Init_ruby_description(void);
58 
59 #ifndef HAVE_STDLIB_H
60 char *getenv();
61 #endif
62 
63 #ifndef DISABLE_RUBYGEMS
64 # define DISABLE_RUBYGEMS 0
65 #endif
66 #if DISABLE_RUBYGEMS
67 #define DEFAULT_RUBYGEMS_ENABLED "disabled"
68 #else
69 #define DEFAULT_RUBYGEMS_ENABLED "enabled"
70 #endif
71 
72 void rb_warning_category_update(unsigned int mask, unsigned int bits);
73 
74 #define COMMA ,
75 #define FEATURE_BIT(bit) (1U << feature_##bit)
76 #define EACH_FEATURES(X, SEP) \
77  X(gems) \
78  SEP \
79  X(did_you_mean) \
80  SEP \
81  X(rubyopt) \
82  SEP \
83  X(frozen_string_literal) \
84  SEP \
85  X(jit) \
86  /* END OF FEATURES */
87 #define EACH_DEBUG_FEATURES(X, SEP) \
88  X(frozen_string_literal) \
89  /* END OF DEBUG FEATURES */
90 #define AMBIGUOUS_FEATURE_NAMES 0 /* no ambiguous feature names now */
91 #define DEFINE_FEATURE(bit) feature_##bit
92 #define DEFINE_DEBUG_FEATURE(bit) feature_debug_##bit
99 };
100 
101 #define DEBUG_BIT(bit) (1U << feature_debug_##bit)
102 
103 #define DUMP_BIT(bit) (1U << dump_##bit)
104 #define DEFINE_DUMP(bit) dump_##bit
105 #define EACH_DUMPS(X, SEP) \
106  X(version) \
107  SEP \
108  X(copyright) \
109  SEP \
110  X(usage) \
111  SEP \
112  X(help) \
113  SEP \
114  X(yydebug) \
115  SEP \
116  X(syntax) \
117  SEP \
118  X(parsetree) \
119  SEP \
120  X(parsetree_with_comment) \
121  SEP \
122  X(insns) \
123  /* END OF DUMPS */
128  DUMP_BIT(parsetree) | DUMP_BIT(parsetree_with_comment) |
129  DUMP_BIT(insns))
130 };
131 
133 
134 typedef struct {
135  unsigned int mask;
136  unsigned int set;
138 
139 static inline void
140 rb_feature_set_to(ruby_features_t *feat, unsigned int bit_mask, unsigned int bit_set)
141 {
142  feat->mask |= bit_mask;
143  feat->set = (feat->set & ~bit_mask) | bit_set;
144 }
145 
146 #define FEATURE_SET_TO(feat, bit_mask, bit_set) \
147  rb_feature_set_to(&(feat), bit_mask, bit_set)
148 #define FEATURE_SET(feat, bits) FEATURE_SET_TO(feat, bits, bits)
149 #define FEATURE_SET_RESTORE(feat, save) FEATURE_SET_TO(feat, (save).mask, (save).set & (save).mask)
150 #define FEATURE_SET_P(feat, bits) ((feat).set & (bits))
151 
153  const char *script;
156  struct {
157  struct {
159  int index;
160  } enc;
161  } src, ext, intern;
165  unsigned int dump;
166 #if USE_MJIT
167  struct mjit_options mjit;
168 #endif
169  int sflag, xflag;
170  unsigned int warning: 1;
171  unsigned int verbose: 1;
172  unsigned int do_loop: 1;
173  unsigned int do_print: 1;
174  unsigned int do_line: 1;
175  unsigned int do_split: 1;
176  unsigned int do_search: 1;
177  unsigned int setids: 2;
178 };
179 
180 static void init_ids(ruby_cmdline_options_t *);
181 
182 #define src_encoding_index GET_VM()->src_encoding_index
183 
184 enum {
186  0
187  | FEATURE_BIT(frozen_string_literal)
188  | FEATURE_BIT(debug_frozen_string_literal)
189  ),
191  (FEATURE_BIT(debug_flag_first)-1)
192 #if DISABLE_RUBYGEMS
193  & ~FEATURE_BIT(gems)
194 #endif
195  & ~FEATURE_BIT(frozen_string_literal)
196  & ~FEATURE_BIT(jit)
197  )
198 };
199 
200 static ruby_cmdline_options_t *
201 cmdline_options_init(ruby_cmdline_options_t *opt)
202 {
203  MEMZERO(opt, *opt, 1);
204  init_ids(opt);
205  opt->src.enc.index = src_encoding_index;
206  opt->ext.enc.index = -1;
207  opt->intern.enc.index = -1;
209 #ifdef MJIT_FORCE_ENABLE /* to use with: ./configure cppflags="-DMJIT_FORCE_ENABLE" */
210  opt->features.set |= FEATURE_BIT(jit);
211 #endif
212  return opt;
213 }
214 
215 static rb_ast_t *load_file(VALUE parser, VALUE fname, VALUE f, int script,
217 static VALUE open_load_file(VALUE fname_v, int *xflag);
218 static void forbid_setid(const char *, const ruby_cmdline_options_t *);
219 #define forbid_setid(s) forbid_setid((s), opt)
220 
221 static struct {
222  int argc;
223  char **argv;
224 } origarg;
225 
226 static void
227 show_usage_line(const char *str, unsigned int namelen, unsigned int secondlen, int help)
228 {
229  const unsigned int w = 16;
230  const int wrap = help && namelen + secondlen - 1 > w;
231  printf(" %.*s%-*.*s%-*s%s\n", namelen-1, str,
232  (wrap ? 0 : w - namelen + 1),
233  (help ? secondlen-1 : 0), str + namelen,
234  (wrap ? w + 3 : 0), (wrap ? "\n" : ""),
235  str + namelen + secondlen);
236 }
237 
238 static void
239 usage(const char *name, int help)
240 {
241  /* This message really ought to be max 23 lines.
242  * Removed -h because the user already knows that option. Others? */
243 
244  struct message {
245  const char *str;
246  unsigned short namelen, secondlen;
247  };
248 #define M(shortopt, longopt, desc) { \
249  shortopt " " longopt " " desc, \
250  (unsigned short)sizeof(shortopt), \
251  (unsigned short)sizeof(longopt), \
252 }
253  static const struct message usage_msg[] = {
254  M("-0[octal]", "", "specify record separator (\\0, if no argument)"),
255  M("-a", "", "autosplit mode with -n or -p (splits $_ into $F)"),
256  M("-c", "", "check syntax only"),
257  M("-Cdirectory", "", "cd to directory before executing your script"),
258  M("-d", ", --debug", "set debugging flags (set $DEBUG to true)"),
259  M("-e 'command'", "", "one line of script. Several -e's allowed. Omit [programfile]"),
260  M("-Eex[:in]", ", --encoding=ex[:in]", "specify the default external and internal character encodings"),
261  M("-Fpattern", "", "split() pattern for autosplit (-a)"),
262  M("-i[extension]", "", "edit ARGV files in place (make backup if extension supplied)"),
263  M("-Idirectory", "", "specify $LOAD_PATH directory (may be used more than once)"),
264  M("-l", "", "enable line ending processing"),
265  M("-n", "", "assume 'while gets(); ... end' loop around your script"),
266  M("-p", "", "assume loop like -n but print line also like sed"),
267  M("-rlibrary", "", "require the library before executing your script"),
268  M("-s", "", "enable some switch parsing for switches after script name"),
269  M("-S", "", "look for the script using PATH environment variable"),
270  M("-v", "", "print the version number, then turn on verbose mode"),
271  M("-w", "", "turn warnings on for your script"),
272  M("-W[level=2|:category]", "", "set warning level; 0=silence, 1=medium, 2=verbose"),
273  M("-x[directory]", "", "strip off text before #!ruby line and perhaps cd to directory"),
274  M("--jit", "", "enable JIT with default options (experimental)"),
275  M("--jit-[option]","", "enable JIT with an option (experimental)"),
276  M("-h", "", "show this message, --help for more info"),
277  };
278  static const struct message help_msg[] = {
279  M("--copyright", "", "print the copyright"),
280  M("--dump={insns|parsetree|...}[,...]", "",
281  "dump debug information. see below for available dump list"),
282  M("--enable={gems|rubyopt|...}[,...]", ", --disable={gems|rubyopt|...}[,...]",
283  "enable or disable features. see below for available features"),
284  M("--external-encoding=encoding", ", --internal-encoding=encoding",
285  "specify the default external or internal character encoding"),
286  M("--verbose", "", "turn on verbose mode and disable script from stdin"),
287  M("--version", "", "print the version number, then exit"),
288  M("--help", "", "show this message, -h for short message"),
289  };
290  static const struct message dumps[] = {
291  M("insns", "", "instruction sequences"),
292  M("yydebug", "", "yydebug of yacc parser generator"),
293  M("parsetree", "", "AST"),
294  M("parsetree_with_comment", "", "AST with comments"),
295  };
296  static const struct message features[] = {
297  M("gems", "", "rubygems (default: "DEFAULT_RUBYGEMS_ENABLED")"),
298  M("did_you_mean", "", "did_you_mean (default: "DEFAULT_RUBYGEMS_ENABLED")"),
299  M("rubyopt", "", "RUBYOPT environment variable (default: enabled)"),
300  M("frozen-string-literal", "", "freeze all string literals (default: disabled)"),
301  M("jit", "", "JIT compiler (default: disabled)"),
302  };
303  static const struct message warn_categories[] = {
304  M("deprecated", "", "deprecated features"),
305  M("experimental", "", "experimental features"),
306  };
307  static const struct message mjit_options[] = {
308  M("--jit-warnings", "", "Enable printing JIT warnings"),
309  M("--jit-debug", "", "Enable JIT debugging (very slow), or add cflags if specified"),
310  M("--jit-wait", "", "Wait until JIT compilation finishes every time (for testing)"),
311  M("--jit-save-temps", "", "Save JIT temporary files in $TMP or /tmp (for testing)"),
312  M("--jit-verbose=num", "", "Print JIT logs of level num or less to stderr (default: 0)"),
313  M("--jit-max-cache=num", "", "Max number of methods to be JIT-ed in a cache (default: 100)"),
314  M("--jit-min-calls=num", "", "Number of calls to trigger JIT (for testing, default: 10000)"),
315  };
316  int i;
317  const int num = numberof(usage_msg) - (help ? 1 : 0);
318 #define SHOW(m) show_usage_line((m).str, (m).namelen, (m).secondlen, help)
319 
320  printf("Usage: %s [switches] [--] [programfile] [arguments]\n", name);
321  for (i = 0; i < num; ++i)
322  SHOW(usage_msg[i]);
323 
324  if (!help) return;
325 
326  for (i = 0; i < numberof(help_msg); ++i)
327  SHOW(help_msg[i]);
328  puts("Dump List:");
329  for (i = 0; i < numberof(dumps); ++i)
330  SHOW(dumps[i]);
331  puts("Features:");
332  for (i = 0; i < numberof(features); ++i)
333  SHOW(features[i]);
334  puts("Warning categories:");
335  for (i = 0; i < numberof(warn_categories); ++i)
336  SHOW(warn_categories[i]);
337  puts("JIT options (experimental):");
338  for (i = 0; i < numberof(mjit_options); ++i)
339  SHOW(mjit_options[i]);
340 }
341 
342 #define rubylib_path_new rb_str_new
343 
344 static void
345 push_include(const char *path, VALUE (*filter)(VALUE))
346 {
347  const char sep = PATH_SEP_CHAR;
348  const char *p, *s;
349  VALUE load_path = GET_VM()->load_path;
350 
351  p = path;
352  while (*p) {
353  while (*p == sep)
354  p++;
355  if (!*p) break;
356  for (s = p; *s && *s != sep; s = CharNext(s));
357  rb_ary_push(load_path, (*filter)(rubylib_path_new(p, s - p)));
358  p = s;
359  }
360 }
361 
362 #ifdef __CYGWIN__
363 static void
364 push_include_cygwin(const char *path, VALUE (*filter)(VALUE))
365 {
366  const char *p, *s;
367  char rubylib[FILENAME_MAX];
368  VALUE buf = 0;
369 
370  p = path;
371  while (*p) {
372  unsigned int len;
373  while (*p == ';')
374  p++;
375  if (!*p) break;
376  for (s = p; *s && *s != ';'; s = CharNext(s));
377  len = s - p;
378  if (*s) {
379  if (!buf) {
380  buf = rb_str_new(p, len);
381  p = RSTRING_PTR(buf);
382  }
383  else {
385  p = strncpy(RSTRING_PTR(buf), p, len);
386  }
387  }
388 #ifdef HAVE_CYGWIN_CONV_PATH
389 #define CONV_TO_POSIX_PATH(p, lib) \
390  cygwin_conv_path(CCP_WIN_A_TO_POSIX|CCP_RELATIVE, (p), (lib), sizeof(lib))
391 #else
392 # error no cygwin_conv_path
393 #endif
394  if (CONV_TO_POSIX_PATH(p, rubylib) == 0)
395  p = rubylib;
396  push_include(p, filter);
397  if (!*s) break;
398  p = s + 1;
399  }
400 }
401 
402 #define push_include push_include_cygwin
403 #endif
404 
405 void
406 ruby_push_include(const char *path, VALUE (*filter)(VALUE))
407 {
408  if (path == 0)
409  return;
410  push_include(path, filter);
411 }
412 
413 static VALUE
414 identical_path(VALUE path)
415 {
416  return path;
417 }
418 static VALUE
419 locale_path(VALUE path)
420 {
422  return path;
423 }
424 
425 void
426 ruby_incpush(const char *path)
427 {
428  ruby_push_include(path, locale_path);
429 }
430 
431 static VALUE
432 expand_include_path(VALUE path)
433 {
434  char *p = RSTRING_PTR(path);
435  if (!p)
436  return path;
437  if (*p == '.' && p[1] == '/')
438  return path;
439  return rb_file_expand_path(path, Qnil);
440 }
441 
442 void
444 {
445  ruby_push_include(path, expand_include_path);
446 }
447 
448 #undef UTF8_PATH
449 #if defined _WIN32 || defined __CYGWIN__
450 static HMODULE libruby;
451 
452 BOOL WINAPI
453 DllMain(HINSTANCE dll, DWORD reason, LPVOID reserved)
454 {
455  if (reason == DLL_PROCESS_ATTACH)
456  libruby = dll;
457  return TRUE;
458 }
459 
460 HANDLE
461 rb_libruby_handle(void)
462 {
463  return libruby;
464 }
465 
466 static inline void
467 translit_char_bin(char *p, int from, int to)
468 {
469  while (*p) {
470  if ((unsigned char)*p == from)
471  *p = to;
472  p++;
473  }
474 }
475 #endif
476 
477 #ifdef _WIN32
478 # define UTF8_PATH 1
479 #endif
480 
481 #ifndef UTF8_PATH
482 # define UTF8_PATH 0
483 #endif
484 #if UTF8_PATH
485 # define IF_UTF8_PATH(t, f) t
486 #else
487 # define IF_UTF8_PATH(t, f) f
488 #endif
489 
490 #if UTF8_PATH
491 static VALUE
493 {
494  return rb_str_conv_enc_opts(str, from, to,
496  Qnil);
497 }
498 #else
499 # define str_conv_enc(str, from, to) (str)
500 #endif
501 
502 void ruby_init_loadpath(void);
503 
504 #if defined(LOAD_RELATIVE)
505 static VALUE
506 runtime_libruby_path(void)
507 {
508 #if defined _WIN32 || defined __CYGWIN__
510  VALUE path;
511  VALUE wsopath = rb_str_new(0, len*sizeof(WCHAR));
512  WCHAR *wlibpath;
513  char *libpath;
514 
515  while (wlibpath = (WCHAR *)RSTRING_PTR(wsopath),
516  ret = GetModuleFileNameW(libruby, wlibpath, len),
517  (ret == len))
518  {
519  rb_str_modify_expand(wsopath, len*sizeof(WCHAR));
520  rb_str_set_len(wsopath, (len += len)*sizeof(WCHAR));
521  }
522  if (!ret || ret > len) rb_fatal("failed to get module file name");
523 #if defined __CYGWIN__
524  {
525  const int win_to_posix = CCP_WIN_W_TO_POSIX | CCP_RELATIVE;
526  size_t newsize = cygwin_conv_path(win_to_posix, wlibpath, 0, 0);
527  if (!newsize) rb_fatal("failed to convert module path to cygwin");
528  path = rb_str_new(0, newsize);
529  libpath = RSTRING_PTR(path);
530  if (cygwin_conv_path(win_to_posix, wlibpath, libpath, newsize)) {
531  rb_str_resize(path, 0);
532  }
533  }
534 #else
535  {
536  DWORD i;
537  for (len = ret, i = 0; i < len; ++i) {
538  if (wlibpath[i] == L'\\') {
539  wlibpath[i] = L'/';
540  ret = i+1; /* chop after the last separator */
541  }
542  }
543  }
544  len = WideCharToMultiByte(CP_UTF8, 0, wlibpath, ret, NULL, 0, NULL, NULL);
545  path = rb_utf8_str_new(0, len);
546  libpath = RSTRING_PTR(path);
547  WideCharToMultiByte(CP_UTF8, 0, wlibpath, ret, libpath, len, NULL, NULL);
548 #endif
549  rb_str_resize(wsopath, 0);
550  return path;
551 #elif defined(HAVE_DLADDR)
552  Dl_info dli;
553  VALUE fname, path;
554  const void* addr = (void *)(VALUE)expand_include_path;
555 
556  if (!dladdr((void *)addr, &dli)) {
557  return rb_str_new(0, 0);
558  }
559 #ifdef __linux__
560  else if (origarg.argc > 0 && origarg.argv && dli.dli_fname == origarg.argv[0]) {
561  fname = rb_str_new_cstr("/proc/self/exe");
562  path = rb_readlink(fname, NULL);
563  }
564 #endif
565  else {
566  fname = rb_str_new_cstr(dli.dli_fname);
567  path = rb_realpath_internal(Qnil, fname, 1);
568  }
569  rb_str_resize(fname, 0);
570  return path;
571 #else
572 # error relative load path is not supported on this platform.
573 #endif
574 }
575 #endif
576 
577 #define INITIAL_LOAD_PATH_MARK rb_intern_const("@gem_prelude_index")
578 
580 
581 void
583 {
584  VALUE load_path, archlibdir = 0;
585  ID id_initial_load_path_mark;
586  const char *paths = ruby_initial_load_paths;
587 #if defined LOAD_RELATIVE
588 #if !defined ENABLE_MULTIARCH
589 # define RUBY_ARCH_PATH ""
590 #elif defined RUBY_ARCH
591 # define RUBY_ARCH_PATH "/"RUBY_ARCH
592 #else
593 # define RUBY_ARCH_PATH "/"RUBY_PLATFORM
594 #endif
595  char *libpath;
596  VALUE sopath;
597  size_t baselen;
598  const char *p;
599 
600  sopath = runtime_libruby_path();
601  libpath = RSTRING_PTR(sopath);
602 
603  p = strrchr(libpath, '/');
604  if (p) {
605  static const char libdir[] = "/"
606 #ifdef LIBDIR_BASENAME
608 #else
609  "lib"
610 #endif
611  RUBY_ARCH_PATH;
612  const ptrdiff_t libdir_len = (ptrdiff_t)sizeof(libdir)
613  - rb_strlen_lit(RUBY_ARCH_PATH) - 1;
614  static const char bindir[] = "/bin";
615  const ptrdiff_t bindir_len = (ptrdiff_t)sizeof(bindir) - 1;
616 
617  const char *p2 = NULL;
618 
619 #ifdef ENABLE_MULTIARCH
620  multiarch:
621 #endif
622  if (p - libpath >= bindir_len && !STRNCASECMP(p - bindir_len, bindir, bindir_len)) {
623  p -= bindir_len;
624  archlibdir = rb_str_subseq(sopath, 0, p - libpath);
625  rb_str_cat_cstr(archlibdir, libdir);
626  OBJ_FREEZE_RAW(archlibdir);
627  }
628  else if (p - libpath >= libdir_len && !strncmp(p - libdir_len, libdir, libdir_len)) {
629  archlibdir = rb_str_subseq(sopath, 0, (p2 ? p2 : p) - libpath);
630  OBJ_FREEZE_RAW(archlibdir);
631  p -= libdir_len;
632  }
633 #ifdef ENABLE_MULTIARCH
634  else if (p2) {
635  p = p2;
636  }
637  else {
638  p2 = p;
640  if (p) goto multiarch;
641  p = p2;
642  }
643 #endif
644  }
645  baselen = p - libpath;
646  rb_str_resize(sopath, baselen);
647  libpath = RSTRING_PTR(sopath);
648 #define PREFIX_PATH() sopath
649 #define BASEPATH() rb_str_buf_cat(rb_str_buf_new(baselen+len), libpath, baselen)
650 #define RUBY_RELATIVE(path, len) rb_str_buf_cat(BASEPATH(), (path), (len))
651 #else
652  const size_t exec_prefix_len = strlen(ruby_exec_prefix);
653 #define RUBY_RELATIVE(path, len) rubylib_path_new((path), (len))
654 #define PREFIX_PATH() RUBY_RELATIVE(ruby_exec_prefix, exec_prefix_len)
655 #endif
659  if (!archlibdir) archlibdir = ruby_prefix_path;
661  ruby_archlibdir_path = archlibdir;
662 
663  load_path = GET_VM()->load_path;
664 
665  ruby_push_include(getenv("RUBYLIB"), identical_path);
666 
667  id_initial_load_path_mark = INITIAL_LOAD_PATH_MARK;
668  while (*paths) {
669  size_t len = strlen(paths);
670  VALUE path = RUBY_RELATIVE(paths, len);
671  rb_ivar_set(path, id_initial_load_path_mark, path);
672  rb_ary_push(load_path, path);
673  paths += len + 1;
674  }
675 
677 }
678 
679 
680 static void
681 add_modules(VALUE *req_list, const char *mod)
682 {
683  VALUE list = *req_list;
684  VALUE feature;
685 
686  if (!list) {
687  *req_list = list = rb_ary_tmp_new(0);
688  }
689  feature = rb_str_cat_cstr(rb_str_tmp_new(0), mod);
690  rb_ary_push(list, feature);
691 }
692 
693 static void
694 require_libraries(VALUE *req_list)
695 {
696  VALUE list = *req_list;
697  VALUE self = rb_vm_top_self();
698  ID require;
700 
701  CONST_ID(require, "require");
702  while (list && RARRAY_LEN(list) > 0) {
703  VALUE feature = rb_ary_shift(list);
704  rb_enc_associate(feature, extenc);
706  OBJ_FREEZE(feature);
707  rb_funcallv(self, require, 1, &feature);
708  }
709  *req_list = 0;
710 }
711 
712 static const struct rb_block*
713 toplevel_context(rb_binding_t *bind)
714 {
715  return &bind->block;
716 }
717 
718 static void
719 process_sflag(int *sflag)
720 {
721  if (*sflag > 0) {
722  long n;
723  const VALUE *args;
724  VALUE argv = rb_argv;
725 
726  n = RARRAY_LEN(argv);
727  args = RARRAY_CONST_PTR(argv);
728  while (n > 0) {
729  VALUE v = *args++;
730  char *s = StringValuePtr(v);
731  char *p;
732  int hyphen = FALSE;
733 
734  if (s[0] != '-')
735  break;
736  n--;
737  if (s[1] == '-' && s[2] == '\0')
738  break;
739 
740  v = Qtrue;
741  /* check if valid name before replacing - with _ */
742  for (p = s + 1; *p; p++) {
743  if (*p == '=') {
744  *p++ = '\0';
745  v = rb_str_new2(p);
746  break;
747  }
748  if (*p == '-') {
749  hyphen = TRUE;
750  }
751  else if (*p != '_' && !ISALNUM(*p)) {
752  VALUE name_error[2];
753  name_error[0] =
754  rb_str_new2("invalid name for global variable - ");
755  if (!(p = strchr(p, '='))) {
756  rb_str_cat2(name_error[0], s);
757  }
758  else {
759  rb_str_cat(name_error[0], s, p - s);
760  }
761  name_error[1] = args[-1];
763  }
764  }
765  s[0] = '$';
766  if (hyphen) {
767  for (p = s + 1; *p; ++p) {
768  if (*p == '-')
769  *p = '_';
770  }
771  }
772  rb_gv_set(s, v);
773  }
774  n = RARRAY_LEN(argv) - n;
775  while (n--) {
777  }
778  *sflag = -1;
779  }
780 }
781 
782 static long proc_options(long argc, char **argv, ruby_cmdline_options_t *opt, int envopt);
783 
784 static void
785 moreswitches(const char *s, ruby_cmdline_options_t *opt, int envopt)
786 {
787  long argc, i, len;
788  char **argv, *p;
789  const char *ap = 0;
790  VALUE argstr, argary;
791  void *ptr;
792 
793  while (ISSPACE(*s)) s++;
794  if (!*s) return;
795  argstr = rb_str_tmp_new((len = strlen(s)) + (envopt!=0));
796  argary = rb_str_tmp_new(0);
797 
798  p = RSTRING_PTR(argstr);
799  if (envopt) *p++ = ' ';
800  memcpy(p, s, len + 1);
801  ap = 0;
802  rb_str_cat(argary, (char *)&ap, sizeof(ap));
803  while (*p) {
804  ap = p;
805  rb_str_cat(argary, (char *)&ap, sizeof(ap));
806  while (*p && !ISSPACE(*p)) ++p;
807  if (!*p) break;
808  *p++ = '\0';
809  while (ISSPACE(*p)) ++p;
810  }
811  argc = RSTRING_LEN(argary) / sizeof(ap);
812  ap = 0;
813  rb_str_cat(argary, (char *)&ap, sizeof(ap));
814  argv = ptr = ALLOC_N(char *, argc);
815  MEMMOVE(argv, RSTRING_PTR(argary), char *, argc);
816 
817  while ((i = proc_options(argc, argv, opt, envopt)) > 1 && envopt && (argc -= i) > 0) {
818  argv += i;
819  if (**argv != '-') {
820  *--*argv = '-';
821  }
822  if ((*argv)[1]) {
823  ++argc;
824  --argv;
825  }
826  }
827 
828  ruby_xfree(ptr);
829  /* get rid of GC */
830  rb_str_resize(argary, 0);
831  rb_str_resize(argstr, 0);
832 }
833 
834 static int
835 name_match_p(const char *name, const char *str, size_t len)
836 {
837  if (len == 0) return 0;
838  while (1) {
839  while (TOLOWER(*str) == *name) {
840  if (!--len || !*++str) return 1;
841  ++name;
842  }
843  if (*str != '-' && *str != '_') return 0;
844  while (ISALNUM(*name)) name++;
845  if (*name != '-' && *name != '_') return 0;
846  ++name;
847  ++str;
848  }
849 }
850 
851 #define NAME_MATCH_P(name, str, len) \
852  ((len) < (int)sizeof(name) && name_match_p((name), (str), (len)))
853 
854 #define UNSET_WHEN(name, bit, str, len) \
855  if (NAME_MATCH_P((name), (str), (len))) { \
856  *(unsigned int *)arg &= ~(bit); \
857  return; \
858  }
859 
860 #define SET_WHEN(name, bit, str, len) \
861  if (NAME_MATCH_P((name), (str), (len))) { \
862  *(unsigned int *)arg |= (bit); \
863  return; \
864  }
865 
866 #define LITERAL_NAME_ELEMENT(name) #name
867 
868 static void
869 feature_option(const char *str, int len, void *arg, const unsigned int enable)
870 {
871  static const char list[] = EACH_FEATURES(LITERAL_NAME_ELEMENT, ", ");
872  ruby_features_t *argp = arg;
873  unsigned int mask = ~0U;
874  unsigned int set = 0U;
875 #if AMBIGUOUS_FEATURE_NAMES
876  int matched = 0;
877 # define FEATURE_FOUND ++matched
878 #else
879 # define FEATURE_FOUND goto found
880 #endif
881 #define SET_FEATURE(bit) \
882  if (NAME_MATCH_P(#bit, str, len)) {set |= mask = FEATURE_BIT(bit); FEATURE_FOUND;}
884  if (NAME_MATCH_P("all", str, len)) {
885  found:
886  FEATURE_SET_TO(*argp, mask, (mask & enable));
887  return;
888  }
889 #if AMBIGUOUS_FEATURE_NAMES
890  if (matched == 1) goto found;
891  if (matched > 1) {
892  VALUE mesg = rb_sprintf("ambiguous feature: `%.*s' (", len, str);
893 #define ADD_FEATURE_NAME(bit) \
894  if (FEATURE_BIT(bit) & set) { \
895  rb_str_cat_cstr(mesg, #bit); \
896  if (--matched) rb_str_cat_cstr(mesg, ", "); \
897  }
898  EACH_FEATURES(ADD_FEATURE_NAME, ;);
899  rb_str_cat_cstr(mesg, ")");
901 #undef ADD_FEATURE_NAME
902  }
903 #endif
904  rb_warn("unknown argument for --%s: `%.*s'",
905  enable ? "enable" : "disable", len, str);
906  rb_warn("features are [%.*s].", (int)strlen(list), list);
907 }
908 
909 static void
910 enable_option(const char *str, int len, void *arg)
911 {
912  feature_option(str, len, arg, ~0U);
913 }
914 
915 static void
916 disable_option(const char *str, int len, void *arg)
917 {
918  feature_option(str, len, arg, 0U);
919 }
920 
922 int ruby_env_debug_option(const char *str, int len, void *arg);
923 
924 static void
925 debug_option(const char *str, int len, void *arg)
926 {
927  static const char list[] = EACH_DEBUG_FEATURES(LITERAL_NAME_ELEMENT, ", ");
928  ruby_features_t *argp = arg;
929 #define SET_WHEN_DEBUG(bit) \
930  if (NAME_MATCH_P(#bit, str, len)) { \
931  FEATURE_SET(*argp, DEBUG_BIT(bit)); \
932  return; \
933  }
935 #ifdef RUBY_DEVEL
936  if (ruby_patchlevel < 0 && ruby_env_debug_option(str, len, 0)) return;
937 #endif
938  rb_warn("unknown argument for --debug: `%.*s'", len, str);
939  rb_warn("debug features are [%.*s].", (int)strlen(list), list);
940 }
941 
942 static void
943 dump_option(const char *str, int len, void *arg)
944 {
945  static const char list[] = EACH_DUMPS(LITERAL_NAME_ELEMENT, ", ");
946 #define SET_WHEN_DUMP(bit) SET_WHEN(#bit, DUMP_BIT(bit), str, len)
948  rb_warn("don't know how to dump `%.*s',", len, str);
949  rb_warn("but only [%.*s].", (int)strlen(list), list);
950 }
951 
952 static void
953 set_option_encoding_once(const char *type, VALUE *name, const char *e, long elen)
954 {
955  VALUE ename;
956 
957  if (!elen) elen = strlen(e);
958  ename = rb_str_new(e, elen);
959 
960  if (*name &&
961  rb_funcall(ename, rb_intern("casecmp"), 1, *name) != INT2FIX(0)) {
963  "%s already set to %"PRIsVALUE, type, *name);
964  }
965  *name = ename;
966 }
967 
968 #define set_internal_encoding_once(opt, e, elen) \
969  set_option_encoding_once("default_internal", &(opt)->intern.enc.name, (e), (elen))
970 #define set_external_encoding_once(opt, e, elen) \
971  set_option_encoding_once("default_external", &(opt)->ext.enc.name, (e), (elen))
972 #define set_source_encoding_once(opt, e, elen) \
973  set_option_encoding_once("source", &(opt)->src.enc.name, (e), (elen))
974 
975 #if USE_MJIT
976 static void
977 setup_mjit_options(const char *s, struct mjit_options *mjit_opt)
978 {
979  if (*s == 0) return;
980  else if (strcmp(s, "-warnings") == 0) {
981  mjit_opt->warnings = 1;
982  }
983  else if (strncmp(s, "-debug=", 7) == 0) {
984  mjit_opt->debug_flags = strdup(s + 7);
985  }
986  else if (strcmp(s, "-debug") == 0) {
987  mjit_opt->debug = 1;
988  }
989  else if (strcmp(s, "-wait") == 0) {
990  mjit_opt->wait = 1;
991  }
992  else if (strcmp(s, "-save-temps") == 0) {
993  mjit_opt->save_temps = 1;
994  }
995  else if (strncmp(s, "-verbose=", 9) == 0) {
996  mjit_opt->verbose = atoi(s + 9);
997  }
998  else if (strncmp(s, "-max-cache=", 11) == 0) {
999  mjit_opt->max_cache_size = atoi(s + 11);
1000  }
1001  else if (strncmp(s, "-min-calls=", 11) == 0) {
1002  mjit_opt->min_calls = atoi(s + 11);
1003  }
1004  else {
1006  "invalid MJIT option `%s' (--help will show valid MJIT options)", s + 1);
1007  }
1008 }
1009 #endif
1010 
1011 static long
1012 proc_options(long argc, char **argv, ruby_cmdline_options_t *opt, int envopt)
1013 {
1014  long n, argc0 = argc;
1015  const char *s;
1016  int warning = opt->warning;
1017 
1018  if (argc <= 0 || !argv)
1019  return 0;
1020 
1021  for (argc--, argv++; argc > 0; argc--, argv++) {
1022  const char *const arg = argv[0];
1023  if (!arg || arg[0] != '-' || !arg[1])
1024  break;
1025 
1026  s = arg + 1;
1027  reswitch:
1028  switch (*s) {
1029  case 'a':
1030  if (envopt) goto noenvopt;
1031  opt->do_split = TRUE;
1032  s++;
1033  goto reswitch;
1034 
1035  case 'p':
1036  if (envopt) goto noenvopt;
1037  opt->do_print = TRUE;
1038  /* through */
1039  case 'n':
1040  if (envopt) goto noenvopt;
1041  opt->do_loop = TRUE;
1042  s++;
1043  goto reswitch;
1044 
1045  case 'd':
1046  ruby_debug = Qtrue;
1047  ruby_verbose = Qtrue;
1048  s++;
1049  goto reswitch;
1050 
1051  case 'y':
1052  if (envopt) goto noenvopt;
1053  opt->dump |= DUMP_BIT(yydebug);
1054  s++;
1055  goto reswitch;
1056 
1057  case 'v':
1058  if (opt->verbose) {
1059  s++;
1060  goto reswitch;
1061  }
1062  opt->dump |= DUMP_BIT(version_v);
1063  opt->verbose = 1;
1064  case 'w':
1065  if (!opt->warning) {
1066  warning = 1;
1067  ruby_verbose = Qtrue;
1068  }
1069  s++;
1070  goto reswitch;
1071 
1072  case 'W':
1073  if (s[1] == ':') {
1074  unsigned int bits = 0;
1075  static const char no_prefix[] = "no-";
1076  int enable = strncmp(s += 2, no_prefix, sizeof(no_prefix)-1) != 0;
1077  if (!enable) s += sizeof(no_prefix)-1;
1078  size_t len = strlen(s);
1079  if (NAME_MATCH_P("deprecated", s, len)) {
1080  bits = 1U << RB_WARN_CATEGORY_DEPRECATED;
1081  }
1082  else if (NAME_MATCH_P("experimental", s, len)) {
1083  bits = 1U << RB_WARN_CATEGORY_EXPERIMENTAL;
1084  }
1085  else {
1086  rb_warn("unknown warning category: `%s'", s);
1087  }
1088  if (bits) FEATURE_SET_TO(opt->warn, bits, enable ? bits : 0);
1089  break;
1090  }
1091  {
1092  size_t numlen;
1093  int v = 2; /* -W as -W2 */
1094 
1095  if (*++s) {
1096  v = scan_oct(s, 1, &numlen);
1097  if (numlen == 0)
1098  v = 1;
1099  s += numlen;
1100  }
1101  if (!opt->warning) {
1102  switch (v) {
1103  case 0:
1104  ruby_verbose = Qnil;
1105  break;
1106  case 1:
1107  ruby_verbose = Qfalse;
1108  break;
1109  default:
1110  ruby_verbose = Qtrue;
1111  break;
1112  }
1113  }
1114  warning = 1;
1115  }
1116  goto reswitch;
1117 
1118  case 'c':
1119  if (envopt) goto noenvopt;
1120  opt->dump |= DUMP_BIT(syntax);
1121  s++;
1122  goto reswitch;
1123 
1124  case 's':
1125  if (envopt) goto noenvopt;
1126  forbid_setid("-s");
1127  if (!opt->sflag) opt->sflag = 1;
1128  s++;
1129  goto reswitch;
1130 
1131  case 'h':
1132  if (envopt) goto noenvopt;
1133  opt->dump |= DUMP_BIT(usage);
1134  goto switch_end;
1135 
1136  case 'l':
1137  if (envopt) goto noenvopt;
1138  opt->do_line = TRUE;
1139  rb_output_rs = rb_rs;
1140  s++;
1141  goto reswitch;
1142 
1143  case 'S':
1144  if (envopt) goto noenvopt;
1145  forbid_setid("-S");
1146  opt->do_search = TRUE;
1147  s++;
1148  goto reswitch;
1149 
1150  case 'e':
1151  if (envopt) goto noenvopt;
1152  forbid_setid("-e");
1153  if (!*++s) {
1154  if (!--argc)
1155  rb_raise(rb_eRuntimeError, "no code specified for -e");
1156  s = *++argv;
1157  }
1158  if (!opt->e_script) {
1159  opt->e_script = rb_str_new(0, 0);
1160  if (opt->script == 0)
1161  opt->script = "-e";
1162  }
1163  rb_str_cat2(opt->e_script, s);
1164  rb_str_cat2(opt->e_script, "\n");
1165  break;
1166 
1167  case 'r':
1168  forbid_setid("-r");
1169  if (*++s) {
1170  add_modules(&opt->req_list, s);
1171  }
1172  else if (argc > 1) {
1173  add_modules(&opt->req_list, argv[1]);
1174  argc--, argv++;
1175  }
1176  break;
1177 
1178  case 'i':
1179  if (envopt) goto noenvopt;
1180  forbid_setid("-i");
1181  ruby_set_inplace_mode(s + 1);
1182  break;
1183 
1184  case 'x':
1185  if (envopt) goto noenvopt;
1186  forbid_setid("-x");
1187  opt->xflag = TRUE;
1188  s++;
1189  if (*s && chdir(s) < 0) {
1190  rb_fatal("Can't chdir to %s", s);
1191  }
1192  break;
1193 
1194  case 'C':
1195  case 'X':
1196  if (envopt) goto noenvopt;
1197  if (!*++s && (!--argc || !(s = *++argv) || !*s)) {
1198  rb_fatal("Can't chdir");
1199  }
1200  if (chdir(s) < 0) {
1201  rb_fatal("Can't chdir to %s", s);
1202  }
1203  break;
1204 
1205  case 'F':
1206  if (envopt) goto noenvopt;
1207  if (*++s) {
1208  rb_fs = rb_reg_new(s, strlen(s), 0);
1209  }
1210  break;
1211 
1212  case 'E':
1213  if (!*++s && (!--argc || !(s = *++argv))) {
1214  rb_raise(rb_eRuntimeError, "missing argument for -E");
1215  }
1216  goto encoding;
1217 
1218  case 'U':
1219  set_internal_encoding_once(opt, "UTF-8", 0);
1220  ++s;
1221  goto reswitch;
1222 
1223  case 'K':
1224  if (*++s) {
1225  const char *enc_name = 0;
1226  switch (*s) {
1227  case 'E': case 'e':
1228  enc_name = "EUC-JP";
1229  break;
1230  case 'S': case 's':
1231  enc_name = "Windows-31J";
1232  break;
1233  case 'U': case 'u':
1234  enc_name = "UTF-8";
1235  break;
1236  case 'N': case 'n': case 'A': case 'a':
1237  enc_name = "ASCII-8BIT";
1238  break;
1239  }
1240  if (enc_name) {
1241  opt->src.enc.name = rb_str_new2(enc_name);
1242  if (!opt->ext.enc.name)
1243  opt->ext.enc.name = opt->src.enc.name;
1244  }
1245  s++;
1246  }
1247  goto reswitch;
1248 
1249  case 'T':
1250  {
1251  size_t numlen;
1252 
1253  if (*++s) {
1254  scan_oct(s, 2, &numlen);
1255  s += numlen;
1256  }
1257  }
1258  rb_warn("ruby -T will be removed in Ruby 3.0");
1259  goto reswitch;
1260 
1261  case 'I':
1262  forbid_setid("-I");
1263  if (*++s)
1265  else if (argc > 1) {
1267  argc--, argv++;
1268  }
1269  break;
1270 
1271  case '0':
1272  if (envopt) goto noenvopt;
1273  {
1274  size_t numlen;
1275  int v;
1276  char c;
1277 
1278  v = scan_oct(s, 4, &numlen);
1279  s += numlen;
1280  if (v > 0377)
1281  rb_rs = Qnil;
1282  else if (v == 0 && numlen >= 2) {
1283  rb_rs = rb_str_new2("");
1284  }
1285  else {
1286  c = v & 0xff;
1287  rb_rs = rb_str_new(&c, 1);
1288  }
1289  }
1290  goto reswitch;
1291 
1292  case '-':
1293  if (!s[1] || (s[1] == '\r' && !s[2])) {
1294  argc--, argv++;
1295  goto switch_end;
1296  }
1297  s++;
1298 
1299 # define is_option_end(c, allow_hyphen) \
1300  (!(c) || ((allow_hyphen) && (c) == '-') || (c) == '=')
1301 # define check_envopt(name, allow_envopt) \
1302  (((allow_envopt) || !envopt) ? (void)0 : \
1303  rb_raise(rb_eRuntimeError, "invalid switch in RUBYOPT: --" name))
1304 # define need_argument(name, s, needs_arg, next_arg) \
1305  ((*(s) ? !*++(s) : (next_arg) && (!argc || !((s) = argv[1]) || (--argc, ++argv, 0))) && (needs_arg) ? \
1306  rb_raise(rb_eRuntimeError, "missing argument for --" name) \
1307  : (void)0)
1308 # define is_option_with_arg(name, allow_hyphen, allow_envopt) \
1309  is_option_with_optarg(name, allow_hyphen, allow_envopt, Qtrue, Qtrue)
1310 # define is_option_with_optarg(name, allow_hyphen, allow_envopt, needs_arg, next_arg) \
1311  (strncmp((name), s, n = sizeof(name) - 1) == 0 && is_option_end(s[n], (allow_hyphen)) ? \
1312  (check_envopt(name, (allow_envopt)), s += n, \
1313  need_argument(name, s, needs_arg, next_arg), 1) : 0)
1314 
1315  if (strcmp("copyright", s) == 0) {
1316  if (envopt) goto noenvopt_long;
1317  opt->dump |= DUMP_BIT(copyright);
1318  }
1319  else if (is_option_with_optarg("debug", Qtrue, Qtrue, Qfalse, Qfalse)) {
1320  if (s && *s) {
1321  ruby_each_words(s, debug_option, &opt->features);
1322  }
1323  else {
1324  ruby_debug = Qtrue;
1325  ruby_verbose = Qtrue;
1326  }
1327  }
1328  else if (is_option_with_arg("enable", Qtrue, Qtrue)) {
1329  ruby_each_words(s, enable_option, &opt->features);
1330  }
1331  else if (is_option_with_arg("disable", Qtrue, Qtrue)) {
1332  ruby_each_words(s, disable_option, &opt->features);
1333  }
1334  else if (is_option_with_arg("encoding", Qfalse, Qtrue)) {
1335  char *p;
1336  encoding:
1337  do {
1338 # define set_encoding_part(type) \
1339  if (!(p = strchr(s, ':'))) { \
1340  set_##type##_encoding_once(opt, s, 0); \
1341  break; \
1342  } \
1343  else if (p > s) { \
1344  set_##type##_encoding_once(opt, s, p-s); \
1345  }
1346  set_encoding_part(external);
1347  if (!*(s = ++p)) break;
1348  set_encoding_part(internal);
1349  if (!*(s = ++p)) break;
1350 #if defined ALLOW_DEFAULT_SOURCE_ENCODING && ALLOW_DEFAULT_SOURCE_ENCODING
1351  set_encoding_part(source);
1352  if (!*(s = ++p)) break;
1353 #endif
1354  rb_raise(rb_eRuntimeError, "extra argument for %s: %s",
1355  (arg[1] == '-' ? "--encoding" : "-E"), s);
1356 # undef set_encoding_part
1357  } while (0);
1358  }
1359  else if (is_option_with_arg("internal-encoding", Qfalse, Qtrue)) {
1360  set_internal_encoding_once(opt, s, 0);
1361  }
1362  else if (is_option_with_arg("external-encoding", Qfalse, Qtrue)) {
1363  set_external_encoding_once(opt, s, 0);
1364  }
1365 #if defined ALLOW_DEFAULT_SOURCE_ENCODING && ALLOW_DEFAULT_SOURCE_ENCODING
1366  else if (is_option_with_arg("source-encoding", Qfalse, Qtrue)) {
1367  set_source_encoding_once(opt, s, 0);
1368  }
1369 #endif
1370  else if (strcmp("version", s) == 0) {
1371  if (envopt) goto noenvopt_long;
1372  opt->dump |= DUMP_BIT(version);
1373  }
1374  else if (strcmp("verbose", s) == 0) {
1375  opt->verbose = 1;
1376  ruby_verbose = Qtrue;
1377  }
1378  else if (strncmp("jit", s, 3) == 0) {
1379 #if USE_MJIT
1380  FEATURE_SET(opt->features, FEATURE_BIT(jit));
1381  setup_mjit_options(s + 3, &opt->mjit);
1382 #else
1383  rb_warn("MJIT support is disabled.");
1384 #endif
1385  }
1386  else if (strcmp("yydebug", s) == 0) {
1387  if (envopt) goto noenvopt_long;
1388  opt->dump |= DUMP_BIT(yydebug);
1389  }
1390  else if (is_option_with_arg("dump", Qfalse, Qfalse)) {
1391  ruby_each_words(s, dump_option, &opt->dump);
1392  }
1393  else if (strcmp("help", s) == 0) {
1394  if (envopt) goto noenvopt_long;
1395  opt->dump |= DUMP_BIT(help);
1396  goto switch_end;
1397  }
1398  else {
1400  "invalid option --%s (-h will show valid options)", s);
1401  }
1402  break;
1403 
1404  case '\r':
1405  if (!s[1])
1406  break;
1407 
1408  default:
1409  {
1411  "invalid option -%c (-h will show valid options)",
1412  (int)(unsigned char)*s);
1413  }
1414  goto switch_end;
1415 
1416  noenvopt:
1417  /* "EIdvwWrKU" only */
1418  rb_raise(rb_eRuntimeError, "invalid switch in RUBYOPT: -%c", *s);
1419  break;
1420 
1421  noenvopt_long:
1422  rb_raise(rb_eRuntimeError, "invalid switch in RUBYOPT: --%s", s);
1423  break;
1424 
1425  case 0:
1426  break;
1427 # undef is_option_end
1428 # undef check_envopt
1429 # undef need_argument
1430 # undef is_option_with_arg
1431 # undef is_option_with_optarg
1432  }
1433  }
1434 
1435  switch_end:
1436  if (warning) opt->warning = warning;
1437  return argc0 - argc;
1438 }
1439 
1440 void Init_builtin_features(void);
1441 
1442 static void
1443 ruby_init_prelude(void)
1444 {
1446  rb_const_remove(rb_cObject, rb_intern_const("TMP_RUBY_PREFIX"));
1447 }
1448 
1449 static int
1450 opt_enc_index(VALUE enc_name)
1451 {
1452  const char *s = RSTRING_PTR(enc_name);
1453  int i = rb_enc_find_index(s);
1454 
1455  if (i < 0) {
1456  rb_raise(rb_eRuntimeError, "unknown encoding name - %s", s);
1457  }
1458  else if (rb_enc_dummy_p(rb_enc_from_index(i))) {
1459  rb_raise(rb_eRuntimeError, "dummy encoding is not acceptable - %s ", s);
1460  }
1461  return i;
1462 }
1463 
1464 #define rb_progname (GET_VM()->progname)
1465 #define rb_orig_progname (GET_VM()->orig_progname)
1468 
1469 static VALUE
1470 false_value(ID _x, VALUE *_y)
1471 {
1472  return Qfalse;
1473 }
1474 
1475 static VALUE
1476 true_value(ID _x, VALUE *_y)
1477 {
1478  return Qtrue;
1479 }
1480 
1481 #define rb_define_readonly_boolean(name, val) \
1482  rb_define_virtual_variable((name), (val) ? true_value : false_value, 0)
1483 
1484 static VALUE
1485 uscore_get(void)
1486 {
1487  VALUE line;
1488 
1489  line = rb_lastline_get();
1490  if (!RB_TYPE_P(line, T_STRING)) {
1491  rb_raise(rb_eTypeError, "$_ value need to be String (%s given)",
1492  NIL_P(line) ? "nil" : rb_obj_classname(line));
1493  }
1494  return line;
1495 }
1496 
1497 /*
1498  * call-seq:
1499  * sub(pattern, replacement) -> $_
1500  * sub(pattern) {|...| block } -> $_
1501  *
1502  * Equivalent to <code>$_.sub(<i>args</i>)</code>, except that
1503  * <code>$_</code> will be updated if substitution occurs.
1504  * Available only when -p/-n command line option specified.
1505  */
1506 
1507 static VALUE
1508 rb_f_sub(int argc, VALUE *argv, VALUE _)
1509 {
1510  VALUE str = rb_funcall_passing_block(uscore_get(), rb_intern("sub"), argc, argv);
1512  return str;
1513 }
1514 
1515 /*
1516  * call-seq:
1517  * gsub(pattern, replacement) -> $_
1518  * gsub(pattern) {|...| block } -> $_
1519  *
1520  * Equivalent to <code>$_.gsub...</code>, except that <code>$_</code>
1521  * will be updated if substitution occurs.
1522  * Available only when -p/-n command line option specified.
1523  *
1524  */
1525 
1526 static VALUE
1527 rb_f_gsub(int argc, VALUE *argv, VALUE _)
1528 {
1529  VALUE str = rb_funcall_passing_block(uscore_get(), rb_intern("gsub"), argc, argv);
1531  return str;
1532 }
1533 
1534 /*
1535  * call-seq:
1536  * chop -> $_
1537  *
1538  * Equivalent to <code>($_.dup).chop!</code>, except <code>nil</code>
1539  * is never returned. See String#chop!.
1540  * Available only when -p/-n command line option specified.
1541  *
1542  */
1543 
1544 static VALUE
1545 rb_f_chop(VALUE _)
1546 {
1547  VALUE str = rb_funcall_passing_block(uscore_get(), rb_intern("chop"), 0, 0);
1549  return str;
1550 }
1551 
1552 
1553 /*
1554  * call-seq:
1555  * chomp -> $_
1556  * chomp(string) -> $_
1557  *
1558  * Equivalent to <code>$_ = $_.chomp(<em>string</em>)</code>. See
1559  * String#chomp.
1560  * Available only when -p/-n command line option specified.
1561  *
1562  */
1563 
1564 static VALUE
1565 rb_f_chomp(int argc, VALUE *argv, VALUE _)
1566 {
1567  VALUE str = rb_funcall_passing_block(uscore_get(), rb_intern("chomp"), argc, argv);
1569  return str;
1570 }
1571 
1572 static VALUE
1573 process_options(int argc, char **argv, ruby_cmdline_options_t *opt)
1574 {
1575  rb_ast_t *ast = 0;
1576  VALUE parser;
1577  VALUE script_name;
1578  const rb_iseq_t *iseq;
1579  rb_encoding *enc, *lenc;
1580 #if UTF8_PATH
1581  rb_encoding *uenc, *ienc = 0;
1582 #endif
1583  const char *s;
1584  char fbuf[MAXPATHLEN];
1585  int i = (int)proc_options(argc, argv, opt, 0);
1586  unsigned int dump = opt->dump & dump_exit_bits;
1587 
1588  if (opt->dump & (DUMP_BIT(usage)|DUMP_BIT(help))) {
1589  const char *const progname =
1590  (argc > 0 && argv && argv[0] ? argv[0] :
1591  origarg.argc > 0 && origarg.argv && origarg.argv[0] ? origarg.argv[0] :
1592  ruby_engine);
1593  usage(progname, (opt->dump & DUMP_BIT(help)));
1594  return Qtrue;
1595  }
1596 
1597  argc -= i;
1598  argv += i;
1599 
1600  if ((opt->features.set & FEATURE_BIT(rubyopt)) && (s = getenv("RUBYOPT"))) {
1601  VALUE src_enc_name = opt->src.enc.name;
1602  VALUE ext_enc_name = opt->ext.enc.name;
1603  VALUE int_enc_name = opt->intern.enc.name;
1604  ruby_features_t feat = opt->features;
1605  ruby_features_t warn = opt->warn;
1606 
1607  opt->src.enc.name = opt->ext.enc.name = opt->intern.enc.name = 0;
1608  moreswitches(s, opt, 1);
1609  if (src_enc_name)
1610  opt->src.enc.name = src_enc_name;
1611  if (ext_enc_name)
1612  opt->ext.enc.name = ext_enc_name;
1613  if (int_enc_name)
1614  opt->intern.enc.name = int_enc_name;
1615  FEATURE_SET_RESTORE(opt->features, feat);
1616  FEATURE_SET_RESTORE(opt->warn, warn);
1617  }
1618 
1619  if (opt->src.enc.name)
1620  rb_warning("-K is specified; it is for 1.8 compatibility and may cause odd behavior");
1621 
1622 #if USE_MJIT
1623  if (opt->features.set & FEATURE_BIT(jit)) {
1624  opt->mjit.on = TRUE; /* set mjit.on for ruby_show_version() API and check to call mjit_init() */
1625  }
1626 #endif
1627  if (opt->dump & (DUMP_BIT(version) | DUMP_BIT(version_v))) {
1628 #if USE_MJIT
1629  mjit_opts.on = opt->mjit.on; /* used by ruby_show_version(). mjit_init() still can't be called here. */
1630 #endif
1632  if (opt->dump & DUMP_BIT(version)) return Qtrue;
1633  }
1634  if (opt->dump & DUMP_BIT(copyright)) {
1636  return Qtrue;
1637  }
1638 
1639  if (!opt->e_script) {
1640  if (argc <= 0) { /* no more args */
1641  if (opt->verbose)
1642  return Qtrue;
1643  opt->script = "-";
1644  }
1645  else {
1646  opt->script = argv[0];
1647  if (!opt->script || opt->script[0] == '\0') {
1648  opt->script = "-";
1649  }
1650  else if (opt->do_search) {
1651  char *path = getenv("RUBYPATH");
1652 
1653  opt->script = 0;
1654  if (path) {
1655  opt->script = dln_find_file_r(argv[0], path, fbuf, sizeof(fbuf));
1656  }
1657  if (!opt->script) {
1658  opt->script = dln_find_file_r(argv[0], getenv(PATH_ENV), fbuf, sizeof(fbuf));
1659  }
1660  if (!opt->script)
1661  opt->script = argv[0];
1662  }
1663  argc--;
1664  argv++;
1665  }
1666  if (opt->script[0] == '-' && !opt->script[1]) {
1667  forbid_setid("program input from stdin");
1668  }
1669  }
1670 
1671  opt->script_name = rb_str_new_cstr(opt->script);
1672  opt->script = RSTRING_PTR(opt->script_name);
1673 
1674 #if _WIN32
1675  translit_char_bin(RSTRING_PTR(opt->script_name), '\\', '/');
1676 #elif defined DOSISH
1677  translit_char(RSTRING_PTR(opt->script_name), '\\', '/');
1678 #endif
1679 
1682 
1683 #if USE_MJIT
1684  if (opt->mjit.on)
1685  /* Using TMP_RUBY_PREFIX created by ruby_init_loadpath(). */
1686  mjit_init(&opt->mjit);
1687 #endif
1688 
1690  Init_enc();
1691  lenc = rb_locale_encoding();
1694  parser = rb_parser_new();
1695  if (opt->dump & DUMP_BIT(yydebug)) {
1696  rb_parser_set_yydebug(parser, Qtrue);
1697  }
1698  if (opt->ext.enc.name != 0) {
1699  opt->ext.enc.index = opt_enc_index(opt->ext.enc.name);
1700  }
1701  if (opt->intern.enc.name != 0) {
1702  opt->intern.enc.index = opt_enc_index(opt->intern.enc.name);
1703  }
1704  if (opt->src.enc.name != 0) {
1705  opt->src.enc.index = opt_enc_index(opt->src.enc.name);
1706  src_encoding_index = opt->src.enc.index;
1707  }
1708  if (opt->ext.enc.index >= 0) {
1709  enc = rb_enc_from_index(opt->ext.enc.index);
1710  }
1711  else {
1712  enc = lenc;
1713  }
1715  if (opt->intern.enc.index >= 0) {
1716  enc = rb_enc_from_index(opt->intern.enc.index);
1718  opt->intern.enc.index = -1;
1719 #if UTF8_PATH
1720  ienc = enc;
1721 #endif
1722  }
1723  script_name = opt->script_name;
1725  IF_UTF8_PATH(uenc = rb_utf8_encoding(), lenc));
1726 #if UTF8_PATH
1727  if (uenc != lenc) {
1728  opt->script_name = str_conv_enc(opt->script_name, uenc, lenc);
1729  opt->script = RSTRING_PTR(opt->script_name);
1730  }
1731 #endif
1732  rb_obj_freeze(opt->script_name);
1733  if (IF_UTF8_PATH(uenc != lenc, 1)) {
1734  long i;
1735  rb_vm_t *vm = GET_VM();
1736  VALUE load_path = vm->load_path;
1737  const ID id_initial_load_path_mark = INITIAL_LOAD_PATH_MARK;
1738  int modifiable = FALSE;
1739 
1741  for (i = 0; i < RARRAY_LEN(load_path); ++i) {
1742  VALUE path = RARRAY_AREF(load_path, i);
1743  int mark = rb_attr_get(path, id_initial_load_path_mark) == path;
1744 #if UTF8_PATH
1745  VALUE newpath = rb_str_conv_enc(path, uenc, lenc);
1746  if (newpath == path) continue;
1747  path = newpath;
1748 #else
1750 #endif
1751  if (mark) rb_ivar_set(path, id_initial_load_path_mark, path);
1752  if (!modifiable) {
1753  rb_ary_modify(load_path);
1754  modifiable = TRUE;
1755  }
1756  RARRAY_ASET(load_path, i, path);
1757  }
1758  if (modifiable) {
1759  rb_ary_replace(vm->load_path_snapshot, load_path);
1760  }
1761  }
1762  Init_ext(); /* load statically linked extensions before rubygems */
1763  if (opt->features.set & FEATURE_BIT(gems)) {
1764  rb_define_module("Gem");
1765  if (opt->features.set & FEATURE_BIT(did_you_mean)) {
1766  rb_define_module("DidYouMean");
1767  }
1768  }
1769  ruby_init_prelude();
1770  if (opt->features.mask & COMPILATION_FEATURES) {
1771  VALUE option = rb_hash_new();
1772 #define SET_COMPILE_OPTION(h, o, name) \
1773  rb_hash_aset((h), ID2SYM(rb_intern_const(#name)), \
1774  (FEATURE_SET_P(o->features, FEATURE_BIT(name)) ? Qtrue : Qfalse));
1775  SET_COMPILE_OPTION(option, opt, frozen_string_literal);
1776  SET_COMPILE_OPTION(option, opt, debug_frozen_string_literal);
1777  rb_funcallv(rb_cISeq, rb_intern_const("compile_option="), 1, &option);
1778 #undef SET_COMPILE_OPTION
1779  }
1781  process_sflag(&opt->sflag);
1782 
1783  rb_parser_set_context(parser, 0, TRUE);
1784 
1785  if (opt->e_script) {
1786  VALUE progname = rb_progname;
1787  rb_encoding *eenc;
1788  if (opt->src.enc.index >= 0) {
1789  eenc = rb_enc_from_index(opt->src.enc.index);
1790  }
1791  else {
1792  eenc = lenc;
1793 #if UTF8_PATH
1794  if (ienc) eenc = ienc;
1795 #endif
1796  }
1797 #if UTF8_PATH
1798  if (eenc != uenc) {
1799  opt->e_script = str_conv_enc(opt->e_script, uenc, eenc);
1800  }
1801 #endif
1802  rb_enc_associate(opt->e_script, eenc);
1803  if (!(opt->dump & ~DUMP_BIT(version_v))) {
1805  require_libraries(&opt->req_list);
1806  }
1807  ruby_set_script_name(progname);
1808  rb_parser_set_options(parser, opt->do_print, opt->do_loop,
1809  opt->do_line, opt->do_split);
1811  ast = rb_parser_compile_string(parser, opt->script, opt->e_script, 1);
1812  }
1813  else {
1814  VALUE f;
1815  f = open_load_file(script_name, &opt->xflag);
1816  ast = load_file(parser, opt->script_name, f, 1, opt);
1817  }
1819  if (dump & DUMP_BIT(yydebug)) {
1820  dump &= ~DUMP_BIT(yydebug);
1821  if (!dump) return Qtrue;
1822  }
1823 
1824  if (opt->ext.enc.index >= 0) {
1825  enc = rb_enc_from_index(opt->ext.enc.index);
1826  }
1827  else {
1828  enc = lenc;
1829  }
1831  if (opt->intern.enc.index >= 0) {
1832  /* Set in the shebang line */
1833  enc = rb_enc_from_index(opt->intern.enc.index);
1835  }
1836  else if (!rb_default_internal_encoding())
1837  /* Freeze default_internal */
1840 
1841  if (!ast->body.root) {
1842  rb_ast_dispose(ast);
1843  return Qfalse;
1844  }
1845 
1846  process_sflag(&opt->sflag);
1847  opt->xflag = 0;
1848 
1849  if (dump & DUMP_BIT(syntax)) {
1850  printf("Syntax OK\n");
1851  dump &= ~DUMP_BIT(syntax);
1852  if (!dump) return Qtrue;
1853  }
1854 
1855  if (opt->do_loop) {
1856  rb_define_global_function("sub", rb_f_sub, -1);
1857  rb_define_global_function("gsub", rb_f_gsub, -1);
1858  rb_define_global_function("chop", rb_f_chop, 0);
1859  rb_define_global_function("chomp", rb_f_chomp, -1);
1860  }
1861 
1862  if (dump & (DUMP_BIT(parsetree)|DUMP_BIT(parsetree_with_comment))) {
1863  rb_io_write(rb_stdout, rb_parser_dump_tree(ast->body.root, dump & DUMP_BIT(parsetree_with_comment)));
1865  dump &= ~DUMP_BIT(parsetree)&~DUMP_BIT(parsetree_with_comment);
1866  if (!dump) {
1867  rb_ast_dispose(ast);
1868  return Qtrue;
1869  }
1870  }
1871 
1872  {
1873  VALUE path = Qnil;
1874  if (!opt->e_script && strcmp(opt->script, "-")) {
1875  path = rb_realpath_internal(Qnil, script_name, 1);
1876 #if UTF8_PATH
1877  if (uenc != lenc) {
1878  path = str_conv_enc(path, uenc, lenc);
1879  }
1880 #endif
1881  if (!ENCODING_GET(path)) { /* ASCII-8BIT */
1882  rb_enc_copy(path, opt->script_name);
1883  }
1884  }
1885 
1886  rb_binding_t *toplevel_binding;
1887  GetBindingPtr(rb_const_get(rb_cObject, rb_intern("TOPLEVEL_BINDING")),
1888  toplevel_binding);
1889  const struct rb_block *base_block = toplevel_context(toplevel_binding);
1890  iseq = rb_iseq_new_main(&ast->body, opt->script_name, path, vm_block_iseq(base_block));
1891  rb_ast_dispose(ast);
1892  }
1893 
1894  if (dump & DUMP_BIT(insns)) {
1897  dump &= ~DUMP_BIT(insns);
1898  if (!dump) return Qtrue;
1899  }
1900  if (opt->dump & dump_exit_bits) return Qtrue;
1901 
1902  rb_define_readonly_boolean("$-p", opt->do_print);
1903  rb_define_readonly_boolean("$-l", opt->do_line);
1904  rb_define_readonly_boolean("$-a", opt->do_split);
1905 
1906  if ((rb_e_script = opt->e_script) != 0) {
1908  }
1909 
1910  {
1912 
1913  if (opt->e_script) {
1914  /* -e */
1915  rb_exec_event_hook_script_compiled(ec, iseq, opt->e_script);
1916  }
1917  else {
1918  /* file */
1919  rb_exec_event_hook_script_compiled(ec, iseq, Qnil);
1920  }
1921  }
1922  return (VALUE)iseq;
1923 }
1924 
1925 #ifndef DOSISH
1926 static void
1927 warn_cr_in_shebang(const char *str, long len)
1928 {
1929  if (str[len-1] == '\n' && str[len-2] == '\r') {
1930  rb_warn("shebang line ending with \\r may cause problems");
1931  }
1932 }
1933 #else
1934 #define warn_cr_in_shebang(str, len) (void)0
1935 #endif
1936 
1940  int script;
1943 };
1944 
1945 static VALUE
1946 load_file_internal(VALUE argp_v)
1947 {
1948  struct load_file_arg *argp = (struct load_file_arg *)argp_v;
1949  VALUE parser = argp->parser;
1950  VALUE orig_fname = argp->fname;
1951  int script = argp->script;
1952  ruby_cmdline_options_t *opt = argp->opt;
1953  VALUE f = argp->f;
1954  int line_start = 1;
1955  rb_ast_t *ast = 0;
1956  rb_encoding *enc;
1957  ID set_encoding;
1958 
1959  CONST_ID(set_encoding, "set_encoding");
1960  if (script) {
1961  VALUE c = 1; /* something not nil */
1962  VALUE line;
1963  char *p, *str;
1964  long len;
1965  int no_src_enc = !opt->src.enc.name;
1966  int no_ext_enc = !opt->ext.enc.name;
1967  int no_int_enc = !opt->intern.enc.name;
1968 
1969  enc = rb_ascii8bit_encoding();
1970  rb_funcall(f, set_encoding, 1, rb_enc_from_encoding(enc));
1971 
1972  if (opt->xflag) {
1973  line_start--;
1974  search_shebang:
1975  while (!NIL_P(line = rb_io_gets(f))) {
1976  line_start++;
1977  RSTRING_GETMEM(line, str, len);
1978  if (len > 2 && str[0] == '#' && str[1] == '!') {
1979  if (line_start == 1) warn_cr_in_shebang(str, len);
1980  if ((p = strstr(str+2, ruby_engine)) != 0) {
1981  goto start_read;
1982  }
1983  }
1984  }
1985  rb_loaderror("no Ruby script found in input");
1986  }
1987 
1988  c = rb_io_getbyte(f);
1989  if (c == INT2FIX('#')) {
1990  c = rb_io_getbyte(f);
1991  if (c == INT2FIX('!') && !NIL_P(line = rb_io_gets(f))) {
1992  RSTRING_GETMEM(line, str, len);
1993  warn_cr_in_shebang(str, len);
1994  if ((p = strstr(str, ruby_engine)) == 0) {
1995  /* not ruby script, assume -x flag */
1996  goto search_shebang;
1997  }
1998 
1999  start_read:
2000  str += len - 1;
2001  if (*str == '\n') *str-- = '\0';
2002  if (*str == '\r') *str-- = '\0';
2003  /* ruby_engine should not contain a space */
2004  if ((p = strstr(p, " -")) != 0) {
2005  opt->warning = 0;
2006  moreswitches(p + 1, opt, 0);
2007  }
2008 
2009  /* push back shebang for pragma may exist in next line */
2010  rb_io_ungetbyte(f, rb_str_new2("!\n"));
2011  }
2012  else if (!NIL_P(c)) {
2013  rb_io_ungetbyte(f, c);
2014  }
2015  rb_io_ungetbyte(f, INT2FIX('#'));
2016  if (no_src_enc && opt->src.enc.name) {
2017  opt->src.enc.index = opt_enc_index(opt->src.enc.name);
2018  src_encoding_index = opt->src.enc.index;
2019  }
2020  if (no_ext_enc && opt->ext.enc.name) {
2021  opt->ext.enc.index = opt_enc_index(opt->ext.enc.name);
2022  }
2023  if (no_int_enc && opt->intern.enc.name) {
2024  opt->intern.enc.index = opt_enc_index(opt->intern.enc.name);
2025  }
2026  }
2027  else if (!NIL_P(c)) {
2028  rb_io_ungetbyte(f, c);
2029  }
2030  if (NIL_P(c)) {
2031  argp->f = f = Qnil;
2032  }
2033  if (!(opt->dump & ~DUMP_BIT(version_v))) {
2035  require_libraries(&opt->req_list); /* Why here? unnatural */
2036  }
2037  }
2038  if (opt->src.enc.index >= 0) {
2039  enc = rb_enc_from_index(opt->src.enc.index);
2040  }
2041  else if (f == rb_stdin) {
2042  enc = rb_locale_encoding();
2043  }
2044  else {
2045  enc = rb_utf8_encoding();
2046  }
2048  opt->do_line, opt->do_split);
2050  if (NIL_P(f)) {
2051  f = rb_str_new(0, 0);
2052  rb_enc_associate(f, enc);
2053  return (VALUE)rb_parser_compile_string_path(parser, orig_fname, f, line_start);
2054  }
2055  rb_funcall(f, set_encoding, 2, rb_enc_from_encoding(enc), rb_str_new_cstr("-"));
2056  ast = rb_parser_compile_file_path(parser, orig_fname, f, line_start);
2057  rb_funcall(f, set_encoding, 1, rb_parser_encoding(parser));
2059  /*
2060  * DATA is a File that contains the data section of the executed file.
2061  * To create a data section use <tt>__END__</tt>:
2062  *
2063  * $ cat t.rb
2064  * puts DATA.gets
2065  * __END__
2066  * hello world!
2067  *
2068  * $ ruby t.rb
2069  * hello world!
2070  */
2071  rb_define_global_const("DATA", f);
2072  argp->f = Qnil;
2073  }
2074  return (VALUE)ast;
2075 }
2076 
2077 static VALUE
2078 open_load_file(VALUE fname_v, int *xflag)
2079 {
2080  const char *fname = (fname_v = rb_str_encode_ospath(fname_v),
2081  StringValueCStr(fname_v));
2082  long flen = RSTRING_LEN(fname_v);
2083  VALUE f;
2084  int e;
2085 
2086  if (flen == 1 && fname[0] == '-') {
2087  f = rb_stdin;
2088  }
2089  else {
2090  int fd;
2091  /* open(2) may block if fname is point to FIFO and it's empty. Let's
2092  use O_NONBLOCK. */
2093 #if defined O_NONBLOCK && HAVE_FCNTL && !(O_NONBLOCK & O_ACCMODE)
2094  /* TODO: fix conflicting O_NONBLOCK in ruby/win32.h */
2095 # define MODE_TO_LOAD (O_RDONLY | O_NONBLOCK)
2096 #elif defined O_NDELAY && HAVE_FCNTL && !(O_NDELAY & O_ACCMODE)
2097 # define MODE_TO_LOAD (O_RDONLY | O_NDELAY)
2098 #else
2099 # define MODE_TO_LOAD (O_RDONLY)
2100 #endif
2101  int mode = MODE_TO_LOAD;
2102 #if defined DOSISH || defined __CYGWIN__
2103 # define isdirsep(x) ((x) == '/' || (x) == '\\')
2104  {
2105  static const char exeext[] = ".exe";
2106  enum {extlen = sizeof(exeext)-1};
2107  if (flen > extlen && !isdirsep(fname[flen-extlen-1]) &&
2108  STRNCASECMP(fname+flen-extlen, exeext, extlen) == 0) {
2109  mode |= O_BINARY;
2110  *xflag = 1;
2111  }
2112  }
2113 #endif
2114 
2115  if ((fd = rb_cloexec_open(fname, mode, 0)) < 0) {
2116  e = errno;
2117  if (!rb_gc_for_fd(e)) {
2118  rb_load_fail(fname_v, strerror(e));
2119  }
2120  if ((fd = rb_cloexec_open(fname, mode, 0)) < 0) {
2121  rb_load_fail(fname_v, strerror(errno));
2122  }
2123  }
2124  rb_update_max_fd(fd);
2125 
2126 #if defined HAVE_FCNTL && MODE_TO_LOAD != O_RDONLY
2127  /* disabling O_NONBLOCK */
2128  if (fcntl(fd, F_SETFL, 0) < 0) {
2129  e = errno;
2130  (void)close(fd);
2131  rb_load_fail(fname_v, strerror(e));
2132  }
2133 #endif
2134 
2135  e = ruby_is_fd_loadable(fd);
2136  if (!e) {
2137  e = errno;
2138  (void)close(fd);
2139  rb_load_fail(fname_v, strerror(e));
2140  }
2141 
2142  f = rb_io_fdopen(fd, mode, fname);
2143  if (e < 0) {
2144  /*
2145  We need to wait if FIFO is empty. It's FIFO's semantics.
2146  rb_thread_wait_fd() release GVL. So, it's safe.
2147  */
2148  rb_thread_wait_fd(fd);
2149  }
2150  }
2151  return f;
2152 }
2153 
2154 static VALUE
2155 restore_load_file(VALUE arg)
2156 {
2157  struct load_file_arg *argp = (struct load_file_arg *)arg;
2158  VALUE f = argp->f;
2159 
2160  if (!NIL_P(f) && f != rb_stdin) {
2161  rb_io_close(f);
2162  }
2163  return Qnil;
2164 }
2165 
2166 static rb_ast_t *
2168 {
2169  struct load_file_arg arg;
2170  arg.parser = parser;
2171  arg.fname = fname;
2172  arg.script = script;
2173  arg.opt = opt;
2174  arg.f = f;
2175  return (rb_ast_t *)rb_ensure(load_file_internal, (VALUE)&arg,
2176  restore_load_file, (VALUE)&arg);
2177 }
2178 
2179 void *
2180 rb_load_file(const char *fname)
2181 {
2182  VALUE fname_v = rb_str_new_cstr(fname);
2183  return rb_load_file_str(fname_v);
2184 }
2185 
2186 void *
2188 {
2189  return rb_parser_load_file(rb_parser_new(), fname_v);
2190 }
2191 
2192 void *
2194 {
2196  VALUE f = open_load_file(fname_v, &cmdline_options_init(&opt)->xflag);
2197  return load_file(parser, fname_v, f, 0, &opt);
2198 }
2199 
2200 /*
2201  * call-seq:
2202  * Process.argv0 -> frozen_string
2203  *
2204  * Returns the name of the script being executed. The value is not
2205  * affected by assigning a new value to $0.
2206  *
2207  * This method first appeared in Ruby 2.1 to serve as a global
2208  * variable free means to get the script name.
2209  */
2210 
2211 static VALUE
2212 proc_argv0(VALUE process)
2213 {
2214  return rb_orig_progname;
2215 }
2216 
2217 static VALUE ruby_setproctitle(VALUE title);
2218 
2219 /*
2220  * call-seq:
2221  * Process.setproctitle(string) -> string
2222  *
2223  * Sets the process title that appears on the ps(1) command. Not
2224  * necessarily effective on all platforms. No exception will be
2225  * raised regardless of the result, nor will NotImplementedError be
2226  * raised even if the platform does not support the feature.
2227  *
2228  * Calling this method does not affect the value of $0.
2229  *
2230  * Process.setproctitle('myapp: worker #%d' % worker_id)
2231  *
2232  * This method first appeared in Ruby 2.1 to serve as a global
2233  * variable free means to change the process title.
2234  */
2235 
2236 static VALUE
2237 proc_setproctitle(VALUE process, VALUE title)
2238 {
2239  return ruby_setproctitle(title);
2240 }
2241 
2242 static VALUE
2243 ruby_setproctitle(VALUE title)
2244 {
2245  const char *ptr = StringValueCStr(title);
2246  setproctitle("%.*s", RSTRING_LENINT(title), ptr);
2247  return title;
2248 }
2249 
2250 static void
2251 set_arg0(VALUE val, ID id, VALUE *_)
2252 {
2253  if (origarg.argv == 0)
2254  rb_raise(rb_eRuntimeError, "$0 not initialized");
2255 
2256  rb_progname = rb_str_new_frozen(ruby_setproctitle(val));
2257 }
2258 
2259 static inline VALUE
2260 external_str_new_cstr(const char *p)
2261 {
2262 #if UTF8_PATH
2265  return str;
2266 #else
2267  return rb_external_str_new_cstr(p);
2268 #endif
2269 }
2270 
2276 void
2277 ruby_script(const char *name)
2278 {
2279  if (name) {
2280  rb_orig_progname = rb_progname = external_str_new_cstr(name);
2282  }
2283 }
2284 
2289 void
2291 {
2294 }
2295 
2296 static void
2297 init_ids(ruby_cmdline_options_t *opt)
2298 {
2299  rb_uid_t uid = getuid();
2300  rb_uid_t euid = geteuid();
2301  rb_gid_t gid = getgid();
2302  rb_gid_t egid = getegid();
2303 
2304  if (uid != euid) opt->setids |= 1;
2305  if (egid != gid) opt->setids |= 2;
2306 }
2307 
2308 #undef forbid_setid
2309 static void
2310 forbid_setid(const char *s, const ruby_cmdline_options_t *opt)
2311 {
2312  if (opt->setids & 1)
2313  rb_raise(rb_eSecurityError, "no %s allowed while running setuid", s);
2314  if (opt->setids & 2)
2315  rb_raise(rb_eSecurityError, "no %s allowed while running setgid", s);
2316 }
2317 
2318 static void
2319 verbose_setter(VALUE val, ID id, VALUE *variable)
2320 {
2321  *variable = RTEST(val) ? Qtrue : val;
2322 }
2323 
2324 static VALUE
2325 opt_W_getter(ID id, VALUE *variable)
2326 {
2327  switch (*variable) {
2328  case Qnil:
2329  return INT2FIX(0);
2330  case Qfalse:
2331  return INT2FIX(1);
2332  case Qtrue:
2333  return INT2FIX(2);
2334  default:
2335  return Qnil;
2336  }
2337 }
2338 
2340 void
2342 {
2343  rb_define_hooked_variable("$VERBOSE", &ruby_verbose, 0, verbose_setter);
2344  rb_define_hooked_variable("$-v", &ruby_verbose, 0, verbose_setter);
2345  rb_define_hooked_variable("$-w", &ruby_verbose, 0, verbose_setter);
2347  rb_define_variable("$DEBUG", &ruby_debug);
2348  rb_define_variable("$-d", &ruby_debug);
2349 
2350  rb_define_hooked_variable("$0", &rb_progname, 0, set_arg0);
2351  rb_define_hooked_variable("$PROGRAM_NAME", &rb_progname, 0, set_arg0);
2352 
2353  rb_define_module_function(rb_mProcess, "argv0", proc_argv0, 0);
2354  rb_define_module_function(rb_mProcess, "setproctitle", proc_setproctitle, 1);
2355 
2356  /*
2357  * ARGV contains the command line arguments used to run ruby.
2358  *
2359  * A library like OptionParser can be used to process command-line
2360  * arguments.
2361  */
2363 }
2364 
2365 void
2367 {
2368  int i;
2369  VALUE av = rb_argv;
2370 
2371 #if defined(USE_DLN_A_OUT)
2372  if (origarg.argc > 0 && origarg.argv)
2373  dln_argv0 = origarg.argv[0];
2374  else if (argc > 0 && argv)
2375  dln_argv0 = argv[0];
2376 #endif
2377  rb_ary_clear(av);
2378  for (i = 0; i < argc; i++) {
2379  VALUE arg = external_str_new_cstr(argv[i]);
2380 
2381  OBJ_FREEZE(arg);
2382  rb_ary_push(av, arg);
2383  }
2384 }
2385 
2386 void *
2388 {
2390  VALUE iseq;
2391  const char *script_name = (argc > 0 && argv[0]) ? argv[0] : ruby_engine;
2392 
2393  if (!origarg.argv || origarg.argc <= 0) {
2394  origarg.argc = argc;
2395  origarg.argv = argv;
2396  }
2397  ruby_script(script_name); /* for the time being */
2400  iseq = process_options(argc, argv, cmdline_options_init(&opt));
2401 
2402 #ifndef HAVE_SETPROCTITLE
2404 #endif
2405 
2406  return (void*)(struct RData*)iseq;
2407 }
2408 
2409 static void
2410 fill_standard_fds(void)
2411 {
2412  int f0, f1, f2, fds[2];
2413  struct stat buf;
2414  f0 = fstat(0, &buf) == -1 && errno == EBADF;
2415  f1 = fstat(1, &buf) == -1 && errno == EBADF;
2416  f2 = fstat(2, &buf) == -1 && errno == EBADF;
2417  if (f0) {
2418  if (pipe(fds) == 0) {
2419  close(fds[1]);
2420  if (fds[0] != 0) {
2421  dup2(fds[0], 0);
2422  close(fds[0]);
2423  }
2424  }
2425  }
2426  if (f1 || f2) {
2427  if (pipe(fds) == 0) {
2428  close(fds[0]);
2429  if (f1 && fds[1] != 1)
2430  dup2(fds[1], 1);
2431  if (f2 && fds[1] != 2)
2432  dup2(fds[1], 2);
2433  if (fds[1] != 1 && fds[1] != 2)
2434  close(fds[1]);
2435  }
2436  }
2437 }
2438 
2446 void
2447 ruby_sysinit(int *argc, char ***argv)
2448 {
2449 #if defined(_WIN32)
2451 #endif
2452  if (*argc >= 0 && *argv) {
2453  origarg.argc = *argc;
2454  origarg.argv = *argv;
2455 #if defined(USE_DLN_A_OUT)
2456  dln_argv0 = origarg.argv[0];
2457 #endif
2458  }
2459  fill_standard_fds();
2460 }
strcmp
int strcmp(const char *, const char *)
rb_readlink
VALUE rb_readlink(VALUE path, rb_encoding *resultenc)
Definition: file.c:618
rb_io_gets
VALUE rb_io_gets(VALUE)
Definition: io.c:3573
rb_gv_set
VALUE rb_gv_set(const char *, VALUE)
Definition: variable.c:671
rb_argv0
VALUE rb_argv0
Definition: ruby.c:1466
rb_parser_new
VALUE rb_parser_new(void)
Definition: ripper.c:19221
i
uint32_t i
Definition: rb_mjit_min_header-2.7.1.h:5425
ID
unsigned long ID
Definition: ruby.h:103
rb_str_cat_cstr
#define rb_str_cat_cstr(str, ptr)
Definition: rb_mjit_min_header-2.7.1.h:6087
ruby_xfree
void ruby_xfree(void *x)
Definition: gc.c:10169
puts
int puts(const char *)
SET_COMPILE_OPTION
#define SET_COMPILE_OPTION(h, o, name)
TRUE
#define TRUE
Definition: nkf.h:175
rb_e_script
VALUE rb_e_script
Definition: ruby.c:1467
stat
Definition: rb_mjit_min_header-2.7.1.h:2352
RSTRING_GETMEM
#define RSTRING_GETMEM(str, ptrvar, lenvar)
Definition: ruby.h:1018
strstr
RUBY_EXTERN char * strstr(const char *, const char *)
Definition: strstr.c:8
rb_gc_for_fd
int rb_gc_for_fd(int err)
Definition: io.c:953
rb_str_new2
#define rb_str_new2
Definition: intern.h:903
pipe
int pipe(int __fildes[2])
load_file_arg::opt
ruby_cmdline_options_t * opt
Definition: ruby.c:1941
rb_ast_struct::body
rb_ast_body_t body
Definition: node.h:402
rb_io_close
VALUE rb_io_close(VALUE)
Definition: io.c:4820
rb_exc_new_str
VALUE rb_exc_new_str(VALUE etype, VALUE str)
Definition: error.c:972
rb_warning_category_update
void rb_warning_category_update(unsigned int mask, unsigned int bits)
Definition: error.c:157
set_internal_encoding_once
#define set_internal_encoding_once(opt, e, elen)
Definition: ruby.c:968
rb_iseq_struct
Definition: vm_core.h:456
M
#define M(shortopt, longopt, desc)
rb_hash_new
VALUE rb_hash_new(void)
Definition: hash.c:1523
rb_gc_register_mark_object
void rb_gc_register_mark_object(VALUE obj)
Definition: gc.c:7065
ruby_engine
const char ruby_engine[]
Definition: version.c:46
IF_UTF8_PATH
#define IF_UTF8_PATH(t, f)
Definition: ruby.c:487
ruby_show_version
void ruby_show_version(void)
Prints the version information of the CRuby interpreter to stdout.
Definition: version.c:119
rb_define_readonly_boolean
#define rb_define_readonly_boolean(name, val)
Definition: ruby.c:1481
rb_warn
void rb_warn(const char *fmt,...)
Definition: error.c:313
rb_warning
void rb_warning(const char *fmt,...)
Definition: error.c:334
rb_iseq_disasm
VALUE rb_iseq_disasm(const rb_iseq_t *iseq)
Definition: iseq.c:2278
ruby_cmdline_options::dump
unsigned int dump
Definition: ruby.c:165
rb_ast_dispose
void rb_ast_dispose(rb_ast_t *ast)
Definition: node.c:1389
rb_load_file_str
void * rb_load_file_str(VALUE fname_v)
Definition: ruby.c:2187
rb_funcall
#define rb_funcall(recv, mid, argc,...)
Definition: rb_mjit_min_header-2.7.1.h:6546
INT2FIX
#define INT2FIX(i)
Definition: ruby.h:263
n
const char size_t n
Definition: rb_mjit_min_header-2.7.1.h:5417
strchr
char * strchr(char *, char)
ruby_cmdline_options::intern
struct ruby_cmdline_options::@153 intern
RSTRING_PTR
#define RSTRING_PTR(str)
Definition: ruby.h:1009
LIBDIR_BASENAME
#define LIBDIR_BASENAME
Definition: rb_mjit_min_header-2.7.1.h:430
Init_ext
void Init_ext(void)
Definition: dmyext.c:2
rb_attr_get
VALUE rb_attr_get(VALUE, ID)
Definition: variable.c:1084
rb_str_new_cstr
#define rb_str_new_cstr(str)
Definition: rb_mjit_min_header-2.7.1.h:6078
rb_locale_encoding
rb_encoding * rb_locale_encoding(void)
Definition: encoding.c:1372
rb_default_external_encoding
rb_encoding * rb_default_external_encoding(void)
Definition: encoding.c:1427
rb_gvar_readonly_setter
void rb_gvar_readonly_setter(VALUE v, ID id, VALUE *_)
Definition: variable.c:412
VALUE
unsigned long VALUE
Definition: ruby.h:102
ruby_cmdline_options::warning
unsigned int warning
Definition: ruby.c:170
GET_VM
#define GET_VM()
Definition: vm_core.h:1764
encoding.h
RSTRING_EMBED_LEN_MAX
@ RSTRING_EMBED_LEN_MAX
Definition: ruby.h:982
rb_ary_replace
VALUE rb_ary_replace(VALUE copy, VALUE orig)
Definition: array.c:3811
ruby_verbose
#define ruby_verbose
Definition: ruby.h:1925
rb_intern
#define rb_intern(str)
RB_TYPE_P
#define RB_TYPE_P(obj, type)
Definition: ruby.h:560
rb_intern_const
#define rb_intern_const(str)
Definition: ruby.h:1879
load_file_arg
Definition: ruby.c:1937
ECONV_UNDEF_REPLACE
#define ECONV_UNDEF_REPLACE
Definition: encoding.h:396
load_file_arg::fname
VALUE fname
Definition: ruby.c:1939
RSTRING_LENINT
#define RSTRING_LENINT(str)
Definition: ruby.h:1017
ruby_cmdline_options::sflag
int sflag
Definition: ruby.c:169
rb_define_module
VALUE rb_define_module(const char *name)
Definition: class.c:772
rb_output_rs
RUBY_EXTERN VALUE rb_output_rs
Definition: intern.h:587
EBADF
#define EBADF
Definition: rb_mjit_min_header-2.7.1.h:10871
rb_enc_set_default_internal
void rb_enc_set_default_internal(VALUE encoding)
Definition: encoding.c:1563
rb_define_global_function
void rb_define_global_function(const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a global function.
Definition: class.c:1787
PREFIX_PATH
#define PREFIX_PATH()
ruby_env_debug_option
int ruby_env_debug_option(const char *str, int len, void *arg)
Definition: debug.c:153
rb_lastline_set
void rb_lastline_set(VALUE)
Definition: vm.c:1322
DWORD
IUnknown DWORD
Definition: win32ole.c:33
scan_oct
#define scan_oct(s, l, e)
Definition: util.h:53
ruby_cmdline_options::do_line
unsigned int do_line
Definition: ruby.c:174
rb_parser_compile_file_path
rb_ast_t * rb_parser_compile_file_path(VALUE vparser, VALUE fname, VALUE file, int start)
Definition: ripper.c:12905
feature_flag_count
@ feature_flag_count
Definition: ruby.c:98
arg
VALUE arg
Definition: rb_mjit_min_header-2.7.1.h:5562
rb_stdin
RUBY_EXTERN VALUE rb_stdin
Definition: ruby.h:2090
rb_str_dup
VALUE rb_str_dup(VALUE)
Definition: string.c:1516
rb_enc_path_last_separator
char * rb_enc_path_last_separator(const char *path, const char *end, rb_encoding *enc)
Definition: file.c:3406
rb_str_cat2
#define rb_str_cat2
Definition: intern.h:912
iseq
const rb_iseq_t * iseq
Definition: rb_mjit_min_header-2.7.1.h:13426
require
#define require(name)
Definition: dmyenc.c:1
rb_parser_load_file
void * rb_parser_load_file(VALUE parser, VALUE fname_v)
Definition: ruby.c:2193
ruby_cmdline_options::features
ruby_features_t features
Definition: ruby.c:163
rb_const_set
void rb_const_set(VALUE, ID, VALUE)
Definition: variable.c:2752
GET_EC
#define GET_EC()
Definition: vm_core.h:1766
rb_eNameError
VALUE rb_eNameError
Definition: error.c:927
FEATURE_SET
#define FEATURE_SET(feat, bits)
Definition: ruby.c:148
rb_enc_dummy_p
int rb_enc_dummy_p(rb_encoding *enc)
Definition: encoding.c:131
rb_ary_shift
VALUE rb_ary_shift(VALUE ary)
Definition: array.c:1294
ptr
struct RIMemo * ptr
Definition: debug.c:74
DEFINE_FEATURE
#define DEFINE_FEATURE(bit)
Definition: ruby.c:91
rb_str_new
#define rb_str_new(str, len)
Definition: rb_mjit_min_header-2.7.1.h:6077
rb_loaderror
void rb_loaderror(const char *fmt,...)
Definition: error.c:2688
Qfalse
#define Qfalse
Definition: ruby.h:467
ruby_cmdline_options::src
struct ruby_cmdline_options::@153 src
rb_stdout
RUBY_EXTERN VALUE rb_stdout
Definition: ruby.h:2090
RARRAY_ASET
#define RARRAY_ASET(a, i, v)
Definition: ruby.h:1102
rb_const_remove
VALUE rb_const_remove(VALUE, ID)
Definition: variable.c:2490
mjit_options::warnings
char warnings
Definition: rb_mjit_min_header-2.7.1.h:11652
NULL
#define NULL
Definition: _sdbm.c:101
rb_reg_new
VALUE rb_reg_new(const char *, long, int)
Definition: re.c:2947
PRIsVALUE
#define PRIsVALUE
Definition: ruby.h:166
fcntl
int fcntl(int, int,...)
Definition: win32.c:4282
rb_enc_from_encoding
VALUE rb_enc_from_encoding(rb_encoding *encoding)
Definition: encoding.c:116
ruby_is_fd_loadable
int ruby_is_fd_loadable(int fd)
Definition: file.c:6195
rb_fatal
void rb_fatal(const char *fmt,...)
Definition: error.c:2720
strlen
size_t strlen(const char *)
OBJ_FREEZE
#define OBJ_FREEZE(x)
Definition: ruby.h:1377
ruby_initial_load_paths
const char ruby_initial_load_paths[]
Definition: loadpath.c:62
ruby_cmdline_options::setids
unsigned int setids
Definition: ruby.c:177
RB_WARN_CATEGORY_EXPERIMENTAL
@ RB_WARN_CATEGORY_EXPERIMENTAL
Definition: internal.h:1563
set_encoding_part
#define set_encoding_part(type)
L
#define L(x)
Definition: asm.h:125
EACH_DUMPS
#define EACH_DUMPS(X, SEP)
Definition: ruby.c:105
ruby_archlibdir_path
VALUE ruby_archlibdir_path
Definition: ruby.c:579
strdup
char * strdup(const char *) __attribute__((__malloc__)) __attribute__((__warn_unused_result__))
chdir
int chdir(const char *__path)
rb_vm_struct::load_path
VALUE load_path
Definition: vm_core.h:615
ALLOC_N
#define ALLOC_N(type, n)
Definition: ruby.h:1663
rb_funcall_passing_block
VALUE rb_funcall_passing_block(VALUE, ID, int, const VALUE *)
Definition: vm_eval.c:1032
rb_get_expanded_load_path
VALUE rb_get_expanded_load_path(void)
Definition: load.c:92
ruby_push_include
void ruby_push_include(const char *path, VALUE(*filter)(VALUE))
Definition: ruby.c:406
load_file_arg::script
int script
Definition: ruby.c:1940
rb_str_resize
VALUE rb_str_resize(VALUE, long)
Definition: string.c:2709
dump_version_v
@ dump_version_v
Definition: ruby.c:125
ruby_show_copyright
#define ruby_show_copyright()
Definition: backward.h:75
FEATURE_SET_RESTORE
#define FEATURE_SET_RESTORE(feat, save)
Definition: ruby.c:149
rb_raise
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:2669
rb_str_conv_enc_opts
VALUE rb_str_conv_enc_opts(VALUE str, rb_encoding *from, rb_encoding *to, int ecflags, VALUE ecopts)
Definition: string.c:914
getuid
rb_uid_t getuid(void)
Definition: win32.c:2765
strncpy
char * strncpy(char *__restrict, const char *__restrict, size_t)
ruby_cmdline_options::req_list
VALUE req_list
Definition: ruby.c:162
getenv
char * getenv()
void
void
Definition: rb_mjit_min_header-2.7.1.h:13198
rb_io_flush
VALUE rb_io_flush(VALUE)
Definition: io.c:1903
MAXPATHLEN
#define MAXPATHLEN
Definition: ruby.c:47
ruby_cmdline_options::do_search
unsigned int do_search
Definition: ruby.c:176
rb_str_new4
#define rb_str_new4
Definition: intern.h:905
ruby_prog_init
void ruby_prog_init(void)
Defines built-in variables.
Definition: ruby.c:2341
mjit_options::wait
unsigned int wait
Definition: rb_mjit_min_header-2.7.1.h:11655
rb_load_fail
void rb_load_fail(VALUE path, const char *err)
Definition: error.c:2965
ruby_incpush
void ruby_incpush(const char *path)
Definition: ruby.c:426
rb_ast_struct
Definition: node.h:399
rb_parser_dump_tree
VALUE rb_parser_dump_tree(const NODE *node, int comment)
Definition: node.c:1076
rb_ascii8bit_encoding
rb_encoding * rb_ascii8bit_encoding(void)
Definition: encoding.c:1316
str_conv_enc
#define str_conv_enc(str, from, to)
Definition: ruby.c:499
strerror
RUBY_EXTERN char * strerror(int)
Definition: strerror.c:11
rb_iseq_new_main
rb_iseq_t * rb_iseq_new_main(const rb_ast_body_t *ast, VALUE path, VALUE realpath, const rb_iseq_t *parent)
Definition: iseq.c:785
ruby_process_options
void * ruby_process_options(int argc, char **argv)
Definition: ruby.c:2387
Init_ruby_description
void Init_ruby_description(void)
Definition: version.c:100
rb_encoding
const typedef OnigEncodingType rb_encoding
Definition: encoding.h:115
src_encoding_index
#define src_encoding_index
Definition: ruby.c:182
DEFAULT_FEATURES
@ DEFAULT_FEATURES
Definition: ruby.c:190
rb_uid_t
#define rb_uid_t
Definition: rb_mjit_min_header-2.7.1.h:105
rb_thread_wait_fd
void rb_thread_wait_fd(int)
Definition: thread.c:4042
DEFINE_DEBUG_FEATURE
#define DEFINE_DEBUG_FEATURE(bit)
Definition: ruby.c:92
rb_enc_from_index
rb_encoding * rb_enc_from_index(int index)
Definition: encoding.c:609
ruby_prefix_path
VALUE ruby_prefix_path
Definition: ruby.c:579
rb_ary_tmp_new
VALUE rb_ary_tmp_new(long capa)
Definition: array.c:768
feature_debug_flag_begin
@ feature_debug_flag_begin
Definition: ruby.c:96
ruby_cmdline_options::index
int index
Definition: ruby.c:159
FEATURE_SET_TO
#define FEATURE_SET_TO(feat, bit_mask, bit_set)
Definition: ruby.c:146
ruby_cmdline_options::enc
struct ruby_cmdline_options::@153::@154 enc
rb_vm_top_self
VALUE rb_vm_top_self(void)
Definition: vm.c:3347
feature_debug_flag_first
@ feature_debug_flag_first
Definition: ruby.c:95
rb_parser_set_yydebug
VALUE rb_parser_set_yydebug(VALUE self, VALUE flag)
Definition: ripper.c:19326
EACH_FEATURES
#define EACH_FEATURES(X, SEP)
Definition: ruby.c:76
FILENAME_MAX
#define FILENAME_MAX
Definition: rb_mjit_min_header-2.7.1.h:1470
rb_vm_set_progname
void rb_vm_set_progname(VALUE filename)
Definition: vm.c:3289
mask
enum @11::@13::@14 mask
rb_realpath_internal
VALUE rb_realpath_internal(VALUE basedir, VALUE path, int strict)
Definition: file.c:4409
rb_parser_set_options
void rb_parser_set_options(VALUE vparser, int print, int loop, int chomp, int split)
Definition: ripper.c:19033
rb_w32_sysinit
void rb_w32_sysinit(int *, char ***)
Definition: win32.c:847
mjit_options::debug_flags
char * debug_flags
Definition: rb_mjit_min_header-2.7.1.h:11654
ISALNUM
#define ISALNUM(c)
Definition: ruby.h:2310
mjit.h
rb_ary_push
VALUE rb_ary_push(VALUE ary, VALUE item)
Definition: array.c:1195
dln_find_file_r
#define dln_find_file_r
Definition: win32.c:85
mjit_options::save_temps
char save_temps
Definition: rb_mjit_min_header-2.7.1.h:11651
ruby_cmdline_options::e_script
VALUE e_script
Definition: ruby.c:155
dump_flag_bits
dump_flag_bits
Definition: ruby.c:124
rb_update_max_fd
void rb_update_max_fd(int fd)
Definition: io.c:218
rb_obj_freeze
VALUE rb_obj_freeze(VALUE)
Make the object unmodifiable.
Definition: object.c:1080
rb_binding_t::block
const struct rb_block block
Definition: vm_core.h:1069
ruby_script
void ruby_script(const char *name)
Sets the current script name to this value.
Definition: ruby.c:2277
rb_eTypeError
VALUE rb_eTypeError
Definition: error.c:922
ruby_cmdline_options::script
const char * script
Definition: ruby.c:153
SET_WHEN_DEBUG
#define SET_WHEN_DEBUG(bit)
ruby_cmdline_options::verbose
unsigned int verbose
Definition: ruby.c:171
rb_eRuntimeError
VALUE rb_eRuntimeError
Definition: error.c:920
is_option_with_arg
#define is_option_with_arg(name, allow_hyphen, allow_envopt)
mod
#define mod(x, y)
Definition: date_strftime.c:28
RARRAY_AREF
#define RARRAY_AREF(a, i)
Definition: ruby.h:1101
STRNCASECMP
#define STRNCASECMP(s1, s2, n)
Definition: ruby.h:2324
isdirsep
#define isdirsep(x)
Definition: dln.c:116
RUBY_RELATIVE
#define RUBY_RELATIVE(path, len)
StringValuePtr
#define StringValuePtr(v)
Definition: ruby.h:603
rb_enc_copy
void rb_enc_copy(VALUE obj1, VALUE obj2)
Definition: encoding.c:990
rb_str_set_len
void rb_str_set_len(VALUE, long)
Definition: string.c:2692
ruby_set_argv
void ruby_set_argv(int argc, char **argv)
Definition: ruby.c:2366
FALSE
#define FALSE
Definition: nkf.h:174
ruby_features_t
Definition: ruby.c:134
rb_parser_compile_string_path
rb_ast_t * rb_parser_compile_string_path(VALUE vparser, VALUE f, VALUE s, int line)
Definition: ripper.c:12890
list
struct rb_encoding_entry * list
Definition: encoding.c:56
MEMZERO
#define MEMZERO(p, type, n)
Definition: ruby.h:1752
ISSPACE
#define ISSPACE(c)
Definition: ruby.h:2307
rb_str_new_frozen
VALUE rb_str_new_frozen(VALUE)
Definition: string.c:1203
rb_gc_register_address
void rb_gc_register_address(VALUE *addr)
Definition: gc.c:7079
rb_parser_end_seen_p
VALUE rb_parser_end_seen_p(VALUE vparser)
Definition: ripper.c:19279
setproctitle
RUBY_EXTERN void setproctitle(const char *fmt,...)
Definition: setproctitle.c:139
rb_define_variable
void rb_define_variable(const char *, VALUE *)
Definition: variable.c:499
ruby_init_loadpath
void ruby_init_loadpath(void)
Definition: ruby.c:582
rb_default_internal_encoding
rb_encoding * rb_default_internal_encoding(void)
Definition: encoding.c:1512
set_external_encoding_once
#define set_external_encoding_once(opt, e, elen)
Definition: ruby.c:970
mjit_init
void mjit_init(const struct mjit_options *opts)
ruby_cmdline_options::do_loop
unsigned int do_loop
Definition: ruby.c:172
CONST_ID
#define CONST_ID(var, str)
Definition: ruby.h:1841
atoi
int atoi(const char *__nptr)
fstat
int fstat(int __fd, struct stat *__sbuf)
StringValueCStr
#define StringValueCStr(v)
Definition: ruby.h:604
ruby_set_script_name
void ruby_set_script_name(VALUE name)
Sets the current script name to this value.
Definition: ruby.c:2290
O_BINARY
#define O_BINARY
Definition: _sdbm.c:87
mjit_options::on
char on
Definition: rb_mjit_min_header-2.7.1.h:11650
path
VALUE path
Definition: rb_mjit_min_header-2.7.1.h:7300
FEATURE_BIT
#define FEATURE_BIT(bit)
Definition: ruby.c:75
rb_cISeq
VALUE rb_cISeq
Definition: iseq.c:32
RARRAY_CONST_PTR
#define RARRAY_CONST_PTR(a)
Definition: ruby.h:1072
rb_lastline_get
VALUE rb_lastline_get(void)
Definition: vm.c:1316
rb_ary_clear
VALUE rb_ary_clear(VALUE ary)
Definition: array.c:3862
ruby_cmdline_options::warn
ruby_features_t warn
Definition: ruby.c:164
U
Definition: dtoa.c:290
rb_fs
RUBY_EXTERN VALUE rb_fs
Definition: intern.h:583
dup2
RUBY_EXTERN int dup2(int, int)
Definition: dup2.c:27
rb_utf8_str_new
#define rb_utf8_str_new(str, len)
Definition: rb_mjit_min_header-2.7.1.h:6080
rb_argv
#define rb_argv
Definition: intern.h:733
RARRAY_LEN
#define RARRAY_LEN(a)
Definition: ruby.h:1070
rb_define_module_function
void rb_define_module_function(VALUE module, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a module function for module.
Definition: class.c:1771
ruby_cmdline_options::name
VALUE name
Definition: ruby.c:158
mjit_options::verbose
int verbose
Definition: rb_mjit_min_header-2.7.1.h:11657
PATH_ENV
#define PATH_ENV
Definition: defines.h:441
rb_cObject
RUBY_EXTERN VALUE rb_cObject
Definition: ruby.h:2010
rb_cloexec_open
int rb_cloexec_open(const char *pathname, int flags, mode_t mode)
Definition: io.c:292
buf
unsigned char buf[MIME_BUF_SIZE]
Definition: nkf.c:4322
rb_exc_raise
void rb_exc_raise(VALUE mesg)
Raises an exception in the current thread.
Definition: eval.c:668
COMMA
#define COMMA
Definition: ruby.c:74
rb_mProcess
RUBY_EXTERN VALUE rb_mProcess
Definition: ruby.h:2005
SET_WHEN_DUMP
#define SET_WHEN_DUMP(bit)
LITERAL_NAME_ELEMENT
#define LITERAL_NAME_ELEMENT(name)
Definition: ruby.c:866
internal.h
rb_parser_compile_string
rb_ast_t * rb_parser_compile_string(VALUE vparser, const char *f, VALUE s, int line)
Definition: ripper.c:12884
rb_parser_encoding
VALUE rb_parser_encoding(VALUE vparser)
Definition: ripper.c:19294
argv
char ** argv
Definition: ruby.c:223
f
#define f
yydebug
#define yydebug
Definition: ripper.c:96
F_SETFL
#define F_SETFL
Definition: win32.h:608
rb_eSecurityError
VALUE rb_eSecurityError
Definition: error.c:931
rb_vm_struct::load_path_snapshot
VALUE load_path_snapshot
Definition: vm_core.h:616
rb_define_global_const
void rb_define_global_const(const char *, VALUE)
Definition: variable.c:2892
rb_enc_set_default_external
void rb_enc_set_default_external(VALUE encoding)
Definition: encoding.c:1479
ENCODING_GET
#define ENCODING_GET(obj)
Definition: encoding.h:62
rb_sprintf
VALUE rb_sprintf(const char *format,...)
Definition: sprintf.c:1197
ruby_patchlevel
const RUBY_EXTERN int ruby_patchlevel
Definition: ruby.c:921
rb_str_subseq
VALUE rb_str_subseq(VALUE, long, long)
Definition: string.c:2474
getegid
rb_gid_t getegid(void)
Definition: win32.c:2786
PATH_SEP_CHAR
#define PATH_SEP_CHAR
Definition: defines.h:439
rb_utf8_encoding
rb_encoding * rb_utf8_encoding(void)
Definition: encoding.c:1328
geteuid
rb_uid_t geteuid(void)
Definition: win32.c:2772
DUMP_BIT
#define DUMP_BIT(bit)
Definition: ruby.c:103
load_file_arg::f
VALUE f
Definition: ruby.c:1942
strrchr
char * strrchr(const char *, const char)
str
char str[HTML_ESCAPE_MAX_LEN+1]
Definition: escape.c:18
mjit_opts
struct mjit_options mjit_opts
Definition: mjit_worker.c:174
ruby_cmdline_options::ext
struct ruby_cmdline_options::@153 ext
close
int close(int __fildes)
INITIAL_LOAD_PATH_MARK
#define INITIAL_LOAD_PATH_MARK
Definition: ruby.c:577
is_option_with_optarg
#define is_option_with_optarg(name, allow_hyphen, allow_envopt, needs_arg, next_arg)
rb_enc_find_index
int rb_enc_find_index(const char *name)
Definition: encoding.c:693
mjit_options::max_cache_size
int max_cache_size
Definition: rb_mjit_min_header-2.7.1.h:11658
rb_parser_set_context
VALUE rb_parser_set_context(VALUE vparser, const struct rb_iseq_struct *base, int main)
Definition: ripper.c:19231
int
__inline__ int
Definition: rb_mjit_min_header-2.7.1.h:2807
rb_cString
RUBY_EXTERN VALUE rb_cString
Definition: ruby.h:2044
DEFAULT_RUBYGEMS_ENABLED
#define DEFAULT_RUBYGEMS_ENABLED
Definition: ruby.c:69
ptrdiff_t
int ptrdiff_t
Definition: rb_mjit_min_header-2.7.1.h:796
rb_str_encode_ospath
VALUE rb_str_encode_ospath(VALUE path)
Definition: file.c:236
rb_io_getbyte
VALUE rb_io_getbyte(VALUE)
Definition: io.c:4215
NIL_P
#define NIL_P(v)
Definition: ruby.h:482
OBJ_FREEZE_RAW
#define OBJ_FREEZE_RAW(x)
Definition: ruby.h:1376
memcpy
void * memcpy(void *__restrict, const void *__restrict, size_t)
ruby_init_setproctitle
void ruby_init_setproctitle(int argc, char *argv[])
rb_str_modify_expand
void rb_str_modify_expand(VALUE, long)
Definition: string.c:2122
rb_binding_t
Definition: vm_core.h:1068
GetBindingPtr
#define GetBindingPtr(obj, ptr)
Definition: vm_core.h:1065
feature_flag_bits
feature_flag_bits
Definition: ruby.c:93
ruby_exec_prefix
const char ruby_exec_prefix[]
Definition: loadpath.c:59
argc
int argc
Definition: ruby.c:222
rb_utf8_str_new_cstr
#define rb_utf8_str_new_cstr(str)
Definition: rb_mjit_min_header-2.7.1.h:6083
rb_obj_classname
const char * rb_obj_classname(VALUE)
Definition: variable.c:289
rubylib_path_new
#define rubylib_path_new
Definition: ruby.c:342
MODE_TO_LOAD
#define MODE_TO_LOAD
ruby_debug
#define ruby_debug
Definition: ruby.h:1926
RUBY_EXTERN
#define RUBY_EXTERN
Definition: missing.h:77
getgid
rb_gid_t getgid(void)
Definition: win32.c:2779
rb_io_write
VALUE rb_io_write(VALUE, VALUE)
Definition: io.c:1804
rb_vm_struct
Definition: vm_core.h:576
CharNext
#define CharNext(p)
Definition: eval_intern.h:296
v
int VALUE v
Definition: rb_mjit_min_header-2.7.1.h:12257
version.h
ruby_features_t::set
unsigned int set
Definition: ruby.c:136
rb_rs
RUBY_EXTERN VALUE rb_rs
Definition: intern.h:585
ruby_sysinit
void ruby_sysinit(int *argc, char ***argv)
Initializes the process for libruby.
Definition: ruby.c:2447
_
#define _(args)
Definition: dln.h:28
rb_io_ungetbyte
VALUE rb_io_ungetbyte(VALUE, VALUE)
Definition: io.c:4276
Init_enc
void Init_enc(void)
Definition: dmyenc.c:5
Qtrue
#define Qtrue
Definition: ruby.h:468
errno
int errno
forbid_setid
#define forbid_setid(s)
Definition: ruby.c:219
rb_load_file
void * rb_load_file(const char *fname)
Definition: ruby.c:2180
ruby_cmdline_options::do_print
unsigned int do_print
Definition: ruby.c:173
len
uint8_t len
Definition: escape.c:17
SHOW
#define SHOW(m)
printf
int int int printf(const char *__restrict,...) __attribute__((__format__(__printf__
mjit_options
Definition: rb_mjit_min_header-2.7.1.h:11649
ruby_incpush_expand
void ruby_incpush_expand(const char *path)
Definition: ruby.c:443
rb_class_new_instance
VALUE rb_class_new_instance(int, const VALUE *, VALUE)
Allocates and initializes an instance of klass.
Definition: object.c:1955
MEMMOVE
#define MEMMOVE(p1, p2, type, n)
Definition: ruby.h:1754
TOLOWER
#define TOLOWER(c)
Definition: ruby.h:2319
rb_ivar_set
VALUE rb_ivar_set(VALUE, ID, VALUE)
Definition: variable.c:1300
RBASIC_SET_CLASS_RAW
#define RBASIC_SET_CLASS_RAW(obj, cls)
Definition: internal.h:1987
ruby_cmdline_options
Definition: ruby.c:152
T_STRING
#define T_STRING
Definition: ruby.h:528
ruby_cmdline_options::xflag
int xflag
Definition: ruby.c:169
rb_block
Definition: vm_core.h:751
strncmp
int strncmp(const char *, const char *, size_t)
EACH_DEBUG_FEATURES
#define EACH_DEBUG_FEATURES(X, SEP)
Definition: ruby.c:87
set_source_encoding_once
#define set_source_encoding_once(opt, e, elen)
Definition: ruby.c:972
ruby::backward::cxxanyargs::rb_define_hooked_variable
void rb_define_hooked_variable(const char *q, VALUE *w, type *e, void_type *r)
Define a function-backended global variable.
Definition: cxxanyargs.hpp:106
eval_intern.h
dump_exit_bits
@ dump_exit_bits
Definition: ruby.c:127
rb_ensure
VALUE rb_ensure(VALUE(*b_proc)(VALUE), VALUE data1, VALUE(*e_proc)(VALUE), VALUE data2)
An equivalent to ensure clause.
Definition: eval.c:1115
ECONV_INVALID_REPLACE
#define ECONV_INVALID_REPLACE
Definition: encoding.h:394
RB_WARN_CATEGORY_DEPRECATED
@ RB_WARN_CATEGORY_DEPRECATED
Definition: internal.h:1562
rb_ast_body_struct::root
const NODE * root
Definition: node.h:395
rb_file_expand_path
VALUE rb_file_expand_path(VALUE fname, VALUE dname)
Definition: file.c:4018
Qnil
#define Qnil
Definition: ruby.h:469
rb_stdio_set_default_encoding
void rb_stdio_set_default_encoding(void)
Definition: io.c:11758
ruby_cmdline_options::script_name
VALUE script_name
Definition: ruby.c:154
SET_FEATURE
#define SET_FEATURE(bit)
thread.h
load_file_arg::parser
VALUE parser
Definition: ruby.c:1938
util.h
rb_orig_progname
#define rb_orig_progname
Definition: ruby.c:1465
DEFINE_DUMP
#define DEFINE_DUMP(bit)
Definition: ruby.c:104
numberof
#define numberof(array)
Definition: etc.c:618
rb_strlen_lit
#define rb_strlen_lit(str)
Definition: intern.h:913
rb_str_tmp_new
VALUE rb_str_tmp_new(long)
Definition: string.c:1343
RSTRING_LEN
#define RSTRING_LEN(str)
Definition: ruby.h:1005
NAME_MATCH_P
#define NAME_MATCH_P(name, str, len)
Definition: ruby.c:851
ruby_set_inplace_mode
void ruby_set_inplace_mode(const char *)
Definition: io.c:12861
COMPILATION_FEATURES
@ COMPILATION_FEATURES
Definition: ruby.c:185
rb_str_conv_enc
VALUE rb_str_conv_enc(VALUE str, rb_encoding *from, rb_encoding *to)
Definition: string.c:1030
RData
Definition: ruby.h:1139
Init_builtin_features
void Init_builtin_features(void)
Definition: builtin.c:66
rb_gid_t
#define rb_gid_t
Definition: rb_mjit_min_header-2.7.1.h:111
rb_str_cat
VALUE rb_str_cat(VALUE, const char *, long)
Definition: string.c:2812
rb_enc_associate
VALUE rb_enc_associate(VALUE obj, rb_encoding *enc)
Definition: encoding.c:866
ruby_gc_set_params
void ruby_gc_set_params(void)
Definition: gc.c:9420
RTEST
#define RTEST(v)
Definition: ruby.h:481
ruby_each_words
void ruby_each_words(const char *, void(*)(const char *, int, void *), void *)
Definition: util.c:585
ruby_cmdline_options::do_split
unsigned int do_split
Definition: ruby.c:175
ruby::backward::cxxanyargs::type
VALUE type(ANYARGS)
ANYARGS-ed function type.
Definition: cxxanyargs.hpp:39
ruby_features_t::mask
unsigned int mask
Definition: ruby.c:135
rb_progname
#define rb_progname
Definition: ruby.c:1464
rb_external_str_new_cstr
#define rb_external_str_new_cstr(str)
Definition: rb_mjit_min_header-2.7.1.h:6084
rb_io_fdopen
VALUE rb_io_fdopen(int, int, const char *)
Definition: io.c:8004
rb_ary_modify
void rb_ary_modify(VALUE ary)
Definition: array.c:548
dln.h
name
const char * name
Definition: nkf.c:208
mjit_options::debug
char debug
Definition: rb_mjit_min_header-2.7.1.h:11653
rb_execution_context_struct
Definition: vm_core.h:843
rb_funcallv
#define rb_funcallv(recv, mid, argc, argv)
Definition: rb_mjit_min_header-2.7.1.h:7826
mjit_options::min_calls
unsigned int min_calls
Definition: rb_mjit_min_header-2.7.1.h:11656
rb_const_get
VALUE rb_const_get(VALUE, ID)
Definition: variable.c:2387