summaryrefslogtreecommitdiff
path: root/trunk/ruby.c
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/ruby.c')
-rw-r--r--trunk/ruby.c1584
1 files changed, 0 insertions, 1584 deletions
diff --git a/trunk/ruby.c b/trunk/ruby.c
deleted file mode 100644
index 5a51bbb52a..0000000000
--- a/trunk/ruby.c
+++ /dev/null
@@ -1,1584 +0,0 @@
-/**********************************************************************
-
- ruby.c -
-
- $Author$
- created at: Tue Aug 10 12:47:31 JST 1993
-
- Copyright (C) 1993-2007 Yukihiro Matsumoto
- Copyright (C) 2000 Network Applied Communication Laboratory, Inc.
- Copyright (C) 2000 Information-technology Promotion Agency, Japan
-
-**********************************************************************/
-
-#ifdef __CYGWIN__
-#include <windows.h>
-#include <sys/cygwin.h>
-#endif
-#ifdef _WIN32_WCE
-#include <winsock.h>
-#include "ruby/wince.h"
-#endif
-#include "ruby/ruby.h"
-#include "ruby/node.h"
-#include "ruby/encoding.h"
-#include "eval_intern.h"
-#include "dln.h"
-#include <stdio.h>
-#include <sys/types.h>
-#include <ctype.h>
-
-#ifdef __hpux
-#include <sys/pstat.h>
-#endif
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#if defined(HAVE_FCNTL_H)
-#include <fcntl.h>
-#elif defined(HAVE_SYS_FCNTL_H)
-#include <sys/fcntl.h>
-#endif
-#ifdef HAVE_SYS_PARAM_H
-# include <sys/param.h>
-#endif
-#ifndef MAXPATHLEN
-# define MAXPATHLEN 1024
-#endif
-
-#if defined(__MACOS__) && defined(__MWERKS__)
-#include <console.h>
-#endif
-
-#include "ruby/util.h"
-
-#ifndef HAVE_STDLIB_H
-char *getenv();
-#endif
-
-VALUE rb_parser_get_yydebug(VALUE);
-VALUE rb_parser_set_yydebug(VALUE, VALUE);
-
-const char *ruby_get_inplace_mode(void);
-void ruby_set_inplace_mode(const char *);
-
-#define DISABLE_BIT(bit) (1U << disable_##bit)
-enum disable_flag_bits {
- disable_gems,
- disable_rubyopt
-};
-
-#define DUMP_BIT(bit) (1U << dump_##bit)
-enum dump_flag_bits {
- dump_insns
-};
-
-struct cmdline_options {
- int sflag, xflag;
- int do_loop, do_print;
- int do_check, do_line;
- int do_split, do_search;
- int usage;
- int version;
- int copyright;
- unsigned int disable;
- int verbose;
- int yydebug;
- unsigned int setids;
- unsigned int dump;
- const char *script;
- VALUE script_name;
- VALUE e_script;
- struct {
- struct {
- VALUE name;
- int index;
- } enc;
- } src, ext;
- VALUE req_list;
-};
-
-static void init_ids(struct cmdline_options *);
-
-#define src_encoding_index GET_VM()->src_encoding_index
-
-static struct cmdline_options *
-cmdline_options_init(struct cmdline_options *opt)
-{
- MEMZERO(opt, *opt, 1);
- init_ids(opt);
- opt->src.enc.index = src_encoding_index;
- return opt;
-}
-
-struct cmdline_arguments {
- int argc;
- char **argv;
- struct cmdline_options *opt;
-};
-
-static NODE *load_file(VALUE, const char *, int, struct cmdline_options *);
-static void forbid_setid(const char *, struct cmdline_options *);
-#define forbid_setid(s) forbid_setid(s, opt)
-
-static struct {
- int argc;
- char **argv;
-#if !defined(PSTAT_SETCMD) && !defined(HAVE_SETPROCTITLE)
- int len;
-#endif
-} origarg;
-
-static void
-usage(const char *name)
-{
- /* This message really ought to be max 23 lines.
- * Removed -h because the user already knows that option. Others? */
-
- static const char *const usage_msg[] = {
- "-0[octal] specify record separator (\\0, if no argument)",
- "-a autosplit mode with -n or -p (splits $_ into $F)",
- "-c check syntax only",
- "-Cdirectory cd to directory, before executing your script",
- "-d set debugging flags (set $DEBUG to true)",
- "-e 'command' one line of script. Several -e's allowed. Omit [programfile]",
- "-Eencoding specifies the character encoding for the program codes",
- "-Fpattern split() pattern for autosplit (-a)",
- "-i[extension] edit ARGV files in place (make backup if extension supplied)",
- "-Idirectory specify $LOAD_PATH directory (may be used more than once)",
- "-l enable line ending processing",
- "-n assume 'while gets(); ... end' loop around your script",
- "-p assume loop like -n but print line also like sed",
- "-rlibrary require the library, before executing your script",
- "-s enable some switch parsing for switches after script name",
- "-S look for the script using PATH environment variable",
- "-T[level] turn on tainting checks",
- "-v print version number, then turn on verbose mode",
- "-w turn warnings on for your script",
- "-W[level] set warning level; 0=silence, 1=medium, 2=verbose (default)",
- "-x[directory] strip off text before #!ruby line and perhaps cd to directory",
- "--copyright print the copyright",
- "--version print the version",
- NULL
- };
- const char *const *p = usage_msg;
-
- printf("Usage: %s [switches] [--] [programfile] [arguments]\n", name);
- while (*p)
- printf(" %s\n", *p++);
-}
-
-VALUE rb_get_load_path(void);
-
-#ifndef CharNext /* defined as CharNext[AW] on Windows. */
-#define CharNext(p) ((p) + mblen(p, RUBY_MBCHAR_MAXSIZE))
-#endif
-
-#if defined DOSISH || defined __CYGWIN__
-static inline void
-translate_char(char *p, int from, int to)
-{
- while (*p) {
- if ((unsigned char)*p == from)
- *p = to;
- p = CharNext(p);
- }
-}
-#endif
-
-#if defined _WIN32 || defined __CYGWIN__ || defined __DJGPP__
-static VALUE
-rubylib_mangled_path(const char *s, unsigned int l)
-{
- static char *newp, *oldp;
- static int newl, oldl, notfound;
- char *ptr;
- VALUE ret;
-
- if (!newp && !notfound) {
- newp = getenv("RUBYLIB_PREFIX");
- if (newp) {
- oldp = newp = strdup(newp);
- while (*newp && !ISSPACE(*newp) && *newp != ';') {
- newp = CharNext(newp); /* Skip digits. */
- }
- oldl = newp - oldp;
- while (*newp && (ISSPACE(*newp) || *newp == ';')) {
- newp = CharNext(newp); /* Skip whitespace. */
- }
- newl = strlen(newp);
- if (newl == 0 || oldl == 0) {
- rb_fatal("malformed RUBYLIB_PREFIX");
- }
- translate_char(newp, '\\', '/');
- }
- else {
- notfound = 1;
- }
- }
- if (!newp || l < oldl || STRNCASECMP(oldp, s, oldl) != 0) {
- return rb_str_new(s, l);
- }
- ret = rb_str_new(0, l + newl - oldl);
- ptr = RSTRING_PTR(ret);
- memcpy(ptr, newp, newl);
- memcpy(ptr + newl, s + oldl, l - oldl);
- ptr[l + newl - oldl] = 0;
- return ret;
-}
-
-static VALUE
-rubylib_mangled_path2(const char *s)
-{
- return rubylib_mangled_path(s, strlen(s));
-}
-#else
-#define rubylib_mangled_path rb_str_new
-#define rubylib_mangled_path2 rb_str_new2
-#endif
-
-static void
-push_include(const char *path, VALUE (*filter)(VALUE))
-{
- const char sep = PATH_SEP_CHAR;
- const char *p, *s;
- VALUE load_path = GET_VM()->load_path;
-
- p = path;
- while (*p) {
- while (*p == sep)
- p++;
- if (!*p) break;
- for (s = p; *s && *s != sep; s = CharNext(s));
- rb_ary_push(load_path, (*filter)(rubylib_mangled_path(p, s - p)));
- p = s;
- }
-}
-
-#ifdef __CYGWIN__
-static void
-push_include_cygwin(const char *path, VALUE (*filter)(VALUE))
-{
- const char *p, *s;
- char rubylib[FILENAME_MAX];
- VALUE buf = 0;
-
- p = path;
- while (*p) {
- unsigned int len;
- while (*p == ';')
- p++;
- if (!*p) break;
- for (s = p; *s && *s != ';'; s = CharNext(s));
- len = s - p;
- if (*s) {
- if (!buf) {
- buf = rb_str_new(p, len);
- p = RSTRING_PTR(buf);
- }
- else {
- rb_str_resize(buf, len);
- p = strncpy(RSTRING_PTR(buf), p, len);
- }
- }
- if (cygwin_conv_to_posix_path(p, rubylib) == 0)
- p = rubylib;
- push_include(p, filter);
- if (!*s) break;
- p = s + 1;
- }
-}
-
-#define push_include push_include_cygwin
-#endif
-
-void
-ruby_push_include(const char *path, VALUE (*filter)(VALUE))
-{
- if (path == 0)
- return;
- push_include(path, filter);
-}
-
-static VALUE
-identical_path(VALUE path)
-{
- return path;
-}
-
-void
-ruby_incpush(const char *path)
-{
- ruby_push_include(path, identical_path);
-}
-
-static VALUE
-expand_include_path(VALUE path)
-{
- char *p = RSTRING_PTR(path);
- if (!p)
- return path;
- if (*p == '.' && p[1] == '/')
- return path;
- return rb_file_expand_path(path, Qnil);
-}
-
-void
-ruby_incpush_expand(const char *path)
-{
- ruby_push_include(path, expand_include_path);
-}
-
-#if defined DOSISH || defined __CYGWIN__
-#define LOAD_RELATIVE 1
-#endif
-
-#if defined _WIN32 || defined __CYGWIN__
-static HMODULE libruby;
-
-BOOL WINAPI
-DllMain(HINSTANCE dll, DWORD reason, LPVOID reserved)
-{
- if (reason == DLL_PROCESS_ATTACH)
- libruby = dll;
- return TRUE;
-}
-#endif
-
-void
-ruby_init_loadpath(void)
-{
- VALUE load_path;
-#if defined LOAD_RELATIVE
- char libpath[MAXPATHLEN + 1];
- char *p;
- int rest;
-
-#if defined _WIN32 || defined __CYGWIN__
- GetModuleFileName(libruby, libpath, sizeof libpath);
-#elif defined(DJGPP)
- extern char *__dos_argv0;
- strncpy(libpath, __dos_argv0, sizeof(libpath) - 1);
-#elif defined(__human68k__)
- extern char **_argv;
- strncpy(libpath, _argv[0], sizeof(libpath) - 1);
-#elif defined(__EMX__)
- _execname(libpath, sizeof(libpath) - 1);
-#endif
-
- libpath[sizeof(libpath) - 1] = '\0';
-#if defined DOSISH
- translate_char(libpath, '\\', '/');
-#elif defined __CYGWIN__
- {
- char rubylib[FILENAME_MAX];
- cygwin_conv_to_posix_path(libpath, rubylib);
- strncpy(libpath, rubylib, sizeof(libpath));
- }
-#endif
- p = strrchr(libpath, '/');
- if (p) {
- *p = 0;
- if (p - libpath > 3 && !STRCASECMP(p - 4, "/bin")) {
- p -= 4;
- *p = 0;
- }
- }
- else {
- strcpy(libpath, ".");
- p = libpath + 1;
- }
-
- rest = sizeof(libpath) - 1 - (p - libpath);
-
-#define RUBY_RELATIVE(path) (strncpy(p, (path), rest), libpath)
-#else
-#define RUBY_RELATIVE(path) (path)
-#endif
-#define incpush(path) rb_ary_push(load_path, rubylib_mangled_path2(path))
- load_path = GET_VM()->load_path;
-
- if (rb_safe_level() == 0) {
- ruby_incpush(getenv("RUBYLIB"));
- }
-
-#ifdef RUBY_SEARCH_PATH
- incpush(RUBY_RELATIVE(RUBY_SEARCH_PATH));
-#endif
-
- incpush(RUBY_RELATIVE(RUBY_SITE_LIB2));
-#ifdef RUBY_SITE_THIN_ARCHLIB
- incpush(RUBY_RELATIVE(RUBY_SITE_THIN_ARCHLIB));
-#endif
- incpush(RUBY_RELATIVE(RUBY_SITE_ARCHLIB));
- incpush(RUBY_RELATIVE(RUBY_SITE_LIB));
-
- incpush(RUBY_RELATIVE(RUBY_VENDOR_LIB2));
-#ifdef RUBY_VENDOR_THIN_ARCHLIB
- incpush(RUBY_RELATIVE(RUBY_VENDOR_THIN_ARCHLIB));
-#endif
- incpush(RUBY_RELATIVE(RUBY_VENDOR_ARCHLIB));
- incpush(RUBY_RELATIVE(RUBY_VENDOR_LIB));
-
- incpush(RUBY_RELATIVE(RUBY_LIB));
-#ifdef RUBY_THIN_ARCHLIB
- incpush(RUBY_RELATIVE(RUBY_THIN_ARCHLIB));
-#endif
- incpush(RUBY_RELATIVE(RUBY_ARCHLIB));
-
- if (rb_safe_level() == 0) {
- incpush(".");
- }
-}
-
-
-static void
-add_modules(struct cmdline_options *opt, const char *mod)
-{
- VALUE list = opt->req_list;
-
- if (!list) {
- opt->req_list = list = rb_ary_new();
- RBASIC(list)->klass = 0;
- }
- rb_ary_push(list, rb_obj_freeze(rb_str_new2(mod)));
-}
-
-extern void Init_ext(void);
-extern VALUE rb_vm_top_self(void);
-
-static void
-require_libraries(struct cmdline_options *opt)
-{
- VALUE list = opt->req_list;
- ID require;
-
- Init_ext(); /* should be called here for some reason :-( */
- CONST_ID(require, "require");
- while (list && RARRAY_LEN(list) > 0) {
- VALUE feature = rb_ary_shift(list);
- rb_funcall2(rb_vm_top_self(), require, 1, &feature);
- }
- opt->req_list = 0;
-}
-
-static void
-process_sflag(struct cmdline_options *opt)
-{
- if (opt->sflag) {
- long n;
- VALUE *args;
- VALUE argv = rb_argv;
-
- n = RARRAY_LEN(argv);
- args = RARRAY_PTR(argv);
- while (n > 0) {
- VALUE v = *args++;
- char *s = StringValuePtr(v);
- char *p;
- int hyphen = Qfalse;
-
- if (s[0] != '-')
- break;
- n--;
- if (s[1] == '-' && s[2] == '\0')
- break;
-
- v = Qtrue;
- /* check if valid name before replacing - with _ */
- for (p = s + 1; *p; p++) {
- if (*p == '=') {
- *p++ = '\0';
- v = rb_str_new2(p);
- break;
- }
- if (*p == '-') {
- hyphen = Qtrue;
- }
- else if (*p != '_' && !ISALNUM(*p)) {
- VALUE name_error[2];
- name_error[0] =
- rb_str_new2("invalid name for global variable - ");
- if (!(p = strchr(p, '='))) {
- rb_str_cat2(name_error[0], s);
- }
- else {
- rb_str_cat(name_error[0], s, p - s);
- }
- name_error[1] = args[-1];
- rb_exc_raise(rb_class_new_instance(2, name_error, rb_eNameError));
- }
- }
- s[0] = '$';
- if (hyphen) {
- for (p = s + 1; *p; ++p) {
- if (*p == '-')
- *p = '_';
- }
- }
- rb_gv_set(s, v);
- }
- n = RARRAY_LEN(argv) - n;
- while (n--) {
- rb_ary_shift(argv);
- }
- }
- opt->sflag = 0;
-}
-
-NODE *rb_parser_append_print(VALUE, NODE *);
-NODE *rb_parser_while_loop(VALUE, NODE *, int, int);
-static int proc_options(int argc, char **argv, struct cmdline_options *opt);
-
-static char *
-moreswitches(const char *s, struct cmdline_options *opt)
-{
- int argc;
- char *argv[3];
- const char *p = s;
-
- argc = 2;
- argv[0] = argv[2] = 0;
- while (*s && !ISSPACE(*s))
- s++;
- argv[1] = ALLOCA_N(char, s - p + 2);
- argv[1][0] = '-';
- strncpy(argv[1] + 1, p, s - p);
- argv[1][s - p + 1] = '\0';
- proc_options(argc, argv, opt);
- while (*s && ISSPACE(*s))
- s++;
- return (char *)s;
-}
-
-#define NAME_MATCH_P(name, str, len) \
- ((len) < sizeof(name) && strncmp((str), name, (len)) == 0)
-
-#define UNSET_WHEN(name, bit, str, len) \
- if (NAME_MATCH_P(name, str, len)) { \
- *(unsigned int *)arg &= ~(bit); \
- return; \
- }
-
-#define SET_WHEN(name, bit, str, len) \
- if (NAME_MATCH_P(name, str, len)) { \
- *(unsigned int *)arg |= (bit); \
- return; \
- }
-
-static void
-enable_option(const char *str, int len, void *arg)
-{
-#define UNSET_WHEN_DISABLE(bit) UNSET_WHEN(#bit, DISABLE_BIT(bit), str, len)
- UNSET_WHEN_DISABLE(gems);
- UNSET_WHEN_DISABLE(rubyopt);
- if (NAME_MATCH_P("all", str, len)) {
- *(unsigned int *)arg = 0U;
- return;
- }
- rb_warn("unknown argument for --enable: `%.*s'", len, str);
-}
-
-static void
-disable_option(const char *str, int len, void *arg)
-{
-#define SET_WHEN_DISABLE(bit) SET_WHEN(#bit, DISABLE_BIT(bit), str, len)
- SET_WHEN_DISABLE(gems);
- SET_WHEN_DISABLE(rubyopt);
- if (NAME_MATCH_P("all", str, len)) {
- *(unsigned int *)arg = ~0U;
- return;
- }
- rb_warn("unknown argument for --disable: `%.*s'", len, str);
-}
-
-static void
-dump_option(const char *str, int len, void *arg)
-{
-#define SET_WHEN_DUMP(bit) SET_WHEN(#bit, DUMP_BIT(bit), str, len)
- SET_WHEN_DUMP(insns);
- rb_warn("don't know how to dump `%.*s', (insns)", len, str);
-}
-
-static int
-proc_options(int argc, char **argv, struct cmdline_options *opt)
-{
- int n, argc0 = argc;
- const char *s;
-
- if (argc == 0)
- return 0;
-
- for (argc--, argv++; argc > 0; argc--, argv++) {
- if (argv[0][0] != '-' || !argv[0][1])
- break;
-
- s = argv[0] + 1;
- reswitch:
- switch (*s) {
- case 'a':
- opt->do_split = Qtrue;
- s++;
- goto reswitch;
-
- case 'p':
- opt->do_print = Qtrue;
- /* through */
- case 'n':
- opt->do_loop = Qtrue;
- s++;
- goto reswitch;
-
- case 'd':
- ruby_debug = Qtrue;
- ruby_verbose = Qtrue;
- s++;
- goto reswitch;
-
- case 'y':
- opt->yydebug = 1;
- s++;
- goto reswitch;
-
- case 'v':
- if (opt->verbose) {
- s++;
- goto reswitch;
- }
- ruby_show_version();
- opt->verbose = 1;
- case 'w':
- ruby_verbose = Qtrue;
- s++;
- goto reswitch;
-
- case 'W':
- {
- int numlen;
- int v = 2; /* -W as -W2 */
-
- if (*++s) {
- v = scan_oct(s, 1, &numlen);
- if (numlen == 0)
- v = 1;
- s += numlen;
- }
- switch (v) {
- case 0:
- ruby_verbose = Qnil;
- break;
- case 1:
- ruby_verbose = Qfalse;
- break;
- default:
- ruby_verbose = Qtrue;
- break;
- }
- }
- goto reswitch;
-
- case 'c':
- opt->do_check = Qtrue;
- s++;
- goto reswitch;
-
- case 's':
- forbid_setid("-s");
- opt->sflag = 1;
- s++;
- goto reswitch;
-
- case 'h':
- usage(origarg.argv[0]);
- rb_exit(EXIT_SUCCESS);
- break;
-
- case 'l':
- opt->do_line = Qtrue;
- rb_output_rs = rb_rs;
- s++;
- goto reswitch;
-
- case 'S':
- forbid_setid("-S");
- opt->do_search = Qtrue;
- s++;
- goto reswitch;
-
- case 'e':
- forbid_setid("-e");
- if (!*++s) {
- s = argv[1];
- argc--, argv++;
- }
- if (!s) {
- rb_raise(rb_eRuntimeError, "no code specified for -e");
- }
- if (!opt->e_script) {
- opt->e_script = rb_str_new(0, 0);
- if (opt->script == 0)
- opt->script = "-e";
- }
- rb_str_cat2(opt->e_script, s);
- rb_str_cat2(opt->e_script, "\n");
- break;
-
- case 'r':
- forbid_setid("-r");
- if (*++s) {
- add_modules(opt, s);
- }
- else if (argv[1]) {
- add_modules(opt, argv[1]);
- argc--, argv++;
- }
- break;
-
- case 'i':
- forbid_setid("-i");
- ruby_set_inplace_mode(s + 1);
- break;
-
- case 'x':
- opt->xflag = Qtrue;
- s++;
- if (*s && chdir(s) < 0) {
- rb_fatal("Can't chdir to %s", s);
- }
- break;
-
- case 'C':
- case 'X':
- s++;
- if (!*s) {
- s = argv[1];
- argc--, argv++;
- }
- if (!s || !*s) {
- rb_fatal("Can't chdir");
- }
- if (chdir(s) < 0) {
- rb_fatal("Can't chdir to %s", s);
- }
- break;
-
- case 'F':
- if (*++s) {
- rb_fs = rb_reg_new(s, strlen(s), 0);
- }
- break;
-
- case 'E':
- if (!*++s) goto next_encoding;
- goto encoding;
-
- case 'K':
- if (*++s) {
- const char *enc_name = 0;
- switch (*s) {
- case 'E': case 'e':
- enc_name = "EUC-JP";
- break;
- case 'S': case 's':
- enc_name = "Windows-31J";
- break;
- case 'U': case 'u':
- enc_name = "UTF-8";
- break;
- case 'N': case 'n': case 'A': case 'a':
- enc_name = "ASCII-8BIT";
- break;
- }
- if (enc_name) {
- opt->src.enc.name = rb_str_new2(enc_name);
- opt->ext.enc.name = opt->src.enc.name;
- }
- s++;
- }
- goto reswitch;
-
- case 'T':
- {
- int numlen;
- int v = 1;
-
- if (*++s) {
- v = scan_oct(s, 2, &numlen);
- if (numlen == 0)
- v = 1;
- s += numlen;
- }
- rb_set_safe_level(v);
- }
- goto reswitch;
-
- case 'I':
- forbid_setid("-I");
- if (*++s)
- ruby_incpush_expand(s);
- else if (argv[1]) {
- ruby_incpush_expand(argv[1]);
- argc--, argv++;
- }
- break;
-
- case '0':
- {
- int numlen;
- int v;
- char c;
-
- v = scan_oct(s, 4, &numlen);
- s += numlen;
- if (v > 0377)
- rb_rs = Qnil;
- else if (v == 0 && numlen >= 2) {
- rb_rs = rb_str_new2("\n\n");
- }
- else {
- c = v & 0xff;
- rb_rs = rb_str_new(&c, 1);
- }
- }
- goto reswitch;
-
- case '-':
- if (!s[1] || (s[1] == '\r' && !s[2])) {
- argc--, argv++;
- goto switch_end;
- }
- s++;
- if (strcmp("copyright", s) == 0)
- opt->copyright = 1;
- else if (strcmp("debug", s) == 0) {
- ruby_debug = Qtrue;
- ruby_verbose = Qtrue;
- }
- else if (strncmp("enable", s, n = 6) == 0 &&
- (!s[n] || s[n] == '-' || s[n] == '=')) {
- if ((s += n + 1)[-1] ? !*s : (!--argc || !(s = *++argv))) {
- rb_raise(rb_eRuntimeError, "missing argument for --enable");
- }
- ruby_each_words(s, enable_option, &opt->disable);
- }
- else if (strncmp("disable", s, n = 7) == 0 &&
- (!s[n] || s[n] == '-' || s[n] == '=')) {
- if ((s += n + 1)[-1] ? !*s : (!--argc || !(s = *++argv))) {
- rb_raise(rb_eRuntimeError, "missing argument for --disable");
- }
- ruby_each_words(s, disable_option, &opt->disable);
- }
- else if (strncmp("encoding", s, n = 8) == 0 && (!s[n] || s[n] == '=')) {
- s += n;
- if (!*s++) {
- next_encoding:
- if (!--argc || !(s = *++argv)) {
- rb_raise(rb_eRuntimeError, "missing argument for --encoding");
- }
- }
- encoding:
- opt->ext.enc.name = rb_str_new2(s);
- }
- else if (strcmp("version", s) == 0)
- opt->version = 1;
- else if (strcmp("verbose", s) == 0) {
- opt->verbose = 1;
- ruby_verbose = Qtrue;
- }
- else if (strcmp("yydebug", s) == 0)
- opt->yydebug = 1;
- else if (strncmp("dump", s, n = 4) == 0 && (!s[n] || s[n] == '=')) {
- if (!(s += n + 1)[-1] && (!--argc || !(s = *++argv)) && *s != '-') break;
- ruby_each_words(s, dump_option, &opt->dump);
- }
- else if (strcmp("help", s) == 0) {
- usage(origarg.argv[0]);
- rb_exit(EXIT_SUCCESS);
- }
- else {
- rb_raise(rb_eRuntimeError,
- "invalid option --%s (-h will show valid options)", s);
- }
- break;
-
- case '\r':
- if (!s[1])
- break;
-
- default:
- {
- if (ISPRINT(*s)) {
- rb_raise(rb_eRuntimeError,
- "invalid option -%c (-h will show valid options)",
- (int)(unsigned char)*s);
- }
- else {
- rb_raise(rb_eRuntimeError,
- "invalid option -\\x%02X (-h will show valid options)",
- (int)(unsigned char)*s);
- }
- }
- goto switch_end;
-
- case 0:
- break;
- }
- }
-
- switch_end:
- return argc0 - argc;
-}
-
-void Init_prelude(void);
-
-static void
-ruby_init_gems(int enable)
-{
- if (enable) rb_define_module("Gem");
- Init_prelude();
-}
-
-static int
-opt_enc_index(VALUE enc_name)
-{
- const char *s = RSTRING_PTR(enc_name);
- int i = rb_enc_find_index(s);
-
- if (i < 0) {
- rb_raise(rb_eRuntimeError, "unknown encoding name - %s", s);
- }
- else if (rb_enc_dummy_p(rb_enc_from_index(i))) {
- rb_raise(rb_eRuntimeError, "dummy encoding is not acceptable - %s ", s);
- }
- return i;
-}
-
-#define rb_progname (GET_VM()->progname)
-VALUE rb_argv0;
-
-static VALUE
-process_options(VALUE arg)
-{
- struct cmdline_arguments *argp = (struct cmdline_arguments *)arg;
- struct cmdline_options *opt = argp->opt;
- int argc = argp->argc;
- char **argv = argp->argv;
- NODE *tree = 0;
- VALUE parser;
- VALUE iseq;
- rb_encoding *enc, *lenc;
- const char *s;
- char fbuf[MAXPATHLEN];
- int i = proc_options(argc, argv, opt);
- int safe;
-
- argc -= i;
- argv += i;
-
- if (!(opt->disable & DISABLE_BIT(rubyopt)) &&
- rb_safe_level() == 0 && (s = getenv("RUBYOPT"))) {
- VALUE src_enc_name = opt->src.enc.name;
- VALUE ext_enc_name = opt->ext.enc.name;
-
- while (ISSPACE(*s))
- s++;
- if (*s == 'T' || (*s == '-' && *(s + 1) == 'T')) {
- int numlen;
- int v = 1;
-
- if (*s != 'T')
- ++s;
- if (*++s) {
- v = scan_oct(s, 2, &numlen);
- if (numlen == 0)
- v = 1;
- }
- rb_set_safe_level(v);
- }
- else {
- while (s && *s) {
- if (*s == '-') {
- s++;
- if (ISSPACE(*s)) {
- do {
- s++;
- } while (ISSPACE(*s));
- continue;
- }
- }
- if (!*s)
- break;
- if (!strchr("EIdvwWrK", *s))
- rb_raise(rb_eRuntimeError,
- "invalid switch in RUBYOPT: -%c", *s);
- s = moreswitches(s, opt);
- }
- }
- if (src_enc_name)
- opt->src.enc.name = src_enc_name;
- if (ext_enc_name)
- opt->ext.enc.name = ext_enc_name;
- }
-
- if (opt->version) {
- ruby_show_version();
- return Qtrue;
- }
- if (opt->copyright) {
- ruby_show_copyright();
- }
-
- if (rb_safe_level() >= 4) {
- OBJ_TAINT(rb_argv);
- OBJ_TAINT(GET_VM()->load_path);
- }
-
- if (!opt->e_script) {
- if (argc == 0) { /* no more args */
- if (opt->verbose)
- return Qtrue;
- opt->script = "-";
- }
- else {
- opt->script = argv[0];
- if (opt->script[0] == '\0') {
- opt->script = "-";
- }
- else if (opt->do_search) {
- char *path = getenv("RUBYPATH");
-
- opt->script = 0;
- if (path) {
- opt->script = dln_find_file_r(argv[0], path, fbuf, sizeof(fbuf));
- }
- if (!opt->script) {
- opt->script = dln_find_file_r(argv[0], getenv(PATH_ENV), fbuf, sizeof(fbuf));
- }
- if (!opt->script)
- opt->script = argv[0];
- }
- argc--;
- argv++;
- }
- }
-
- ruby_script(opt->script);
-#if defined DOSISH || defined __CYGWIN__
- translate_char(RSTRING_PTR(rb_progname), '\\', '/');
-#endif
- opt->script_name = rb_str_new4(rb_progname);
- opt->script = RSTRING_PTR(opt->script_name);
- safe = rb_safe_level();
- rb_set_safe_level_force(0);
- ruby_set_argv(argc, argv);
- process_sflag(opt);
-
- ruby_init_loadpath();
- ruby_init_gems(!(opt->disable & DISABLE_BIT(gems)));
- lenc = rb_locale_encoding();
- for (i = 0; i < RARRAY_LEN(rb_argv); i++) {
- rb_enc_associate(RARRAY_PTR(rb_argv)[i], lenc);
- }
- parser = rb_parser_new();
- if (opt->yydebug) rb_parser_set_yydebug(parser, Qtrue);
- if (opt->ext.enc.name != 0) {
- opt->ext.enc.index = opt_enc_index(opt->ext.enc.name);
- }
- if (opt->src.enc.name != 0) {
- opt->src.enc.index = opt_enc_index(opt->src.enc.name);
- src_encoding_index = opt->src.enc.index;
- }
- if (opt->ext.enc.index >= 0) {
- enc = rb_enc_from_index(opt->ext.enc.index);
- }
- else {
- enc = lenc;
- }
- rb_enc_set_default_external(rb_enc_from_encoding(enc));
-
- rb_set_safe_level_force(safe);
- if (opt->e_script) {
- rb_encoding *eenc;
- if (opt->src.enc.index >= 0) {
- eenc = rb_enc_from_index(opt->src.enc.index);
- }
- else {
- eenc = lenc;
- }
- rb_enc_associate(opt->e_script, eenc);
- require_libraries(opt);
- tree = rb_parser_compile_string(parser, opt->script, opt->e_script, 1);
- }
- else {
- if (opt->script[0] == '-' && !opt->script[1]) {
- forbid_setid("program input from stdin");
- }
- tree = load_file(parser, opt->script, 1, opt);
- }
-
- if (!tree) return Qfalse;
-
- process_sflag(opt);
- opt->xflag = 0;
-
- if (rb_safe_level() >= 4) {
- FL_UNSET(rb_argv, FL_TAINT);
- FL_UNSET(GET_VM()->load_path, FL_TAINT);
- }
-
- if (opt->do_check) {
- printf("Syntax OK\n");
- return Qtrue;
- }
-
- if (opt->do_print) {
- tree = rb_parser_append_print(parser, tree);
- }
- if (opt->do_loop) {
- tree = rb_parser_while_loop(parser, tree, opt->do_line, opt->do_split);
- }
-
- iseq = rb_iseq_new(tree, rb_str_new2("<main>"),
- opt->script_name, Qfalse, ISEQ_TYPE_TOP);
-
- if (opt->dump & DUMP_BIT(insns)) {
- rb_io_write(rb_stdout, ruby_iseq_disasm(iseq));
- rb_io_flush(rb_stdout);
- return Qtrue;
- }
-
- return iseq;
-}
-
-static NODE *
-load_file(VALUE parser, const char *fname, int script, struct cmdline_options *opt)
-{
- extern VALUE rb_stdin;
- VALUE f;
- int line_start = 1;
- NODE *tree = 0;
- rb_encoding *enc;
-
- if (!fname)
- rb_load_fail(fname);
- if (strcmp(fname, "-") == 0) {
- f = rb_stdin;
- }
- else {
- int fd, mode = O_RDONLY;
-#if defined DOSISH || defined __CYGWIN__
- {
- const char *ext = strrchr(fname, '.');
- if (ext && STRCASECMP(ext, ".exe") == 0)
- mode |= O_BINARY;
- }
-#endif
- if ((fd = open(fname, mode)) < 0) {
- rb_load_fail(fname);
- }
-
- f = rb_io_fdopen(fd, mode, fname);
- }
-
- if (script) {
- VALUE c = 1; /* something not nil */
- VALUE line;
- char *p;
- int no_src_enc = !opt->src.enc.name;
- int no_ext_enc = !opt->ext.enc.name;
-
- enc = rb_usascii_encoding();
- rb_funcall(f, rb_intern("set_encoding"), 1, rb_enc_from_encoding(enc));
-
- if (opt->xflag) {
- forbid_setid("-x");
- opt->xflag = Qfalse;
- while (!NIL_P(line = rb_io_gets(f))) {
- line_start++;
- if (RSTRING_LEN(line) > 2
- && RSTRING_PTR(line)[0] == '#'
- && RSTRING_PTR(line)[1] == '!') {
- if ((p = strstr(RSTRING_PTR(line), "ruby")) != 0) {
- goto start_read;
- }
- }
- }
- rb_raise(rb_eLoadError, "no Ruby script found in input");
- }
-
- c = rb_io_getbyte(f);
- if (c == INT2FIX('#')) {
- c = rb_io_getbyte(f);
- if (c == INT2FIX('!')) {
- line = rb_io_gets(f);
- if (NIL_P(line))
- return 0;
-
- if ((p = strstr(RSTRING_PTR(line), "ruby")) == 0) {
- /* not ruby script, kick the program */
- char **argv;
- char *path;
- char *pend = RSTRING_PTR(line) + RSTRING_LEN(line);
-
- p = RSTRING_PTR(line); /* skip `#!' */
- if (pend[-1] == '\n')
- pend--; /* chomp line */
- if (pend[-1] == '\r')
- pend--;
- *pend = '\0';
- while (p < pend && ISSPACE(*p))
- p++;
- path = p; /* interpreter path */
- while (p < pend && !ISSPACE(*p))
- p++;
- *p++ = '\0';
- if (p < pend) {
- argv = ALLOCA_N(char *, origarg.argc + 3);
- argv[1] = p;
- MEMCPY(argv + 2, origarg.argv + 1, char *, origarg.argc);
- }
- else {
- argv = origarg.argv;
- }
- argv[0] = path;
- execv(path, argv);
-
- rb_fatal("Can't exec %s", path);
- }
-
- start_read:
- p += 4;
- RSTRING_PTR(line)[RSTRING_LEN(line) - 1] = '\0';
- if (RSTRING_PTR(line)[RSTRING_LEN(line) - 2] == '\r')
- RSTRING_PTR(line)[RSTRING_LEN(line) - 2] = '\0';
- if ((p = strstr(p, " -")) != 0) {
- p++; /* skip space before `-' */
- while (*p == '-') {
- p = moreswitches(p + 1, opt);
- }
- }
-
- /* push back shebang for pragma may exist in next line */
- rb_io_ungetbyte(f, rb_str_new2("!\n"));
- }
- else if (!NIL_P(c)) {
- rb_io_ungetbyte(f, c);
- }
- rb_io_ungetbyte(f, INT2FIX('#'));
- if (no_src_enc && opt->src.enc.name) {
- opt->src.enc.index = opt_enc_index(opt->src.enc.name);
- src_encoding_index = opt->src.enc.index;
- }
- if (no_ext_enc && opt->ext.enc.name) {
- opt->ext.enc.index = opt_enc_index(opt->ext.enc.name);
- }
- }
- else if (!NIL_P(c)) {
- rb_io_ungetbyte(f, c);
- }
- require_libraries(opt); /* Why here? unnatural */
- }
- if (opt->src.enc.index >= 0) {
- enc = rb_enc_from_index(opt->src.enc.index);
- }
- else if (f == rb_stdin) {
- enc = rb_locale_encoding();
- }
- else {
- enc = rb_usascii_encoding();
- }
- rb_funcall(f, rb_intern("set_encoding"), 1, rb_enc_from_encoding(enc));
- tree = (NODE *)rb_parser_compile_file(parser, fname, f, line_start);
- rb_funcall(f, rb_intern("set_encoding"), 1, rb_parser_encoding(parser));
- if (script && rb_parser_end_seen_p(parser)) {
- rb_define_global_const("DATA", f);
- }
- else if (f != rb_stdin) {
- rb_io_close(f);
- }
- return tree;
-}
-
-void *
-rb_load_file(const char *fname)
-{
- struct cmdline_options opt;
-
- return load_file(rb_parser_new(), fname, 0, cmdline_options_init(&opt));
-}
-
-#if !defined(PSTAT_SETCMD) && !defined(HAVE_SETPROCTITLE)
-#if !defined(_WIN32) && !(defined(HAVE_SETENV) && defined(HAVE_UNSETENV))
-#define USE_ENVSPACE_FOR_ARG0
-#endif
-
-#ifdef USE_ENVSPACE_FOR_ARG0
-extern char **environ;
-#endif
-
-static int
-get_arglen(int argc, char **argv)
-{
- char *s = argv[0];
- int i;
-
- if (!argc) return 0;
- s += strlen(s);
- /* See if all the arguments are contiguous in memory */
- for (i = 1; i < argc; i++) {
- if (argv[i] == s + 1) {
- s++;
- s += strlen(s); /* this one is ok too */
- }
- else {
- break;
- }
- }
-#if defined(USE_ENVSPACE_FOR_ARG0)
- if (environ && (s == environ[0])) {
- s += strlen(s);
- for (i = 1; environ[i]; i++) {
- if (environ[i] == s + 1) {
- s++;
- s += strlen(s); /* this one is ok too */
- }
- }
- ruby_setenv("", NULL); /* duplicate environ vars */
- }
-#endif
- return s - argv[0];
-}
-#endif
-
-static void
-set_arg0(VALUE val, ID id)
-{
- char *s;
- long i;
-
- if (origarg.argv == 0)
- rb_raise(rb_eRuntimeError, "$0 not initialized");
- StringValue(val);
- s = RSTRING_PTR(val);
- i = RSTRING_LEN(val);
-#if defined(PSTAT_SETCMD)
- if (i > PST_CLEN) {
- union pstun un;
- char buf[PST_CLEN + 1]; /* PST_CLEN is 64 (HP-UX 11.23) */
- strncpy(buf, s, PST_CLEN);
- buf[PST_CLEN] = '\0';
- un.pst_command = buf;
- pstat(PSTAT_SETCMD, un, PST_CLEN, 0, 0);
- }
- else {
- union pstun un;
- un.pst_command = s;
- pstat(PSTAT_SETCMD, un, i, 0, 0);
- }
-#elif defined(HAVE_SETPROCTITLE)
- setproctitle("%.*s", (int)i, s);
-#else
-
- if (i >= origarg.len) {
- i = origarg.len;
- }
-
- memcpy(origarg.argv[0], s, i);
-
- {
- int j;
- char *t = origarg.argv[0] + i;
- *t = '\0';
-
- if (i + 1 < origarg.len) memset(t + 1, ' ', origarg.len - i - 1);
- for (j = 1; j < origarg.argc; j++) {
- origarg.argv[j] = t;
- }
- }
-#endif
- rb_progname = rb_obj_freeze(rb_tainted_str_new(s, i));
-}
-
-void
-ruby_script(const char *name)
-{
- if (name) {
- rb_progname = rb_obj_freeze(rb_tainted_str_new2(name));
- }
-}
-
-static void
-init_ids(struct cmdline_options *opt)
-{
- rb_uid_t uid = getuid();
- rb_uid_t euid = geteuid();
- rb_gid_t gid = getgid();
- rb_gid_t egid = getegid();
-
-#ifdef VMS
- uid |= gid << 16;
- euid |= egid << 16;
-#endif
- if (uid != euid) opt->setids |= 1;
- if (egid != gid) opt->setids |= 2;
- if (uid && opt->setids) {
- rb_set_safe_level(1);
- }
-}
-
-#undef forbid_setid
-static void
-forbid_setid(const char *s, struct cmdline_options *opt)
-{
- if (opt->setids & 1)
- rb_raise(rb_eSecurityError, "no %s allowed while running setuid", s);
- if (opt->setids & 2)
- rb_raise(rb_eSecurityError, "no %s allowed while running setgid", s);
- if (rb_safe_level() > 0)
- rb_raise(rb_eSecurityError, "no %s allowed in tainted mode", s);
-}
-
-static void
-verbose_setter(VALUE val, ID id, void *data)
-{
- VALUE *variable = data;
- *variable = RTEST(val) ? Qtrue : val;
-}
-
-static VALUE
-opt_W_getter(ID id, void *data)
-{
- VALUE *variable = data;
- switch (*variable) {
- case Qnil:
- return INT2FIX(0);
- case Qfalse:
- return INT2FIX(1);
- case Qtrue:
- return INT2FIX(2);
- }
- return Qnil; /* not reached */
-}
-
-void
-ruby_prog_init(void)
-{
- rb_define_hooked_variable("$VERBOSE", &ruby_verbose, 0, verbose_setter);
- rb_define_hooked_variable("$-v", &ruby_verbose, 0, verbose_setter);
- rb_define_hooked_variable("$-w", &ruby_verbose, 0, verbose_setter);
- rb_define_hooked_variable("$-W", &ruby_verbose, opt_W_getter, 0);
- rb_define_variable("$DEBUG", &ruby_debug);
- rb_define_variable("$-d", &ruby_debug);
-
- rb_define_hooked_variable("$0", &rb_progname, 0, set_arg0);
- rb_define_hooked_variable("$PROGRAM_NAME", &rb_progname, 0, set_arg0);
-
- rb_define_global_const("ARGV", rb_argv);
- rb_global_variable(&rb_argv0);
-
-#ifdef MSDOS
- /*
- * There is no way we can refer to them from ruby, so close them to save
- * space.
- */
- (void)fclose(stdaux);
- (void)fclose(stdprn);
-#endif
-}
-
-void
-ruby_set_argv(int argc, char **argv)
-{
- int i;
- VALUE av = rb_argv;
-
-#if defined(USE_DLN_A_OUT)
- if (origarg.argv)
- dln_argv0 = origarg.argv[0];
- else
- dln_argv0 = argv[0];
-#endif
- rb_ary_clear(av);
- for (i = 0; i < argc; i++) {
- VALUE arg = rb_tainted_str_new2(argv[i]);
-
- OBJ_FREEZE(arg);
- rb_ary_push(av, arg);
- }
-}
-
-static VALUE
-false_value(void)
-{
- return Qfalse;
-}
-
-static VALUE
-true_value(void)
-{
- return Qtrue;
-}
-
-#define rb_define_readonly_boolean(name, val) \
- rb_define_virtual_variable((name), (val) ? true_value : false_value, 0)
-
-void *
-ruby_process_options(int argc, char **argv)
-{
- struct cmdline_arguments args;
- struct cmdline_options opt;
- NODE *tree;
-
- ruby_script(argv[0]); /* for the time being */
- rb_argv0 = rb_str_new4(rb_progname);
- args.argc = argc;
- args.argv = argv;
- args.opt = cmdline_options_init(&opt);
- opt.ext.enc.index = -1;
- tree = (NODE *)rb_vm_call_cfunc(rb_vm_top_self(),
- process_options, (VALUE)&args,
- 0, rb_progname);
-
- rb_define_readonly_boolean("$-p", opt.do_print);
- rb_define_readonly_boolean("$-l", opt.do_line);
- rb_define_readonly_boolean("$-a", opt.do_split);
-
- return tree;
-}
-
-void
-ruby_sysinit(int *argc, char ***argv)
-{
-#if defined(__APPLE__) && (defined(__MACH__) || defined(__DARWIN__))
- int i, n = *argc, len = 0;
- char **v1 = *argv, **v2, *p;
-
- for (i = 0; i < n; ++i) {
- len += strlen(v1[i]) + 1;
- }
- v2 = malloc((n + 1)* sizeof(char*) + len);
- p = (char *)&v2[n + 1];
- for (i = 0; i < n; ++i) {
- int l = strlen(v1[i]);
- memcpy(p, v1[i], l + 1);
- v2[i] = p;
- p += l + 1;
- }
- v2[n] = 0;
- *argv = v2;
-#elif defined(__MACOS__) && defined(__MWERKS__)
- *argc = ccommand(argv);
-#elif defined(_WIN32)
- void rb_w32_sysinit(int *argc, char ***argv);
- rb_w32_sysinit(argc, argv);
-#endif
- origarg.argc = *argc;
- origarg.argv = *argv;
-#if !defined(PSTAT_SETCMD) && !defined(HAVE_SETPROCTITLE)
- origarg.len = get_arglen(origarg.argc, origarg.argv);
-#endif
-#if defined(USE_DLN_A_OUT)
- dln_argv0 = origarg.argv[0];
-#endif
-}