mirror of
https://github.com/ruby/ruby.git
synced 2025-08-15 13:39:04 +02:00
* prelude.rb, Makefile.in, common.mk: Introduce prelude.rb.
* eval.c (rb_eval_prelude): New function exported only for use in preludes. * configure.in: Define RUBY_EXEC_PREFIX and RUBY_LIB_PREFIX. * ruby.c (proc_options, ruby_init_loadpath, ruby_prelude): Load prelude. * compile_prelude.rb: Port the prelude compiler from trunk. * miniprelude.c: Currently miniruby does not include prelude.rb. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8@27053 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
908667e45a
commit
5c54c57521
8 changed files with 247 additions and 6 deletions
|
@ -51,7 +51,7 @@ LDSHARED = @LIBRUBY_LDSHARED@
|
|||
DLDFLAGS = @LIBRUBY_DLDFLAGS@ $(EXTLDFLAGS) @ARCH_FLAG@
|
||||
SOLIBS = @SOLIBS@
|
||||
MAINLIBS = @MAINLIBS@
|
||||
MINIOBJS = @MINIOBJS@
|
||||
ARCHMINIOBJS = @MINIOBJS@
|
||||
|
||||
RUBY_INSTALL_NAME=@RUBY_INSTALL_NAME@
|
||||
RUBY_SO_NAME=@RUBY_SO_NAME@
|
||||
|
@ -107,7 +107,7 @@ all:
|
|||
|
||||
miniruby$(EXEEXT):
|
||||
@$(RM) $@
|
||||
$(PURIFY) $(CC) $(LDFLAGS) $(XLDFLAGS) $(MAINLIBS) $(MAINOBJ) $(MINIOBJS) $(LIBRUBY_A) $(LIBS) $(OUTFLAG)$@
|
||||
$(PURIFY) $(CC) $(LDFLAGS) $(XLDFLAGS) $(MAINLIBS) $(MAINOBJ) $(MINIOBJS) $(COMMONOBJS) $(DMYEXT) $(LIBS) $(OUTFLAG)$@
|
||||
|
||||
$(PROGRAM):
|
||||
@$(RM) $@
|
||||
|
|
20
common.mk
20
common.mk
|
@ -20,8 +20,9 @@ DMYEXT = dmyext.$(OBJEXT)
|
|||
MAINOBJ = main.$(OBJEXT)
|
||||
EXTOBJS =
|
||||
DLDOBJS = $(DMYEXT)
|
||||
MINIOBJS = $(ARCHMINIOBJS) miniprelude.$(OBJEXT)
|
||||
|
||||
OBJS = array.$(OBJEXT) \
|
||||
COMMONOBJS = array.$(OBJEXT) \
|
||||
bignum.$(OBJEXT) \
|
||||
class.$(OBJEXT) \
|
||||
compar.$(OBJEXT) \
|
||||
|
@ -60,6 +61,11 @@ OBJS = array.$(OBJEXT) \
|
|||
version.$(OBJEXT) \
|
||||
$(MISSING)
|
||||
|
||||
OBJS = $(COMMONOBJS) prelude.$(OBJEXT)
|
||||
|
||||
PRELUDE_SCRIPTS = $(srcdir)/prelude.rb
|
||||
PRELUDES = prelude.c miniprelude.c
|
||||
|
||||
SCRIPT_ARGS = --dest-dir="$(DESTDIR)" \
|
||||
--extout="$(EXTOUT)" \
|
||||
--mflags="$(MFLAGS)" \
|
||||
|
@ -81,6 +87,8 @@ TESTWORKDIR = testwork
|
|||
|
||||
VCS = svn
|
||||
|
||||
COMPILE_PRELUDE = $(MINIRUBY) -I$(srcdir) $(srcdir)/compile_prelude.rb
|
||||
|
||||
all: main $(RDOCTARGET)
|
||||
|
||||
main: exts
|
||||
|
@ -93,7 +101,7 @@ $(MKMAIN_CMD): $(MKFILES) $(PREP) $(RBCONFIG) $(LIBRUBY)
|
|||
|
||||
prog: $(PROGRAM) $(WPROGRAM)
|
||||
|
||||
miniruby$(EXEEXT): config.status $(LIBRUBY_A) $(MAINOBJ) $(MINIOBJS) $(OBJS) $(DMYEXT)
|
||||
miniruby$(EXEEXT): config.status $(MAINOBJ) $(MINIOBJS) $(COMMONOBJS) $(DMYEXT)
|
||||
|
||||
$(PROGRAM): $(LIBRUBY) $(MAINOBJ) $(OBJS) $(EXTOBJS) $(SETUP) $(PREP)
|
||||
|
||||
|
@ -307,7 +315,7 @@ clean-ext::
|
|||
distclean: distclean-ext distclean-local
|
||||
distclean-local:: clean-local
|
||||
@$(RM) $(MKFILES) config.h rbconfig.rb
|
||||
@$(RM) config.cache config.log config.status
|
||||
@$(RM) config.cache config.log config.status $(PRELUDES)
|
||||
@$(RM) *~ *.bak *.stackdump core *.core gmon.out $(PREP)
|
||||
distclean-ext::
|
||||
|
||||
|
@ -455,6 +463,12 @@ variable.$(OBJEXT): {$(VPATH)}variable.c $(RUBY_H_INCLUDES) \
|
|||
version.$(OBJEXT): {$(VPATH)}version.c $(RUBY_H_INCLUDES) \
|
||||
{$(VPATH)}version.h {$(VPATH)}revision.h
|
||||
|
||||
prelude.c: $(srcdir)/compile_prelude.rb $(RBCONFIG) $(PRELUDE_SCRIPTS) $(PREP)
|
||||
$(COMPILE_PRELUDE) $(PRELUDE_SCRIPTS) $@
|
||||
|
||||
miniprelude.$(OBJEXT): {$(VPATH)}miniprelude.c $(RUBY_H_INCLUDES)
|
||||
prelude.$(OBJEXT): {$(VPATH)}prelude.c $(RUBY_H_INCLUDES)
|
||||
|
||||
dist: $(PROGRAM)
|
||||
$(RUNRUBY) $(srcdir)/distruby.rb
|
||||
|
||||
|
|
187
compile_prelude.rb
Executable file
187
compile_prelude.rb
Executable file
|
@ -0,0 +1,187 @@
|
|||
# This file is interpreted by miniruby.
|
||||
# Do not use features that miniruby does not provide,
|
||||
# including what's in prelude.rb.
|
||||
|
||||
require 'erb'
|
||||
|
||||
class Prelude
|
||||
SRCDIR = File.dirname(__FILE__)
|
||||
$:.unshift(SRCDIR)
|
||||
|
||||
C_ESC = {
|
||||
"\\" => "\\\\",
|
||||
'"' => '\"',
|
||||
"\n" => '\n',
|
||||
}
|
||||
|
||||
0x00.upto(0x1f) {|ch| C_ESC[[ch].pack("C")] ||= "\\%03o" % ch }
|
||||
0x7f.upto(0xff) {|ch| C_ESC[[ch].pack("C")] = "\\%03o" % ch }
|
||||
C_ESC_PAT = Regexp.union(*C_ESC.keys)
|
||||
|
||||
def c_esc(str)
|
||||
'"' + str.gsub(C_ESC_PAT) { C_ESC[$&] } + '"'
|
||||
end
|
||||
def prelude_base(filename)
|
||||
filename[/\A#{Regexp.quote(SRCDIR)}\/(.*?)(\.rb)?\z/om, 1]
|
||||
end
|
||||
def prelude_name(filename)
|
||||
"<internal:" + prelude_base(filename) + ">"
|
||||
end
|
||||
|
||||
def initialize(preludes)
|
||||
@mkconf = nil
|
||||
@have_sublib = false
|
||||
@need_ruby_prefix = false
|
||||
@preludes = {}
|
||||
@mains = preludes.map {|filename| translate(filename)[0]}
|
||||
end
|
||||
|
||||
def translate(filename, sub = false)
|
||||
idx = @preludes[filename]
|
||||
return idx if idx
|
||||
lines = []
|
||||
@preludes[filename] = result = [@preludes.size, filename, lines, sub]
|
||||
File.readlines(filename).each do |line|
|
||||
line.gsub!(/RbConfig::CONFIG\["(\w+)"\]/) {
|
||||
key = $1
|
||||
unless @mkconf
|
||||
require './rbconfig'
|
||||
@mkconf = RbConfig::MAKEFILE_CONFIG.merge('prefix'=>'#{TMP_RUBY_PREFIX}')
|
||||
end
|
||||
if RbConfig::MAKEFILE_CONFIG.has_key? key
|
||||
val = RbConfig.expand("$(#{key})", @mkconf)
|
||||
@need_ruby_prefix ||= /\A\#\{TMP_RUBY_PREFIX\}/ =~ val
|
||||
c_esc(val)
|
||||
else
|
||||
"nil"
|
||||
end
|
||||
}
|
||||
line.sub!(/require\s*\(?\s*(["'])(.*?)\1\)?/) do
|
||||
orig, path = $&, $2
|
||||
path = File.join(SRCDIR, path)
|
||||
if File.exist?(path)
|
||||
@have_sublib = true
|
||||
"TMP_RUBY_PREFIX.require(#{translate(path, true)[0]})"
|
||||
else
|
||||
orig
|
||||
end
|
||||
end
|
||||
lines << c_esc(line)
|
||||
end
|
||||
result
|
||||
end
|
||||
|
||||
def emit(outfile)
|
||||
init_name = outfile[/\w+(?=_prelude.c\b)/] || 'prelude'
|
||||
erb = ERB.new(<<'EOS', nil, '%')
|
||||
/* -*-c-*-
|
||||
THIS FILE WAS AUTOGENERATED BY compile_prelude.rb. DO NOT EDIT.
|
||||
|
||||
soruces: <%= @preludes.map {|n,*| prelude_base(n)}.join(', ') %>
|
||||
*/
|
||||
#include "ruby.h"
|
||||
|
||||
VALUE rb_eval_prelude _((VALUE, const char *));
|
||||
|
||||
% preludes = @preludes.values.sort
|
||||
% preludes.each {|i, prelude, lines, sub|
|
||||
|
||||
static const char prelude_name<%=i%>[] = <%=c_esc(prelude_name(*prelude))%>;
|
||||
static const char prelude_code<%=i%>[] =
|
||||
% lines.each {|line|
|
||||
<%=line%>
|
||||
% }
|
||||
;
|
||||
% }
|
||||
|
||||
#define PRELUDE_COUNT <%=@have_sublib ? preludes.size : 0%>
|
||||
|
||||
% if @have_sublib or @need_ruby_prefix
|
||||
struct prelude_env {
|
||||
volatile VALUE prefix_path;
|
||||
#if PRELUDE_COUNT > 0
|
||||
char loaded[PRELUDE_COUNT];
|
||||
#endif
|
||||
};
|
||||
|
||||
static VALUE
|
||||
prelude_prefix_path(VALUE self)
|
||||
{
|
||||
struct prelude_env *ptr = DATA_PTR(self);
|
||||
return ptr->prefix_path;
|
||||
}
|
||||
% end
|
||||
|
||||
% if @have_sublib
|
||||
static VALUE
|
||||
prelude_require(VALUE self, VALUE nth)
|
||||
{
|
||||
struct prelude_env *ptr = DATA_PTR(self);
|
||||
VALUE code;
|
||||
const char *name;
|
||||
int n = FIX2INT(nth);
|
||||
|
||||
if (n > PRELUDE_COUNT) return Qfalse;
|
||||
if (ptr->loaded[n]) return Qfalse;
|
||||
ptr->loaded[n] = 1;
|
||||
switch (n) {
|
||||
% @preludes.each_value do |i, prelude, lines, sub|
|
||||
% if sub
|
||||
case <%=i%>:
|
||||
code = rb_str_new(prelude_code<%=i%>, sizeof(prelude_code<%=i%>) - 1);
|
||||
name = prelude_name<%=i%>;
|
||||
break;
|
||||
% end
|
||||
% end
|
||||
default:
|
||||
return Qfalse;
|
||||
}
|
||||
rb_eval_prelude(code, name);
|
||||
return Qtrue;
|
||||
}
|
||||
|
||||
% end
|
||||
void Init_<%=init_name%> _((void));
|
||||
|
||||
void
|
||||
Init_<%=init_name%>()
|
||||
{
|
||||
% if @have_sublib or @need_ruby_prefix
|
||||
struct prelude_env memo;
|
||||
ID name = rb_intern("TMP_RUBY_PREFIX");
|
||||
VALUE prelude = Data_Wrap_Struct(rb_cData, 0, 0, &memo);
|
||||
|
||||
memo.prefix_path = rb_const_remove(rb_cObject, name);
|
||||
rb_const_set(rb_cObject, name, prelude);
|
||||
rb_define_singleton_method(prelude, "to_s", prelude_prefix_path, 0);
|
||||
% end
|
||||
% if @have_sublib
|
||||
memset(memo.loaded, 0, sizeof(memo.loaded));
|
||||
rb_define_singleton_method(prelude, "require", prelude_require, 1);
|
||||
% end
|
||||
% preludes.each do |i, prelude, lines, sub|
|
||||
% next if sub
|
||||
rb_eval_prelude(rb_str_new(prelude_code<%=i%>, sizeof(prelude_code<%=i%>) - 1), prelude_name<%=i%>);
|
||||
% end
|
||||
% if @have_sublib or @need_ruby_prefix
|
||||
rb_gc_force_recycle(prelude);
|
||||
% end
|
||||
|
||||
#if 0
|
||||
% preludes.length.times {|i|
|
||||
puts(prelude_code<%=i%>);
|
||||
% }
|
||||
#endif
|
||||
}
|
||||
EOS
|
||||
tmp = erb.result(binding)
|
||||
open(outfile, 'w'){|f|
|
||||
f << tmp
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
preludes = ARGV.dup
|
||||
outfile = preludes.pop
|
||||
Prelude.new(preludes).emit(outfile)
|
||||
|
|
@ -1829,6 +1829,8 @@ esac
|
|||
RUBY_LIB_PATH="${RUBY_LIB_PREFIX}/${ruby_version}"
|
||||
RUBY_SITE_LIB_PATH2="${RUBY_SITE_LIB_PATH}/${ruby_version}"
|
||||
|
||||
AC_DEFINE_UNQUOTED(RUBY_EXEC_PREFIX, "${RUBY_EXEC_PREFIX}")
|
||||
AC_DEFINE_UNQUOTED(RUBY_LIB_PREFIX, ${RUBY_LIB_PREFIX})
|
||||
AC_DEFINE_UNQUOTED(RUBY_LIB, "${RUBY_LIB_PATH}")
|
||||
AC_DEFINE_UNQUOTED(RUBY_SITE_LIB, "${RUBY_SITE_LIB_PATH}")
|
||||
AC_DEFINE_UNQUOTED(RUBY_SITE_LIB2, "${RUBY_SITE_LIB_PATH2}")
|
||||
|
|
8
eval.c
8
eval.c
|
@ -6722,6 +6722,14 @@ eval(self, src, scope, file, line)
|
|||
return result;
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_eval_prelude(src, name)
|
||||
VALUE src;
|
||||
const char *name;
|
||||
{
|
||||
return eval(ruby_top_self, src, Qnil, name, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* eval(string [, binding [, filename [,lineno]]]) => obj
|
||||
|
|
11
miniprelude.c
Normal file
11
miniprelude.c
Normal file
|
@ -0,0 +1,11 @@
|
|||
#include "ruby.h"
|
||||
|
||||
void Init_prelude _((void));
|
||||
|
||||
void Init_prelude()
|
||||
{
|
||||
/*
|
||||
* Do nada, meaning miniruby does not support features implemented
|
||||
* in prelude.rb.
|
||||
*/
|
||||
}
|
1
prelude.rb
Normal file
1
prelude.rb
Normal file
|
@ -0,0 +1 @@
|
|||
# currently empty
|
20
ruby.c
20
ruby.c
|
@ -254,6 +254,7 @@ ruby_init_loadpath()
|
|||
{
|
||||
#if defined LOAD_RELATIVE
|
||||
char libpath[FILENAME_MAX+1];
|
||||
size_t baselen;
|
||||
char *p;
|
||||
int rest;
|
||||
#if defined _WIN32 || defined __CYGWIN__
|
||||
|
@ -298,12 +299,16 @@ ruby_init_loadpath()
|
|||
strcpy(libpath, ".");
|
||||
p = libpath + 1;
|
||||
}
|
||||
#define PREFIX_PATH() rb_str_new(libpath, baselen)
|
||||
|
||||
rest = FILENAME_MAX - (p - libpath);
|
||||
baselen = p - libpath;
|
||||
rest = FILENAME_MAX - baselen;
|
||||
|
||||
#define RUBY_RELATIVE(path) (strncpy(p, (path), rest), libpath)
|
||||
#else
|
||||
static const char exec_prefix[] = RUBY_EXEC_PREFIX;
|
||||
#define RUBY_RELATIVE(path) (path)
|
||||
#define PREFIX_PATH() rubylib_mangled_path(exec_prefix, sizeof(exec_prefix)-1)
|
||||
#endif
|
||||
#define incpush(path) rb_ary_push(rb_load_path, rubylib_mangled_path2(path))
|
||||
|
||||
|
@ -338,6 +343,8 @@ ruby_init_loadpath()
|
|||
if (rb_safe_level() == 0) {
|
||||
incpush(".");
|
||||
}
|
||||
|
||||
rb_const_set(rb_cObject, rb_intern("TMP_RUBY_PREFIX"), rb_obj_freeze(PREFIX_PATH()));
|
||||
}
|
||||
|
||||
struct req_list {
|
||||
|
@ -481,6 +488,16 @@ moreswitches(s)
|
|||
return s;
|
||||
}
|
||||
|
||||
static void ruby_prelude _((void));
|
||||
void Init_prelude _((void));
|
||||
|
||||
static void
|
||||
ruby_prelude()
|
||||
{
|
||||
Init_prelude();
|
||||
rb_const_remove(rb_cObject, rb_intern("TMP_RUBY_PREFIX"));
|
||||
}
|
||||
|
||||
static void
|
||||
proc_options(argc, argv)
|
||||
int argc;
|
||||
|
@ -841,6 +858,7 @@ proc_options(argc, argv)
|
|||
process_sflag();
|
||||
|
||||
ruby_init_loadpath();
|
||||
ruby_prelude();
|
||||
ruby_sourcefile = rb_source_filename(argv0);
|
||||
if (e_script) {
|
||||
require_libraries();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue