Ruby 2.7.6p219 (2022-04-12 revision c9c2245c0a25176072e02db9254f0e0c84c805cd)
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
57void Init_ruby_description(void);
58
59#ifndef HAVE_STDLIB_H
60char *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
72void 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))
131
133
134typedef struct {
135 unsigned int mask;
136 unsigned int set;
138
139static inline void
140rb_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;
165 unsigned int dump;
166#if USE_MJIT
167 struct mjit_options mjit;
168#endif
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
180static void init_ids(ruby_cmdline_options_t *);
181
182#define src_encoding_index GET_VM()->src_encoding_index
183
184enum {
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 )
199
201cmdline_options_init(ruby_cmdline_options_t *opt)
202{
203 MEMZERO(opt, *opt, 1);
204 init_ids(opt);
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
215static rb_ast_t *load_file(VALUE parser, VALUE fname, VALUE f, int script,
217static VALUE open_load_file(VALUE fname_v, int *xflag);
218static void forbid_setid(const char *, const ruby_cmdline_options_t *);
219#define forbid_setid(s) forbid_setid((s), opt)
220
221static struct {
222 int argc;
223 char **argv;
224} origarg;
225
226static void
227show_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
238static void
239usage(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)
340}
341
342#define rubylib_path_new rb_str_new
343
344static void
345push_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__
363static void
364push_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
405void
406ruby_push_include(const char *path, VALUE (*filter)(VALUE))
407{
408 if (path == 0)
409 return;
410 push_include(path, filter);
411}
412
413static VALUE
414identical_path(VALUE path)
415{
416 return path;
417}
418static VALUE
419locale_path(VALUE path)
420{
422 return path;
423}
424
425void
426ruby_incpush(const char *path)
427{
428 ruby_push_include(path, locale_path);
429}
430
431static VALUE
432expand_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;
440}
441
442void
444{
445 ruby_push_include(path, expand_include_path);
446}
447
448#undef UTF8_PATH
449#if defined _WIN32 || defined __CYGWIN__
450static HMODULE libruby;
451
452BOOL WINAPI
453DllMain(HINSTANCE dll, DWORD reason, LPVOID reserved)
454{
455 if (reason == DLL_PROCESS_ATTACH)
456 libruby = dll;
457 return TRUE;
458}
459
460HANDLE
461rb_libruby_handle(void)
462{
463 return libruby;
464}
465
466static inline void
467translit_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
491static 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
502void ruby_init_loadpath(void);
503
504#if defined(LOAD_RELATIVE)
505static VALUE
506runtime_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)) {
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);
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
581void
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
680static void
681add_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
693static void
694require_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
712static const struct rb_block*
713toplevel_context(rb_binding_t *bind)
714{
715 return &bind->block;
716}
717
718static void
719process_sflag(int *sflag)
720{
721 if (*sflag > 0) {
722 long n;
723 const VALUE *args;
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
782static long proc_options(long argc, char **argv, ruby_cmdline_options_t *opt, int envopt);
783
784static void
785moreswitches(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
829 /* get rid of GC */
830 rb_str_resize(argary, 0);
831 rb_str_resize(argstr, 0);
832}
833
834static int
835name_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
868static void
869feature_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
909static void
910enable_option(const char *str, int len, void *arg)
911{
912 feature_option(str, len, arg, ~0U);
913}
914
915static void
916disable_option(const char *str, int len, void *arg)
917{
918 feature_option(str, len, arg, 0U);
919}
920
922int ruby_env_debug_option(const char *str, int len, void *arg);
923
924static void
925debug_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
942static void
943dump_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
952static void
953set_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
976static void
977setup_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
1011static long
1012proc_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;
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;
1068 }
1070 s++;
1071 goto reswitch;
1072
1073 case 'W':
1074 if (s[1] == ':') {
1075 unsigned int bits = 0;
1076 static const char no_prefix[] = "no-";
1077 int enable = strncmp(s += 2, no_prefix, sizeof(no_prefix)-1) != 0;
1078 if (!enable) s += sizeof(no_prefix)-1;
1079 size_t len = strlen(s);
1080 if (NAME_MATCH_P("deprecated", s, len)) {
1081 bits = 1U << RB_WARN_CATEGORY_DEPRECATED;
1082 }
1083 else if (NAME_MATCH_P("experimental", s, len)) {
1084 bits = 1U << RB_WARN_CATEGORY_EXPERIMENTAL;
1085 }
1086 else {
1087 rb_warn("unknown warning category: `%s'", s);
1088 }
1089 if (bits) FEATURE_SET_TO(opt->warn, bits, enable ? bits : 0);
1090 break;
1091 }
1092 {
1093 size_t numlen;
1094 int v = 2; /* -W as -W2 */
1095
1096 if (*++s) {
1097 v = scan_oct(s, 1, &numlen);
1098 if (numlen == 0)
1099 v = 1;
1100 s += numlen;
1101 }
1102 if (!opt->warning) {
1103 switch (v) {
1104 case 0:
1106 break;
1107 case 1:
1109 break;
1110 default:
1112 break;
1113 }
1114 }
1115 warning = 1;
1116 switch (v) {
1117 case 0:
1119 break;
1120 case 1:
1122 break;
1123 default:
1125 break;
1126 }
1127 }
1128 goto reswitch;
1129
1130 case 'c':
1131 if (envopt) goto noenvopt;
1132 opt->dump |= DUMP_BIT(syntax);
1133 s++;
1134 goto reswitch;
1135
1136 case 's':
1137 if (envopt) goto noenvopt;
1138 forbid_setid("-s");
1139 if (!opt->sflag) opt->sflag = 1;
1140 s++;
1141 goto reswitch;
1142
1143 case 'h':
1144 if (envopt) goto noenvopt;
1145 opt->dump |= DUMP_BIT(usage);
1146 goto switch_end;
1147
1148 case 'l':
1149 if (envopt) goto noenvopt;
1150 opt->do_line = TRUE;
1152 s++;
1153 goto reswitch;
1154
1155 case 'S':
1156 if (envopt) goto noenvopt;
1157 forbid_setid("-S");
1158 opt->do_search = TRUE;
1159 s++;
1160 goto reswitch;
1161
1162 case 'e':
1163 if (envopt) goto noenvopt;
1164 forbid_setid("-e");
1165 if (!*++s) {
1166 if (!--argc)
1167 rb_raise(rb_eRuntimeError, "no code specified for -e");
1168 s = *++argv;
1169 }
1170 if (!opt->e_script) {
1171 opt->e_script = rb_str_new(0, 0);
1172 if (opt->script == 0)
1173 opt->script = "-e";
1174 }
1175 rb_str_cat2(opt->e_script, s);
1176 rb_str_cat2(opt->e_script, "\n");
1177 break;
1178
1179 case 'r':
1180 forbid_setid("-r");
1181 if (*++s) {
1182 add_modules(&opt->req_list, s);
1183 }
1184 else if (argc > 1) {
1185 add_modules(&opt->req_list, argv[1]);
1186 argc--, argv++;
1187 }
1188 break;
1189
1190 case 'i':
1191 if (envopt) goto noenvopt;
1192 forbid_setid("-i");
1193 ruby_set_inplace_mode(s + 1);
1194 break;
1195
1196 case 'x':
1197 if (envopt) goto noenvopt;
1198 forbid_setid("-x");
1199 opt->xflag = TRUE;
1200 s++;
1201 if (*s && chdir(s) < 0) {
1202 rb_fatal("Can't chdir to %s", s);
1203 }
1204 break;
1205
1206 case 'C':
1207 case 'X':
1208 if (envopt) goto noenvopt;
1209 if (!*++s && (!--argc || !(s = *++argv) || !*s)) {
1210 rb_fatal("Can't chdir");
1211 }
1212 if (chdir(s) < 0) {
1213 rb_fatal("Can't chdir to %s", s);
1214 }
1215 break;
1216
1217 case 'F':
1218 if (envopt) goto noenvopt;
1219 if (*++s) {
1220 rb_fs = rb_reg_new(s, strlen(s), 0);
1221 }
1222 break;
1223
1224 case 'E':
1225 if (!*++s && (!--argc || !(s = *++argv))) {
1226 rb_raise(rb_eRuntimeError, "missing argument for -E");
1227 }
1228 goto encoding;
1229
1230 case 'U':
1231 set_internal_encoding_once(opt, "UTF-8", 0);
1232 ++s;
1233 goto reswitch;
1234
1235 case 'K':
1236 if (*++s) {
1237 const char *enc_name = 0;
1238 switch (*s) {
1239 case 'E': case 'e':
1240 enc_name = "EUC-JP";
1241 break;
1242 case 'S': case 's':
1243 enc_name = "Windows-31J";
1244 break;
1245 case 'U': case 'u':
1246 enc_name = "UTF-8";
1247 break;
1248 case 'N': case 'n': case 'A': case 'a':
1249 enc_name = "ASCII-8BIT";
1250 break;
1251 }
1252 if (enc_name) {
1253 opt->src.enc.name = rb_str_new2(enc_name);
1254 if (!opt->ext.enc.name)
1255 opt->ext.enc.name = opt->src.enc.name;
1256 }
1257 s++;
1258 }
1259 goto reswitch;
1260
1261 case 'T':
1262 {
1263 size_t numlen;
1264
1265 if (*++s) {
1266 scan_oct(s, 2, &numlen);
1267 s += numlen;
1268 }
1269 }
1270 rb_warn("ruby -T will be removed in Ruby 3.0");
1271 goto reswitch;
1272
1273 case 'I':
1274 forbid_setid("-I");
1275 if (*++s)
1277 else if (argc > 1) {
1279 argc--, argv++;
1280 }
1281 break;
1282
1283 case '0':
1284 if (envopt) goto noenvopt;
1285 {
1286 size_t numlen;
1287 int v;
1288 char c;
1289
1290 v = scan_oct(s, 4, &numlen);
1291 s += numlen;
1292 if (v > 0377)
1293 rb_rs = Qnil;
1294 else if (v == 0 && numlen >= 2) {
1295 rb_rs = rb_str_new2("");
1296 }
1297 else {
1298 c = v & 0xff;
1299 rb_rs = rb_str_new(&c, 1);
1300 }
1301 }
1302 goto reswitch;
1303
1304 case '-':
1305 if (!s[1] || (s[1] == '\r' && !s[2])) {
1306 argc--, argv++;
1307 goto switch_end;
1308 }
1309 s++;
1310
1311# define is_option_end(c, allow_hyphen) \
1312 (!(c) || ((allow_hyphen) && (c) == '-') || (c) == '=')
1313# define check_envopt(name, allow_envopt) \
1314 (((allow_envopt) || !envopt) ? (void)0 : \
1315 rb_raise(rb_eRuntimeError, "invalid switch in RUBYOPT: --" name))
1316# define need_argument(name, s, needs_arg, next_arg) \
1317 ((*(s) ? !*++(s) : (next_arg) && (!argc || !((s) = argv[1]) || (--argc, ++argv, 0))) && (needs_arg) ? \
1318 rb_raise(rb_eRuntimeError, "missing argument for --" name) \
1319 : (void)0)
1320# define is_option_with_arg(name, allow_hyphen, allow_envopt) \
1321 is_option_with_optarg(name, allow_hyphen, allow_envopt, Qtrue, Qtrue)
1322# define is_option_with_optarg(name, allow_hyphen, allow_envopt, needs_arg, next_arg) \
1323 (strncmp((name), s, n = sizeof(name) - 1) == 0 && is_option_end(s[n], (allow_hyphen)) ? \
1324 (check_envopt(name, (allow_envopt)), s += n, \
1325 need_argument(name, s, needs_arg, next_arg), 1) : 0)
1326
1327 if (strcmp("copyright", s) == 0) {
1328 if (envopt) goto noenvopt_long;
1329 opt->dump |= DUMP_BIT(copyright);
1330 }
1331 else if (is_option_with_optarg("debug", Qtrue, Qtrue, Qfalse, Qfalse)) {
1332 if (s && *s) {
1333 ruby_each_words(s, debug_option, &opt->features);
1334 }
1335 else {
1336 ruby_debug = Qtrue;
1338 }
1339 }
1340 else if (is_option_with_arg("enable", Qtrue, Qtrue)) {
1341 ruby_each_words(s, enable_option, &opt->features);
1342 }
1343 else if (is_option_with_arg("disable", Qtrue, Qtrue)) {
1344 ruby_each_words(s, disable_option, &opt->features);
1345 }
1346 else if (is_option_with_arg("encoding", Qfalse, Qtrue)) {
1347 char *p;
1348 encoding:
1349 do {
1350# define set_encoding_part(type) \
1351 if (!(p = strchr(s, ':'))) { \
1352 set_##type##_encoding_once(opt, s, 0); \
1353 break; \
1354 } \
1355 else if (p > s) { \
1356 set_##type##_encoding_once(opt, s, p-s); \
1357 }
1358 set_encoding_part(external);
1359 if (!*(s = ++p)) break;
1360 set_encoding_part(internal);
1361 if (!*(s = ++p)) break;
1362#if defined ALLOW_DEFAULT_SOURCE_ENCODING && ALLOW_DEFAULT_SOURCE_ENCODING
1363 set_encoding_part(source);
1364 if (!*(s = ++p)) break;
1365#endif
1366 rb_raise(rb_eRuntimeError, "extra argument for %s: %s",
1367 (arg[1] == '-' ? "--encoding" : "-E"), s);
1368# undef set_encoding_part
1369 } while (0);
1370 }
1371 else if (is_option_with_arg("internal-encoding", Qfalse, Qtrue)) {
1372 set_internal_encoding_once(opt, s, 0);
1373 }
1374 else if (is_option_with_arg("external-encoding", Qfalse, Qtrue)) {
1375 set_external_encoding_once(opt, s, 0);
1376 }
1377#if defined ALLOW_DEFAULT_SOURCE_ENCODING && ALLOW_DEFAULT_SOURCE_ENCODING
1378 else if (is_option_with_arg("source-encoding", Qfalse, Qtrue)) {
1379 set_source_encoding_once(opt, s, 0);
1380 }
1381#endif
1382 else if (strcmp("version", s) == 0) {
1383 if (envopt) goto noenvopt_long;
1384 opt->dump |= DUMP_BIT(version);
1385 }
1386 else if (strcmp("verbose", s) == 0) {
1387 opt->verbose = 1;
1389 }
1390 else if (strncmp("jit", s, 3) == 0) {
1391#if USE_MJIT
1392 FEATURE_SET(opt->features, FEATURE_BIT(jit));
1393 setup_mjit_options(s + 3, &opt->mjit);
1394#else
1395 rb_warn("MJIT support is disabled.");
1396#endif
1397 }
1398 else if (strcmp("yydebug", s) == 0) {
1399 if (envopt) goto noenvopt_long;
1400 opt->dump |= DUMP_BIT(yydebug);
1401 }
1402 else if (is_option_with_arg("dump", Qfalse, Qfalse)) {
1403 ruby_each_words(s, dump_option, &opt->dump);
1404 }
1405 else if (strcmp("help", s) == 0) {
1406 if (envopt) goto noenvopt_long;
1407 opt->dump |= DUMP_BIT(help);
1408 goto switch_end;
1409 }
1410 else {
1412 "invalid option --%s (-h will show valid options)", s);
1413 }
1414 break;
1415
1416 case '\r':
1417 if (!s[1])
1418 break;
1419
1420 default:
1421 {
1423 "invalid option -%c (-h will show valid options)",
1424 (int)(unsigned char)*s);
1425 }
1426 goto switch_end;
1427
1428 noenvopt:
1429 /* "EIdvwWrKU" only */
1430 rb_raise(rb_eRuntimeError, "invalid switch in RUBYOPT: -%c", *s);
1431 break;
1432
1433 noenvopt_long:
1434 rb_raise(rb_eRuntimeError, "invalid switch in RUBYOPT: --%s", s);
1435 break;
1436
1437 case 0:
1438 break;
1439# undef is_option_end
1440# undef check_envopt
1441# undef need_argument
1442# undef is_option_with_arg
1443# undef is_option_with_optarg
1444 }
1445 }
1446
1447 switch_end:
1448 if (warning) opt->warning = warning;
1449 return argc0 - argc;
1450}
1451
1452void Init_builtin_features(void);
1453
1454static void
1455ruby_init_prelude(void)
1456{
1458 rb_const_remove(rb_cObject, rb_intern_const("TMP_RUBY_PREFIX"));
1459}
1460
1461static int
1462opt_enc_index(VALUE enc_name)
1463{
1464 const char *s = RSTRING_PTR(enc_name);
1465 int i = rb_enc_find_index(s);
1466
1467 if (i < 0) {
1468 rb_raise(rb_eRuntimeError, "unknown encoding name - %s", s);
1469 }
1470 else if (rb_enc_dummy_p(rb_enc_from_index(i))) {
1471 rb_raise(rb_eRuntimeError, "dummy encoding is not acceptable - %s ", s);
1472 }
1473 return i;
1474}
1475
1476#define rb_progname (GET_VM()->progname)
1477#define rb_orig_progname (GET_VM()->orig_progname)
1480
1481static VALUE
1482false_value(ID _x, VALUE *_y)
1483{
1484 return Qfalse;
1485}
1486
1487static VALUE
1488true_value(ID _x, VALUE *_y)
1489{
1490 return Qtrue;
1491}
1492
1493#define rb_define_readonly_boolean(name, val) \
1494 rb_define_virtual_variable((name), (val) ? true_value : false_value, 0)
1495
1496static VALUE
1497uscore_get(void)
1498{
1499 VALUE line;
1500
1501 line = rb_lastline_get();
1502 if (!RB_TYPE_P(line, T_STRING)) {
1503 rb_raise(rb_eTypeError, "$_ value need to be String (%s given)",
1504 NIL_P(line) ? "nil" : rb_obj_classname(line));
1505 }
1506 return line;
1507}
1508
1509/*
1510 * call-seq:
1511 * sub(pattern, replacement) -> $_
1512 * sub(pattern) {|...| block } -> $_
1513 *
1514 * Equivalent to <code>$_.sub(<i>args</i>)</code>, except that
1515 * <code>$_</code> will be updated if substitution occurs.
1516 * Available only when -p/-n command line option specified.
1517 */
1518
1519static VALUE
1520rb_f_sub(int argc, VALUE *argv, VALUE _)
1521{
1522 VALUE str = rb_funcall_passing_block(uscore_get(), rb_intern("sub"), argc, argv);
1524 return str;
1525}
1526
1527/*
1528 * call-seq:
1529 * gsub(pattern, replacement) -> $_
1530 * gsub(pattern) {|...| block } -> $_
1531 *
1532 * Equivalent to <code>$_.gsub...</code>, except that <code>$_</code>
1533 * will be updated if substitution occurs.
1534 * Available only when -p/-n command line option specified.
1535 *
1536 */
1537
1538static VALUE
1539rb_f_gsub(int argc, VALUE *argv, VALUE _)
1540{
1541 VALUE str = rb_funcall_passing_block(uscore_get(), rb_intern("gsub"), argc, argv);
1543 return str;
1544}
1545
1546/*
1547 * call-seq:
1548 * chop -> $_
1549 *
1550 * Equivalent to <code>($_.dup).chop!</code>, except <code>nil</code>
1551 * is never returned. See String#chop!.
1552 * Available only when -p/-n command line option specified.
1553 *
1554 */
1555
1556static VALUE
1557rb_f_chop(VALUE _)
1558{
1559 VALUE str = rb_funcall_passing_block(uscore_get(), rb_intern("chop"), 0, 0);
1561 return str;
1562}
1563
1564
1565/*
1566 * call-seq:
1567 * chomp -> $_
1568 * chomp(string) -> $_
1569 *
1570 * Equivalent to <code>$_ = $_.chomp(<em>string</em>)</code>. See
1571 * String#chomp.
1572 * Available only when -p/-n command line option specified.
1573 *
1574 */
1575
1576static VALUE
1577rb_f_chomp(int argc, VALUE *argv, VALUE _)
1578{
1579 VALUE str = rb_funcall_passing_block(uscore_get(), rb_intern("chomp"), argc, argv);
1581 return str;
1582}
1583
1584static VALUE
1585process_options(int argc, char **argv, ruby_cmdline_options_t *opt)
1586{
1587 rb_ast_t *ast = 0;
1588 VALUE parser;
1589 VALUE script_name;
1590 const rb_iseq_t *iseq;
1591 rb_encoding *enc, *lenc;
1592#if UTF8_PATH
1593 rb_encoding *uenc, *ienc = 0;
1594#endif
1595 const char *s;
1596 char fbuf[MAXPATHLEN];
1597 int i = (int)proc_options(argc, argv, opt, 0);
1598 unsigned int dump = opt->dump & dump_exit_bits;
1599
1600 if (opt->dump & (DUMP_BIT(usage)|DUMP_BIT(help))) {
1601 const char *const progname =
1602 (argc > 0 && argv && argv[0] ? argv[0] :
1603 origarg.argc > 0 && origarg.argv && origarg.argv[0] ? origarg.argv[0] :
1604 ruby_engine);
1605 usage(progname, (opt->dump & DUMP_BIT(help)));
1606 return Qtrue;
1607 }
1608
1609 argc -= i;
1610 argv += i;
1611
1612 if ((opt->features.set & FEATURE_BIT(rubyopt)) && (s = getenv("RUBYOPT"))) {
1613 VALUE src_enc_name = opt->src.enc.name;
1614 VALUE ext_enc_name = opt->ext.enc.name;
1615 VALUE int_enc_name = opt->intern.enc.name;
1616 ruby_features_t feat = opt->features;
1617 ruby_features_t warn = opt->warn;
1618
1619 opt->src.enc.name = opt->ext.enc.name = opt->intern.enc.name = 0;
1620 moreswitches(s, opt, 1);
1621 if (src_enc_name)
1622 opt->src.enc.name = src_enc_name;
1623 if (ext_enc_name)
1624 opt->ext.enc.name = ext_enc_name;
1625 if (int_enc_name)
1626 opt->intern.enc.name = int_enc_name;
1627 FEATURE_SET_RESTORE(opt->features, feat);
1628 FEATURE_SET_RESTORE(opt->warn, warn);
1629 }
1630
1631 if (opt->src.enc.name)
1632 rb_warning("-K is specified; it is for 1.8 compatibility and may cause odd behavior");
1633
1634#if USE_MJIT
1635 if (opt->features.set & FEATURE_BIT(jit)) {
1636 opt->mjit.on = TRUE; /* set mjit.on for ruby_show_version() API and check to call mjit_init() */
1637 }
1638#endif
1639 if (opt->dump & (DUMP_BIT(version) | DUMP_BIT(version_v))) {
1640#if USE_MJIT
1641 mjit_opts.on = opt->mjit.on; /* used by ruby_show_version(). mjit_init() still can't be called here. */
1642#endif
1644 if (opt->dump & DUMP_BIT(version)) return Qtrue;
1645 }
1646 if (opt->dump & DUMP_BIT(copyright)) {
1648 return Qtrue;
1649 }
1650
1651 if (!opt->e_script) {
1652 if (argc <= 0) { /* no more args */
1653 if (opt->verbose)
1654 return Qtrue;
1655 opt->script = "-";
1656 }
1657 else {
1658 opt->script = argv[0];
1659 if (!opt->script || opt->script[0] == '\0') {
1660 opt->script = "-";
1661 }
1662 else if (opt->do_search) {
1663 char *path = getenv("RUBYPATH");
1664
1665 opt->script = 0;
1666 if (path) {
1667 opt->script = dln_find_file_r(argv[0], path, fbuf, sizeof(fbuf));
1668 }
1669 if (!opt->script) {
1670 opt->script = dln_find_file_r(argv[0], getenv(PATH_ENV), fbuf, sizeof(fbuf));
1671 }
1672 if (!opt->script)
1673 opt->script = argv[0];
1674 }
1675 argc--;
1676 argv++;
1677 }
1678 if (opt->script[0] == '-' && !opt->script[1]) {
1679 forbid_setid("program input from stdin");
1680 }
1681 }
1682
1683 opt->script_name = rb_str_new_cstr(opt->script);
1684 opt->script = RSTRING_PTR(opt->script_name);
1685
1686#if _WIN32
1687 translit_char_bin(RSTRING_PTR(opt->script_name), '\\', '/');
1688#elif defined DOSISH
1689 translit_char(RSTRING_PTR(opt->script_name), '\\', '/');
1690#endif
1691
1694
1695#if USE_MJIT
1696 if (opt->mjit.on)
1697 /* Using TMP_RUBY_PREFIX created by ruby_init_loadpath(). */
1698 mjit_init(&opt->mjit);
1699#endif
1700
1702 Init_enc();
1703 lenc = rb_locale_encoding();
1706 parser = rb_parser_new();
1707 if (opt->dump & DUMP_BIT(yydebug)) {
1709 }
1710 if (opt->ext.enc.name != 0) {
1711 opt->ext.enc.index = opt_enc_index(opt->ext.enc.name);
1712 }
1713 if (opt->intern.enc.name != 0) {
1714 opt->intern.enc.index = opt_enc_index(opt->intern.enc.name);
1715 }
1716 if (opt->src.enc.name != 0) {
1717 opt->src.enc.index = opt_enc_index(opt->src.enc.name);
1719 }
1720 if (opt->ext.enc.index >= 0) {
1721 enc = rb_enc_from_index(opt->ext.enc.index);
1722 }
1723 else {
1724 enc = lenc;
1725 }
1727 if (opt->intern.enc.index >= 0) {
1728 enc = rb_enc_from_index(opt->intern.enc.index);
1730 opt->intern.enc.index = -1;
1731#if UTF8_PATH
1732 ienc = enc;
1733#endif
1734 }
1735 script_name = opt->script_name;
1737 IF_UTF8_PATH(uenc = rb_utf8_encoding(), lenc));
1738#if UTF8_PATH
1739 if (uenc != lenc) {
1740 opt->script_name = str_conv_enc(opt->script_name, uenc, lenc);
1741 opt->script = RSTRING_PTR(opt->script_name);
1742 }
1743#endif
1745 if (IF_UTF8_PATH(uenc != lenc, 1)) {
1746 long i;
1747 rb_vm_t *vm = GET_VM();
1748 VALUE load_path = vm->load_path;
1749 const ID id_initial_load_path_mark = INITIAL_LOAD_PATH_MARK;
1750 int modifiable = FALSE;
1751
1753 for (i = 0; i < RARRAY_LEN(load_path); ++i) {
1754 VALUE path = RARRAY_AREF(load_path, i);
1755 int mark = rb_attr_get(path, id_initial_load_path_mark) == path;
1756#if UTF8_PATH
1757 VALUE newpath = rb_str_conv_enc(path, uenc, lenc);
1758 if (newpath == path) continue;
1759 path = newpath;
1760#else
1762#endif
1763 if (mark) rb_ivar_set(path, id_initial_load_path_mark, path);
1764 if (!modifiable) {
1765 rb_ary_modify(load_path);
1766 modifiable = TRUE;
1767 }
1768 RARRAY_ASET(load_path, i, path);
1769 }
1770 if (modifiable) {
1771 rb_ary_replace(vm->load_path_snapshot, load_path);
1772 }
1773 }
1774
1776
1777 Init_ext(); /* load statically linked extensions before rubygems */
1778 if (opt->features.set & FEATURE_BIT(gems)) {
1779 rb_define_module("Gem");
1780 if (opt->features.set & FEATURE_BIT(did_you_mean)) {
1781 rb_define_module("DidYouMean");
1782 }
1783 }
1784 ruby_init_prelude();
1785 if (opt->features.mask & COMPILATION_FEATURES) {
1786 VALUE option = rb_hash_new();
1787#define SET_COMPILE_OPTION(h, o, name) \
1788 rb_hash_aset((h), ID2SYM(rb_intern_const(#name)), \
1789 (FEATURE_SET_P(o->features, FEATURE_BIT(name)) ? Qtrue : Qfalse));
1790 SET_COMPILE_OPTION(option, opt, frozen_string_literal);
1791 SET_COMPILE_OPTION(option, opt, debug_frozen_string_literal);
1792 rb_funcallv(rb_cISeq, rb_intern_const("compile_option="), 1, &option);
1793#undef SET_COMPILE_OPTION
1794 }
1796 process_sflag(&opt->sflag);
1797
1798 rb_parser_set_context(parser, 0, TRUE);
1799
1800 if (opt->e_script) {
1801 VALUE progname = rb_progname;
1802 rb_encoding *eenc;
1803 if (opt->src.enc.index >= 0) {
1804 eenc = rb_enc_from_index(opt->src.enc.index);
1805 }
1806 else {
1807 eenc = lenc;
1808#if UTF8_PATH
1809 if (ienc) eenc = ienc;
1810#endif
1811 }
1812#if UTF8_PATH
1813 if (eenc != uenc) {
1814 opt->e_script = str_conv_enc(opt->e_script, uenc, eenc);
1815 }
1816#endif
1817 rb_enc_associate(opt->e_script, eenc);
1818 if (!(opt->dump & ~DUMP_BIT(version_v))) {
1820 require_libraries(&opt->req_list);
1821 }
1822 ruby_set_script_name(progname);
1823 rb_parser_set_options(parser, opt->do_print, opt->do_loop,
1824 opt->do_line, opt->do_split);
1825 ast = rb_parser_compile_string(parser, opt->script, opt->e_script, 1);
1826 }
1827 else {
1828 VALUE f;
1829 f = open_load_file(script_name, &opt->xflag);
1830 ast = load_file(parser, opt->script_name, f, 1, opt);
1831 }
1833 if (dump & DUMP_BIT(yydebug)) {
1834 dump &= ~DUMP_BIT(yydebug);
1835 if (!dump) return Qtrue;
1836 }
1837
1838 if (opt->ext.enc.index >= 0) {
1839 enc = rb_enc_from_index(opt->ext.enc.index);
1840 }
1841 else {
1842 enc = lenc;
1843 }
1845 if (opt->intern.enc.index >= 0) {
1846 /* Set in the shebang line */
1847 enc = rb_enc_from_index(opt->intern.enc.index);
1849 }
1850 else if (!rb_default_internal_encoding())
1851 /* Freeze default_internal */
1854
1855 if (!ast->body.root) {
1856 rb_ast_dispose(ast);
1857 return Qfalse;
1858 }
1859
1860 process_sflag(&opt->sflag);
1861 opt->xflag = 0;
1862
1863 if (dump & DUMP_BIT(syntax)) {
1864 printf("Syntax OK\n");
1865 dump &= ~DUMP_BIT(syntax);
1866 if (!dump) return Qtrue;
1867 }
1868
1869 if (opt->do_loop) {
1870 rb_define_global_function("sub", rb_f_sub, -1);
1871 rb_define_global_function("gsub", rb_f_gsub, -1);
1872 rb_define_global_function("chop", rb_f_chop, 0);
1873 rb_define_global_function("chomp", rb_f_chomp, -1);
1874 }
1875
1876 if (dump & (DUMP_BIT(parsetree)|DUMP_BIT(parsetree_with_comment))) {
1877 rb_io_write(rb_stdout, rb_parser_dump_tree(ast->body.root, dump & DUMP_BIT(parsetree_with_comment)));
1879 dump &= ~DUMP_BIT(parsetree)&~DUMP_BIT(parsetree_with_comment);
1880 if (!dump) {
1881 rb_ast_dispose(ast);
1882 return Qtrue;
1883 }
1884 }
1885
1886 {
1887 VALUE path = Qnil;
1888 if (!opt->e_script && strcmp(opt->script, "-")) {
1889 path = rb_realpath_internal(Qnil, script_name, 1);
1890#if UTF8_PATH
1891 if (uenc != lenc) {
1892 path = str_conv_enc(path, uenc, lenc);
1893 }
1894#endif
1895 if (!ENCODING_GET(path)) { /* ASCII-8BIT */
1897 }
1898 }
1899
1900 rb_binding_t *toplevel_binding;
1901 GetBindingPtr(rb_const_get(rb_cObject, rb_intern("TOPLEVEL_BINDING")),
1902 toplevel_binding);
1903 const struct rb_block *base_block = toplevel_context(toplevel_binding);
1904 iseq = rb_iseq_new_main(&ast->body, opt->script_name, path, vm_block_iseq(base_block));
1905 rb_ast_dispose(ast);
1906 }
1907
1908 if (dump & DUMP_BIT(insns)) {
1911 dump &= ~DUMP_BIT(insns);
1912 if (!dump) return Qtrue;
1913 }
1914 if (opt->dump & dump_exit_bits) return Qtrue;
1915
1919
1920 if ((rb_e_script = opt->e_script) != 0) {
1922 }
1923
1924 {
1926
1927 if (opt->e_script) {
1928 /* -e */
1929 rb_exec_event_hook_script_compiled(ec, iseq, opt->e_script);
1930 }
1931 else {
1932 /* file */
1933 rb_exec_event_hook_script_compiled(ec, iseq, Qnil);
1934 }
1935 }
1936 return (VALUE)iseq;
1937}
1938
1939#ifndef DOSISH
1940static void
1941warn_cr_in_shebang(const char *str, long len)
1942{
1943 if (str[len-1] == '\n' && str[len-2] == '\r') {
1944 rb_warn("shebang line ending with \\r may cause problems");
1945 }
1946}
1947#else
1948#define warn_cr_in_shebang(str, len) (void)0
1949#endif
1950
1957};
1958
1959static VALUE
1960load_file_internal(VALUE argp_v)
1961{
1962 struct load_file_arg *argp = (struct load_file_arg *)argp_v;
1963 VALUE parser = argp->parser;
1964 VALUE orig_fname = argp->fname;
1965 int script = argp->script;
1967 VALUE f = argp->f;
1968 int line_start = 1;
1969 rb_ast_t *ast = 0;
1970 rb_encoding *enc;
1971 ID set_encoding;
1972
1973 CONST_ID(set_encoding, "set_encoding");
1974 if (script) {
1975 VALUE c = 1; /* something not nil */
1976 VALUE line;
1977 char *p, *str;
1978 long len;
1979 int no_src_enc = !opt->src.enc.name;
1980 int no_ext_enc = !opt->ext.enc.name;
1981 int no_int_enc = !opt->intern.enc.name;
1982
1983 enc = rb_ascii8bit_encoding();
1984 rb_funcall(f, set_encoding, 1, rb_enc_from_encoding(enc));
1985
1986 if (opt->xflag) {
1987 line_start--;
1988 search_shebang:
1989 while (!NIL_P(line = rb_io_gets(f))) {
1990 line_start++;
1991 RSTRING_GETMEM(line, str, len);
1992 if (len > 2 && str[0] == '#' && str[1] == '!') {
1993 if (line_start == 1) warn_cr_in_shebang(str, len);
1994 if ((p = strstr(str+2, ruby_engine)) != 0) {
1995 goto start_read;
1996 }
1997 }
1998 }
1999 rb_loaderror("no Ruby script found in input");
2000 }
2001
2002 c = rb_io_getbyte(f);
2003 if (c == INT2FIX('#')) {
2004 c = rb_io_getbyte(f);
2005 if (c == INT2FIX('!') && !NIL_P(line = rb_io_gets(f))) {
2006 RSTRING_GETMEM(line, str, len);
2007 warn_cr_in_shebang(str, len);
2008 if ((p = strstr(str, ruby_engine)) == 0) {
2009 /* not ruby script, assume -x flag */
2010 goto search_shebang;
2011 }
2012
2013 start_read:
2014 str += len - 1;
2015 if (*str == '\n') *str-- = '\0';
2016 if (*str == '\r') *str-- = '\0';
2017 /* ruby_engine should not contain a space */
2018 if ((p = strstr(p, " -")) != 0) {
2019 opt->warning = 0;
2020 moreswitches(p + 1, opt, 0);
2021 }
2022
2023 /* push back shebang for pragma may exist in next line */
2024 rb_io_ungetbyte(f, rb_str_new2("!\n"));
2025 }
2026 else if (!NIL_P(c)) {
2027 rb_io_ungetbyte(f, c);
2028 }
2029 rb_io_ungetbyte(f, INT2FIX('#'));
2030 if (no_src_enc && opt->src.enc.name) {
2031 opt->src.enc.index = opt_enc_index(opt->src.enc.name);
2033 }
2034 if (no_ext_enc && opt->ext.enc.name) {
2035 opt->ext.enc.index = opt_enc_index(opt->ext.enc.name);
2036 }
2037 if (no_int_enc && opt->intern.enc.name) {
2038 opt->intern.enc.index = opt_enc_index(opt->intern.enc.name);
2039 }
2040 }
2041 else if (!NIL_P(c)) {
2042 rb_io_ungetbyte(f, c);
2043 }
2044 if (NIL_P(c)) {
2045 argp->f = f = Qnil;
2046 }
2047 if (!(opt->dump & ~DUMP_BIT(version_v))) {
2049 require_libraries(&opt->req_list); /* Why here? unnatural */
2050 }
2051 }
2052 if (opt->src.enc.index >= 0) {
2054 }
2055 else if (f == rb_stdin) {
2056 enc = rb_locale_encoding();
2057 }
2058 else {
2059 enc = rb_utf8_encoding();
2060 }
2062 opt->do_line, opt->do_split);
2063 if (NIL_P(f)) {
2064 f = rb_str_new(0, 0);
2065 rb_enc_associate(f, enc);
2066 return (VALUE)rb_parser_compile_string_path(parser, orig_fname, f, line_start);
2067 }
2068 rb_funcall(f, set_encoding, 2, rb_enc_from_encoding(enc), rb_str_new_cstr("-"));
2069 ast = rb_parser_compile_file_path(parser, orig_fname, f, line_start);
2070 rb_funcall(f, set_encoding, 1, rb_parser_encoding(parser));
2072 /*
2073 * DATA is a File that contains the data section of the executed file.
2074 * To create a data section use <tt>__END__</tt>:
2075 *
2076 * $ cat t.rb
2077 * puts DATA.gets
2078 * __END__
2079 * hello world!
2080 *
2081 * $ ruby t.rb
2082 * hello world!
2083 */
2084 rb_define_global_const("DATA", f);
2085 argp->f = Qnil;
2086 }
2087 return (VALUE)ast;
2088}
2089
2090static VALUE
2091open_load_file(VALUE fname_v, int *xflag)
2092{
2093 const char *fname = (fname_v = rb_str_encode_ospath(fname_v),
2094 StringValueCStr(fname_v));
2095 long flen = RSTRING_LEN(fname_v);
2096 VALUE f;
2097 int e;
2098
2099 if (flen == 1 && fname[0] == '-') {
2100 f = rb_stdin;
2101 }
2102 else {
2103 int fd;
2104 /* open(2) may block if fname is point to FIFO and it's empty. Let's
2105 use O_NONBLOCK. */
2106#if defined O_NONBLOCK && HAVE_FCNTL && !(O_NONBLOCK & O_ACCMODE)
2107 /* TODO: fix conflicting O_NONBLOCK in ruby/win32.h */
2108# define MODE_TO_LOAD (O_RDONLY | O_NONBLOCK)
2109#elif defined O_NDELAY && HAVE_FCNTL && !(O_NDELAY & O_ACCMODE)
2110# define MODE_TO_LOAD (O_RDONLY | O_NDELAY)
2111#else
2112# define MODE_TO_LOAD (O_RDONLY)
2113#endif
2114 int mode = MODE_TO_LOAD;
2115#if defined DOSISH || defined __CYGWIN__
2116# define isdirsep(x) ((x) == '/' || (x) == '\\')
2117 {
2118 static const char exeext[] = ".exe";
2119 enum {extlen = sizeof(exeext)-1};
2120 if (flen > extlen && !isdirsep(fname[flen-extlen-1]) &&
2121 STRNCASECMP(fname+flen-extlen, exeext, extlen) == 0) {
2122 mode |= O_BINARY;
2123 *xflag = 1;
2124 }
2125 }
2126#endif
2127
2128 if ((fd = rb_cloexec_open(fname, mode, 0)) < 0) {
2129 e = errno;
2130 if (!rb_gc_for_fd(e)) {
2131 rb_load_fail(fname_v, strerror(e));
2132 }
2133 if ((fd = rb_cloexec_open(fname, mode, 0)) < 0) {
2134 rb_load_fail(fname_v, strerror(errno));
2135 }
2136 }
2137 rb_update_max_fd(fd);
2138
2139#if defined HAVE_FCNTL && MODE_TO_LOAD != O_RDONLY
2140 /* disabling O_NONBLOCK */
2141 if (fcntl(fd, F_SETFL, 0) < 0) {
2142 e = errno;
2143 (void)close(fd);
2144 rb_load_fail(fname_v, strerror(e));
2145 }
2146#endif
2147
2148 e = ruby_is_fd_loadable(fd);
2149 if (!e) {
2150 e = errno;
2151 (void)close(fd);
2152 rb_load_fail(fname_v, strerror(e));
2153 }
2154
2155 f = rb_io_fdopen(fd, mode, fname);
2156 if (e < 0) {
2157 /*
2158 We need to wait if FIFO is empty. It's FIFO's semantics.
2159 rb_thread_wait_fd() release GVL. So, it's safe.
2160 */
2162 }
2163 }
2164 return f;
2165}
2166
2167static VALUE
2168restore_load_file(VALUE arg)
2169{
2170 struct load_file_arg *argp = (struct load_file_arg *)arg;
2171 VALUE f = argp->f;
2172
2173 if (!NIL_P(f) && f != rb_stdin) {
2174 rb_io_close(f);
2175 }
2176 return Qnil;
2177}
2178
2179static rb_ast_t *
2181{
2182 struct load_file_arg arg;
2183 arg.parser = parser;
2184 arg.fname = fname;
2185 arg.script = script;
2186 arg.opt = opt;
2187 arg.f = f;
2188 return (rb_ast_t *)rb_ensure(load_file_internal, (VALUE)&arg,
2189 restore_load_file, (VALUE)&arg);
2190}
2191
2192void *
2194{
2195 VALUE fname_v = rb_str_new_cstr(fname);
2196 return rb_load_file_str(fname_v);
2197}
2198
2199void *
2201{
2202 return rb_parser_load_file(rb_parser_new(), fname_v);
2203}
2204
2205void *
2207{
2209 VALUE f = open_load_file(fname_v, &cmdline_options_init(&opt)->xflag);
2210 return load_file(parser, fname_v, f, 0, &opt);
2211}
2212
2213/*
2214 * call-seq:
2215 * Process.argv0 -> frozen_string
2216 *
2217 * Returns the name of the script being executed. The value is not
2218 * affected by assigning a new value to $0.
2219 *
2220 * This method first appeared in Ruby 2.1 to serve as a global
2221 * variable free means to get the script name.
2222 */
2223
2224static VALUE
2225proc_argv0(VALUE process)
2226{
2227 return rb_orig_progname;
2228}
2229
2230static VALUE ruby_setproctitle(VALUE title);
2231
2232/*
2233 * call-seq:
2234 * Process.setproctitle(string) -> string
2235 *
2236 * Sets the process title that appears on the ps(1) command. Not
2237 * necessarily effective on all platforms. No exception will be
2238 * raised regardless of the result, nor will NotImplementedError be
2239 * raised even if the platform does not support the feature.
2240 *
2241 * Calling this method does not affect the value of $0.
2242 *
2243 * Process.setproctitle('myapp: worker #%d' % worker_id)
2244 *
2245 * This method first appeared in Ruby 2.1 to serve as a global
2246 * variable free means to change the process title.
2247 */
2248
2249static VALUE
2250proc_setproctitle(VALUE process, VALUE title)
2251{
2252 return ruby_setproctitle(title);
2253}
2254
2255static VALUE
2256ruby_setproctitle(VALUE title)
2257{
2258 const char *ptr = StringValueCStr(title);
2259 setproctitle("%.*s", RSTRING_LENINT(title), ptr);
2260 return title;
2261}
2262
2263static void
2264set_arg0(VALUE val, ID id, VALUE *_)
2265{
2266 if (origarg.argv == 0)
2267 rb_raise(rb_eRuntimeError, "$0 not initialized");
2268
2269 rb_progname = rb_str_new_frozen(ruby_setproctitle(val));
2270}
2271
2272static inline VALUE
2273external_str_new_cstr(const char *p)
2274{
2275#if UTF8_PATH
2278 return str;
2279#else
2280 return rb_external_str_new_cstr(p);
2281#endif
2282}
2283
2289void
2290ruby_script(const char *name)
2291{
2292 if (name) {
2293 rb_orig_progname = rb_progname = external_str_new_cstr(name);
2295 }
2296}
2297
2302void
2304{
2307}
2308
2309static void
2310init_ids(ruby_cmdline_options_t *opt)
2311{
2312 rb_uid_t uid = getuid();
2313 rb_uid_t euid = geteuid();
2314 rb_gid_t gid = getgid();
2315 rb_gid_t egid = getegid();
2316
2317 if (uid != euid) opt->setids |= 1;
2318 if (egid != gid) opt->setids |= 2;
2319}
2320
2321#undef forbid_setid
2322static void
2323forbid_setid(const char *s, const ruby_cmdline_options_t *opt)
2324{
2325 if (opt->setids & 1)
2326 rb_raise(rb_eSecurityError, "no %s allowed while running setuid", s);
2327 if (opt->setids & 2)
2328 rb_raise(rb_eSecurityError, "no %s allowed while running setgid", s);
2329}
2330
2331static void
2332verbose_setter(VALUE val, ID id, VALUE *variable)
2333{
2334 *variable = RTEST(val) ? Qtrue : val;
2335}
2336
2337static VALUE
2338opt_W_getter(ID id, VALUE *variable)
2339{
2340 switch (*variable) {
2341 case Qnil:
2342 return INT2FIX(0);
2343 case Qfalse:
2344 return INT2FIX(1);
2345 case Qtrue:
2346 return INT2FIX(2);
2347 default:
2348 return Qnil;
2349 }
2350}
2351
2353void
2355{
2356 rb_define_hooked_variable("$VERBOSE", &ruby_verbose, 0, verbose_setter);
2357 rb_define_hooked_variable("$-v", &ruby_verbose, 0, verbose_setter);
2358 rb_define_hooked_variable("$-w", &ruby_verbose, 0, verbose_setter);
2360 rb_define_variable("$DEBUG", &ruby_debug);
2362
2363 rb_define_hooked_variable("$0", &rb_progname, 0, set_arg0);
2364 rb_define_hooked_variable("$PROGRAM_NAME", &rb_progname, 0, set_arg0);
2365
2366 rb_define_module_function(rb_mProcess, "argv0", proc_argv0, 0);
2367 rb_define_module_function(rb_mProcess, "setproctitle", proc_setproctitle, 1);
2368
2369 /*
2370 * ARGV contains the command line arguments used to run ruby.
2371 *
2372 * A library like OptionParser can be used to process command-line
2373 * arguments.
2374 */
2376}
2377
2378void
2380{
2381 int i;
2382 VALUE av = rb_argv;
2383
2384#if defined(USE_DLN_A_OUT)
2385 if (origarg.argc > 0 && origarg.argv)
2386 dln_argv0 = origarg.argv[0];
2387 else if (argc > 0 && argv)
2388 dln_argv0 = argv[0];
2389#endif
2390 rb_ary_clear(av);
2391 for (i = 0; i < argc; i++) {
2392 VALUE arg = external_str_new_cstr(argv[i]);
2393
2394 OBJ_FREEZE(arg);
2395 rb_ary_push(av, arg);
2396 }
2397}
2398
2399void *
2401{
2403 VALUE iseq;
2404 const char *script_name = (argc > 0 && argv[0]) ? argv[0] : ruby_engine;
2405
2406 if (!origarg.argv || origarg.argc <= 0) {
2407 origarg.argc = argc;
2408 origarg.argv = argv;
2409 }
2410 ruby_script(script_name); /* for the time being */
2413 iseq = process_options(argc, argv, cmdline_options_init(&opt));
2414
2415#ifndef HAVE_SETPROCTITLE
2417#endif
2418
2419 return (void*)(struct RData*)iseq;
2420}
2421
2422static void
2423fill_standard_fds(void)
2424{
2425 int f0, f1, f2, fds[2];
2426 struct stat buf;
2427 f0 = fstat(0, &buf) == -1 && errno == EBADF;
2428 f1 = fstat(1, &buf) == -1 && errno == EBADF;
2429 f2 = fstat(2, &buf) == -1 && errno == EBADF;
2430 if (f0) {
2431 if (pipe(fds) == 0) {
2432 close(fds[1]);
2433 if (fds[0] != 0) {
2434 dup2(fds[0], 0);
2435 close(fds[0]);
2436 }
2437 }
2438 }
2439 if (f1 || f2) {
2440 if (pipe(fds) == 0) {
2441 close(fds[0]);
2442 if (f1 && fds[1] != 1)
2443 dup2(fds[1], 1);
2444 if (f2 && fds[1] != 2)
2445 dup2(fds[1], 2);
2446 if (fds[1] != 1 && fds[1] != 2)
2447 close(fds[1]);
2448 }
2449 }
2450}
2451
2459void
2460ruby_sysinit(int *argc, char ***argv)
2461{
2462#if defined(_WIN32)
2464#endif
2465 if (*argc >= 0 && *argv) {
2466 origarg.argc = *argc;
2467 origarg.argv = *argv;
2468#if defined(USE_DLN_A_OUT)
2469 dln_argv0 = origarg.argv[0];
2470#endif
2471 }
2472 fill_standard_fds();
2473}
#define O_BINARY
Definition: _sdbm.c:87
int errno
#define L(x)
Definition: asm.h:125
#define ruby_show_copyright()
Definition: backward.h:75
#define mod(x, y)
Definition: date_strftime.c:28
enum @73::@75::@76 mask
struct RIMemo * ptr
Definition: debug.c:65
#define isdirsep(x)
Definition: dln.c:116
#define require(name)
Definition: dmyenc.c:1
struct rb_encoding_entry * list
Definition: encoding.c:56
int rb_enc_dummy_p(rb_encoding *enc)
Definition: encoding.c:131
VALUE rb_enc_associate(VALUE obj, rb_encoding *enc)
Definition: encoding.c:866
rb_encoding * rb_utf8_encoding(void)
Definition: encoding.c:1328
rb_encoding * rb_ascii8bit_encoding(void)
Definition: encoding.c:1316
rb_encoding * rb_enc_from_index(int index)
Definition: encoding.c:609
rb_encoding * rb_default_internal_encoding(void)
Definition: encoding.c:1512
void rb_enc_copy(VALUE obj1, VALUE obj2)
Definition: encoding.c:990
void rb_enc_set_default_internal(VALUE encoding)
Definition: encoding.c:1563
rb_encoding * rb_default_external_encoding(void)
Definition: encoding.c:1427
rb_encoding * rb_locale_encoding(void)
Definition: encoding.c:1372
VALUE rb_enc_from_encoding(rb_encoding *encoding)
Definition: encoding.c:116
void rb_enc_set_default_external(VALUE encoding)
Definition: encoding.c:1479
int rb_enc_find_index(const char *name)
Definition: encoding.c:693
VALUE rb_str_conv_enc(VALUE str, rb_encoding *from, rb_encoding *to)
Definition: string.c:1030
#define ECONV_UNDEF_REPLACE
Definition: encoding.h:396
VALUE rb_str_conv_enc_opts(VALUE str, rb_encoding *from, rb_encoding *to, int ecflags, VALUE ecopts)
Definition: string.c:914
#define ENCODING_GET(obj)
Definition: encoding.h:62
#define ECONV_INVALID_REPLACE
Definition: encoding.h:394
char str[HTML_ESCAPE_MAX_LEN+1]
Definition: escape.c:18
char * rb_enc_path_last_separator(const char *path, const char *end, rb_encoding *enc)
Definition: file.c:3406
VALUE rb_define_module(const char *)
Definition: class.c:785
VALUE rb_cObject
Object class.
Definition: ruby.h:2012
VALUE rb_cString
Definition: ruby.h:2046
VALUE rb_mProcess
Definition: ruby.h:2007
@ RSTRING_EMBED_LEN_MAX
Definition: ruby.h:982
VALUE rb_stdin
Definition: ruby.h:2092
void ruby_set_argv(int argc, char **argv)
Definition: ruby.c:2379
void ruby_incpush(const char *path)
Definition: ruby.c:426
void ruby_script(const char *name)
Sets the current script name to this value.
Definition: ruby.c:2290
void ruby_set_script_name(VALUE name)
Sets the current script name to this value.
Definition: ruby.c:2303
void ruby_init_loadpath(void)
Definition: ruby.c:582
void * ruby_process_options(int argc, char **argv)
Definition: ruby.c:2400
void ruby_prog_init(void)
Defines built-in variables.
Definition: ruby.c:2354
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:2671
void rb_warning_category_update(unsigned int mask, unsigned int bits)
Definition: error.c:159
void rb_exc_raise(VALUE mesg)
Raises an exception in the current thread.
Definition: eval.c:668
VALUE rb_eTypeError
Definition: error.c:924
void rb_fatal(const char *fmt,...)
Definition: error.c:2722
void rb_load_fail(VALUE path, const char *err)
Definition: error.c:2967
VALUE rb_eNameError
Definition: error.c:929
VALUE rb_eRuntimeError
Definition: error.c:922
void rb_warn(const char *fmt,...)
Definition: error.c:315
VALUE rb_exc_new_str(VALUE, VALUE)
Definition: error.c:974
void rb_loaderror(const char *fmt,...)
Definition: error.c:2690
VALUE rb_ensure(VALUE(*)(VALUE), VALUE, VALUE(*)(VALUE), VALUE)
An equivalent to ensure clause.
Definition: eval.c:1115
VALUE rb_eSecurityError
Definition: error.c:933
VALUE rb_class_new_instance(int, const VALUE *, VALUE)
Allocates and initializes an instance of klass.
Definition: object.c:1955
VALUE rb_obj_freeze(VALUE)
Make the object unmodifiable.
Definition: object.c:1080
void ruby_sysinit(int *argc, char ***argv)
Initializes the process for libruby.
Definition: ruby.c:2460
VALUE type(ANYARGS)
ANYARGS-ed function type.
Definition: cxxanyargs.hpp:39
const char * name
Definition: nkf.c:208
#define RARRAY_LEN(a)
#define ruby_debug
VALUE rb_parser_encoding(VALUE)
Definition: ripper.c:19462
#define rb_str_new2
void rb_ast_dispose(rb_ast_t *)
Definition: node.c:1387
#define NULL
rb_ast_t * rb_parser_compile_file_path(VALUE vparser, VALUE fname, VALUE input, int line)
Definition: ripper.c:13075
#define rb_funcallv(recv, mid, argc, argv)
#define CharNext(p)
VALUE rb_str_resize(VALUE, long)
Definition: string.c:2709
@ RB_WARN_CATEGORY_DEPRECATED
@ RB_WARN_CATEGORY_ALL_BITS
@ RB_WARN_CATEGORY_EXPERIMENTAL
#define RSTRING_LEN(str)
VALUE rb_parser_dump_tree(const NODE *node, int comment)
Definition: node.c:1076
#define _(args)
#define RTEST(v)
VALUE rb_rs
Definition: intern.h:585
VALUE rb_io_getbyte(VALUE)
Definition: io.c:4219
#define PATH_ENV
VALUE rb_parser_new(void)
Definition: ripper.c:19389
VALUE rb_const_get(VALUE, ID)
Definition: variable.c:2391
int ruby_is_fd_loadable(int fd)
Definition: file.c:6216
char * strstr(const char *, const char *)
Definition: strstr.c:8
VALUE rb_parser_set_context(VALUE, const struct rb_iseq_struct *, int)
Definition: ripper.c:19399
#define LIBDIR_BASENAME
size_t strlen(const char *)
int strcmp(const char *, const char *)
#define T_STRING
#define rb_utf8_str_new_cstr(str)
long int ptrdiff_t
VALUE rb_str_encode_ospath(VALUE)
Definition: file.c:236
#define StringValuePtr(v)
int fstat(int __fd, struct stat *__sbuf)
int close(int __fildes)
int atoi(const char *__nptr)
void rb_define_global_function(const char *, VALUE(*)(), int)
void Init_enc(void)
Definition: dmyenc.c:5
uid_t getuid(void)
Definition: win32.c:2795
#define rb_str_cat2
VALUE rb_cISeq
Definition: iseq.c:32
VALUE rb_gv_set(const char *, VALUE)
Definition: variable.c:671
void rb_thread_wait_fd(int)
Definition: thread.c:4041
VALUE rb_io_close(VALUE)
Definition: io.c:4824
VALUE rb_io_fdopen(int, int, const char *)
Definition: io.c:8008
gid_t getegid(void)
Definition: win32.c:2816
#define RSTRING_PTR(str)
void rb_gc_register_mark_object(VALUE)
Definition: gc.c:7079
void ruby_set_inplace_mode(const char *)
Definition: io.c:12872
char * strerror(int)
Definition: strerror.c:11
char * strncpy(char *__restrict__, const char *__restrict__, size_t)
#define rb_uid_t
int int int printf(const char *__restrict__,...) __attribute__((__format__(__printf__
#define GET_EC()
#define rb_gid_t
#define rb_str_new(str, len)
#define NIL_P(v)
#define GetBindingPtr(obj, ptr)
void rb_ary_modify(VALUE)
Definition: array.c:548
#define numberof(array)
VALUE rb_str_cat(VALUE, const char *, long)
Definition: string.c:2812
VALUE rb_io_gets(VALUE)
Definition: io.c:3577
char * strrchr(const char *, int)
Definition: strchr.c:20
#define RSTRING_LENINT(str)
const char size_t n
const char *const char ruby_exec_prefix[]
Definition: loadpath.c:59
#define ruby_verbose
#define MEMZERO(p, type, n)
int pipe(int __fildes[2])
#define rb_intern_const(str)
void rb_define_variable(const char *, VALUE *)
Definition: variable.c:499
VALUE rb_io_write(VALUE, VALUE)
Definition: io.c:1804
gid_t getgid(void)
Definition: win32.c:2809
void rb_define_global_const(const char *, VALUE)
Definition: variable.c:2903
void rb_str_set_len(VALUE, long)
Definition: string.c:2692
unsigned long VALUE
VALUE rb_ary_push(VALUE, VALUE)
Definition: array.c:1195
void rb_update_max_fd(int fd)
Definition: io.c:218
void ruby_init_setproctitle(int argc, char *argv[])
int rb_gc_for_fd(int err)
Definition: io.c:953
#define RARRAY_ASET(a, i, v)
#define GET_VM()
VALUE rb_parser_end_seen_p(VALUE)
Definition: ripper.c:19447
VALUE rb_funcall_passing_block(VALUE, ID, int, const VALUE *)
Definition: vm_eval.c:1032
uint32_t i
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
#define RSTRING_GETMEM(str, ptrvar, lenvar)
int strncmp(const char *, const char *, size_t)
__inline__ const void *__restrict__ size_t len
int rb_cloexec_open(const char *pathname, int flags, mode_t mode)
Definition: io.c:292
VALUE rb_io_flush(VALUE)
Definition: io.c:1903
const char * rb_obj_classname(VALUE)
Definition: variable.c:289
#define ALLOC_N(type, n)
void Init_ext(void)
Definition: dmyext.c:2
VALUE rb_fs
Definition: intern.h:583
#define OBJ_FREEZE(x)
int dup2(int __fildes, int __fildes2)
Definition: dup2.c:27
VALUE rb_output_rs
Definition: intern.h:587
void rb_define_module_function(VALUE, const char *, VALUE(*)(), int)
void rb_vm_set_progname(VALUE filename)
Definition: vm.c:3291
#define rb_external_str_new_cstr(str)
void mjit_init(const struct mjit_options *opts)
VALUE rb_ary_replace(VALUE copy, VALUE orig)
Definition: array.c:3811
void ruby_gc_set_params(void)
Definition: gc.c:9434
void rb_stdio_set_default_encoding(void)
Definition: io.c:11769
uid_t geteuid(void)
Definition: win32.c:2802
#define ISALNUM(c)
void rb_gvar_readonly_setter(VALUE v, ID id, VALUE *_)
Definition: variable.c:412
#define PRIsVALUE
struct mjit_options mjit_opts
Definition: mjit_worker.c:174
VALUE rb_ary_clear(VALUE)
Definition: array.c:3862
VALUE rb_ary_tmp_new(long)
Definition: array.c:768
#define rb_funcall(recv, mid, argc,...)
int VALUE v
void rb_gc_register_address(VALUE *)
Definition: gc.c:7093
const char ruby_initial_load_paths[]
Definition: loadpath.c:62
#define rb_str_cat_cstr(str, ptr)
VALUE rb_str_tmp_new(long)
Definition: string.c:1343
#define rb_intern(str)
VALUE rb_reg_new(const char *, long, int)
Definition: re.c:2947
void rb_parser_set_options(VALUE, int, int, int, int)
Definition: ripper.c:19201
const rb_iseq_t * iseq
char * strchr(const char *, int)
Definition: strchr.c:8
#define CONST_ID(var, str)
VALUE rb_parser_set_yydebug(VALUE, VALUE)
Definition: ripper.c:19494
#define RBASIC_SET_CLASS_RAW(obj, cls)
#define TRUE
#define FALSE
void rb_const_set(VALUE, ID, VALUE)
Definition: variable.c:2756
#define Qtrue
#define MEMMOVE(p1, p2, type, n)
#define FILENAME_MAX
VALUE rb_str_subseq(VALUE, long, long)
Definition: string.c:2474
char * strdup(const char *) __attribute__((__malloc__)) __attribute__((__warn_unused_result__))
#define rb_strlen_lit(str)
#define PATH_SEP_CHAR
struct rb_call_cache buf
VALUE rb_str_new_frozen(VALUE)
Definition: string.c:1203
VALUE rb_attr_get(VALUE, ID)
Definition: variable.c:1084
#define Qnil
#define Qfalse
void rb_str_modify_expand(VALUE, long)
Definition: string.c:2122
void * memcpy(void *__restrict__, const void *__restrict__, size_t)
#define OBJ_FREEZE_RAW(x)
VALUE rb_lastline_get(void)
Definition: vm.c:1316
void setproctitle(const char *fmt,...)
Definition: setproctitle.c:139
#define RB_TYPE_P(obj, type)
#define EBADF
#define INT2FIX(i)
void rb_define_hooked_variable(const char *, VALUE *, rb_gvar_getter_t *, rb_gvar_setter_t *)
Definition: variable.c:480
void void ruby_xfree(void *)
Definition: gc.c:10183
__inline__ int
VALUE rb_ary_shift(VALUE)
Definition: array.c:1294
VALUE rb_ivar_set(VALUE, ID, VALUE)
Definition: variable.c:1300
VALUE rb_iseq_disasm(const rb_iseq_t *iseq)
Definition: iseq.c:2278
rb_ast_t * rb_parser_compile_string(VALUE, const char *, VALUE, int)
Definition: ripper.c:13054
#define TOLOWER(c)
VALUE rb_io_ungetbyte(VALUE, VALUE)
Definition: io.c:4280
int puts(const char *)
VALUE rb_const_remove(VALUE, ID)
Definition: variable.c:2494
void rb_lastline_set(VALUE)
Definition: vm.c:1322
#define rb_utf8_str_new(str, len)
#define RUBY_EXTERN
VALUE rb_str_dup(VALUE)
Definition: string.c:1516
VALUE rb_sprintf(const char *,...) __attribute__((format(printf
VALUE rb_file_expand_path(VALUE, VALUE)
Definition: file.c:4039
unsigned long ID
int chdir(const char *__path)
const char *void rb_warning(const char *,...) __attribute__((format(printf
#define ISSPACE(c)
rb_ast_t * rb_parser_compile_string_path(VALUE vparser, VALUE fname, VALUE src, int line)
Definition: ripper.c:13060
#define RARRAY_AREF(a, i)
VALUE rb_get_expanded_load_path(void)
Definition: load.c:97
VALUE rb_stdout
void ruby_show_version(void)
Prints the version information of the CRuby interpreter to stdout.
Definition: version.c:119
VALUE rb_hash_new(void)
Definition: hash.c:1523
#define rb_str_new_cstr(str)
VALUE rb_realpath_internal(VALUE basedir, VALUE path, int strict)
Definition: file.c:4430
#define RARRAY_CONST_PTR(a)
#define rb_str_new4
#define StringValueCStr(v)
#define STRNCASECMP(s1, s2, n)
#define rb_argv
#define yydebug
Definition: ripper.c:100
#define INITIAL_LOAD_PATH_MARK
Definition: ruby.c:577
#define str_conv_enc(str, from, to)
Definition: ruby.c:499
VALUE rb_argv0
Definition: ruby.c:1478
int ruby_env_debug_option(const char *str, int len, void *arg)
Definition: debug.c:153
#define set_source_encoding_once(opt, e, elen)
Definition: ruby.c:972
#define rb_orig_progname
Definition: ruby.c:1477
VALUE rb_e_script
Definition: ruby.c:1479
#define FEATURE_BIT(bit)
Definition: ruby.c:75
#define src_encoding_index
Definition: ruby.c:182
void ruby_incpush_expand(const char *path)
Definition: ruby.c:443
#define rb_define_readonly_boolean(name, val)
Definition: ruby.c:1493
#define EACH_DEBUG_FEATURES(X, SEP)
Definition: ruby.c:87
#define IF_UTF8_PATH(t, f)
Definition: ruby.c:487
#define is_option_with_arg(name, allow_hyphen, allow_envopt)
VALUE ruby_prefix_path
Definition: ruby.c:579
feature_flag_bits
Definition: ruby.c:93
@ feature_flag_count
Definition: ruby.c:98
@ feature_debug_flag_first
Definition: ruby.c:95
@ feature_debug_flag_begin
Definition: ruby.c:96
#define DUMP_BIT(bit)
Definition: ruby.c:103
void Init_builtin_features(void)
Definition: builtin.c:66
#define RUBY_RELATIVE(path, len)
#define SET_WHEN_DEBUG(bit)
VALUE ruby_archlibdir_path
Definition: ruby.c:579
RUBY_EXTERN const int ruby_patchlevel
Definition: ruby.c:921
#define FEATURE_SET_RESTORE(feat, save)
Definition: ruby.c:149
#define DEFINE_DUMP(bit)
Definition: ruby.c:104
#define SET_FEATURE(bit)
#define DEFINE_DEBUG_FEATURE(bit)
Definition: ruby.c:92
#define is_option_with_optarg(name, allow_hyphen, allow_envopt, needs_arg, next_arg)
#define FEATURE_SET_TO(feat, bit_mask, bit_set)
Definition: ruby.c:146
#define SHOW(m)
#define FEATURE_SET(feat, bits)
Definition: ruby.c:148
dump_flag_bits
Definition: ruby.c:124
@ dump_version_v
Definition: ruby.c:125
@ dump_exit_bits
Definition: ruby.c:127
#define NAME_MATCH_P(name, str, len)
Definition: ruby.c:851
void * rb_load_file_str(VALUE fname_v)
Definition: ruby.c:2200
#define DEFINE_FEATURE(bit)
Definition: ruby.c:91
#define EACH_FEATURES(X, SEP)
Definition: ruby.c:76
void Init_ruby_description(void)
Definition: version.c:100
#define COMMA
Definition: ruby.c:74
#define SET_COMPILE_OPTION(h, o, name)
#define SET_WHEN_DUMP(bit)
#define M(shortopt, longopt, desc)
void * rb_parser_load_file(VALUE parser, VALUE fname_v)
Definition: ruby.c:2206
#define set_internal_encoding_once(opt, e, elen)
Definition: ruby.c:968
#define EACH_DUMPS(X, SEP)
Definition: ruby.c:105
char * getenv()
int argc
Definition: ruby.c:222
#define set_encoding_part(type)
#define MAXPATHLEN
Definition: ruby.c:47
#define rb_progname
Definition: ruby.c:1476
void * rb_load_file(const char *fname)
Definition: ruby.c:2193
void ruby_push_include(const char *path, VALUE(*filter)(VALUE))
Definition: ruby.c:406
#define DEFAULT_RUBYGEMS_ENABLED
Definition: ruby.c:69
#define set_external_encoding_once(opt, e, elen)
Definition: ruby.c:970
#define forbid_setid(s)
Definition: ruby.c:219
#define rubylib_path_new
Definition: ruby.c:342
char ** argv
Definition: ruby.c:223
#define PREFIX_PATH()
@ DEFAULT_FEATURES
Definition: ruby.c:190
@ COMPILATION_FEATURES
Definition: ruby.c:185
#define LITERAL_NAME_ELEMENT(name)
Definition: ruby.c:866
#define MODE_TO_LOAD
#define f
Definition: ruby.h:1139
VALUE parser
Definition: ruby.c:1952
VALUE fname
Definition: ruby.c:1953
VALUE f
Definition: ruby.c:1956
ruby_cmdline_options_t * opt
Definition: ruby.c:1955
int script
Definition: ruby.c:1954
const struct rb_block block
unsigned int verbose
Definition: ruby.c:171
struct ruby_cmdline_options::@215 ext
unsigned int do_search
Definition: ruby.c:176
unsigned int do_loop
Definition: ruby.c:172
unsigned int dump
Definition: ruby.c:165
ruby_features_t warn
Definition: ruby.c:164
VALUE script_name
Definition: ruby.c:154
struct ruby_cmdline_options::@215 intern
struct ruby_cmdline_options::@215::@216 enc
ruby_features_t features
Definition: ruby.c:163
unsigned int warning
Definition: ruby.c:170
unsigned int do_split
Definition: ruby.c:175
const char * script
Definition: ruby.c:153
unsigned int do_line
Definition: ruby.c:174
unsigned int do_print
Definition: ruby.c:173
struct ruby_cmdline_options::@215 src
unsigned int setids
Definition: ruby.c:177
unsigned int mask
Definition: ruby.c:135
unsigned int set
Definition: ruby.c:136
Definition: dtoa.c:290
void ruby_each_words(const char *, void(*)(const char *, int, void *), void *)
Definition: util.c:585
#define scan_oct(s, l, e)
Definition: util.h:53
const char ruby_engine[]
Definition: version.c:46
VALUE rb_vm_top_self(void)
Definition: vm.c:3349
VALUE rb_readlink(VALUE path, rb_encoding *resultenc)
Definition: file.c:618
#define dln_find_file_r
Definition: win32.c:85
void rb_w32_sysinit(int *, char ***)
Definition: win32.c:877
int fcntl(int, int,...)
Definition: win32.c:4312
#define F_SETFL
Definition: win32.h:608
IUnknown DWORD
Definition: win32ole.c:33