22# include <sys/cygwin.h>
26# include <sys/pstat.h>
29#if (defined(LOAD_RELATIVE) || defined(__MACH__)) && defined(HAVE_DLADDR)
37#if defined(HAVE_FCNTL_H)
39#elif defined(HAVE_SYS_FCNTL_H)
40# include <sys/fcntl.h>
43#ifdef HAVE_SYS_PARAM_H
44# include <sys/param.h>
50#include "internal/error.h"
60#include "internal/variable.h"
69# define MAXPATHLEN 1024
72# define O_ACCMODE (O_RDONLY | O_WRONLY | O_RDWR)
81#ifndef DISABLE_RUBYGEMS
82# define DISABLE_RUBYGEMS 0
85#define DEFAULT_RUBYGEMS_ENABLED "disabled"
87#define DEFAULT_RUBYGEMS_ENABLED "enabled"
93#define FEATURE_BIT(bit) (1U << feature_##bit)
94#define EACH_FEATURES(X, SEP) \
101 X(frozen_string_literal) \
105#define EACH_DEBUG_FEATURES(X, SEP) \
106 X(frozen_string_literal) \
108#define AMBIGUOUS_FEATURE_NAMES 0
109#define DEFINE_FEATURE(bit) feature_##bit
110#define DEFINE_DEBUG_FEATURE(bit) feature_debug_##bit
119#define DEBUG_BIT(bit) (1U << feature_debug_##bit)
121#define DUMP_BIT(bit) (1U << dump_##bit)
122#define DEFINE_DUMP(bit) dump_##bit
123#define EACH_DUMPS(X, SEP) \
138 X(parsetree_with_comment) \
158rb_feature_set_to(
ruby_features_t *feat,
unsigned int bit_mask,
unsigned int bit_set)
160 feat->
mask |= bit_mask;
161 feat->
set = (feat->
set & ~bit_mask) | bit_set;
164#define FEATURE_SET_TO(feat, bit_mask, bit_set) \
165 rb_feature_set_to(&(feat), bit_mask, bit_set)
166#define FEATURE_SET(feat, bits) FEATURE_SET_TO(feat, bits, bits)
167#define FEATURE_SET_RESTORE(feat, save) FEATURE_SET_TO(feat, (save).mask, (save).set & (save).mask)
168#define FEATURE_SET_P(feat, bits) ((feat).set & (bits))
185 struct mjit_options mjit;
200#define src_encoding_index GET_VM()->src_encoding_index
213 & ~FEATURE_BIT(frozen_string_literal)
227#ifdef MJIT_FORCE_ENABLE
235static VALUE open_load_file(
VALUE fname_v,
int *xflag);
237#define forbid_setid(s) forbid_setid((s), opt)
244static const char esc_standout[] =
"\n\033[1;7m";
245static const char esc_bold[] =
"\033[1m";
246static const char esc_reset[] =
"\033[0m";
247static const char esc_none[] =
"";
250show_usage_line(
const char *
str,
unsigned int namelen,
unsigned int secondlen,
int help,
int highlight,
unsigned int w)
252 const char *sb = highlight ? esc_bold : esc_none;
253 const char *se = highlight ? esc_reset : esc_none;
254 const int wrap =
help && namelen + secondlen - 1 > w;
255 printf(
" %s%.*s%-*.*s%s%-*s%s\n", sb, namelen-1,
str,
256 (wrap ? 0 : w - namelen + 1),
257 (
help ? secondlen-1 : 0),
str + namelen, se,
258 (wrap ? w + 3 : 0), (wrap ?
"\n" :
""),
259 str + namelen + secondlen);
263usage(
const char *
name,
int help,
int highlight,
int columns)
270 unsigned short namelen, secondlen;
272#define M(shortopt, longopt, desc) { \
273 shortopt " " longopt " " desc, \
274 (unsigned short)sizeof(shortopt), \
275 (unsigned short)sizeof(longopt), \
277 static const struct message usage_msg[] = {
278 M(
"-0[octal]",
"",
"specify record separator (\\0, if no argument)"),
279 M(
"-a",
"",
"autosplit mode with -n or -p (splits $_ into $F)"),
280 M(
"-c",
"",
"check syntax only"),
281 M(
"-Cdirectory",
"",
"cd to directory before executing your script"),
282 M(
"-d",
", --debug",
"set debugging flags (set $DEBUG to true)"),
283 M(
"-e 'command'",
"",
"one line of script. Several -e's allowed. Omit [programfile]"),
284 M(
"-Eex[:in]",
", --encoding=ex[:in]",
"specify the default external and internal character encodings"),
285 M(
"-Fpattern",
"",
"split() pattern for autosplit (-a)"),
286 M(
"-i[extension]",
"",
"edit ARGV files in place (make backup if extension supplied)"),
287 M(
"-Idirectory",
"",
"specify $LOAD_PATH directory (may be used more than once)"),
288 M(
"-l",
"",
"enable line ending processing"),
289 M(
"-n",
"",
"assume 'while gets(); ... end' loop around your script"),
290 M(
"-p",
"",
"assume loop like -n but print line also like sed"),
291 M(
"-rlibrary",
"",
"require the library before executing your script"),
292 M(
"-s",
"",
"enable some switch parsing for switches after script name"),
293 M(
"-S",
"",
"look for the script using PATH environment variable"),
294 M(
"-v",
"",
"print the version number, then turn on verbose mode"),
295 M(
"-w",
"",
"turn warnings on for your script"),
296 M(
"-W[level=2|:category]",
"",
"set warning level; 0=silence, 1=medium, 2=verbose"),
297 M(
"-x[directory]",
"",
"strip off text before #!ruby line and perhaps cd to directory"),
298 M(
"--jit",
"",
"enable JIT with default options (experimental)"),
299 M(
"--jit-[option]",
"",
"enable JIT with an option (experimental)"),
300 M(
"-h",
"",
"show this message, --help for more info"),
302 static const struct message help_msg[] = {
303 M(
"--copyright",
"",
"print the copyright"),
304 M(
"--dump={insns|parsetree|...}[,...]",
"",
305 "dump debug information. see below for available dump list"),
306 M(
"--enable={gems|rubyopt|...}[,...]",
", --disable={gems|rubyopt|...}[,...]",
307 "enable or disable features. see below for available features"),
308 M(
"--external-encoding=encoding",
", --internal-encoding=encoding",
309 "specify the default external or internal character encoding"),
310 M(
"--verbose",
"",
"turn on verbose mode and disable script from stdin"),
311 M(
"--version",
"",
"print the version number, then exit"),
312 M(
"--help",
"",
"show this message, -h for short message"),
313 M(
"--backtrace-limit=num",
"",
"limit the maximum length of backtrace"),
315 static const struct message dumps[] = {
316 M(
"insns",
"",
"instruction sequences"),
317 M(
"yydebug",
"",
"yydebug of yacc parser generator"),
318 M(
"parsetree",
"",
"AST"),
319 M(
"parsetree_with_comment",
"",
"AST with comments"),
321 static const struct message features[] = {
324 M(
"rubyopt",
"",
"RUBYOPT environment variable (default: enabled)"),
325 M(
"frozen-string-literal",
"",
"freeze all string literals (default: disabled)"),
326 M(
"jit",
"",
"JIT compiler (default: disabled)"),
328 static const struct message warn_categories[] = {
329 M(
"deprecated",
"",
"deprecated features"),
330 M(
"experimental",
"",
"experimental features"),
332 static const struct message mjit_options[] = {
333 M(
"--jit-warnings",
"",
"Enable printing JIT warnings"),
334 M(
"--jit-debug",
"",
"Enable JIT debugging (very slow), or add cflags if specified"),
335 M(
"--jit-wait",
"",
"Wait until JIT compilation finishes every time (for testing)"),
336 M(
"--jit-save-temps",
"",
"Save JIT temporary files in $TMP or /tmp (for testing)"),
337 M(
"--jit-verbose=num",
"",
"Print JIT logs of level num or less to stderr (default: 0)"),
338 M(
"--jit-max-cache=num",
"",
"Max number of methods to be JIT-ed in a cache (default: 100)"),
339 M(
"--jit-min-calls=num",
"",
"Number of calls to trigger JIT (for testing, default: 10000)"),
342 const char *sb = highlight ? esc_standout+1 : esc_none;
343 const char *se = highlight ? esc_reset : esc_none;
345 unsigned int w = (columns > 80 ? (columns - 79) / 2 : 0) + 16;
346#define SHOW(m) show_usage_line((m).str, (m).namelen, (m).secondlen, help, highlight, w)
348 printf(
"%sUsage:%s %s [switches] [--] [programfile] [arguments]\n", sb, se,
name);
349 for (i = 0; i <
num; ++i)
354 if (highlight) sb = esc_standout;
356 for (i = 0; i <
numberof(help_msg); ++i)
358 printf(
"%s""Dump List:%s\n", sb, se);
359 for (i = 0; i <
numberof(dumps); ++i)
361 printf(
"%s""Features:%s\n", sb, se);
362 for (i = 0; i <
numberof(features); ++i)
364 printf(
"%s""Warning categories:%s\n", sb, se);
365 for (i = 0; i <
numberof(warn_categories); ++i)
366 SHOW(warn_categories[i]);
367 printf(
"%s""JIT options (experimental):%s\n", sb, se);
368 for (i = 0; i <
numberof(mjit_options); ++i)
369 SHOW(mjit_options[i]);
372#define rubylib_path_new rb_str_new
375push_include(
const char *path,
VALUE (*filter)(
VALUE))
379 VALUE load_path = GET_VM()->load_path;
386 for (s = p; *s && *s != sep; s =
CharNext(s));
394push_include_cygwin(
const char *path,
VALUE (*filter)(
VALUE))
397 char rubylib[FILENAME_MAX];
406 for (s = p; *s && *s !=
';'; s =
CharNext(s));
418#ifdef HAVE_CYGWIN_CONV_PATH
419#define CONV_TO_POSIX_PATH(p, lib) \
420 cygwin_conv_path(CCP_WIN_A_TO_POSIX|CCP_RELATIVE, (p), (lib), sizeof(lib))
422# error no cygwin_conv_path
424 if (CONV_TO_POSIX_PATH(p, rubylib) == 0)
426 push_include(p, filter);
432#define push_include push_include_cygwin
440 push_include(path, filter);
444identical_path(
VALUE path)
449locale_path(
VALUE path)
462expand_include_path(
VALUE path)
467 if (*p ==
'.' && p[1] ==
'/')
479#if defined _WIN32 || defined __CYGWIN__
480static HMODULE libruby;
483DllMain(HINSTANCE dll,
DWORD reason, LPVOID reserved)
485 if (reason == DLL_PROCESS_ATTACH)
491rb_libruby_handle(
void)
497translit_char_bin(
char *p,
int from,
int to)
500 if ((
unsigned char)*p == from)
515# define IF_UTF8_PATH(t, f) t
517# define IF_UTF8_PATH(t, f) f
529# define str_conv_enc(str, from, to) (str)
534#if defined(LOAD_RELATIVE) || defined(__MACH__)
536runtime_libruby_path(
void)
538#if defined _WIN32 || defined __CYGWIN__
546 ret = GetModuleFileNameW(libruby, wlibpath,
len),
552 if (!ret || ret >
len)
rb_fatal(
"failed to get module file name");
553#if defined __CYGWIN__
555 const int win_to_posix = CCP_WIN_W_TO_POSIX | CCP_RELATIVE;
556 size_t newsize = cygwin_conv_path(win_to_posix, wlibpath, 0, 0);
557 if (!newsize)
rb_fatal(
"failed to convert module path to cygwin");
560 if (cygwin_conv_path(win_to_posix, wlibpath, libpath, newsize)) {
567 for (
len = ret, i = 0; i <
len; ++i) {
568 if (wlibpath[i] ==
L'\\') {
574 len = WideCharToMultiByte(CP_UTF8, 0, wlibpath, ret,
NULL, 0,
NULL,
NULL);
577 WideCharToMultiByte(CP_UTF8, 0, wlibpath, ret, libpath,
len,
NULL,
NULL);
581#elif defined(HAVE_DLADDR)
584 const void* addr = (
void *)(
VALUE)expand_include_path;
586 if (!dladdr((
void *)addr, &dli)) {
590 else if (origarg.argc > 0 && origarg.argv && dli.dli_fname == origarg.argv[0]) {
602# error relative load path is not supported on this platform.
607#define INITIAL_LOAD_PATH_MARK rb_intern_const("@gem_prelude_index")
612VALUE rb_libruby_selfpath;
618 VALUE load_path, archlibdir = 0;
619 ID id_initial_load_path_mark;
621#if defined(LOAD_RELATIVE) || defined(__MACH__)
622 VALUE libruby_path = runtime_libruby_path();
623# if defined(__MACH__)
624 rb_libruby_selfpath = libruby_path;
629#if defined LOAD_RELATIVE
630#if !defined ENABLE_MULTIARCH
631# define RUBY_ARCH_PATH ""
632#elif defined RUBY_ARCH
633# define RUBY_ARCH_PATH "/"RUBY_ARCH
635# define RUBY_ARCH_PATH "/"RUBY_PLATFORM
642 sopath = libruby_path;
647 static const char libdir[] =
"/"
648#ifdef LIBDIR_BASENAME
654 const ptrdiff_t libdir_len = (ptrdiff_t)
sizeof(libdir)
656 static const char bindir[] =
"/bin";
657 const ptrdiff_t bindir_len = (ptrdiff_t)
sizeof(bindir) - 1;
659 const char *p2 =
NULL;
661#ifdef ENABLE_MULTIARCH
664 if (p - libpath >= bindir_len && !
STRNCASECMP(p - bindir_len, bindir, bindir_len)) {
670 else if (p - libpath >= libdir_len && !strncmp(p - libdir_len, libdir, libdir_len)) {
671 archlibdir =
rb_str_subseq(sopath, 0, (p2 ? p2 : p) - libpath);
675#ifdef ENABLE_MULTIARCH
682 if (p)
goto multiarch;
687 baselen = p - libpath;
690#define PREFIX_PATH() sopath
691#define BASEPATH() rb_str_buf_cat(rb_str_buf_new(baselen+len), libpath, baselen)
692#define RUBY_RELATIVE(path, len) rb_str_buf_cat(BASEPATH(), (path), (len))
695#define RUBY_RELATIVE(path, len) rubylib_path_new((path), (len))
696#define PREFIX_PATH() RUBY_RELATIVE(ruby_exec_prefix, exec_prefix_len)
705 load_path = GET_VM()->load_path;
713 rb_ivar_set(path, id_initial_load_path_mark, path);
723add_modules(
VALUE *req_list,
const char *
mod)
725 VALUE list = *req_list;
736require_libraries(
VALUE *req_list)
738 VALUE list = *req_list;
761process_sflag(
int *sflag)
779 if (s[1] ==
'-' && s[2] ==
'\0')
784 for (p = s + 1; *p; p++) {
793 else if (*p !=
'_' && !
ISALNUM(*p)) {
796 rb_str_new2(
"invalid name for global variable - ");
797 if (!(p =
strchr(p,
'='))) {
803 name_error[1] = args[-1];
809 for (p = s + 1; *p; ++p) {
832 VALUE argstr, argary;
841 if (envopt) *p++ =
' ';
848 while (*p && !
ISSPACE(*p)) ++p;
859 while ((i = proc_options(
argc,
argv, opt, envopt)) > 1 && envopt && (
argc -= i) > 0) {
877name_match_p(
const char *
name,
const char *
str,
size_t len)
879 if (
len == 0)
return 0;
882 if (!--
len || !*++
str)
return 1;
885 if (*
str !=
'-' && *
str !=
'_')
return 0;
887 if (*
name !=
'-' && *
name !=
'_')
return 0;
893#define NAME_MATCH_P(name, str, len) \
894 ((len) < (int)sizeof(name) && name_match_p((name), (str), (len)))
896#define UNSET_WHEN(name, bit, str, len) \
897 if (NAME_MATCH_P((name), (str), (len))) { \
898 *(unsigned int *)arg &= ~(bit); \
902#define SET_WHEN(name, bit, str, len) \
903 if (NAME_MATCH_P((name), (str), (len))) { \
904 *(unsigned int *)arg |= (bit); \
908#define LITERAL_NAME_ELEMENT(name) #name
911feature_option(
const char *
str,
int len,
void *arg,
const unsigned int enable)
915 unsigned int mask = ~0
U;
916 unsigned int set = 0
U;
917#if AMBIGUOUS_FEATURE_NAMES
919# define FEATURE_FOUND ++matched
921# define FEATURE_FOUND goto found
923#define SET_FEATURE(bit) \
924 if (NAME_MATCH_P(#bit, str, len)) {set |= mask = FEATURE_BIT(bit); FEATURE_FOUND;}
929#if AMBIGUOUS_FEATURE_NAMES
930 if (matched == 1)
goto found;
933#define ADD_FEATURE_NAME(bit) \
934 if (FEATURE_BIT(bit) & set) { \
935 rb_str_cat_cstr(mesg, #bit); \
936 if (--matched) rb_str_cat_cstr(mesg, ", "); \
941#undef ADD_FEATURE_NAME
944 rb_warn(
"unknown argument for --%s: `%.*s'",
945 enable ?
"enable" :
"disable",
len,
str);
955enable_option(
const char *
str,
int len,
void *arg)
957 feature_option(
str,
len, arg, ~0
U);
961disable_option(
const char *
str,
int len,
void *arg)
963 feature_option(
str,
len, arg, 0
U);
970debug_option(
const char *
str,
int len,
void *arg)
974#define SET_WHEN_DEBUG(bit) \
975 if (NAME_MATCH_P(#bit, str, len)) { \
976 FEATURE_SET(*argp, DEBUG_BIT(bit)); \
984 rb_warn(
"debug features are [%.*s].", (
int)
strlen(list), list);
988dump_option(
const char *
str,
int len,
void *arg)
991#define SET_WHEN_DUMP(bit) SET_WHEN(#bit, DUMP_BIT(bit), str, len)
998set_option_encoding_once(
const char *
type,
VALUE *
name,
const char *e,
long elen)
1002 if (!elen) elen =
strlen(e);
1013#define set_internal_encoding_once(opt, e, elen) \
1014 set_option_encoding_once("default_internal", &(opt)->intern.enc.name, (e), (elen))
1015#define set_external_encoding_once(opt, e, elen) \
1016 set_option_encoding_once("default_external", &(opt)->ext.enc.name, (e), (elen))
1017#define set_source_encoding_once(opt, e, elen) \
1018 set_option_encoding_once("source", &(opt)->src.enc.name, (e), (elen))
1022setup_mjit_options(
const char *s,
struct mjit_options *mjit_opt)
1024#define opt_match(s, l, name) \
1025 ((((l) > rb_strlen_lit(name)) ? (s)[rb_strlen_lit(name)] == '=' : \
1026 (l) == rb_strlen_lit(name)) && \
1027 memcmp((s), name, rb_strlen_lit(name)) == 0 && \
1028 (((s) += rb_strlen_lit(name)), 1))
1029#define opt_match_noarg(s, l, name) \
1030 opt_match(s, l, name) && (*(s) ? (rb_warn("argument to --jit-" name " is ignored"), 1) : 1)
1031#define opt_match_arg(s, l, name) \
1032 opt_match(s, l, name) && (*(s) ? 1 : (rb_raise(rb_eRuntimeError, "--jit-" name " needs an argument"), 0))
1033 if (*s !=
'-')
return;
1034 const size_t l =
strlen(++s);
1035 if (*s == 0)
return;
1036 else if (opt_match_noarg(s, l,
"warnings")) {
1037 mjit_opt->warnings = 1;
1039 else if (opt_match(s, l,
"debug")) {
1041 mjit_opt->debug_flags =
strdup(s + 1);
1043 mjit_opt->debug = 1;
1045 else if (opt_match_noarg(s, l,
"wait")) {
1048 else if (opt_match_noarg(s, l,
"save-temps")) {
1049 mjit_opt->save_temps = 1;
1051 else if (opt_match(s, l,
"verbose")) {
1052 mjit_opt->verbose = *s ? atoi(s + 1) : 1;
1054 else if (opt_match_arg(s, l,
"max-cache")) {
1055 mjit_opt->max_cache_size = atoi(s + 1);
1057 else if (opt_match_arg(s, l,
"min-calls")) {
1058 mjit_opt->min_calls = atoi(s + 1);
1062 "invalid MJIT option `%s' (--help will show valid MJIT options)", s);
1070 long n, argc0 =
argc;
1078 const char *
const arg =
argv[0];
1079 if (!arg || arg[0] !=
'-' || !arg[1])
1086 if (envopt)
goto noenvopt;
1092 if (envopt)
goto noenvopt;
1096 if (envopt)
goto noenvopt;
1108 if (envopt)
goto noenvopt;
1131 unsigned int bits = 0;
1132 static const char no_prefix[] =
"no-";
1133 int enable = strncmp(s += 2, no_prefix,
sizeof(no_prefix)-1) != 0;
1134 if (!enable) s +=
sizeof(no_prefix)-1;
1143 rb_warn(
"unknown warning category: `%s'", s);
1187 if (envopt)
goto noenvopt;
1193 if (envopt)
goto noenvopt;
1200 if (envopt)
goto noenvopt;
1205 if (envopt)
goto noenvopt;
1212 if (envopt)
goto noenvopt;
1219 if (envopt)
goto noenvopt;
1240 else if (
argc > 1) {
1247 if (envopt)
goto noenvopt;
1253 if (envopt)
goto noenvopt;
1257 if (*s && chdir(s) < 0) {
1264 if (envopt)
goto noenvopt;
1265 if (!*++s && (!--
argc || !(s = *++
argv) || !*s)) {
1274 if (envopt)
goto noenvopt;
1281 if (!*++s && (!--
argc || !(s = *++
argv))) {
1293 const char *enc_name = 0;
1296 enc_name =
"EUC-JP";
1299 enc_name =
"Windows-31J";
1304 case 'N':
case 'n':
case 'A':
case 'a':
1305 enc_name =
"ASCII-8BIT";
1321 else if (
argc > 1) {
1328 if (envopt)
goto noenvopt;
1338 else if (v == 0 && numlen >= 2) {
1349 if (!s[1] || (s[1] ==
'\r' && !s[2])) {
1355# define is_option_end(c, allow_hyphen) \
1356 (!(c) || ((allow_hyphen) && (c) == '-') || (c) == '=')
1357# define check_envopt(name, allow_envopt) \
1358 (((allow_envopt) || !envopt) ? (void)0 : \
1359 rb_raise(rb_eRuntimeError, "invalid switch in RUBYOPT: --" name))
1360# define need_argument(name, s, needs_arg, next_arg) \
1361 ((*(s) ? !*++(s) : (next_arg) && (!argc || !((s) = argv[1]) || (--argc, ++argv, 0))) && (needs_arg) ? \
1362 rb_raise(rb_eRuntimeError, "missing argument for --" name) \
1364# define is_option_with_arg(name, allow_hyphen, allow_envopt) \
1365 is_option_with_optarg(name, allow_hyphen, allow_envopt, Qtrue, Qtrue)
1366# define is_option_with_optarg(name, allow_hyphen, allow_envopt, needs_arg, next_arg) \
1367 (strncmp((name), s, n = sizeof(name) - 1) == 0 && is_option_end(s[n], (allow_hyphen)) ? \
1368 (check_envopt(name, (allow_envopt)), s += n, \
1369 need_argument(name, s, needs_arg, next_arg), 1) : 0)
1371 if (strcmp(
"copyright", s) == 0) {
1372 if (envopt)
goto noenvopt_long;
1394# define set_encoding_part(type) \
1395 if (!(p = strchr(s, ':'))) { \
1396 set_##type##_encoding_once(opt, s, 0); \
1400 set_##type##_encoding_once(opt, s, p-s); \
1403 if (!*(s = ++p))
break;
1405 if (!*(s = ++p))
break;
1406#if defined ALLOW_DEFAULT_SOURCE_ENCODING && ALLOW_DEFAULT_SOURCE_ENCODING
1408 if (!*(s = ++p))
break;
1411 (arg[1] ==
'-' ?
"--encoding" :
"-E"), s);
1412# undef set_encoding_part
1421#if defined ALLOW_DEFAULT_SOURCE_ENCODING && ALLOW_DEFAULT_SOURCE_ENCODING
1426 else if (strcmp(
"version", s) == 0) {
1427 if (envopt)
goto noenvopt_long;
1430 else if (strcmp(
"verbose", s) == 0) {
1434 else if (strncmp(
"jit", s, 3) == 0) {
1437 setup_mjit_options(s + 3, &opt->mjit);
1439 rb_warn(
"MJIT support is disabled.");
1442 else if (strcmp(
"yydebug", s) == 0) {
1443 if (envopt)
goto noenvopt_long;
1449 else if (strcmp(
"help", s) == 0) {
1450 if (envopt)
goto noenvopt_long;
1456 long n = strtol(s, &e, 10);
1462 "invalid option --%s (-h will show valid options)", s);
1473 "invalid option -%c (-h will show valid options)",
1474 (
int)(
unsigned char)*s);
1489# undef is_option_end
1491# undef need_argument
1492# undef is_option_with_arg
1493# undef is_option_with_optarg
1498 if (warning) opt->
warning = warning;
1499 return argc0 -
argc;
1505ruby_init_prelude(
void)
1529 ruby_init_prelude();
1536opt_enc_index(
VALUE enc_name)
1550#define rb_progname (GET_VM()->progname)
1551#define rb_orig_progname (GET_VM()->orig_progname)
1567#define rb_define_readonly_boolean(name, val) \
1568 rb_define_virtual_variable((name), (val) ? true_value : false_value, 0)
1659setup_pager_env(
void)
1668 HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE);
1670 if (!GetConsoleMode(h, &m))
return 0;
1671# ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING
1672# define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x4
1677#elif !defined(HAVE_WORKING_FORK)
1678# define tty_enabled() 0
1712 int tty = isatty(1);
1713 const char *
const progname =
1715 origarg.argc > 0 && origarg.argv && origarg.argv[0] ? origarg.argv[0] :
1719 const char *pager_env =
getenv(
"RUBY_PAGER");
1720 if (!pager_env) pager_env =
getenv(
"PAGER");
1721 if (pager_env && *pager_env && isatty(0)) {
1722 const char *columns_env =
getenv(
"COLUMNS");
1723 if (columns_env) columns = atoi(columns_env);
1725#ifdef HAVE_WORKING_FORK
1728 rb_pid_t pid = rb_fork();
1733 else if (pid == 0) {
1751 int oldout = dup(1);
1752 int olderr = dup(2);
1753 int fd =
RFILE(port)->fptr->fd;
1757 usage(progname, 1, tty, columns);
1782 moreswitches(s, opt, 1);
1797 rb_warning(
"-K is specified; it is for 1.8 compatibility and may cause odd behavior");
1801 opt->mjit.on =
TRUE;
1828 char *path =
getenv(
"RUBYPATH");
1863 mjit_init(&opt->mjit);
1913 int modifiable =
FALSE;
1916 for (i = 0; i <
RARRAY_LEN(load_path); ++i) {
1918 int mark =
rb_attr_get(path, id_initial_load_path_mark) == path;
1921 if (newpath == path)
continue;
1924 if (!(path = copy_str(path, lenc, !mark)))
continue;
1926 if (mark)
rb_ivar_set(path, id_initial_load_path_mark, path);
1931 RARRAY_ASET(load_path, i, path);
1939 bool modified =
false;
1940 for (
long i = loaded_before_enc; i <
RARRAY_LEN(loaded_features); ++i) {
1942 if (!(path = copy_str(path,
IF_UTF8_PATH(uenc, lenc),
true)))
continue;
1944 RARRAY_ASET(loaded_features, i, path);
1953#define SET_COMPILE_OPTION(h, o, name) \
1954 rb_hash_aset((h), ID2SYM(rb_intern_const(#name)), \
1955 (FEATURE_SET_P(o->features, FEATURE_BIT(name)) ? Qtrue : Qfalse));
1959#undef SET_COMPILE_OPTION
1962 process_sflag(&opt->
sflag);
1975 if (ienc) eenc = ienc;
1992 f = open_load_file(script_name, &opt->
xflag);
1998 if (!dump)
return Qtrue;
2023 process_sflag(&opt->
sflag);
2027 printf(
"Syntax OK\n");
2028 dump &= ~DUMP_BIT(syntax);
2029 if (!dump)
return Qtrue;
2042 dump &= ~DUMP_BIT(parsetree)&~DUMP_BIT(parsetree_with_comment);
2066 const struct rb_block *base_block = toplevel_context(toplevel_binding);
2074 dump &= ~DUMP_BIT(insns);
2075 if (!dump)
return Qtrue;
2096 rb_exec_event_hook_script_compiled(ec, iseq, opt->
e_script);
2100 rb_exec_event_hook_script_compiled(ec, iseq,
Qnil);
2108warn_cr_in_shebang(
const char *
str,
long len)
2111 rb_warn(
"shebang line ending with \\r may cause problems");
2115#define warn_cr_in_shebang(str, len) (void)0
2127load_file_internal(
VALUE argp_v)
2140 CONST_ID(set_encoding,
"set_encoding");
2159 if (
len > 2 &&
str[0] ==
'#' &&
str[1] ==
'!') {
2160 if (line_start == 1) warn_cr_in_shebang(
str,
len);
2174 warn_cr_in_shebang(
str,
len);
2177 goto search_shebang;
2182 if (*
str ==
'\n') *
str-- =
'\0';
2183 if (*
str ==
'\r') *
str-- =
'\0';
2185 if ((p =
strstr(p,
" -")) != 0) {
2187 moreswitches(p + 1,
opt, 0);
2193 else if (!
NIL_P(c)) {
2208 else if (!
NIL_P(c)) {
2255open_load_file(
VALUE fname_v,
int *xflag)
2263 if (flen == 1 &&
fname[0] ==
'-') {
2270#if defined O_NONBLOCK && HAVE_FCNTL && !(O_NONBLOCK & O_ACCMODE)
2272# define MODE_TO_LOAD (O_RDONLY | O_NONBLOCK)
2273#elif defined O_NDELAY && HAVE_FCNTL && !(O_NDELAY & O_ACCMODE)
2274# define MODE_TO_LOAD (O_RDONLY | O_NDELAY)
2276# define MODE_TO_LOAD (O_RDONLY)
2279#if defined DOSISH || defined __CYGWIN__
2280# define isdirsep(x) ((x) == '/' || (x) == '\\')
2282 static const char exeext[] =
".exe";
2283 enum {extlen =
sizeof(exeext)-1};
2303#if defined HAVE_FCNTL && MODE_TO_LOAD != O_RDONLY
2305# define IS_SUPPORTED_OP(e) ((e) != ENOTSUP)
2307# define IS_SUPPORTED_OP(e) ((void)(e), 1)
2310 if (
fcntl(fd,
F_SETFL, 0) < 0 && IS_SUPPORTED_OP(e = errno)) {
2336restore_load_file(
VALUE arg)
2357 restore_load_file, (
VALUE)&arg);
2377 VALUE f = open_load_file(fname_v, &cmdline_options_init(&
opt)->xflag);
2378 return load_file(
parser, fname_v,
f, 0, &
opt);
2393proc_argv0(
VALUE process)
2420 return ruby_setproctitle(title);
2424ruby_setproctitle(
VALUE title)
2434 if (origarg.argv == 0)
2441external_str_new_cstr(
const char *p)
2512opt_W_getter(
ID id,
VALUE *dmy)
2529debug_getter(
ID id,
VALUE *dmy)
2579#if defined(USE_DLN_A_OUT)
2580 if (origarg.argc > 0 && origarg.argv)
2581 dln_argv0 = origarg.argv[0];
2583 dln_argv0 =
argv[0];
2586 for (i = 0; i <
argc; i++) {
2587 VALUE arg = external_str_new_cstr(
argv[i]);
2601 if (!origarg.argv || origarg.argc <= 0) {
2602 origarg.argc =
argc;
2603 origarg.argv =
argv;
2608 iseq = process_options(
argc,
argv, cmdline_options_init(&
opt));
2610#ifndef HAVE_SETPROCTITLE
2614 return (
void*)(
struct RData*)iseq;
2618fill_standard_fds(
void)
2620 int f0, f1, f2, fds[2];
2622 f0 =
fstat(0, &
buf) == -1 && errno == EBADF;
2623 f1 =
fstat(1, &
buf) == -1 && errno == EBADF;
2624 f2 =
fstat(2, &
buf) == -1 && errno == EBADF;
2626 if (pipe(fds) == 0) {
2635 if (pipe(fds) == 0) {
2637 if (f1 && fds[1] != 1)
2639 if (f2 && fds[1] != 2)
2641 if (fds[1] != 1 && fds[1] != 2)
2661 origarg.argc = *
argc;
2662 origarg.argv = *
argv;
2663#if defined(USE_DLN_A_OUT)
2664 dln_argv0 = origarg.argv[0];
2667 fill_standard_fds();
VALUE rb_ary_shift(VALUE ary)
VALUE rb_ary_push(VALUE ary, VALUE item)
void rb_ary_modify(VALUE ary)
VALUE rb_ary_replace(VALUE copy, VALUE orig)
VALUE rb_ary_tmp_new(long capa)
VALUE rb_ary_clear(VALUE ary)
int bits(struct state *s, int need)
Our own, locale independent, character handling routines.
#define rb_define_module_function(klass, mid, func, arity)
Defines klass#mid and makes it a module function.
#define rb_define_global_function(mid, func, arity)
Defines rb_mKernel #mid.
char * strchr(char *, char)
int rb_enc_dummy_p(rb_encoding *enc)
VALUE rb_enc_associate(VALUE obj, rb_encoding *enc)
rb_encoding * rb_utf8_encoding(void)
rb_encoding * rb_ascii8bit_encoding(void)
rb_encoding * rb_enc_from_index(int index)
rb_encoding * rb_default_internal_encoding(void)
void rb_enc_copy(VALUE obj1, VALUE obj2)
void rb_enc_set_default_internal(VALUE encoding)
rb_encoding * rb_default_external_encoding(void)
rb_encoding * rb_locale_encoding(void)
VALUE rb_enc_from_encoding(rb_encoding *encoding)
void rb_enc_set_default_external(VALUE encoding)
int rb_enc_find_index(const char *name)
char str[HTML_ESCAPE_MAX_LEN+1]
char * strrchr(const char *, const char)
void rb_vm_set_progname(VALUE filename)
#define RSTRING_LEN(string)
#define RSTRING_PTR(string)
int ruby_is_fd_loadable(int fd)
VALUE rb_str_encode_ospath(VALUE path)
char * rb_enc_path_last_separator(const char *path, const char *end, rb_encoding *enc)
VALUE rb_file_expand_path(VALUE fname, VALUE dname)
VALUE rb_realpath_internal(VALUE basedir, VALUE path, int strict)
void ruby_xfree(void *x)
Deallocates a storage instance.
void ruby_gc_set_params(void)
void rb_gc_register_address(VALUE *addr)
Inform the garbage collector that valptr points to a live Ruby object that should not be moved.
void rb_gc_register_mark_object(VALUE obj)
Inform the garbage collector that object is a live Ruby object that should not be moved.
VALUE rb_define_module(const char *name)
void ruby_set_argv(int argc, char **argv)
void ruby_incpush(const char *path)
void ruby_script(const char *name)
Sets the current script name to this value.
void ruby_set_script_name(VALUE name)
Sets the current script name to this value.
void ruby_init_loadpath(void)
void * ruby_process_options(int argc, char **argv)
void ruby_prog_init(void)
Defines built-in variables.
void rb_raise(VALUE exc, const char *fmt,...)
void rb_warning_category_update(unsigned int mask, unsigned int bits)
void rb_exc_raise(VALUE mesg)
Raises an exception in the current thread.
void rb_fatal(const char *fmt,...)
void rb_load_fail(VALUE path, const char *err)
void rb_warn(const char *fmt,...)
VALUE rb_exc_new_str(VALUE etype, VALUE str)
void rb_loaderror(const char *fmt,...)
VALUE rb_ensure(VALUE(*b_proc)(VALUE), VALUE data1, VALUE(*e_proc)(VALUE), VALUE data2)
An equivalent to ensure clause.
long rb_backtrace_length_limit
void rb_warning(const char *fmt,...)
VALUE rb_cObject
Object class.
VALUE rb_class_new_instance(int, const VALUE *, VALUE)
Allocates and initializes an instance of klass.
VALUE rb_obj_freeze(VALUE)
Make the object unmodifiable.
void ruby_show_copyright(void)
Prints the copyright notice of the CRuby interpreter to stdout.
void ruby_sysinit(int *argc, char ***argv)
Initializes the process for libruby.
void ruby_show_version(void)
Prints the version information of the CRuby interpreter to stdout.
void ruby_setenv(const char *name, const char *value)
VALUE rb_str_conv_enc(VALUE str, rb_encoding *from, rb_encoding *to)
#define ECONV_UNDEF_REPLACE
VALUE rb_str_conv_enc_opts(VALUE str, rb_encoding *from, rb_encoding *to, int ecflags, VALUE ecopts)
#define ENCODING_GET(obj)
#define ECONV_INVALID_REPLACE
VALUE rb_enc_interned_str(const char *, long, rb_encoding *)
#define ENC_CODERANGE_BROKEN
Thin wrapper to ruby/config.h.
@ RB_WARN_CATEGORY_DEPRECATED
@ RB_WARN_CATEGORY_ALL_BITS
@ RB_WARN_CATEGORY_EXPERIMENTAL
VALUE * rb_ruby_verbose_ptr(void)
VALUE * rb_ruby_debug_ptr(void)
VALUE rb_funcall(VALUE, ID, int,...)
Calls a method.
VALUE rb_funcall_passing_block(VALUE, ID, int, const VALUE *)
VALUE rb_io_getbyte(VALUE)
VALUE rb_io_fdopen(int, int, const char *)
VALUE rb_io_write(VALUE, VALUE)
void rb_update_max_fd(int fd)
int rb_cloexec_open(const char *pathname, int flags, mode_t mode)
VALUE rb_io_ungetbyte(VALUE, VALUE)
VALUE rb_lastline_get(void)
void rb_lastline_set(VALUE)
rb_pid_t rb_waitpid(rb_pid_t pid, int *status, int flags)
VALUE rb_f_exec(int, const VALUE *)
VALUE rb_reg_new(const char *, long, int)
VALUE rb_str_resize(VALUE, long)
#define rb_utf8_str_new_cstr(str)
#define rb_str_new_lit(str)
#define rb_str_new(str, len)
VALUE rb_str_cat(VALUE, const char *, long)
void rb_str_set_len(VALUE, long)
#define rb_external_str_new_cstr(str)
VALUE rb_str_tmp_new(long)
VALUE rb_str_subseq(VALUE, long, long)
#define rb_strlen_lit(str)
VALUE rb_str_new_frozen(VALUE)
void rb_str_modify_expand(VALUE, long)
#define rb_str_cat_cstr(buf, str)
#define rb_utf8_str_new(str, len)
#define rb_str_new_cstr(str)
void rb_thread_wait_fd(int)
VALUE rb_const_get(VALUE, ID)
void rb_const_set(VALUE, ID, VALUE)
VALUE rb_attr_get(VALUE, ID)
VALUE rb_ivar_set(VALUE, ID, VALUE)
VALUE rb_const_remove(VALUE, ID)
ID rb_intern(const char *)
VALUE rb_gv_set(const char *, VALUE)
void rb_define_global_const(const char *, VALUE)
rb_gvar_setter_t rb_gvar_readonly_setter
char * strstr(const char *, const char *)
void setproctitle(const char *fmt,...)
void ruby_each_words(const char *, void(*)(const char *, int, void *), void *)
#define scan_oct(s, l, e)
Internal header aggregating init functions.
Internal header for File.
void ruby_set_inplace_mode(const char *)
int rb_gc_for_fd(int err)
void rb_stdio_set_default_encoding(void)
VALUE rb_io_popen(VALUE pname, VALUE pmode, VALUE env, VALUE opt)
Internal header for require.
VALUE rb_get_expanded_load_path(void)
Internal header corresponding missing.
void ruby_init_setproctitle(int argc, char *argv[])
Internal header for Object.
Internal header for the parser.
Internal header for Process.
int rb_enc_str_coderange_scan(VALUE str, rb_encoding *enc)
void rb_gvar_ractor_local(const char *name)
VALUE rb_vm_top_self(void)
typedef int(ZCALLBACK *close_file_func) OF((voidpf opaque
rb_iseq_t * rb_iseq_new_main(const rb_ast_body_t *ast, VALUE path, VALUE realpath, const rb_iseq_t *parent)
VALUE rb_iseq_disasm(const rb_iseq_t *iseq)
Internal header for $LOAD_PATH.
const char ruby_exec_prefix[]
const char ruby_initial_load_paths[]
#define MEMZERO(p, type, n)
#define MEMMOVE(p1, p2, type, n)
struct mjit_options mjit_opts
void rb_define_hooked_variable(const char *q, VALUE *w, type *e, void_type *r)
Define a function-backended global variable.
VALUE type(ANYARGS)
ANYARGS-ed function type.
void rb_define_virtual_variable(const char *q, type *w, void_type *e)
Define a function-backended global variable.
VALUE rb_parser_dump_tree(const NODE *node, int comment)
void rb_ast_dispose(rb_ast_t *ast)
#define RARRAY_CONST_PTR(s)
#define RARRAY_AREF(a, i)
VALUE rb_parser_new(void)
rb_ast_t * rb_parser_compile_string(VALUE vparser, const char *f, VALUE s, int line)
rb_ast_t * rb_parser_compile_string_path(VALUE vparser, VALUE f, VALUE s, int line)
void rb_parser_set_options(VALUE vparser, int print, int loop, int chomp, int split)
VALUE rb_parser_set_context(VALUE vparser, const struct rb_iseq_struct *base, int main)
VALUE rb_parser_encoding(VALUE vparser)
VALUE rb_parser_set_yydebug(VALUE self, VALUE flag)
VALUE rb_parser_end_seen_p(VALUE vparser)
rb_ast_t * rb_parser_compile_file_path(VALUE vparser, VALUE fname, VALUE file, int start)
#define StringValuePtr(v)
#define RSTRING_GETMEM(str, ptrvar, lenvar)
#define RSTRING_EMBED_LEN_MAX
#define StringValueCStr(v)
const char * rb_obj_classname(VALUE)
#define INITIAL_LOAD_PATH_MARK
#define str_conv_enc(str, from, to)
int ruby_env_debug_option(const char *str, int len, void *arg)
#define set_source_encoding_once(opt, e, elen)
#define src_encoding_index
void ruby_incpush_expand(const char *path)
#define rb_define_readonly_boolean(name, val)
#define EACH_DEBUG_FEATURES(X, SEP)
#define IF_UTF8_PATH(t, f)
#define is_option_with_arg(name, allow_hyphen, allow_envopt)
@ feature_debug_flag_first
@ feature_debug_flag_begin
void Init_builtin_features(void)
#define RUBY_RELATIVE(path, len)
#define SET_WHEN_DEBUG(bit)
VALUE ruby_archlibdir_path
#define FEATURE_SET_RESTORE(feat, save)
#define DEFINE_DEBUG_FEATURE(bit)
#define is_option_with_optarg(name, allow_hyphen, allow_envopt, needs_arg, next_arg)
#define FEATURE_SET_TO(feat, bit_mask, bit_set)
#define FEATURE_SET(feat, bits)
#define NAME_MATCH_P(name, str, len)
void * rb_load_file_str(VALUE fname_v)
#define DEFINE_FEATURE(bit)
#define EACH_FEATURES(X, SEP)
void Init_ruby_description(void)
#define SET_COMPILE_OPTION(h, o, name)
#define SET_WHEN_DUMP(bit)
#define M(shortopt, longopt, desc)
void rb_call_builtin_inits(void)
void * rb_parser_load_file(VALUE parser, VALUE fname_v)
#define set_internal_encoding_once(opt, e, elen)
#define EACH_DUMPS(X, SEP)
#define set_encoding_part(type)
const int ruby_patchlevel
void * rb_load_file(const char *fname)
void ruby_push_include(const char *path, VALUE(*filter)(VALUE))
#define DEFAULT_RUBYGEMS_ENABLED
#define set_external_encoding_once(opt, e, elen)
#define LITERAL_NAME_ELEMENT(name)
VALUE rb_sprintf(const char *,...)
size_t strlen(const char *)
ruby_cmdline_options_t * opt
const struct rb_block block
VALUE loaded_features_snapshot
struct ruby_cmdline_options::@161 ext
struct ruby_cmdline_options::@161 intern
struct ruby_cmdline_options::@161 src
struct ruby_cmdline_options::@161::@162 enc
#define GetBindingPtr(obj, ptr)
VALUE rb_readlink(VALUE path, rb_encoding *resultenc)
#define ENABLE_VIRTUAL_TERMINAL_PROCESSING
void rb_w32_sysinit(int *, char ***)