mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
add mruby sources
This commit is contained in:
+18
@@ -0,0 +1,18 @@
|
||||
# /
|
||||
*.bak
|
||||
*.dylib
|
||||
*.inc
|
||||
*.o
|
||||
*.orig
|
||||
*.rej
|
||||
*.sav
|
||||
*.swp
|
||||
*.d
|
||||
*~
|
||||
.DS_Store
|
||||
.ccmalloc
|
||||
.svn
|
||||
/.git
|
||||
cscope.out
|
||||
mruby.exe
|
||||
y.tab.c
|
||||
@@ -0,0 +1,120 @@
|
||||
# makefile discription.
|
||||
# basic build file for Rite-VM(mruby)
|
||||
# 11.Apr.2011 coded by Kenji Yoshimoto.
|
||||
# 17.Jan.2012 coded by Hiroshi Mimaki.
|
||||
|
||||
# project-specific macros
|
||||
# extension of the executable-file is modifiable(.exe .out ...)
|
||||
TARGET := bin/mrubysample
|
||||
RITEVM := lib/ritevm
|
||||
MRUBY := tools/mruby/mruby
|
||||
ifeq ($(OS),Windows_NT)
|
||||
EXE := $(TARGET).exe
|
||||
LIB := $(RITEVM).lib
|
||||
MRB := $(MRUBY).exe
|
||||
else
|
||||
EXE := $(TARGET)
|
||||
LIB := $(RITEVM).a
|
||||
MRB := $(MRUBY)
|
||||
endif
|
||||
MSRC := src/minimain.c
|
||||
YSRC := src/parse.y
|
||||
YC := src/y.tab.c
|
||||
EXCEPT1 := $(YC) $(MSRC)
|
||||
OBJM := $(patsubst %.c,%.o,$(MSRC))
|
||||
OBJY := $(patsubst %.c,%.o,$(YC))
|
||||
OBJ1 := $(patsubst %.c,%.o,$(filter-out $(EXCEPT1),$(wildcard src/*.c)))
|
||||
#OBJ2 := $(patsubst %.c,%.o,$(wildcard ext/regex/*.c))
|
||||
#OBJ3 := $(patsubst %.c,%.o,$(wildcard ext/enc/*.c))
|
||||
OBJS := $(OBJ1) $(OBJ2) $(OBJ3)
|
||||
# mruby libraries
|
||||
EXTC := mrblib/mrblib.c
|
||||
EXTRB := $(wildcard mrblib/*.rb)
|
||||
EXT0 := $(patsubst %.c,%.o,src/$(EXTC))
|
||||
# ext libraries
|
||||
EXTS := $(EXT0)
|
||||
|
||||
# libraries, includes
|
||||
LIBS = $(LIB) -lm
|
||||
INCLUDES = -I./src -I./include
|
||||
|
||||
# library for iOS
|
||||
IOSLIB := $(RITEVM)-ios.a
|
||||
IOSSIMLIB := $(RITEVM)-iossim.a
|
||||
IOSDEVLIB := $(RITEVM)-iosdev.a
|
||||
IOSSIMCC := xcrun -sdk iphoneos llvm-gcc-4.2 -arch i386 -isysroot "/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator5.0.sdk/"
|
||||
IOSDEVCC := xcrun -sdk iphoneos llvm-gcc-4.2 -arch armv7 -isysroot "/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk/"
|
||||
|
||||
# compiler, linker (gcc)
|
||||
CC = gcc
|
||||
LL = gcc
|
||||
YACC = bison
|
||||
DEBUG_MODE = 1
|
||||
ifeq ($(DEBUG_MODE),1)
|
||||
CFLAGS = -g
|
||||
else
|
||||
CFLAGS = -O3
|
||||
endif
|
||||
ALL_CFLAGS = -Wall -Werror-implicit-function-declaration $(CFLAGS)
|
||||
MAKE_FLAGS = --no-print-directory CC="$(CC)" LL="$(LL)"
|
||||
|
||||
##############################
|
||||
# generic build targets, rules
|
||||
|
||||
.PHONY : all
|
||||
all : $(LIB) $(MRB) $(EXE)
|
||||
@echo "make: built targets of `pwd`"
|
||||
|
||||
##############################
|
||||
# make library for iOS
|
||||
.PHONY : ios
|
||||
ios : $(IOSLIB)
|
||||
|
||||
$(IOSLIB) : $(IOSSIMLIB) $(IOSDEVLIB)
|
||||
lipo -arch i386 $(IOSSIMLIB) -arch armv7 $(IOSDEVLIB) -create -output $(IOSLIB)
|
||||
|
||||
$(IOSSIMLIB) :
|
||||
$(MAKE) clean -C src $(MAKE_FLAGS)
|
||||
$(MAKE) -C src $(MAKE_FLAGS) CC="$(IOSSIMCC)" LL="$(IOSSIMCC)"
|
||||
cp $(LIB) $(IOSSIMLIB)
|
||||
|
||||
$(IOSDEVLIB) :
|
||||
$(MAKE) clean -C src $(MAKE_FLAGS)
|
||||
$(MAKE) -C src $(MAKE_FLAGS) CC="$(IOSDEVCC)" LL="$(IOSDEVCC)"
|
||||
cp $(LIB) $(IOSDEVLIB)
|
||||
|
||||
# executable constructed using linker from object files
|
||||
$(EXE) : $(OBJM) $(LIB)
|
||||
$(LL) -o $@ $(OBJM) $(LIBS)
|
||||
|
||||
-include $(OBJS:.o=.d)
|
||||
|
||||
# src compile
|
||||
$(LIB) : $(EXTS) $(OBJS) $(OBJY)
|
||||
$(MAKE) -C src $(MAKE_FLAGS)
|
||||
|
||||
# mruby interpreter compile
|
||||
$(MRB) : $(EXTS) $(OBJS) $(OBJY)
|
||||
$(MAKE) -C tools/mruby $(MAKE_FLAGS)
|
||||
|
||||
# objects compiled from source
|
||||
$(OBJS) :
|
||||
$(MAKE) -C src $(MAKE_FLAGS) && $(MAKE) -C tools/mruby $(MAKE_FLAGS)
|
||||
|
||||
# extend libraries complile
|
||||
$(EXTS) : $(EXTRB)
|
||||
$(MAKE) -C mrblib $(MAKE_FLAGS)
|
||||
|
||||
# test module compile
|
||||
$(OBJM) : $(MSRC)
|
||||
$(CC) $(ALL_CFLAGS) -MMD $(INCLUDES) -c $(MSRC) -o $(OBJM)
|
||||
|
||||
# clean up
|
||||
.PHONY : clean
|
||||
clean :
|
||||
$(MAKE) clean -C src $(MAKE_FLAGS)
|
||||
$(MAKE) clean -C tools/mruby $(MAKE_FLAGS)
|
||||
-rm -f $(EXE) $(OBJM)
|
||||
-rm -f $(OBJM:.o=.d)
|
||||
-rm -f $(IOSLIB) $(IOSSIMLIB) $(IOSDEVLIB)
|
||||
@echo "make: removing targets, objects and depend files of `pwd`"
|
||||
@@ -0,0 +1,14 @@
|
||||
やること(まだできてないこと) / not yet complete
|
||||
|
||||
* ヒアドキュメント / here document
|
||||
* 特殊変数 ($1,$2..) / special variables
|
||||
* super in aliased methods
|
||||
* BEGIN/END (対応しないんだっけ?)
|
||||
* const_missing
|
||||
* respond_to_missing
|
||||
|
||||
改善すること(できているが直すこと)
|
||||
|
||||
* Hash (サイズを減らす。khashを使うか、順序を保存するか)
|
||||
* stringEx (encoding削除、CODERANGE削除、UTF-8 or ASCII以外削除)
|
||||
* 気づいたら書き加える
|
||||
@@ -0,0 +1,42 @@
|
||||
#ifndef MRUBYCONF_H
|
||||
#define MRUBYCONF_H
|
||||
|
||||
#include <stdint.h>
|
||||
typedef double mrb_float;
|
||||
typedef int32_t mrb_int;
|
||||
typedef intptr_t mrb_sym;
|
||||
|
||||
#define readint(p,base) strtol((p),NULL,(base))
|
||||
#define readfloat(p) strtod((p),NULL)
|
||||
|
||||
#undef INCLUDE_ENCODING /* not use encoding classes (ascii only) */
|
||||
#define INCLUDE_ENCODING /* use UTF-8 encoding classes */
|
||||
|
||||
#undef INCLUDE_REGEXP /* not use regular expression classes */
|
||||
#define INCLUDE_REGEXP /* use regular expression classes */
|
||||
|
||||
#ifdef INCLUDE_REGEXP
|
||||
# define INCLUDE_ENCODING /* Regexp depends Encoding */
|
||||
#endif
|
||||
|
||||
#undef HAVE_UNISTD_H /* WINDOWS */
|
||||
#define HAVE_UNISTD_H /* LINUX */
|
||||
|
||||
#define SIZEOF_INT 4
|
||||
#define SIZEOF_SHORT 2
|
||||
#define SIZEOF_LONG 4
|
||||
#define SIZEOF_LONG_LONG 8
|
||||
#define SIZEOF___INT64 0
|
||||
#define SIZEOF_VOIDP 4
|
||||
#define SIZEOF_FLOAT 4
|
||||
#define SIZEOF_DOUBLE 8
|
||||
|
||||
#ifndef FALSE
|
||||
# define FALSE 0
|
||||
#endif
|
||||
|
||||
#ifndef TRUE
|
||||
# define TRUE 1
|
||||
#endif
|
||||
|
||||
#endif /* MRUBYCONF_H */
|
||||
+623
@@ -0,0 +1,623 @@
|
||||
#ifndef MRUBY_H
|
||||
#define MRUBY_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "mrbconf.h"
|
||||
|
||||
enum mrb_vtype {
|
||||
MRB_TT_FALSE = 0, /* 0 */
|
||||
MRB_TT_FREE, /* 1 */
|
||||
MRB_TT_TRUE, /* 2 */
|
||||
MRB_TT_FIXNUM, /* 3 */
|
||||
MRB_TT_SYMBOL, /* 4 */
|
||||
MRB_TT_UNDEF, /* 5 */
|
||||
MRB_TT_FLOAT, /* 6 */
|
||||
MRB_TT_OBJECT, /* 7 */
|
||||
MRB_TT_CLASS, /* 8 */
|
||||
MRB_TT_MODULE, /* 9 */
|
||||
MRB_TT_ICLASS, /* 10 */
|
||||
MRB_TT_SCLASS, /* 11 */
|
||||
MRB_TT_PROC, /* 12 */
|
||||
MRB_TT_ARRAY, /* 13 */
|
||||
MRB_TT_HASH, /* 14 */
|
||||
MRB_TT_STRING, /* 15 */
|
||||
MRB_TT_RANGE, /* 16 */
|
||||
MRB_TT_REGEX, /* 17 */
|
||||
MRB_TT_STRUCT, /* 18 */
|
||||
MRB_TT_EXCEPTION, /* 19 */
|
||||
MRB_TT_MATCH, /* 20 */
|
||||
MRB_TT_FILE, /* 21 */
|
||||
MRB_TT_ENV, /* 22 */
|
||||
MRB_TT_DATA, /* 23 */
|
||||
MRB_TT_THREAD, /* 24 */
|
||||
MRB_TT_THREADGRP, /* 25 */
|
||||
MRB_TT_MAXDEFINE /* 26 */
|
||||
};
|
||||
|
||||
typedef struct mrb_value {
|
||||
union {
|
||||
mrb_float f;
|
||||
void *p;
|
||||
mrb_int i;
|
||||
mrb_sym sym;
|
||||
} value;
|
||||
enum mrb_vtype tt:8;
|
||||
} mrb_value;
|
||||
|
||||
#define mrb_type(o) (o).tt
|
||||
#define mrb_nil_p(o) ((o).tt == MRB_TT_FALSE && !(o).value.i)
|
||||
#define mrb_test(o) ((o).tt != MRB_TT_FALSE)
|
||||
#define mrb_fixnum(o) (o).value.i
|
||||
#define mrb_float(o) (o).value.f
|
||||
#define mrb_symbol(o) (o).value.sym
|
||||
#define mrb_object(o) (o).value.p
|
||||
#define FIXNUM_P(o) ((o).tt == MRB_TT_FIXNUM)
|
||||
#define UNDEF_P(o) ((o).tt == MRB_TT_UNDEF)
|
||||
|
||||
#include "mruby/object.h"
|
||||
|
||||
#define IMMEDIATE_P(x) ((mrb_type(x) >= MRB_TT_FALSE) && (mrb_type(x) <= MRB_TT_FLOAT))
|
||||
#define SPECIAL_CONST_P(x) IMMEDIATE_P(x)
|
||||
#define SYMBOL_P(o) (mrb_type(o) == MRB_TT_SYMBOL)
|
||||
#define RTEST(o) mrb_test(o)
|
||||
|
||||
#define FL_ABLE(x) (!SPECIAL_CONST_P(x))
|
||||
#define FL_TEST(x,f) (FL_ABLE(x)?(RBASIC(x)->flags&(f)):0)
|
||||
#define FL_ANY(x,f) FL_TEST(x,f)
|
||||
#define FL_ALL(x,f) (FL_TEST(x,f) == (f))
|
||||
#define FL_SET(x,f) do {if (FL_ABLE(x)) RBASIC(x)->flags |= (f);} while (0)
|
||||
#define FL_UNSET(x,f) do {if (FL_ABLE(x)) RBASIC(x)->flags &= ~(f);} while (0)
|
||||
|
||||
static inline mrb_int
|
||||
mrb_special_const_p(mrb_value obj)
|
||||
{
|
||||
if (SPECIAL_CONST_P(obj)) return 1;
|
||||
return 0;
|
||||
}
|
||||
static inline mrb_value
|
||||
mrb_fixnum_value(mrb_int i)
|
||||
{
|
||||
mrb_value v;
|
||||
|
||||
v.tt = MRB_TT_FIXNUM;
|
||||
v.value.i = i;
|
||||
return v;
|
||||
}
|
||||
|
||||
static inline mrb_value
|
||||
mrb_float_value(mrb_float f)
|
||||
{
|
||||
mrb_value v;
|
||||
|
||||
v.tt = MRB_TT_FLOAT;
|
||||
v.value.f = f;
|
||||
return v;
|
||||
}
|
||||
|
||||
static inline mrb_value
|
||||
mrb_symbol_value(mrb_sym i)
|
||||
{
|
||||
mrb_value v;
|
||||
|
||||
v.tt = MRB_TT_SYMBOL;
|
||||
v.value.sym = i;
|
||||
return v;
|
||||
}
|
||||
|
||||
static inline mrb_value
|
||||
mrb_obj_value(void *p)
|
||||
{
|
||||
mrb_value v;
|
||||
struct RBasic *b = p;
|
||||
|
||||
v.tt = b->tt;
|
||||
v.value.p = p;
|
||||
return v;
|
||||
}
|
||||
|
||||
static inline mrb_value
|
||||
mrb_false_value()
|
||||
{
|
||||
mrb_value v;
|
||||
|
||||
v.tt = MRB_TT_FALSE;
|
||||
v.value.i = 1;
|
||||
return v;
|
||||
}
|
||||
|
||||
static inline mrb_value
|
||||
mrb_nil_value()
|
||||
{
|
||||
mrb_value v;
|
||||
|
||||
v.tt = MRB_TT_FALSE;
|
||||
v.value.p = 0;
|
||||
return v;
|
||||
}
|
||||
|
||||
static inline mrb_value
|
||||
mrb_true_value()
|
||||
{
|
||||
mrb_value v;
|
||||
|
||||
v.tt = MRB_TT_TRUE;
|
||||
v.value.i = 1;
|
||||
return v;
|
||||
}
|
||||
|
||||
static inline mrb_value
|
||||
mrb_undef_value()
|
||||
{
|
||||
mrb_value v;
|
||||
|
||||
v.tt = MRB_TT_UNDEF;
|
||||
v.value.i = 0;
|
||||
return v;
|
||||
}
|
||||
|
||||
typedef int32_t mrb_code;
|
||||
|
||||
struct mrb_state;
|
||||
|
||||
typedef void* (*mrb_allocf) (struct mrb_state *mrb, void*, size_t);
|
||||
|
||||
#define MRB_ARENA_SIZE 1024 //256 up kusuda 2011/04/30
|
||||
#define ruby_debug (mrb_nil_value())
|
||||
#define ruby_verbose (mrb_nil_value())
|
||||
|
||||
typedef struct {
|
||||
mrb_sym mid;
|
||||
struct RProc *proc;
|
||||
int stackidx;
|
||||
int nregs;
|
||||
int argc;
|
||||
mrb_code *pc;
|
||||
int acc;
|
||||
struct RClass *target_class;
|
||||
int ridx;
|
||||
int eidx;
|
||||
struct REnv *env;
|
||||
} mrb_callinfo;
|
||||
|
||||
enum gc_state {
|
||||
GC_STATE_NONE = 0,
|
||||
GC_STATE_MARK,
|
||||
GC_STATE_SWEEP
|
||||
};
|
||||
|
||||
typedef struct mrb_state {
|
||||
void *jmp;
|
||||
|
||||
mrb_allocf allocf;
|
||||
|
||||
mrb_value *stack;
|
||||
mrb_value *stbase, *stend;
|
||||
|
||||
mrb_callinfo *ci;
|
||||
mrb_callinfo *cibase, *ciend;
|
||||
|
||||
mrb_code **rescue;
|
||||
int rsize;
|
||||
struct RProc **ensure;
|
||||
int esize;
|
||||
|
||||
struct RObject *exc;
|
||||
struct kh_iv *globals;
|
||||
|
||||
struct mrb_irep **irep;
|
||||
size_t irep_len, irep_capa;
|
||||
|
||||
struct RClass *object_class;
|
||||
struct RClass *class_class;
|
||||
struct RClass *module_class;
|
||||
struct RClass *proc_class;
|
||||
struct RClass *string_class;
|
||||
struct RClass *array_class;
|
||||
struct RClass *hash_class;
|
||||
struct RClass *range_class;
|
||||
#ifdef INCLUDE_REGEXP
|
||||
struct RClass *regex_class;
|
||||
struct RClass *match_class;
|
||||
#endif
|
||||
#ifdef INCLUDE_ENCODING
|
||||
struct RClass *encode_class;
|
||||
struct RClass *converter_class;
|
||||
#endif
|
||||
|
||||
struct RClass *float_class;
|
||||
struct RClass *fixnum_class;
|
||||
struct RClass *true_class;
|
||||
struct RClass *false_class;
|
||||
struct RClass *nil_class;
|
||||
struct RClass *symbol_class;
|
||||
|
||||
struct RClass *kernel_module;
|
||||
struct heap_page *heaps;
|
||||
struct heap_page *sweeps;
|
||||
struct heap_page *free_heaps;
|
||||
size_t live; /* count of live objects */
|
||||
struct RBasic *arena[MRB_ARENA_SIZE];
|
||||
int arena_idx;
|
||||
|
||||
enum gc_state gc_state; /* state of gc */
|
||||
int current_white_part; /* make white object by white_part */
|
||||
struct RBasic *gray_list; /* list of gray objects */
|
||||
struct RBasic *variable_gray_list; /* list of objects to be traversed atomically */
|
||||
size_t gc_live_after_mark;
|
||||
size_t gc_threshold;
|
||||
mrb_int gc_interval_ratio;
|
||||
mrb_int gc_step_ratio;
|
||||
|
||||
mrb_sym symidx;
|
||||
struct kh_n2s *name2sym; /* symbol table */
|
||||
struct kh_s2n *sym2name; /* reverse symbol table */
|
||||
struct RNode *local_svar;/* regexp */
|
||||
|
||||
struct RClass *eException_class;
|
||||
struct RClass *eStandardError_class;
|
||||
struct RClass *eRuntimeError_class;
|
||||
} mrb_state;
|
||||
|
||||
typedef mrb_value (*mrb_func_t)(mrb_state *mrb, mrb_value);
|
||||
typedef mrb_value (*mrb_funcargv_t)(mrb_state *mrb, mrb_value, int argc, mrb_value* argv);
|
||||
struct RClass *mrb_define_class(mrb_state *, const char*, struct RClass*);
|
||||
struct RClass *mrb_define_module(mrb_state *, const char*);
|
||||
mrb_value mrb_singleton_class(mrb_state*, mrb_value);
|
||||
void mrb_include_module(mrb_state*, struct RClass*, struct RClass*);
|
||||
|
||||
void mrb_define_method(mrb_state*, struct RClass*, const char*, mrb_func_t,int);
|
||||
void mrb_define_class_method(mrb_state *, struct RClass *, const char *, mrb_func_t, int);
|
||||
void mrb_define_singleton_method(mrb_state*, void*, const char*, mrb_func_t,int);
|
||||
void mrb_define_const(mrb_state*, struct RClass*, const char *name, mrb_value);
|
||||
mrb_value mrb_instance_new(mrb_state *mrb, mrb_value cv);
|
||||
struct RClass * mrb_class_new(mrb_state *mrb, struct RClass *super);
|
||||
struct RClass * mrb_module_new(mrb_state *mrb);
|
||||
struct RClass * mrb_class_from_sym(mrb_state *mrb, struct RClass *klass, mrb_sym name);
|
||||
struct RClass * mrb_class_get(mrb_state *mrb, char *name);
|
||||
struct RClass * mrb_class_obj_get(mrb_state *mrb, char *name);
|
||||
|
||||
mrb_value mrb_obj_dup(mrb_state *mrb, mrb_value obj);
|
||||
mrb_value mrb_check_to_integer(mrb_state *mrb, mrb_value val, const char *method);
|
||||
int mrb_obj_respond_to(struct RClass* c, mrb_sym mid);
|
||||
struct RClass * mrb_define_class_under(mrb_state *mrb, struct RClass *outer, const char *name, struct RClass *super);
|
||||
struct RClass * mrb_define_module_under(mrb_state *mrb, struct RClass *outer, const char *name);
|
||||
|
||||
/* required arguments */
|
||||
#define ARGS_REQ(n) (((n)&0x1f) << 19)
|
||||
/* optional arguments */
|
||||
#define ARGS_OPT(n) (((n)&0x1f) << 14)
|
||||
/* rest argument */
|
||||
#define ARGS_REST() (1 << 13)
|
||||
/* required arguments after rest */
|
||||
#define ARGS_POST(n) (((n)&0x1f) << 8)
|
||||
/* keyword arguments (n of keys, kdict) */
|
||||
#define ARGS_KEY(n1,n2) ((((n1)&0x1f) << 3) | ((n2)?(1<<2):0))
|
||||
/* block argument */
|
||||
#define ARGS_BLOCK() (1 << 1)
|
||||
|
||||
/* accept any number of arguments */
|
||||
#define ARGS_ANY() ARGS_REST()
|
||||
/* accept no arguments */
|
||||
#define ARGS_NONE() 0
|
||||
|
||||
int mrb_get_args(mrb_state *mrb, const char *format, ...);
|
||||
|
||||
mrb_value mrb_funcall(mrb_state*, mrb_value, const char*, int,...);
|
||||
mrb_value mrb_funcall_argv(mrb_state*, mrb_value, const char*, int, mrb_value*);
|
||||
mrb_value mrb_funcall_with_block(mrb_state*, mrb_value, const char*, int, mrb_value*, struct RProc*);
|
||||
mrb_sym mrb_intern(mrb_state*,const char*);
|
||||
const char *mrb_sym2name(mrb_state*,mrb_sym);
|
||||
mrb_value mrb_str_format(mrb_state *, int, const mrb_value *, mrb_value);
|
||||
|
||||
void *mrb_malloc(mrb_state*, size_t);
|
||||
void *mrb_calloc(mrb_state*, size_t, size_t);
|
||||
void *mrb_realloc(mrb_state*, void*, size_t);
|
||||
void *mrb_obj_alloc(mrb_state*, enum mrb_vtype, struct RClass*);
|
||||
void *mrb_free(mrb_state*, void*);
|
||||
|
||||
mrb_value mrb_str_new_cstr(mrb_state*, const char*);
|
||||
|
||||
mrb_state* mrb_open(void);
|
||||
mrb_state* mrb_open_allocf(mrb_allocf);
|
||||
void mrb_close(mrb_state*);
|
||||
int mrb_checkstack(mrb_state*,int);
|
||||
|
||||
mrb_value mrb_run(mrb_state*, struct RProc*, mrb_value);
|
||||
|
||||
mrb_value mrb_p(mrb_state*, mrb_value);
|
||||
int mrb_obj_id(mrb_value obj);
|
||||
mrb_sym mrb_to_id(mrb_state *mrb, mrb_value name);
|
||||
|
||||
int mrb_obj_equal(mrb_state*, mrb_value, mrb_value);
|
||||
int mrb_equal(mrb_state *mrb, mrb_value obj1, mrb_value obj2);
|
||||
mrb_value mrb_Integer(mrb_state *mrb, mrb_value val);
|
||||
mrb_value mrb_Float(mrb_state *mrb, mrb_value val);
|
||||
mrb_value mrb_inspect(mrb_state *mrb, mrb_value obj);
|
||||
int mrb_eql(mrb_state *mrb, mrb_value obj1, mrb_value obj2);
|
||||
|
||||
void mrb_garbage_collect(mrb_state*);
|
||||
void mrb_incremental_gc(mrb_state *);
|
||||
int mrb_gc_arena_save(mrb_state*);
|
||||
void mrb_gc_arena_restore(mrb_state*,int);
|
||||
void mrb_gc_mark(mrb_state*,struct RBasic*);
|
||||
#define mrb_gc_mark_value(mrb,val) do {\
|
||||
if ((val).tt >= MRB_TT_OBJECT) mrb_gc_mark((mrb), mrb_object(val));\
|
||||
} while (0);
|
||||
void mrb_gc_mark_gv(mrb_state*);
|
||||
void mrb_gc_free_gv(mrb_state*);
|
||||
void mrb_gc_mark_iv(mrb_state*, struct RObject*);
|
||||
size_t mrb_gc_mark_iv_size(mrb_state*, struct RObject*);
|
||||
void mrb_gc_free_iv(mrb_state*, struct RObject*);
|
||||
void mrb_gc_mark_mt(mrb_state*, struct RClass*);
|
||||
size_t mrb_gc_mark_mt_size(mrb_state*, struct RClass*);
|
||||
void mrb_gc_free_mt(mrb_state*, struct RClass*);
|
||||
void mrb_gc_mark_ht(mrb_state*, struct RClass*);
|
||||
size_t mrb_gc_mark_ht_size(mrb_state*, struct RClass*);
|
||||
void mrb_gc_free_ht(mrb_state*, struct RClass*);
|
||||
void mrb_field_write_barrier(mrb_state *, struct RBasic*, struct RBasic*);
|
||||
#define mrb_field_write_barrier_value(mrb, obj, val) do{\
|
||||
if ((val.tt >= MRB_TT_OBJECT)) mrb_field_write_barrier((mrb), (obj), mrb_object(val));\
|
||||
} while (0);
|
||||
void mrb_write_barrier(mrb_state *, struct RBasic*);
|
||||
|
||||
#define MRUBY_VERSION "Rite"
|
||||
|
||||
#if 0
|
||||
#define DEBUG(x) x
|
||||
#else
|
||||
#define DEBUG(x)
|
||||
#endif
|
||||
|
||||
mrb_value mrb_check_convert_type(mrb_state *mrb, mrb_value val, mrb_int type, const char *tname, const char *method);
|
||||
mrb_value mrb_any_to_s(mrb_state *mrb, mrb_value obj);
|
||||
const char * mrb_obj_classname(mrb_state *mrb, mrb_value obj);
|
||||
struct RClass* mrb_obj_class(mrb_state *mrb, mrb_value obj);
|
||||
mrb_value mrb_class_path(mrb_state *mrb, struct RClass *c);
|
||||
mrb_value mrb_convert_type(mrb_state *mrb, mrb_value val, mrb_int type, const char *tname, const char *method);
|
||||
mrb_int mrb_obj_is_kind_of(mrb_state *mrb, mrb_value obj, struct RClass *c);
|
||||
mrb_value mrb_obj_inspect(mrb_state *mrb, mrb_value self);
|
||||
mrb_value mrb_obj_clone(mrb_state *mrb, mrb_value self);
|
||||
mrb_value mrb_check_funcall(mrb_state *mrb, mrb_value recv, mrb_sym mid, int argc, mrb_value *argv);
|
||||
|
||||
/* need to include <ctype.h> to use these macros */
|
||||
#ifndef ISPRINT
|
||||
//#define ISASCII(c) isascii((int)(unsigned char)(c))
|
||||
#define ISASCII(c) 1
|
||||
#undef ISPRINT
|
||||
#define ISPRINT(c) (ISASCII(c) && isprint((int)(unsigned char)(c)))
|
||||
#define ISSPACE(c) (ISASCII(c) && isspace((int)(unsigned char)(c)))
|
||||
#define ISUPPER(c) (ISASCII(c) && isupper((int)(unsigned char)(c)))
|
||||
#define ISLOWER(c) (ISASCII(c) && islower((int)(unsigned char)(c)))
|
||||
#define ISALNUM(c) (ISASCII(c) && isalnum((int)(unsigned char)(c)))
|
||||
#define ISALPHA(c) (ISASCII(c) && isalpha((int)(unsigned char)(c)))
|
||||
#define ISDIGIT(c) (ISASCII(c) && isdigit((int)(unsigned char)(c)))
|
||||
#define ISXDIGIT(c) (ISASCII(c) && isxdigit((int)(unsigned char)(c)))
|
||||
#endif
|
||||
|
||||
extern mrb_value mrb_rs;
|
||||
extern mrb_value mrb_default_rs;
|
||||
|
||||
int mrb_block_given_p(void);
|
||||
void mrb_raise(mrb_state *mrb, struct RClass *c, const char *fmt, ...);
|
||||
void rb_raise(struct RClass *c, const char *fmt, ...);
|
||||
void mrb_warn(const char *fmt, ...);
|
||||
void mrb_warning(const char *fmt, ...);
|
||||
void mrb_bug(const char *fmt, ...);
|
||||
|
||||
#define E_TYPE_ERROR (mrb_class_obj_get(mrb, "TypeError"))
|
||||
#define E_ARGUMENT_ERROR (mrb_class_obj_get(mrb, "ArgumentError"))
|
||||
#define E_INDEX_ERROR (mrb_class_obj_get(mrb, "IndexError"))
|
||||
#define E_RANGE_ERROR (mrb_class_obj_get(mrb, "RangeError"))
|
||||
#define E_NAME_ERROR (mrb_class_obj_get(mrb, "NameError"))
|
||||
#define E_NOMETHOD_ERROR (mrb_class_obj_get(mrb, "NoMethodError"))
|
||||
#define E_SCRIPT_ERROR (mrb_class_obj_get(mrb, "ScriptError"))
|
||||
#define E_SYNTAX_ERROR (mrb_class_obj_get(mrb, "SyntaxError"))
|
||||
#define E_LOAD_ERROR (mrb_class_obj_get(mrb, "LoadError"))
|
||||
#define E_SYSTEMCALL_ERROR (mrb_class_obj_get(mrb, "SystemCallError"))
|
||||
#define E_LOCALJUMP_ERROR (mrb_class_obj_get(mrb, "LocalJumpError"))
|
||||
#define E_REGEXP_ERROR (mrb_class_obj_get(mrb, "RegexpError"))
|
||||
#define E_ZERODIVISION_ERROR (mrb_class_obj_get(mrb, "ZeroDivisionError"))
|
||||
|
||||
#define E_ENCODING_ERROR (mrb_class_obj_get(mrb, "EncodingError"))
|
||||
#define E_NOTIMP_ERROR (mrb_class_obj_get(mrb, "NotImplementedError"))
|
||||
#define E_FLOATDOMAIN_ERROR (mrb_class_obj_get(mrb, "FloatDomainError"))
|
||||
|
||||
#define E_KEY_ERROR (mrb_class_obj_get(mrb, "KeyError"))
|
||||
|
||||
#define SYM2ID(x) ((x).value.sym)
|
||||
|
||||
#define CONST_ID_CACHE(mrb, result, str) \
|
||||
{ \
|
||||
static mrb_sym mrb_intern_id_cache;\
|
||||
if (!mrb_intern_id_cache) \
|
||||
mrb_intern_id_cache = mrb_intern(mrb, str); \
|
||||
result mrb_intern_id_cache; \
|
||||
}
|
||||
#define CONST_ID(mrb, var, str) \
|
||||
do CONST_ID_CACHE(mrb, var =, str) while (0)
|
||||
|
||||
#define NUM2CHR_internal(x) (((mrb_type(x) == MRB_TT_STRING)&&(RSTRING_LEN(x)>=1))?\
|
||||
RSTRING_PTR(x)[0]:(char)(mrb_fixnum_number(x)&0xff))
|
||||
#ifdef __GNUC__
|
||||
# define NUM2CHR(x) __extension__ ({mrb_value num2chr_x = (x); NUM2CHR_internal(num2chr_x);})
|
||||
#else
|
||||
static inline char
|
||||
NUM2CHR(mrb_value x)
|
||||
{
|
||||
return NUM2CHR_internal(x);
|
||||
}
|
||||
#endif
|
||||
mrb_value mrb_io_gets(mrb_state *mrb, mrb_value);
|
||||
mrb_value mrb_io_getbyte(mrb_state *mrb, mrb_value);
|
||||
mrb_value mrb_io_ungetc(mrb_state *, mrb_value, mrb_value);
|
||||
mrb_value mrb_io_ungetbyte(mrb_state *mrb, mrb_value, mrb_value);
|
||||
mrb_value mrb_io_close(mrb_state *mrb, mrb_value);
|
||||
mrb_value mrb_io_flush(mrb_state *mrb, mrb_value);
|
||||
mrb_value mrb_io_eof(mrb_value);
|
||||
mrb_value mrb_io_binmode(mrb_state *mrb, mrb_value);
|
||||
mrb_value mrb_io_ascii8bit_binmode(mrb_value);
|
||||
mrb_value mrb_io_addstr(mrb_state *mrb, mrb_value, mrb_value);
|
||||
mrb_value mrb_io_printf(mrb_state *mrb, int, mrb_value*, mrb_value);
|
||||
mrb_value mrb_io_print(mrb_state *mrb, int, mrb_value*, mrb_value);
|
||||
mrb_value mrb_io_puts(mrb_state *mrb, /*int argc, mrb_value *argv,*/ mrb_value);
|
||||
mrb_value mrb_io_fdopen(int, int, const char*);
|
||||
mrb_value mrb_io_get_io(mrb_state *mrb, mrb_value);
|
||||
mrb_value mrb_file_open(mrb_state *mrb, const char*, const char*);
|
||||
mrb_value mrb_file_open_str(mrb_value, const char*);
|
||||
mrb_value mrb_gets(mrb_state *mrb);
|
||||
|
||||
mrb_value mrb_yield(mrb_state *mrb, mrb_value v, mrb_value blk);
|
||||
mrb_value mrb_yield_argv(mrb_state *mrb, mrb_value b, int argc, mrb_value *argv);
|
||||
mrb_value mrb_yield_with_self(mrb_state *mrb, mrb_value b, int argc, mrb_value *argv, mrb_value self);
|
||||
mrb_value mrb_class_new_instance(mrb_state *mrb, int, mrb_value*, struct RClass *);
|
||||
mrb_value mrb_class_new_instance_m(mrb_state *mrb, mrb_value klass);
|
||||
|
||||
mrb_value mrb_exec_recursive(mrb_state *mrb, mrb_value(*)(mrb_state *, mrb_value, mrb_value, int),mrb_value,void *);
|
||||
|
||||
#ifndef xmalloc
|
||||
#define xmalloc malloc
|
||||
#define xrealloc realloc
|
||||
#define xcalloc calloc
|
||||
#define xfree free
|
||||
#endif
|
||||
|
||||
void mrb_gc(void);
|
||||
#define thread_debug if(0)printf
|
||||
|
||||
#define RUBY_VM 1 /* YARV */
|
||||
#define HAVE_NATIVETHREAD
|
||||
int ruby_native_thread_p(void);
|
||||
|
||||
#define RUBY_EVENT_NONE 0x0000
|
||||
#define RUBY_EVENT_LINE 0x0001
|
||||
#define RUBY_EVENT_CLASS 0x0002
|
||||
#define RUBY_EVENT_END 0x0004
|
||||
#define RUBY_EVENT_CALL 0x0008
|
||||
#define RUBY_EVENT_RETURN 0x0010
|
||||
#define RUBY_EVENT_C_CALL 0x0020
|
||||
#define RUBY_EVENT_C_RETURN 0x0040
|
||||
#define RUBY_EVENT_RAISE 0x0080
|
||||
#define RUBY_EVENT_ALL 0xffff
|
||||
#define RUBY_EVENT_VM 0x10000
|
||||
#define RUBY_EVENT_SWITCH 0x20000
|
||||
#define RUBY_EVENT_COVERAGE 0x40000
|
||||
|
||||
typedef unsigned int mrb_event_flag_t;
|
||||
typedef void (*mrb_event_hook_func_t)(mrb_state *mrb, mrb_event_flag_t, mrb_value data, mrb_value, mrb_sym, mrb_value klass);
|
||||
|
||||
typedef struct mrb_event_hook_struct {
|
||||
mrb_event_flag_t flag;
|
||||
mrb_event_hook_func_t func;
|
||||
mrb_value data;
|
||||
struct mrb_event_hook_struct *next;
|
||||
} mrb_event_hook_t;
|
||||
|
||||
#define RB_EVENT_HOOKS_HAVE_CALLBACK_DATA 1
|
||||
void mrb_add_event_hook(mrb_state *mrb, mrb_event_hook_func_t func, mrb_event_flag_t events,
|
||||
mrb_value data);
|
||||
int mrb_remove_event_hook(mrb_event_hook_func_t func);
|
||||
mrb_value mrb_to_int(mrb_state *mrb, mrb_value val);
|
||||
void mrb_check_type(mrb_state *mrb, mrb_value x, enum mrb_vtype t);
|
||||
|
||||
//#define RUBY_SETJMP(env) ${setjmp_prefix}setjmp(env${setjmp_sigmask+,0})
|
||||
//#define RUBY_LONGJMP(env,val) ${setjmp_prefix}longjmp(env,val)
|
||||
//#define RUBY_JMP_BUF ${setjmp_sigmask+${setjmp_prefix}}jmp_buf
|
||||
#define RUBY_SETJMP(env) __builtin_setjmp(env)
|
||||
#define RUBY_LONGJMP(env,val) __builtin_longjmp(env,1)//(env,val)
|
||||
//#define RUBY_JMP_BUF ${setjmp_sigmask+${setjmp_prefix}}jmp_buf
|
||||
#define select(n, r, w, e, t) select_large_fdset(n, r, w, e, t)
|
||||
|
||||
//int RUBY_SETJMP(mrb_jmpbuf_t env); /* add kusuda */
|
||||
#define ruby_setjmp(env) RUBY_SETJMP(env)
|
||||
#define ruby_longjmp(env,val) RUBY_LONGJMP(env,val)
|
||||
|
||||
#if defined PRIdPTR && !defined PRI_VALUE_PREFIX
|
||||
#define PRIdVALUE PRIdPTR
|
||||
#define PRIiVALUE PRIiPTR
|
||||
#define PRIoVALUE PRIoPTR
|
||||
#define PRIuVALUE PRIuPTR
|
||||
#define PRIxVALUE PRIxPTR
|
||||
#define PRIXVALUE PRIXPTR
|
||||
#else
|
||||
#define PRIdVALUE PRI_VALUE_PREFIX"d"
|
||||
#define PRIiVALUE PRI_VALUE_PREFIX"i"
|
||||
#define PRIoVALUE PRI_VALUE_PREFIX"o"
|
||||
#define PRIuVALUE PRI_VALUE_PREFIX"u"
|
||||
#define PRIxVALUE PRI_VALUE_PREFIX"x"
|
||||
#define PRIXVALUE PRI_VALUE_PREFIX"X"
|
||||
#endif
|
||||
#ifndef PRI_VALUE_PREFIX
|
||||
# define PRI_VALUE_PREFIX ""
|
||||
#endif
|
||||
|
||||
#if defined PRIdPTR
|
||||
# define PRI_PTRDIFF_PREFIX "t"
|
||||
#elif SIZEOF_PTRDIFF_T == SIZEOF_INT
|
||||
# define PRI_PTRDIFF_PREFIX
|
||||
#elif SIZEOF_PTRDIFF_T == SIZEOF_LONG
|
||||
# define PRI_PTRDIFF_PREFIX "l"
|
||||
#elif SIZEOF_PTRDIFF_T == SIZEOF_LONG_LONG
|
||||
# define PRI_PTRDIFF_PREFIX "ll"
|
||||
#else
|
||||
# define PRI_PTRDIFF_PREFIX
|
||||
#endif
|
||||
#define PRIdPTRDIFF PRI_PTRDIFF_PREFIX"d"
|
||||
#define PRIiPTRDIFF PRI_PTRDIFF_PREFIX"i"
|
||||
#define PRIoPTRDIFF PRI_PTRDIFF_PREFIX"o"
|
||||
#define PRIuPTRDIFF PRI_PTRDIFF_PREFIX"u"
|
||||
#define PRIxPTRDIFF PRI_PTRDIFF_PREFIX"x"
|
||||
#define PRIXPTRDIFF PRI_PTRDIFF_PREFIX"X"
|
||||
|
||||
#if defined PRIdPTR
|
||||
# define PRI_SIZE_PREFIX "z"
|
||||
#elif SIZEOF_SIZE_T == SIZEOF_INT
|
||||
# define PRI_SIZE_PREFIX
|
||||
#elif SIZEOF_SIZE_T == SIZEOF_LONG
|
||||
# define PRI_SIZE_PREFIX "l"
|
||||
#elif SIZEOF_SIZE_T == SIZEOF_LONG_LONG
|
||||
# define PRI_SIZE_PREFIX "ll"
|
||||
#endif
|
||||
#define PRIdSIZE PRI_SIZE_PREFIX"d"
|
||||
#define PRIiSIZE PRI_SIZE_PREFIX"i"
|
||||
#define PRIoSIZE PRI_SIZE_PREFIX"o"
|
||||
#define PRIuSIZE PRI_SIZE_PREFIX"u"
|
||||
#define PRIxSIZE PRI_SIZE_PREFIX"x"
|
||||
#define PRIXSIZE PRI_SIZE_PREFIX"X"
|
||||
#define PRIdPTRDIFF PRI_PTRDIFF_PREFIX"d"
|
||||
|
||||
#define KHASH 0
|
||||
#define STHASH 1
|
||||
#define BASICHASH 2
|
||||
#define HASH_CLASS_METHOD BASICHASH
|
||||
|
||||
typedef enum call_type {
|
||||
CALL_PUBLIC,
|
||||
CALL_FCALL,
|
||||
CALL_VCALL,
|
||||
CALL_TYPE_MAX
|
||||
} call_type;
|
||||
|
||||
/* compar.c */
|
||||
void mrb_cmperr(mrb_state *mrb, mrb_value x, mrb_value y);
|
||||
int mrb_cmpint(mrb_state *mrb, mrb_value val, mrb_value a, mrb_value b);
|
||||
|
||||
#define REALLOC_N(mrb,var,type,n) (var)=(type*)mrb_realloc(mrb, (char*)(var), sizeof(type)*(n))
|
||||
|
||||
#ifndef ANYARGS
|
||||
# ifdef __cplusplus
|
||||
# define ANYARGS ...
|
||||
# else
|
||||
# define ANYARGS
|
||||
# endif
|
||||
#endif
|
||||
void st_foreach_safe(mrb_state *mrb, void *table, int (*func)(ANYARGS), void * a);
|
||||
void mrb_define_alias(mrb_state *mrb, struct RClass *klass, const char *name1, const char *name2);
|
||||
const char *mrb_class_name(mrb_state *mrb, struct RClass* klass);
|
||||
void mrb_define_global_const(mrb_state *mrb, const char *name, mrb_value val);
|
||||
|
||||
mrb_value mrb_block_proc(void);
|
||||
int mrb_sourceline(void);
|
||||
void ruby_default_signal(int sig);
|
||||
mrb_value mrb_attr_get(mrb_state *mrb, mrb_value obj, mrb_sym id);
|
||||
|
||||
#endif /* MRUBY_H */
|
||||
@@ -0,0 +1,42 @@
|
||||
#ifndef MRUBY_ARRAY_H
|
||||
#define MRUBY_ARRAY_H
|
||||
|
||||
struct RArray {
|
||||
MRUBY_OBJECT_HEADER;
|
||||
size_t len;
|
||||
size_t capa;
|
||||
mrb_value *buf;
|
||||
};
|
||||
|
||||
#define mrb_ary_ptr(v) ((struct RArray*)((v).value.p))
|
||||
#define mrb_ary_value(p) mrb_obj_value((void*)(p))
|
||||
#define RARRAY(v) ((struct RArray*)((v).value.p))
|
||||
|
||||
#define RARRAY_LEN(a) (RARRAY(a)->len)
|
||||
#define RARRAY_PTR(a) (RARRAY(a)->buf)
|
||||
|
||||
mrb_value mrb_ary_new_capa(mrb_state*, size_t);
|
||||
mrb_value mrb_ary_new(mrb_state *mrb);
|
||||
mrb_value mrb_ary_new_elts(mrb_state *mrb, long n, const mrb_value *elts);
|
||||
void mrb_ary_concat(mrb_state*, mrb_value, mrb_value);
|
||||
mrb_value mrb_ary_splat(mrb_state*, mrb_value);
|
||||
void mrb_ary_push(mrb_state*, mrb_value, mrb_value);
|
||||
mrb_value mrb_ary_pop(mrb_state *mrb, mrb_value ary);
|
||||
mrb_value mrb_ary_new_from_values(mrb_state *mrb, mrb_value *vals, size_t size);
|
||||
mrb_value mrb_ary_aget(mrb_state *mrb, mrb_value self);
|
||||
mrb_value mrb_ary_ref(mrb_state *mrb, mrb_value ary, mrb_int n);
|
||||
void mrb_ary_set(mrb_state *mrb, mrb_value ary, mrb_int n, mrb_value val);
|
||||
int mrb_ary_len(mrb_state *mrb, mrb_value ary);
|
||||
mrb_value mrb_ary_replace_m(mrb_state *mrb, mrb_value self);
|
||||
void mrb_ary_replace(mrb_state *mrb, struct RArray *a, mrb_value *argv, size_t len);
|
||||
mrb_value mrb_check_array_type(mrb_state *mrb, mrb_value self);
|
||||
mrb_value mrb_ary_unshift(mrb_state *mrb, mrb_value self, mrb_value item);
|
||||
mrb_value mrb_ary_new4(mrb_state *mrb, long n, const mrb_value *elts);
|
||||
mrb_value mrb_assoc_new(mrb_state *mrb, mrb_value car, mrb_value cdr);
|
||||
mrb_value mrb_ary_entry(mrb_value ary, long offset);
|
||||
void mrb_mem_clear(mrb_value *mem, long size);
|
||||
mrb_value mrb_ary_tmp_new(mrb_state *mrb, long capa);
|
||||
mrb_value mrb_ary_sort(mrb_state *mrb, mrb_value ary);
|
||||
mrb_value mrb_ary_shift(mrb_state *mrb, mrb_value self);
|
||||
|
||||
#endif /* MRUBY_ARRAY_H */
|
||||
@@ -0,0 +1,71 @@
|
||||
#ifndef MRUBY_CLASS_H
|
||||
#define MRUBY_CLASS_H
|
||||
|
||||
struct RClass {
|
||||
MRUBY_OBJECT_HEADER;
|
||||
struct kh_iv *iv;
|
||||
struct kh_mt *mt;
|
||||
struct RClass *super;
|
||||
};
|
||||
|
||||
#define mrb_class_ptr(v) ((struct RClass*)((v).value.p))
|
||||
#define RCLASS_SUPER(v) (((struct RClass*)((v).value.p))->super)
|
||||
#define RCLASS_IV_TBL(v) (((struct RClass*)((v).value.p))->iv)
|
||||
#define RCLASS_M_TBL(v) (((struct RClass*)((v).value.p))->mt)
|
||||
|
||||
static inline struct RClass*
|
||||
mrb_class(mrb_state *mrb, mrb_value v)
|
||||
{
|
||||
switch (mrb_type(v)) {
|
||||
case MRB_TT_FALSE:
|
||||
if (v.value.p)
|
||||
return mrb->false_class;
|
||||
return mrb->nil_class;
|
||||
case MRB_TT_TRUE:
|
||||
return mrb->true_class;
|
||||
case MRB_TT_SYMBOL:
|
||||
return mrb->symbol_class;
|
||||
case MRB_TT_FIXNUM:
|
||||
return mrb->fixnum_class;
|
||||
case MRB_TT_FLOAT:
|
||||
return mrb->float_class;
|
||||
|
||||
#ifdef INCLUDE_REGEXP
|
||||
// case MRB_TT_REGEX:
|
||||
// return mrb->regex_class;
|
||||
// case MRB_TT_MATCH:
|
||||
// return mrb->match_class;
|
||||
// case MRB_TT_DATA:
|
||||
// return mrb->encode_class;
|
||||
#else
|
||||
case MRB_TT_REGEX:
|
||||
case MRB_TT_MATCH:
|
||||
mrb_raise(mrb, E_TYPE_ERROR, "type mismatch: %s given",
|
||||
mrb_obj_classname(mrb, v));
|
||||
return mrb->nil_class; /* not reach */
|
||||
#endif
|
||||
default:
|
||||
return ((struct RBasic*)mrb_object(v))->c;
|
||||
}
|
||||
}
|
||||
|
||||
#define MRB_SET_INSTANCE_TT(c, tt) c->flags = ((c->flags & ~0xff) | (char)tt)
|
||||
#define MRB_INSTANCE_TT(c) (enum mrb_vtype)(c->flags & 0xff)
|
||||
|
||||
struct RClass* mrb_define_class_id(mrb_state*, mrb_sym, struct RClass*);
|
||||
struct RClass* mrb_define_module_id(mrb_state*, mrb_sym);
|
||||
struct RClass *mrb_vm_define_class(mrb_state*, mrb_value, mrb_value, mrb_sym);
|
||||
struct RClass *mrb_vm_define_module(mrb_state*, mrb_value, mrb_sym);
|
||||
void mrb_define_method_vm(mrb_state*, struct RClass*, mrb_sym, mrb_value);
|
||||
void mrb_define_method_raw(mrb_state*, struct RClass*, mrb_sym, struct RProc *);
|
||||
|
||||
struct RClass *mrb_class_outer_module(mrb_state*, struct RClass *);
|
||||
struct RProc *mrb_method_search_vm(mrb_state*, struct RClass**, mrb_sym);
|
||||
struct RProc *mrb_method_search(mrb_state*, struct RClass*, mrb_sym);
|
||||
|
||||
int mrb_respond_to(mrb_state *mrb, mrb_value obj, mrb_sym mid);
|
||||
void mrb_define_method_id(mrb_state *mrb, struct RClass *c, mrb_sym mid, mrb_func_t func, int aspec);
|
||||
|
||||
void mrb_obj_call_init(mrb_state *mrb, mrb_value obj, int argc, mrb_value *argv);
|
||||
|
||||
#endif /* MRUBY_CLASS_H */
|
||||
@@ -0,0 +1,59 @@
|
||||
#ifndef MRUBY_HASH_H
|
||||
#define MRUBY_HASH_H
|
||||
|
||||
struct RHash {
|
||||
MRUBY_OBJECT_HEADER;
|
||||
struct kh_ht *ht;
|
||||
mrb_value ifnone;
|
||||
};
|
||||
|
||||
#define N 624
|
||||
#define M 397
|
||||
#define MATRIX_A 0x9908b0dfU /* constant vector a */
|
||||
#define UMASK 0x80000000U /* most significant w-r bits */
|
||||
#define LMASK 0x7fffffffU /* least significant r bits */
|
||||
#define MIXBITS(u,v) ( ((u) & UMASK) | ((v) & LMASK) )
|
||||
#define TWIST(u,v) ((MIXBITS(u,v) >> 1) ^ ((v)&1U ? MATRIX_A : 0U))
|
||||
enum {MT_MAX_STATE = N};
|
||||
|
||||
struct MT {
|
||||
/* assume int is enough to store 32bits */
|
||||
unsigned int state[N]; /* the array for the state vector */
|
||||
unsigned int *next;
|
||||
int left;
|
||||
};
|
||||
|
||||
#define mrb_hash_end(h) st_hash_end(h)
|
||||
#define mrb_hash_uint(h, i) st_hash_uint(h, i)
|
||||
|
||||
#define mrb_hash_ptr(v) ((struct RHash*)((v).value.p))
|
||||
#define mrb_hash_value(p) mrb_obj_value((void*)(p))
|
||||
|
||||
mrb_value mrb_hash_new_capa(mrb_state*, size_t);
|
||||
mrb_value mrb_hash_new(mrb_state *mrb, int capa);
|
||||
|
||||
void mrb_hash_set(mrb_state *mrb, mrb_value hash, mrb_value key, mrb_value val);
|
||||
mrb_value mrb_hash_get(mrb_state *mrb, mrb_value hash, mrb_value key);
|
||||
mrb_value mrb_hash_getWithDef(mrb_state *mrb, mrb_value hash, mrb_value vkey, mrb_value def);
|
||||
mrb_value mrb_hash_delete_key(mrb_state *mrb, mrb_value hash, mrb_value key);
|
||||
mrb_value mrb_hash(mrb_state *mrb, mrb_value obj);
|
||||
void ruby_setenv(mrb_state *mrb, const char *name, const char *value);
|
||||
|
||||
/* RHASH_TBL allocates st_table if not available. */
|
||||
#define RHASH(obj) ((struct RHash*)((obj).value.p))
|
||||
#define RHASH_TBL(h) mrb_hash_tbl(h)
|
||||
#define RHASH_H_TBL(h) (RHASH(h)->ht)
|
||||
#define RHASH_SIZE(h) (RHASH_H_TBL(h)->size)
|
||||
#define RHASH_EMPTY_P(h) (RHASH_SIZE(h) == 0)
|
||||
#define RHASH_IFNONE(h) (RHASH(h)->ifnone)
|
||||
#define RHASH_PROCDEFAULT(h) (RHASH(h)->ifnone)
|
||||
struct kh_ht * mrb_hash_tbl(mrb_state *mrb, mrb_value hash);
|
||||
|
||||
#define MRB_HASH_PROC_DEFAULT 256
|
||||
#define MRB_RHASH_PROCDEFAULT_P(h) (RHASH(h)->flags & MRB_HASH_PROC_DEFAULT)
|
||||
|
||||
char * ruby_strdup(const char *str);
|
||||
void mrb_reset_random_seed(void);
|
||||
mrb_value mrb_obj_is_proc(mrb_value proc);
|
||||
|
||||
#endif /* MRUBY_HASH_H */
|
||||
@@ -0,0 +1,17 @@
|
||||
#ifndef MRUBY_NUMERIC_H
|
||||
#define MRUBY_NUMERIC_H
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#define RSHIFT(x,y) ((x)>>(int)(y))
|
||||
#define FIXNUM_MAX (LONG_MAX>>1)
|
||||
#define FIXNUM_MIN RSHIFT((long)LONG_MIN,1)
|
||||
#define POSFIXABLE(f) ((f) < FIXNUM_MAX+1)
|
||||
#define NEGFIXABLE(f) ((f) >= FIXNUM_MIN)
|
||||
#define FIXABLE(f) (POSFIXABLE(f) && NEGFIXABLE(f))
|
||||
|
||||
mrb_value mrb_dbl2big(mrb_state *mrb, float d);
|
||||
void mrb_num_zerodiv(mrb_state *mrb);
|
||||
mrb_value mrb_fix2str(mrb_state *mrb, mrb_value x, int base);
|
||||
|
||||
#endif /* MRUBY_NUMERIC_H */
|
||||
@@ -0,0 +1,46 @@
|
||||
#ifndef MRUBY_OBJECT_H
|
||||
#define MRUBY_OBJECT_H
|
||||
|
||||
#define MRUBY_OBJECT_HEADER \
|
||||
enum mrb_vtype tt:8;\
|
||||
int color:3;\
|
||||
unsigned int flags:21;\
|
||||
struct RClass *c;\
|
||||
struct RBasic *gcnext;
|
||||
|
||||
|
||||
/* white: 011, black: 100, gray: 000 */
|
||||
#define MRB_GC_GRAY 0
|
||||
#define MRB_GC_WHITE_A 1
|
||||
#define MRB_GC_WHITE_B (1 << 1)
|
||||
#define MRB_GC_BLACK (1 << 2)
|
||||
#define MRB_GC_WHITES (MRB_GC_WHITE_A | MRB_GC_WHITE_B)
|
||||
#define MRB_GC_COLOR_MASK 7
|
||||
|
||||
#define paint_gray(o) ((o)->color = MRB_GC_GRAY)
|
||||
#define paint_black(o) ((o)->color = MRB_GC_BLACK)
|
||||
#define paint_white(o) ((o)->color = MRB_GC_WHITES)
|
||||
#define paint_partial_white(s, o) ((o)->color = (s)->current_white_part)
|
||||
#define is_gray(o) ((o)->color == MRB_GC_GRAY)
|
||||
#define is_white(o) ((o)->color & MRB_GC_WHITES)
|
||||
#define is_black(o) ((o)->color & MRB_GC_BLACK)
|
||||
#define is_dead(s, o) (((o)->color & other_white_part(s) & MRB_GC_WHITES) || (o)->tt == MRB_TT_FREE)
|
||||
#define flip_white_part(s) ((s)->current_white_part = other_white_part(s))
|
||||
#define other_white_part(s) ((s)->current_white_part ^ MRB_GC_WHITES)
|
||||
|
||||
struct RBasic {
|
||||
MRUBY_OBJECT_HEADER;
|
||||
};
|
||||
|
||||
struct RObject {
|
||||
MRUBY_OBJECT_HEADER;
|
||||
struct kh_iv *iv;
|
||||
};
|
||||
|
||||
#define mrb_obj_ptr(v) ((struct RObject*)((v).value.p))
|
||||
#define RBASIC(obj) ((struct RBasic*)((obj).value.p))
|
||||
#define RBASIC_KLASS(v) ((struct RClass *)(((struct RBasic*)((v).value.p))->c))
|
||||
#define ROBJECT(v) ((struct RObject*)((v).value.p))
|
||||
#define ROBJECT_IVPTR(v) (((struct RObject*)((v).value.p))->iv)
|
||||
#define ROBJECT_NUMIV(v) (ROBJECT_IVPTR(v) ? ROBJECT_IVPTR(v)->size : 0)
|
||||
#endif /* MRUBY_OBJECT_H */
|
||||
@@ -0,0 +1,44 @@
|
||||
#ifndef MRUBY_PROC_H
|
||||
#define MRUBY_PROC_H
|
||||
|
||||
#include "mruby.h"
|
||||
#include "irep.h"
|
||||
|
||||
struct REnv {
|
||||
MRUBY_OBJECT_HEADER;
|
||||
mrb_value *stack;
|
||||
mrb_sym mid;
|
||||
int cioff;
|
||||
};
|
||||
|
||||
struct RProc {
|
||||
MRUBY_OBJECT_HEADER;
|
||||
union {
|
||||
mrb_irep *irep;
|
||||
mrb_func_t func;
|
||||
} body;
|
||||
struct RClass *target_class;
|
||||
struct REnv *env;
|
||||
};
|
||||
|
||||
/* aspec access */
|
||||
#define ARGS_GETREQ(a) (((a) >> 19) & 0x1f)
|
||||
#define ARGS_GETOPT(a) (((a) >> 14) & 0x1f)
|
||||
#define ARGS_GETREST(a) ((a) & (1<<13))
|
||||
#define ARGS_GETPOST(a) (((a) >> 8) & 0x1f)
|
||||
#define ARGS_GETKEY(a) (((a) >> 3) & 0x1f))
|
||||
#define ARGS_GETKDICT(a) ((a) & (1<<2))
|
||||
#define ARGS_GETBLOCK(a) ((a) & (1<<1))
|
||||
|
||||
#define MRB_PROC_CFUNC 128
|
||||
#define MRB_PROC_CFUNC_P(p) ((p)->flags & MRB_PROC_CFUNC)
|
||||
#define MRB_PROC_STRICT 256
|
||||
#define MRB_PROC_STRICT_P(p) ((p)->flags & MRB_PROC_STRICT)
|
||||
|
||||
#define mrb_proc_ptr(v) ((struct RProc*)((v).value.p))
|
||||
|
||||
struct RProc *mrb_proc_new(mrb_state*, mrb_irep*);
|
||||
struct RProc *mrb_proc_new_cfunc(mrb_state*, mrb_func_t);
|
||||
struct RProc *mrb_closure_new(mrb_state*, mrb_irep*);
|
||||
|
||||
#endif /* MRUBY_STRING_H */
|
||||
@@ -0,0 +1,21 @@
|
||||
#ifndef MRUBY_RANGE_H
|
||||
#define MRUBY_RANGE_H
|
||||
|
||||
struct RRange {
|
||||
MRUBY_OBJECT_HEADER;
|
||||
struct mrb_range_edges {
|
||||
mrb_value beg;
|
||||
mrb_value end;
|
||||
} *edges;
|
||||
int excl;
|
||||
};
|
||||
|
||||
#define mrb_range_ptr(v) ((struct RRange*)((v).value.p))
|
||||
#define mrb_range_value(p) mrb_obj_value((void*)(p))
|
||||
|
||||
mrb_value mrb_range_new(mrb_state*, mrb_value, mrb_value, int);
|
||||
mrb_int mrb_range_beg_len(mrb_state *mrb, mrb_value range, mrb_int *begp, mrb_int *lenp, mrb_int len, mrb_int err);
|
||||
int mrb_obj_is_instance_of(mrb_state *mrb, mrb_value obj, struct RClass* c);
|
||||
struct RClass* mrb_class_real(struct RClass* cl);
|
||||
|
||||
#endif /* MRUBY_RANGE_H */
|
||||
@@ -0,0 +1,133 @@
|
||||
#ifndef MRUBY_STRING_H
|
||||
#define MRUBY_STRING_H
|
||||
|
||||
#ifdef INCLUDE_ENCODING
|
||||
#include "encoding.h"
|
||||
#endif
|
||||
|
||||
#ifndef RB_GC_GUARD
|
||||
#define RB_GC_GUARD(v) v
|
||||
#endif
|
||||
|
||||
#define IS_EVSTR(p,e) ((p) < (e) && (*(p) == '$' || *(p) == '@' || *(p) == '{'))
|
||||
|
||||
#define mrb_str_new4 mrb_str_new_frozen
|
||||
|
||||
#define STR_BUF_MIN_SIZE 128
|
||||
//#define RSTRING_EMBED_LEN_MAX STR_BUF_MIN_SIZE
|
||||
|
||||
extern const char ruby_digitmap[];
|
||||
|
||||
struct RString {
|
||||
MRUBY_OBJECT_HEADER;
|
||||
size_t len;
|
||||
union {
|
||||
size_t capa;
|
||||
mrb_value shared;
|
||||
} aux;
|
||||
char *buf;
|
||||
};
|
||||
|
||||
extern struct SCOPE {
|
||||
struct RBasic super;
|
||||
mrb_sym *local_tbl;
|
||||
mrb_value *local_vars;
|
||||
int flags;
|
||||
} *ruby_scope;
|
||||
|
||||
struct RVarmap {
|
||||
struct RBasic super;
|
||||
mrb_sym id;
|
||||
mrb_value val;
|
||||
struct RVarmap *next;
|
||||
};
|
||||
extern struct RVarmap *ruby_dyna_vars;
|
||||
|
||||
//struct st_hash_type {
|
||||
// int (*compare)();
|
||||
// int (*hash)();
|
||||
//};
|
||||
|
||||
#define mrb_str_ptr(s) ((struct RString*)((s).value.p))
|
||||
#define RSTRING(s) ((struct RString*)((s).value.p))
|
||||
#define RSTRING_PTR(s) (RSTRING(s)->buf)
|
||||
#define RSTRING_LEN(s) (RSTRING(s)->len)
|
||||
#define RSTRING_CAPA(s) (RSTRING(s)->aux.capa)
|
||||
#define RSTRING_SHARED(s) (RSTRING(s)->aux.shared)
|
||||
#define RSTRING_END(s) (RSTRING(s)->buf + RSTRING(s)->len)
|
||||
|
||||
#define MRB_STR_SHARED 256
|
||||
#define MRB_STR_SHARED_P(s) (FL_ALL(s, MRB_STR_SHARED))
|
||||
#define MRB_STR_NOCAPA (MRB_STR_SHARED)
|
||||
#define MRB_STR_NOCAPA_P(s) (FL_ANY(s, MRB_STR_NOCAPA))
|
||||
#define MRB_STR_UNSET_NOCAPA(s) do {\
|
||||
FL_UNSET(s, MRB_STR_NOCAPA);\
|
||||
} while (0)
|
||||
|
||||
mrb_value mrb_str_literal(mrb_state*, mrb_value);
|
||||
void mrb_str_concat(mrb_state*, mrb_value, mrb_value);
|
||||
mrb_value mrb_obj_to_str(mrb_state*, mrb_value);
|
||||
mrb_value mrb_str_plus(mrb_state*, mrb_value, mrb_value);
|
||||
mrb_value mrb_obj_as_string(mrb_state *mrb, mrb_value obj);
|
||||
mrb_value mrb_str_new(mrb_state *mrb, const char *p, size_t len); /* mrb_str_new */
|
||||
mrb_value mrb_str_resize(mrb_state *mrb, mrb_value str, size_t len); /* mrb_str_resize */
|
||||
mrb_value mrb_string_value(mrb_state *mrb, mrb_value *ptr); /* StringValue */
|
||||
mrb_value mrb_str_substr(mrb_state *mrb, mrb_value str, mrb_int beg, int len);
|
||||
mrb_value mrb_check_string_type(mrb_state *mrb, mrb_value str);
|
||||
mrb_value mrb_str_buf_new(mrb_state *mrb, size_t capa);
|
||||
mrb_value mrb_str_buf_cat(mrb_state *mrb, mrb_value str, const char *ptr, size_t len);
|
||||
mrb_value str_buf_cat(mrb_state *mrb, mrb_value str, const char *ptr, size_t len);
|
||||
|
||||
char * mrb_string_value_cstr(mrb_state *mrb, mrb_value *ptr);
|
||||
char * mrb_string_value_ptr(mrb_state *mrb, mrb_value ptr);
|
||||
mrb_value mrb_str_subseq(mrb_state *mrb, mrb_value str, long beg, long len);
|
||||
size_t mrb_str_sublen(mrb_state *mrb, mrb_value str, long pos);
|
||||
mrb_value mrb_str_size(mrb_state *mrb, mrb_value self);
|
||||
long mrb_str_offset(mrb_state *mrb, mrb_value str, long pos);
|
||||
mrb_value mrb_str_new2(mrb_state *mrb, const char *p);
|
||||
mrb_value mrb_str_dup(mrb_state *mrb, mrb_value str); /* mrb_str_dup */
|
||||
mrb_value mrb_str_new_frozen(mrb_state *mrb, mrb_value orig);
|
||||
mrb_value mrb_lastline_get(mrb_state *mrb);
|
||||
mrb_value mrb_usascii_str_new(mrb_state *mrb, const char *ptr, long len);
|
||||
void mrb_lastline_set(mrb_value val);
|
||||
mrb_value mrb_str_buf_cat_ascii(mrb_state *mrb, mrb_value str, const char *ptr);
|
||||
void mrb_str_modify(mrb_state *mrb, mrb_value str);
|
||||
void mrb_str_set_len(mrb_state *mrb, mrb_value str, long len);
|
||||
mrb_value mrb_str_intern(mrb_state *mrb, mrb_value self);
|
||||
void mrb_str_shared_replace(mrb_state *mrb, mrb_value str, mrb_value str2);
|
||||
mrb_value mrb_str_cat2(mrb_state *mrb, mrb_value str, const char *ptr);
|
||||
mrb_value mrb_str_catf(mrb_state *mrb, mrb_value str, const char *format, ...);
|
||||
mrb_value mrb_str_to_inum(mrb_state *mrb, mrb_value str, int base, int badcheck);
|
||||
double mrb_str_to_dbl(mrb_state *mrb, mrb_value str, int badcheck);
|
||||
mrb_value mrb_str_to_str(mrb_state *mrb, mrb_value str);
|
||||
mrb_value mrb_locale_str_new(mrb_state *mrb, const char *ptr, long len);
|
||||
mrb_value mrb_filesystem_str_new_cstr(mrb_state *mrb, const char *ptr);
|
||||
mrb_int mrb_str_hash(mrb_state *mrb, mrb_value str);
|
||||
int mrb_str_hash_cmp(mrb_state *mrb, mrb_value str1, mrb_value str2);
|
||||
mrb_value str_new3(mrb_state *mrb, struct RClass* klass, mrb_value str);
|
||||
mrb_value mrb_str_buf_append(mrb_state *mrb, mrb_value str, mrb_value str2);
|
||||
void mrb_str_setter(mrb_state *mrb, mrb_value val, mrb_sym id, mrb_value *var);
|
||||
int mrb_str_is_ascii_only_p(mrb_state *mrb, mrb_value str);
|
||||
mrb_value mrb_str_inspect(mrb_state *mrb, mrb_value str);
|
||||
int mrb_str_equal(mrb_state *mrb, mrb_value str1, mrb_value str2);
|
||||
mrb_value str_new4(mrb_state *mrb, enum mrb_vtype ttype, mrb_value str);
|
||||
mrb_value * mrb_svar(mrb_int cnt);
|
||||
mrb_value mrb_str_drop_bytes(mrb_state *mrb, mrb_value str, long len);
|
||||
mrb_value mrb_str_dump(mrb_state *mrb, mrb_value str);
|
||||
mrb_value mrb_str_cat(mrb_state *mrb, mrb_value str, const char *ptr, long len);
|
||||
mrb_value mrb_str_append(mrb_state *mrb, mrb_value str, mrb_value str2);
|
||||
size_t mrb_str_capacity(mrb_value str);
|
||||
|
||||
#ifdef INCLUDE_ENCODING
|
||||
int sym_printable(mrb_state *mrb, const char *s, const char *send, mrb_encoding *enc);
|
||||
mrb_value mrb_str_conv_enc(mrb_state *mrb, mrb_value str, mrb_encoding *from, mrb_encoding *to);
|
||||
mrb_value mrb_str_conv_enc_opts(mrb_state *mrb, mrb_value str, mrb_encoding *from, mrb_encoding *to, int ecflags, mrb_value ecopts);
|
||||
mrb_value mrb_enc_str_new(mrb_state *mrb, const char *ptr, long len, mrb_encoding *enc);
|
||||
#else
|
||||
int mrb_symname_p(const char *name);
|
||||
#endif
|
||||
|
||||
mrb_value mrb_tainted_str_new(mrb_state *mrb, const char *ptr, long len);
|
||||
int mrb_str_cmp(mrb_state *mrb, mrb_value str1, mrb_value str2);
|
||||
|
||||
#endif /* MRUBY_STRING_H */
|
||||
@@ -0,0 +1,16 @@
|
||||
#ifndef MSTRUCT_H
|
||||
#define MSTRUCT_H
|
||||
|
||||
struct RStruct {
|
||||
struct RBasic basic;
|
||||
long len;
|
||||
mrb_value *ptr;
|
||||
};
|
||||
#define RSTRUCT(st) ((struct RStruct*)((st).value.p))
|
||||
#define RSTRUCT_LEN(st) ((int)(RSTRUCT(st)->len))
|
||||
#define RSTRUCT_PTR(st) (RSTRUCT(st)->ptr)
|
||||
|
||||
mrb_value mrb_yield_values(int n, ...);
|
||||
mrb_value mrb_mod_module_eval(mrb_state *mrb, int argc, mrb_value *argv, mrb_value mod);
|
||||
|
||||
#endif //MSTRUCT_H
|
||||
@@ -0,0 +1,62 @@
|
||||
# makefile discription.
|
||||
# basic build file for RiteVM library
|
||||
# 11.Oct.2011 coded by Hiroshi Mimaki.
|
||||
|
||||
# project-specific macros
|
||||
# extension of the executable-file is modifiable(.exe .out ...)
|
||||
BASEDIR = .
|
||||
TARGET := mrblib
|
||||
MLIB := $(TARGET).o
|
||||
CLIB := $(TARGET).c
|
||||
DLIB := $(TARGET).ctmp
|
||||
RLIB := $(TARGET).rbtmp
|
||||
MRB1 := $(BASEDIR)/*.rb
|
||||
MRBS := $(MRB1)
|
||||
|
||||
# C compiler (gcc)
|
||||
CC = gcc
|
||||
DEBUG_MODE = 1
|
||||
ifeq ($(DEBUG_MODE),1)
|
||||
CFLAGS = -g
|
||||
else
|
||||
CFLAGS = -O3
|
||||
endif
|
||||
INCLUDES = -I../src -I../include
|
||||
ALL_CFLAGS = -Wall -Werror-implicit-function-declaration $(CFLAGS)
|
||||
MAKE_FLAGS = --no-print-directory CC="$(CC)" LL="$(LL)"
|
||||
|
||||
# mruby compiler
|
||||
ifeq ($(OS),Windows_NT)
|
||||
MRBC = ../bin/mrbc.exe
|
||||
else
|
||||
MRBC = ../bin/mrbc
|
||||
endif
|
||||
|
||||
##############################
|
||||
# generic build targets, rules
|
||||
|
||||
.PHONY : all
|
||||
all : $(MRBC) $(MLIB)
|
||||
@echo "make: built targets of `pwd`"
|
||||
|
||||
# Compile mrblib source
|
||||
$(MLIB) : $(CLIB)
|
||||
$(CC) $(ALL_CFLAGS) -MMD $(INCLUDES) -c $(CLIB) -o $(MLIB)
|
||||
|
||||
# Compile C source from merged mruby source
|
||||
$(CLIB) : $(RLIB) $(MRBC)
|
||||
$(MRBC) -Bmrblib_irep -o$(DLIB) $(RLIB); cat init_$(TARGET).c $(DLIB) > $@
|
||||
|
||||
$(MRBC) : ../src/opcode.h ../src/codegen.c ../src/parse.y
|
||||
$(MAKE) -C ../tools/mrbc $(MAKE_FLAGS)
|
||||
|
||||
# merge mruby sources
|
||||
$(RLIB) : $(MRBS)
|
||||
cat $? > $@
|
||||
|
||||
# clean up
|
||||
.PHONY : clean
|
||||
clean :
|
||||
-rm -f $(MRBC) $(MLIB) $(CLIB) $(RLIB) $(DLIB)
|
||||
@echo "make: removing targets, objects and depend files of `pwd`"
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
#
|
||||
# Array
|
||||
#
|
||||
class Array
|
||||
# 15.2.12.5.10
|
||||
def each(&block)
|
||||
idx = 0
|
||||
while(idx < length)
|
||||
block.call(self[idx])
|
||||
idx += 1
|
||||
end
|
||||
self
|
||||
end
|
||||
|
||||
# 15.2.12.5.11
|
||||
def each_index(&block)
|
||||
idx = 0
|
||||
while(idx < length)
|
||||
block.call(idx)
|
||||
idx += 1
|
||||
end
|
||||
self
|
||||
end
|
||||
|
||||
# 15.2.12.5.7
|
||||
def collect!(&block)
|
||||
self.each_index{|idx|
|
||||
self[idx] = block.call(self[idx])
|
||||
}
|
||||
self
|
||||
end
|
||||
|
||||
# 15.2.12.5.20
|
||||
# map!(&block)
|
||||
alias map! collect!
|
||||
|
||||
# 15.2.12.5.15
|
||||
def initialize(size=0, obj=nil, &block)
|
||||
raise TypeError, "expected Integer for 1st argument" unless size.kind_of? Integer
|
||||
raise ArgumentError, "negative array size" if size < 0
|
||||
|
||||
self.clear
|
||||
if size > 0
|
||||
self[size - 1] = nil # allocate
|
||||
|
||||
idx = 0
|
||||
while(idx < size)
|
||||
self[idx] = (block)? block.call(idx): obj
|
||||
idx += 1
|
||||
end
|
||||
end
|
||||
|
||||
self
|
||||
end
|
||||
|
||||
def delete(key, &block)
|
||||
while i = self.index(key)
|
||||
self.delete_at(i)
|
||||
ret = key
|
||||
end
|
||||
if ret == nil && block
|
||||
block.call
|
||||
else
|
||||
ret
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# include modules
|
||||
module Enumerable; end
|
||||
module Comparable; end
|
||||
class Array
|
||||
include Enumerable
|
||||
include Comparable
|
||||
|
||||
def sort!(&block)
|
||||
self.replace(self.sort(&block))
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,63 @@
|
||||
### move to compar.c
|
||||
# module Comparable
|
||||
# def == other
|
||||
# cmp = self <=> other
|
||||
# if cmp == 0
|
||||
# true
|
||||
# else
|
||||
# false
|
||||
# end
|
||||
# end
|
||||
|
||||
# def < other
|
||||
# cmp = self <=> other
|
||||
# if cmp.nil?
|
||||
# false
|
||||
# elsif cmp < 0
|
||||
# true
|
||||
# else
|
||||
# false
|
||||
# end
|
||||
# end
|
||||
|
||||
# def <= other
|
||||
# cmp = self <=> other
|
||||
# if cmp.nil?
|
||||
# false
|
||||
# elsif cmp <= 0
|
||||
# true
|
||||
# else
|
||||
# false
|
||||
# end
|
||||
# end
|
||||
|
||||
# def > other
|
||||
# cmp = self <=> other
|
||||
# if cmp.nil?
|
||||
# false
|
||||
# elsif cmp > 0
|
||||
# true
|
||||
# else
|
||||
# false
|
||||
# end
|
||||
# end
|
||||
|
||||
# def >= other
|
||||
# cmp = self <=> other
|
||||
# if cmp.nil?
|
||||
# false
|
||||
# elsif cmp >= 0
|
||||
# true
|
||||
# else
|
||||
# false
|
||||
# end
|
||||
# end
|
||||
|
||||
# def between?(min,max)
|
||||
# if self < min or self > max
|
||||
# false
|
||||
# else
|
||||
# true
|
||||
# end
|
||||
# end
|
||||
# end
|
||||
+266
@@ -0,0 +1,266 @@
|
||||
#
|
||||
# Enumerable
|
||||
#
|
||||
module Enumerable
|
||||
# 15.3.2.2.1
|
||||
def all?(&block)
|
||||
st = true
|
||||
if block
|
||||
self.each{|val|
|
||||
unless block.call(val)
|
||||
st = false
|
||||
break
|
||||
end
|
||||
}
|
||||
else
|
||||
self.each{|val|
|
||||
unless val
|
||||
st = false
|
||||
break
|
||||
end
|
||||
}
|
||||
end
|
||||
st
|
||||
end
|
||||
|
||||
# 15.3.2.2.2
|
||||
def any?(&block)
|
||||
st = false
|
||||
if block
|
||||
self.each{|val|
|
||||
if block.call(val)
|
||||
st = true
|
||||
break
|
||||
end
|
||||
}
|
||||
else
|
||||
self.each{|val|
|
||||
if val
|
||||
st = true
|
||||
break
|
||||
end
|
||||
}
|
||||
end
|
||||
st
|
||||
end
|
||||
|
||||
# 15.3.2.2.3
|
||||
def collect(&block)
|
||||
ary = []
|
||||
self.each{|val|
|
||||
ary.push(block.call(val))
|
||||
}
|
||||
ary
|
||||
end
|
||||
|
||||
# 15.3.2.2.4
|
||||
def detect(ifnone=nil, &block)
|
||||
ret = ifnone
|
||||
self.each{|val|
|
||||
if block.call(val)
|
||||
ret = val
|
||||
break
|
||||
end
|
||||
}
|
||||
ret
|
||||
end
|
||||
|
||||
# 15.3.2.2.5
|
||||
def each_with_index(&block)
|
||||
i = 0
|
||||
self.each{|val|
|
||||
block.call(val, i)
|
||||
i += 1
|
||||
}
|
||||
self
|
||||
end
|
||||
|
||||
# 15.3.2.2.6
|
||||
def entries
|
||||
ary = []
|
||||
self.each{|val|
|
||||
ary.push val
|
||||
}
|
||||
ary
|
||||
end
|
||||
|
||||
# 15.3.2.2.7
|
||||
# find(ifnone=nil, &block)
|
||||
alias find detect
|
||||
|
||||
# 15.3.2.2.8
|
||||
def find_all(&block)
|
||||
ary = []
|
||||
self.each{|val|
|
||||
ary.push(val) if block.call(val)
|
||||
}
|
||||
ary
|
||||
end
|
||||
|
||||
# 15.3.2.2.9
|
||||
def grep(pattern, &block)
|
||||
ary = []
|
||||
self.each{|val|
|
||||
if pattern === val
|
||||
ary.push((block)? block.call(val): val)
|
||||
end
|
||||
}
|
||||
ary
|
||||
end
|
||||
|
||||
# 15.3.2.2.10
|
||||
def include?(obj)
|
||||
st = false
|
||||
self.each{|val|
|
||||
if val == obj
|
||||
st = true
|
||||
break
|
||||
end
|
||||
}
|
||||
st
|
||||
end
|
||||
|
||||
# 15.3.2.2.11
|
||||
def inject(*args, &block)
|
||||
raise ArgumentError, "too many arguments" if args.size > 2
|
||||
flag = true # 1st element?
|
||||
result = nil
|
||||
self.each{|val|
|
||||
if flag
|
||||
# 1st element
|
||||
result = (args.empty?)? val: block.call(args[0], val)
|
||||
flag = false
|
||||
else
|
||||
result = block.call(result, val)
|
||||
end
|
||||
}
|
||||
result
|
||||
end
|
||||
|
||||
# 15.3.2.2.12
|
||||
# map(&block)
|
||||
alias map collect
|
||||
|
||||
# 15.3.2.2.13
|
||||
def max(&block)
|
||||
flag = true # 1st element?
|
||||
result = nil
|
||||
self.each{|val|
|
||||
if flag
|
||||
# 1st element
|
||||
result = val
|
||||
flag = false
|
||||
else
|
||||
if block
|
||||
result = val if block.call(val, result) > 0
|
||||
else
|
||||
result = val if (val <=> result) > 0
|
||||
end
|
||||
end
|
||||
}
|
||||
result
|
||||
end
|
||||
|
||||
# 15.3.2.2.14
|
||||
def min(&block)
|
||||
flag = true # 1st element?
|
||||
result = nil
|
||||
self.each{|val|
|
||||
if flag
|
||||
# 1st element
|
||||
result = val
|
||||
flag = false
|
||||
else
|
||||
if block
|
||||
result = val if block.call(val, result) < 0
|
||||
else
|
||||
result = val if (val <=> result) < 0
|
||||
end
|
||||
end
|
||||
}
|
||||
result
|
||||
end
|
||||
|
||||
# 15.3.2.2.15
|
||||
# member?(obj)
|
||||
alias member? include?
|
||||
|
||||
# 15.3.2.2.16
|
||||
def partition(&block)
|
||||
ary_T = []
|
||||
ary_F = []
|
||||
self.each{|val|
|
||||
if block.call(val)
|
||||
ary_T.push(val)
|
||||
else
|
||||
ary_F.push(val)
|
||||
end
|
||||
}
|
||||
[ary_T, ary_F]
|
||||
end
|
||||
|
||||
# 15.3.2.2.17
|
||||
def reject(&block)
|
||||
ary = []
|
||||
self.each{|val|
|
||||
ary.push(val) unless block.call(val)
|
||||
}
|
||||
ary
|
||||
end
|
||||
|
||||
# 15.3.2.2.18
|
||||
# select(&block)
|
||||
alias select find_all
|
||||
|
||||
|
||||
# Does this OK? Please test it.
|
||||
def __sort_sub__(sorted, work, src_ary, head, tail, &block)
|
||||
if head == tail
|
||||
sorted[head] = work[head] if src_ary == 1
|
||||
return
|
||||
end
|
||||
|
||||
# on current step, which is a src ary?
|
||||
if src_ary == 0
|
||||
src, dst = sorted, work
|
||||
else
|
||||
src, dst = work, sorted
|
||||
end
|
||||
|
||||
key = src[head] # key value for dividing values
|
||||
i, j = head, tail # position to store on the dst ary
|
||||
|
||||
(head + 1).upto(tail){|idx|
|
||||
if ((block)? block.call(src[idx], key): (src[idx] <=> key)) > 0
|
||||
# larger than key
|
||||
dst[j] = src[idx]
|
||||
j -= 1
|
||||
else
|
||||
dst[i] = src[idx]
|
||||
i += 1
|
||||
end
|
||||
}
|
||||
|
||||
sorted[i] = key
|
||||
|
||||
# sort each sub-array
|
||||
src_ary = (src_ary + 1) % 2 # exchange a src ary
|
||||
__sort_sub__(sorted, work, src_ary, head, i - 1, &block) if i > head
|
||||
__sort_sub__(sorted, work, src_ary, i + 1, tail, &block) if i < tail
|
||||
end
|
||||
# private :__sort_sub__
|
||||
|
||||
# 15.3.2.2.19
|
||||
def sort(&block)
|
||||
ary = []
|
||||
self.each{|val| ary.push(val)}
|
||||
unless ary.empty?
|
||||
__sort_sub__(ary, ::Array.new(ary.size), 0, 0, ary.size - 1, &block)
|
||||
end
|
||||
ary
|
||||
end
|
||||
|
||||
# 15.3.2.2.20
|
||||
# to_a
|
||||
alias to_a entries
|
||||
end
|
||||
@@ -0,0 +1,9 @@
|
||||
#
|
||||
# Exception
|
||||
#
|
||||
class Exception
|
||||
# 15.2.22.4.1
|
||||
def self.exception(*args, &block)
|
||||
self.new(*args, &block)
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,58 @@
|
||||
#
|
||||
# Hash
|
||||
#
|
||||
class Hash
|
||||
# 15.2.13.4.8
|
||||
def delete(key, &block)
|
||||
if block && ! self.has_key?(key)
|
||||
block.call(key)
|
||||
else
|
||||
self.__delete(key)
|
||||
end
|
||||
end
|
||||
|
||||
# 15.2.13.4.9
|
||||
def each(&block)
|
||||
self.keys.each{|k| block.call([k, self[k]])}
|
||||
self
|
||||
end
|
||||
|
||||
# 15.2.13.4.10
|
||||
def each_key(&block)
|
||||
self.keys.each{|k| block.call(k)}
|
||||
self
|
||||
end
|
||||
|
||||
# 15.2.13.4.11
|
||||
def each_value(&block)
|
||||
self.keys.each{|k| block.call(self[k])}
|
||||
self
|
||||
end
|
||||
|
||||
# 15.2.13.4.16
|
||||
def initialize(*args, &block)
|
||||
self.__init_core(block, *args)
|
||||
end
|
||||
|
||||
# 15.2.13.4.22
|
||||
def merge(other, &block)
|
||||
h = {}
|
||||
raise "can't convert argument into Hash" unless other.respond_to?(:to_hash)
|
||||
other = other.to_hash
|
||||
self.each_key{|k| h[k] = self[k]}
|
||||
if block
|
||||
other.each_key{|k|
|
||||
h[k] = (self.has_key?(k))? block.call(k, self[k], other[k]): other[k]
|
||||
}
|
||||
else
|
||||
other.each_key{|k| h[k] = other[k]}
|
||||
end
|
||||
h
|
||||
end
|
||||
end
|
||||
|
||||
# include modules
|
||||
module Enumerable; end
|
||||
class Hash
|
||||
include Enumerable
|
||||
end
|
||||
@@ -0,0 +1,17 @@
|
||||
#include "mruby.h"
|
||||
#include "irep.h"
|
||||
#include "dump.h"
|
||||
#include "mruby/string.h"
|
||||
#include "mruby/proc.h"
|
||||
|
||||
extern const char mrblib_irep[];
|
||||
|
||||
void
|
||||
mrb_init_mrblib(mrb_state *mrb)
|
||||
{
|
||||
int n = mrb_read_irep(mrb, mrblib_irep);
|
||||
|
||||
extern mrb_value mrb_top_self(mrb_state *mrb);
|
||||
mrb_run(mrb, mrb_proc_new(mrb, mrb->irep[n]), mrb_top_self(mrb));
|
||||
}
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
#
|
||||
# Kernel
|
||||
#
|
||||
module Kernel
|
||||
# 15.3.1.2.6
|
||||
def self.lambda(&block)
|
||||
### *** TODO *** ###
|
||||
block # dummy
|
||||
end
|
||||
|
||||
# 15.3.1.2.8
|
||||
def self.loop #(&block)
|
||||
while(true)
|
||||
yield
|
||||
end
|
||||
end
|
||||
|
||||
# 15.3.1.3.4
|
||||
def __send__(symbol, *args, &block)
|
||||
### *** TODO *** ###
|
||||
end
|
||||
|
||||
# 15.3.1.3.18
|
||||
def instance_eval(string=nil, &block)
|
||||
### *** TODO *** ###
|
||||
end
|
||||
|
||||
# 15.3.1.3.27
|
||||
def lambda(&block)
|
||||
### *** TODO *** ###
|
||||
block # dummy
|
||||
end
|
||||
|
||||
# 15.3.1.3.29
|
||||
def loop #(&block)
|
||||
while(true)
|
||||
yield
|
||||
end
|
||||
end
|
||||
|
||||
# 15.3.1.3.44
|
||||
def send(symbol, *args, &block)
|
||||
### *** TODO *** ###
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,42 @@
|
||||
#
|
||||
# Integer
|
||||
#
|
||||
class Integer
|
||||
# 15.2.8.3.15
|
||||
def downto(num, &block)
|
||||
raise TypeError, "expected Integer" unless num.kind_of? Integer
|
||||
i = self
|
||||
while(i >= num)
|
||||
block.call(i)
|
||||
i -= 1
|
||||
end
|
||||
self
|
||||
end
|
||||
|
||||
# 15.2.8.3.22
|
||||
def times(&block)
|
||||
i = 0
|
||||
while(i < self)
|
||||
block.call(i)
|
||||
i += 1
|
||||
end
|
||||
self
|
||||
end
|
||||
|
||||
# 15.2.8.3.27
|
||||
def upto(num, &block)
|
||||
raise TypeError, "expected Integer" unless num.kind_of? Integer
|
||||
i = self
|
||||
while(i <= num)
|
||||
block.call(i)
|
||||
i += 1
|
||||
end
|
||||
self
|
||||
end
|
||||
end
|
||||
|
||||
# include modules
|
||||
module Comparable; end
|
||||
class Numeric
|
||||
include Comparable
|
||||
end
|
||||
@@ -0,0 +1,20 @@
|
||||
module Kernel
|
||||
def print(*args)
|
||||
i = 0
|
||||
len = args.size
|
||||
while i < len
|
||||
__printstr__ args[i].to_s
|
||||
i += 1
|
||||
end
|
||||
end
|
||||
def puts(*args)
|
||||
i = 0
|
||||
len = args.size
|
||||
while i < len
|
||||
__printstr__ args[i].to_s
|
||||
__printstr__ "\n"
|
||||
i += 1
|
||||
end
|
||||
__printstr__ "\n" if len == 0
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,30 @@
|
||||
#
|
||||
# Range
|
||||
#
|
||||
class Range
|
||||
# 15.2.14.4.4
|
||||
def each(&block)
|
||||
val = self.first
|
||||
unless val.respond_to? :succ
|
||||
raise TypeError, "can't iterate"
|
||||
end
|
||||
|
||||
last = self.last
|
||||
return self if (val <=> last) > 0
|
||||
|
||||
while((val <=> last) < 0)
|
||||
block.call(val)
|
||||
val = val.succ
|
||||
end
|
||||
|
||||
block.call(val) unless exclude_end?
|
||||
|
||||
self
|
||||
end
|
||||
end
|
||||
|
||||
# include modules
|
||||
module Enumerable; end
|
||||
class Range
|
||||
include Enumerable
|
||||
end
|
||||
@@ -0,0 +1,93 @@
|
||||
#
|
||||
# String
|
||||
#
|
||||
class String
|
||||
# 15.2.10.5.15
|
||||
def each_line(&block)
|
||||
# expect that str.index accepts an Integer for 1st argument as a byte data
|
||||
offset = 0
|
||||
while(pos = self.index(0x0a, offset))
|
||||
block.call(self[offset, pos + 1 - offset])
|
||||
offset = pos + 1
|
||||
end
|
||||
block.call(self[offset, self.size - offset]) if self.size > offset
|
||||
self
|
||||
end
|
||||
|
||||
# 15.2.10.5.18
|
||||
def gsub(*args, &block)
|
||||
unless (args.size == 1 && block) || args.size == 2
|
||||
raise ArgumentError, "wrong number of arguments"
|
||||
end
|
||||
|
||||
### *** TODO *** ###
|
||||
end
|
||||
|
||||
# 15.2.10.5.19
|
||||
def gsub!(*args, &block)
|
||||
str = self.gsub(*args, &block)
|
||||
if str != self
|
||||
self.replace(str)
|
||||
self
|
||||
else
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
# 15.2.10.5.32
|
||||
def scan(reg, &block)
|
||||
### *** TODO *** ###
|
||||
end
|
||||
|
||||
# 15.2.10.5.36
|
||||
def sub(*args, &block)
|
||||
unless (args.size == 1 && block) || args.size == 2
|
||||
raise ArgumentError, "wrong number of arguments"
|
||||
end
|
||||
|
||||
### *** TODO *** ###
|
||||
end
|
||||
|
||||
# 15.2.10.5.37
|
||||
def sub!(*args, &block)
|
||||
str = self.sub(*args, &block)
|
||||
if str != self
|
||||
self.replace(str)
|
||||
self
|
||||
else
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
def each_char(&block)
|
||||
pos = 0
|
||||
while(pos < self.size)
|
||||
block.call(self[pos])
|
||||
pos += 1
|
||||
end
|
||||
self
|
||||
end
|
||||
|
||||
def each_byte(&block)
|
||||
bytes = self.unpack("C*")
|
||||
pos = 0
|
||||
while(pos < bytes.size)
|
||||
block.call(bytes[pos])
|
||||
pos += 1
|
||||
end
|
||||
self
|
||||
end
|
||||
|
||||
def []=(pos, value)
|
||||
b = self[0, pos]
|
||||
a = self[pos+1..-1]
|
||||
p [b, value, a].join('')
|
||||
self.replace([b, value, a].join(''))
|
||||
end
|
||||
end
|
||||
|
||||
# include modules
|
||||
module Comparable; end
|
||||
class String
|
||||
include Comparable
|
||||
end
|
||||
@@ -0,0 +1,30 @@
|
||||
#
|
||||
# Struct
|
||||
#
|
||||
class Struct
|
||||
# 15.2.18.4.4
|
||||
def each(&block)
|
||||
self.class.members.each{|field|
|
||||
block.call(self[field])
|
||||
}
|
||||
self
|
||||
end
|
||||
|
||||
# 15.2.18.4.5
|
||||
def each_pair(&block)
|
||||
self.class.members.each{|field|
|
||||
block.call(field.to_sym, self[field])
|
||||
}
|
||||
self
|
||||
end
|
||||
|
||||
# 15.2.18.4.7
|
||||
def select(&block)
|
||||
ary = []
|
||||
self.class.members.each{|field|
|
||||
val = self[field]
|
||||
ary.push(val) if block.call(val)
|
||||
}
|
||||
ary
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,89 @@
|
||||
# makefile discription.
|
||||
# basic build file for RiteVM library
|
||||
# 11.Apr.2011 coded by Kenji Yoshimoto.
|
||||
# 31.Aug.2011 coded by Hiroshi Mimaki.
|
||||
|
||||
# project-specific macros
|
||||
# extension of the executable-file is modifiable(.exe .out ...)
|
||||
BASEDIR = .
|
||||
TARGET := ../lib/ritevm
|
||||
ifeq ($(OS),Windows_NT)
|
||||
LIB := $(TARGET).lib
|
||||
else
|
||||
LIB := $(TARGET).a
|
||||
endif
|
||||
YSRC := $(BASEDIR)/parse.y
|
||||
YC := $(BASEDIR)/y.tab.c
|
||||
EXCEPT1 := $(YC) $(BASEDIR)/minimain.c $(BASEDIR)/compile.c $(BASEDIR)/dump.c $(BASEDIR)/cdump.c
|
||||
OBJY := $(patsubst %.c,%.o,$(YC))
|
||||
OBJ1 := $(patsubst %.c,%.o,$(filter-out $(EXCEPT1),$(wildcard $(BASEDIR)/*.c)))
|
||||
#OBJ2 := $(patsubst %.c,%.o,$(wildcard $(BASEDIR)/ext/regex/*.c))
|
||||
#OBJ3 := $(patsubst %.c,%.o,$(wildcard $(BASEDIR)/ext/enc/*.c))
|
||||
OBJS := $(OBJ1) $(OBJ2) $(OBJ3)
|
||||
# mruby libraries
|
||||
EXTC := $(BASEDIR)/../mrblib/mrblib.c
|
||||
EXTRB := $(wildcard $(BASEDIR)/../mrblib/*.rb)
|
||||
EXTM := $(patsubst %.c,%.o,$(EXTC))
|
||||
# extend libraries
|
||||
#EXT1 := $(patsubst %.c,%.o,$(wildcard $(BASEDIR)/ext/socket/*.c))
|
||||
EXTS := $(EXT1)
|
||||
|
||||
# libraries, includes
|
||||
INCLUDES = -I$(BASEDIR) -I$(BASEDIR)/../include
|
||||
#INCLUDES = -I$(RITEVM_ROOT)
|
||||
|
||||
# compiler, linker (gcc)
|
||||
CC = gcc
|
||||
AR = ar
|
||||
YACC = bison
|
||||
|
||||
DEBUG_MODE = 1
|
||||
ifeq ($(DEBUG_MODE),1)
|
||||
CFLAGS = -g
|
||||
else
|
||||
CFLAGS = -O3
|
||||
endif
|
||||
ALL_CFLAGS = -Wall -Werror-implicit-function-declaration $(CFLAGS)
|
||||
MAKE_FLAGS = --no-print-directory CC="$(CC)" LL="$(LL)"
|
||||
|
||||
##############################
|
||||
# generic build targets, rules
|
||||
|
||||
.PHONY : all
|
||||
all : $(EXTM) $(LIB)
|
||||
@echo "make: built targets of `pwd`"
|
||||
|
||||
# executable constructed using linker from object files
|
||||
$(LIB) : $(OBJS) $(OBJY) $(EXTM) $(EXTS)
|
||||
$(AR) r $@ $(OBJS) $(OBJY) $(EXTM) $(EXTS)
|
||||
|
||||
-include $(OBJS:.o=.d) $(OBJY:.o=.d)
|
||||
|
||||
# objects compiled from source
|
||||
$(OBJS) : %.o : %.c
|
||||
$(CC) $(ALL_CFLAGS) -MMD $(INCLUDES) -c $< -o $@
|
||||
|
||||
# mruby library compile
|
||||
$(EXTM) : $(EXTRB) $(OBJS) $(OBJY)
|
||||
$(MAKE) -C ../mrblib $(MAKE_FLAGS)
|
||||
|
||||
# extend libraries complile
|
||||
$(EXTS) : %.o : %.c
|
||||
$(CC) $(ALL_CFLAGS) -MMD $(INCLUDES) -c $< -o $@
|
||||
|
||||
# parser complie
|
||||
$(OBJY) : $(YC)
|
||||
$(CC) $(ALL_CFLAGS) -MMD $(INCLUDES) -c $(YC) -o $(OBJY)
|
||||
|
||||
# yacc complie
|
||||
$(YC) : $(YSRC)
|
||||
$(YACC) -o $(YC) $(YSRC)
|
||||
|
||||
# clean up
|
||||
.PHONY : clean #cleandep
|
||||
clean :
|
||||
$(MAKE) clean -C ../mrblib $(MAKE_FLAGS)
|
||||
-rm -f $(LIB) $(OBJS) $(OBJY) $(YC)
|
||||
-rm -f $(OBJS:.o=.d) $(OBJY:.o=.d)
|
||||
@echo "make: removing targets, objects and depend files of `pwd`"
|
||||
|
||||
+1458
File diff suppressed because it is too large
Load Diff
+96
@@ -0,0 +1,96 @@
|
||||
/**********************************************************************
|
||||
ascii.c - Oniguruma (regular expression library)
|
||||
**********************************************************************/
|
||||
/*-
|
||||
* Copyright (c) 2002-2006 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "mruby.h"
|
||||
#ifdef INCLUDE_ENCODING
|
||||
#include "regenc.h"
|
||||
|
||||
OnigEncodingDefine(ascii, ASCII) = {
|
||||
onigenc_single_byte_mbc_enc_len,
|
||||
"ASCII-8BIT",/* name */
|
||||
1, /* max byte length */
|
||||
1, /* min byte length */
|
||||
onigenc_is_mbc_newline_0x0a,
|
||||
onigenc_single_byte_mbc_to_code,
|
||||
onigenc_single_byte_code_to_mbclen,
|
||||
onigenc_single_byte_code_to_mbc,
|
||||
onigenc_ascii_mbc_case_fold,
|
||||
onigenc_ascii_apply_all_case_fold,
|
||||
onigenc_ascii_get_case_fold_codes_by_str,
|
||||
onigenc_minimum_property_name_to_ctype,
|
||||
onigenc_ascii_is_code_ctype,
|
||||
onigenc_not_support_get_ctype_code_range,
|
||||
onigenc_single_byte_left_adjust_char_head,
|
||||
onigenc_always_true_is_allowed_reverse_match
|
||||
};
|
||||
ENC_ALIAS("BINARY", "ASCII-8BIT")
|
||||
ENC_REPLICATE("IBM437", "ASCII-8BIT")
|
||||
ENC_ALIAS("CP437", "IBM437")
|
||||
ENC_REPLICATE("IBM737", "ASCII-8BIT")
|
||||
ENC_ALIAS("CP737", "IBM737")
|
||||
ENC_REPLICATE("IBM775", "ASCII-8BIT")
|
||||
ENC_ALIAS("CP775", "IBM775")
|
||||
ENC_REPLICATE("CP850", "ASCII-8BIT")
|
||||
ENC_ALIAS("IBM850", "CP850")
|
||||
ENC_REPLICATE("IBM852", "ASCII-8BIT")
|
||||
ENC_REPLICATE("CP852", "IBM852")
|
||||
ENC_REPLICATE("IBM855", "ASCII-8BIT")
|
||||
ENC_REPLICATE("CP855", "IBM855")
|
||||
ENC_REPLICATE("IBM857", "ASCII-8BIT")
|
||||
ENC_ALIAS("CP857", "IBM857")
|
||||
ENC_REPLICATE("IBM860", "ASCII-8BIT")
|
||||
ENC_ALIAS("CP860", "IBM860")
|
||||
ENC_REPLICATE("IBM861", "ASCII-8BIT")
|
||||
ENC_ALIAS("CP861", "IBM861")
|
||||
ENC_REPLICATE("IBM862", "ASCII-8BIT")
|
||||
ENC_ALIAS("CP862", "IBM862")
|
||||
ENC_REPLICATE("IBM863", "ASCII-8BIT")
|
||||
ENC_ALIAS("CP863", "IBM863")
|
||||
ENC_REPLICATE("IBM864", "ASCII-8BIT")
|
||||
ENC_ALIAS("CP864", "IBM864")
|
||||
ENC_REPLICATE("IBM865", "ASCII-8BIT")
|
||||
ENC_ALIAS("CP865", "IBM865")
|
||||
ENC_REPLICATE("IBM866", "ASCII-8BIT")
|
||||
ENC_ALIAS("CP866", "IBM866")
|
||||
ENC_REPLICATE("IBM869", "ASCII-8BIT")
|
||||
ENC_ALIAS("CP869", "IBM869")
|
||||
ENC_REPLICATE("Windows-1258", "ASCII-8BIT")
|
||||
ENC_ALIAS("CP1258", "Windows-1258")
|
||||
ENC_REPLICATE("GB1988", "ASCII-8BIT")
|
||||
ENC_REPLICATE("macCentEuro", "ASCII-8BIT")
|
||||
ENC_REPLICATE("macCroatian", "ASCII-8BIT")
|
||||
ENC_REPLICATE("macCyrillic", "ASCII-8BIT")
|
||||
ENC_REPLICATE("macGreek", "ASCII-8BIT")
|
||||
ENC_REPLICATE("macIceland", "ASCII-8BIT")
|
||||
ENC_REPLICATE("macRoman", "ASCII-8BIT")
|
||||
ENC_REPLICATE("macRomania", "ASCII-8BIT")
|
||||
ENC_REPLICATE("macThai", "ASCII-8BIT")
|
||||
ENC_REPLICATE("macTurkish", "ASCII-8BIT")
|
||||
ENC_REPLICATE("macUkraine", "ASCII-8BIT")
|
||||
#endif //INCLUDE_ENCODING
|
||||
+197
@@ -0,0 +1,197 @@
|
||||
#include "cdump.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "irep.h"
|
||||
#include "mruby/string.h"
|
||||
#include "re.h"
|
||||
|
||||
#define MRB_CDUMP_LINE_LEN 128
|
||||
|
||||
#define SOURCE_CODE(fmt, ...) fprintf(f, fmt"\n", __VA_ARGS__)
|
||||
#define SOURCE_CODE0(str) do {fputs(str, f); putc('\n', f);} while (0)
|
||||
|
||||
static int
|
||||
make_cdump_isec(mrb_state *mrb, int irep_no, FILE *f)
|
||||
{
|
||||
int i;
|
||||
mrb_irep *irep = mrb->irep[irep_no];
|
||||
|
||||
if (irep == 0)
|
||||
return -1;
|
||||
|
||||
/* dump isec struct*/
|
||||
if (irep->ilen > 0) {
|
||||
SOURCE_CODE ("static mrb_code iseq_%d[] = {", irep_no);
|
||||
for (i=0; i<irep->ilen; i++)
|
||||
SOURCE_CODE(" 0x%08x," , irep->iseq[i]);
|
||||
SOURCE_CODE0 ("};");
|
||||
SOURCE_CODE0 ("");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static size_t
|
||||
str_format_len(mrb_value str)
|
||||
{
|
||||
size_t dump_len = 0;
|
||||
|
||||
char *src;
|
||||
|
||||
for (src = RSTRING_PTR(str); src < RSTRING_END(str);) {
|
||||
switch (*src) {
|
||||
case 0x07:/* BEL */ /* fall through */
|
||||
case 0x08:/* BS */ /* fall through */
|
||||
case 0x09:/* HT */ /* fall through */
|
||||
case 0x0A:/* LF */ /* fall through */
|
||||
case 0x0B:/* VT */ /* fall through */
|
||||
case 0x0C:/* FF */ /* fall through */
|
||||
case 0x0D:/* CR */ /* fall through */
|
||||
case 0x22:/* " */ /* fall through */
|
||||
case 0x27:/* ' */ /* fall through */
|
||||
case 0x3F:/* ? */ /* fall through */
|
||||
case 0x5C:/* \ */ /* fall through */
|
||||
dump_len += 2; src += 2;
|
||||
break;
|
||||
|
||||
default:
|
||||
dump_len++; src++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return dump_len;
|
||||
}
|
||||
|
||||
static char*
|
||||
str_to_format(mrb_value str, char *buf)
|
||||
{
|
||||
char *src, *dst;
|
||||
|
||||
for (src = RSTRING_PTR(str), dst = buf; src < RSTRING_END(str);) {
|
||||
switch (*src) {
|
||||
case 0x07:/* BEL */ memcpy(dst, "\\a", 2); dst+=2; src+=2; break;
|
||||
case 0x08:/* BS */ memcpy(dst, "\\b", 2); dst+=2; src+=2; break;
|
||||
case 0x09:/* HT */ memcpy(dst, "\\t", 2); dst+=2; src+=2; break;
|
||||
case 0x0A:/* LF */ memcpy(dst, "\\n", 2); dst+=2; src+=2; break;
|
||||
case 0x0B:/* VT */ memcpy(dst, "\\v", 2); dst+=2; src+=2; break;
|
||||
case 0x0C:/* FF */ memcpy(dst, "\\f", 2); dst+=2; src+=2; break;
|
||||
case 0x0D:/* CR */ memcpy(dst, "\\r", 2); dst+=2; src+=2; break;
|
||||
case 0x22:/* " */ memcpy(dst, "\\\"", 2); dst+=2; src+=2; break;
|
||||
case 0x27:/* ' */ memcpy(dst, "\\\'", 2); dst+=2; src+=2; break;
|
||||
case 0x3F:/* ? */ memcpy(dst, "\\\?", 2); dst+=2; src+=2; break;
|
||||
case 0x5C:/* \ */ memcpy(dst, "\\\\", 2); dst+=2; src+=2; break;
|
||||
default: *dst++ = *src++; break;
|
||||
}
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
int
|
||||
make_cdump_irep(mrb_state *mrb, int irep_no, FILE *f)
|
||||
{
|
||||
mrb_irep *irep = mrb->irep[irep_no];
|
||||
int n;
|
||||
char *buf = 0;
|
||||
size_t buf_len, str_len;
|
||||
|
||||
if (irep == 0)
|
||||
return -1;
|
||||
|
||||
buf_len = MRB_CDUMP_LINE_LEN;
|
||||
if ((buf = mrb_malloc(mrb, buf_len)) == 0 ) {
|
||||
return MRB_CDUMP_GENERAL_FAILURE;
|
||||
}
|
||||
|
||||
SOURCE_CODE0 (" irep = mrb->irep[idx] = mrb_malloc(mrb, sizeof(mrb_irep));");
|
||||
SOURCE_CODE0 (" irep->idx = idx++;");
|
||||
SOURCE_CODE (" irep->flags = %d | MRB_ISEQ_NOFREE;", irep->flags);
|
||||
SOURCE_CODE (" irep->nlocals = %d;", irep->nlocals);
|
||||
SOURCE_CODE (" irep->nregs = %d;", irep->nregs);
|
||||
SOURCE_CODE (" irep->ilen = %d;", irep->ilen);
|
||||
SOURCE_CODE (" irep->iseq = iseq_%d;", irep_no);
|
||||
|
||||
SOURCE_CODE (" irep->slen = %d;", irep->slen);
|
||||
if(irep->slen > 0) {
|
||||
SOURCE_CODE (" irep->syms = mrb_malloc(mrb, sizeof(mrb_sym)*%d);", irep->slen);
|
||||
for (n=0; n<irep->slen; n++)
|
||||
if (irep->syms[n]) {
|
||||
SOURCE_CODE (" irep->syms[%d] = mrb_intern(mrb, \"%s\");", n, mrb_sym2name(mrb, irep->syms[n]));
|
||||
}
|
||||
}
|
||||
else
|
||||
SOURCE_CODE0 (" irep->syms = NULL;");
|
||||
|
||||
SOURCE_CODE (" irep->plen = %d;", irep->plen);
|
||||
if(irep->plen > 0) {
|
||||
SOURCE_CODE (" irep->pool = mrb_malloc(mrb, sizeof(mrb_value)*%d);", irep->plen);
|
||||
for (n=0; n<irep->plen; n++) {
|
||||
switch (irep->pool[n].tt) {
|
||||
case MRB_TT_FLOAT:
|
||||
SOURCE_CODE(" irep->pool[%d] = mrb_float_value(%.16e);", n, irep->pool[n].value.f); break;
|
||||
case MRB_TT_STRING:
|
||||
str_len = str_format_len(irep->pool[n]) + 1;
|
||||
if ( str_len > buf_len ) {
|
||||
buf_len = str_len;
|
||||
if ((buf = mrb_realloc(mrb, buf, buf_len)) == 0 ) {
|
||||
return MRB_CDUMP_GENERAL_FAILURE;
|
||||
}
|
||||
}
|
||||
memset(buf, 0, buf_len);
|
||||
SOURCE_CODE(" irep->pool[%d] = mrb_str_new(mrb, \"%s\", %d);", n, str_to_format(irep->pool[n], buf), RSTRING_LEN(irep->pool[n])); break;
|
||||
/* TODO MRB_TT_REGEX */
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
SOURCE_CODE0 (" irep->pool = NULL;");
|
||||
SOURCE_CODE0("");
|
||||
return MRB_CDUMP_OK;
|
||||
}
|
||||
|
||||
int
|
||||
mrb_cdump_irep(mrb_state *mrb, int n, FILE *f,const char *initname)
|
||||
{
|
||||
int irep_no, irep_num;
|
||||
|
||||
if (mrb == 0 || n < 0 || n >= mrb->irep_len || f == 0 || initname == 0)
|
||||
return -1;
|
||||
|
||||
irep_num = mrb->irep_len - n;
|
||||
|
||||
SOURCE_CODE0("#include \"mruby.h\"");
|
||||
SOURCE_CODE0("#include \"irep.h\"");
|
||||
SOURCE_CODE0("#include \"mruby/string.h\"");
|
||||
SOURCE_CODE0("#include \"mruby/proc.h\"");
|
||||
SOURCE_CODE0("");
|
||||
|
||||
for (irep_no=n; irep_no<mrb->irep_len; irep_no++) {
|
||||
if (make_cdump_isec(mrb, irep_no, f) != 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
SOURCE_CODE0("void");
|
||||
SOURCE_CODE ("%s(mrb_state *mrb)", initname);
|
||||
SOURCE_CODE0("{");
|
||||
SOURCE_CODE0(" int n = mrb->irep_len;");
|
||||
SOURCE_CODE0(" int idx = n;");
|
||||
SOURCE_CODE0(" mrb_irep *irep;");
|
||||
SOURCE_CODE0("");
|
||||
SOURCE_CODE (" mrb_add_irep(mrb, idx+%d);", irep_num);
|
||||
SOURCE_CODE0("");
|
||||
for (irep_no=n; irep_no<mrb->irep_len; irep_no++) {
|
||||
if (make_cdump_irep(mrb, irep_no, f) != 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
SOURCE_CODE0(" mrb->irep_len = idx;");
|
||||
SOURCE_CODE0("");
|
||||
SOURCE_CODE0(" extern mrb_value mrb_top_self(mrb_state *mrb);");
|
||||
SOURCE_CODE0(" mrb_run(mrb, mrb_proc_new(mrb, mrb->irep[n]), mrb_top_self(mrb));");
|
||||
SOURCE_CODE0("}");
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
#include "mruby.h"
|
||||
#include <stdio.h>
|
||||
|
||||
int mrb_cdump_irep(mrb_state *mrb, int n, FILE *f,const char *initname);
|
||||
|
||||
/* error code */
|
||||
#define MRB_CDUMP_OK 0
|
||||
#define MRB_CDUMP_GENERAL_FAILURE -1
|
||||
+1049
File diff suppressed because it is too large
Load Diff
+2273
File diff suppressed because it is too large
Load Diff
+144
@@ -0,0 +1,144 @@
|
||||
#include "mruby.h"
|
||||
#include "mruby/string.h"
|
||||
#include "mruby/numeric.h"
|
||||
|
||||
void
|
||||
mrb_cmperr(mrb_state *mrb, mrb_value x, mrb_value y)
|
||||
{
|
||||
const char *classname;
|
||||
|
||||
if (SPECIAL_CONST_P(y)) {
|
||||
y = mrb_inspect(mrb, y);
|
||||
//classname = StringValuePtr(y);
|
||||
classname = mrb_string_value_ptr(mrb, y);
|
||||
}
|
||||
else {
|
||||
classname = mrb_obj_classname(mrb, y);
|
||||
}
|
||||
mrb_raise(mrb, E_ARGUMENT_ERROR, "comparison of %s with %s failed",
|
||||
mrb_obj_classname(mrb, x), classname);
|
||||
}
|
||||
|
||||
int
|
||||
mrb_cmpint(mrb_state *mrb, mrb_value val, mrb_value a, mrb_value b)
|
||||
{
|
||||
if (mrb_nil_p(val)) {
|
||||
mrb_cmperr(mrb, a, b);
|
||||
}
|
||||
if (FIXNUM_P(val)) {
|
||||
long l = mrb_fixnum(val);
|
||||
if (l > 0) return 1;
|
||||
if (l < 0) return -1;
|
||||
return 0;
|
||||
}
|
||||
if (mrb_test(mrb_funcall(mrb, val, ">", 1, mrb_fixnum_value(0)))) return 1;
|
||||
if (mrb_test(mrb_funcall(mrb, val, "<", 1, mrb_fixnum_value(0)))) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static mrb_value
|
||||
cmp_equal(mrb_state *mrb, mrb_value x)
|
||||
{
|
||||
mrb_value y, c;
|
||||
|
||||
/* *** TEMPORAL IMPLEMENT *** */
|
||||
|
||||
mrb_get_args(mrb, "o", &y);
|
||||
if (mrb_obj_equal(mrb, x, y)) return mrb_true_value();
|
||||
|
||||
c = mrb_funcall(mrb, x, "<=>", 1, y);
|
||||
|
||||
if (mrb_cmpint(mrb, c, x, y) == 0) return mrb_true_value();
|
||||
return mrb_false_value();
|
||||
}
|
||||
|
||||
#include <stdio.h>
|
||||
static mrb_value
|
||||
cmp_gt(mrb_state *mrb, mrb_value x, mrb_value y)
|
||||
{
|
||||
mrb_value c;
|
||||
|
||||
c = mrb_funcall(mrb, x, "<=>", 1, y);
|
||||
|
||||
if (mrb_cmpint(mrb, c, x, y) > 0) return mrb_true_value();
|
||||
return mrb_false_value();
|
||||
}
|
||||
|
||||
static mrb_value
|
||||
cmp_gt_m(mrb_state *mrb, mrb_value x)
|
||||
{
|
||||
mrb_value y;
|
||||
|
||||
mrb_get_args(mrb, "o", &y);
|
||||
return cmp_gt(mrb, x, y);
|
||||
}
|
||||
|
||||
static mrb_value
|
||||
cmp_ge_m(mrb_state *mrb, mrb_value x)
|
||||
{
|
||||
mrb_value y, c;
|
||||
|
||||
mrb_get_args(mrb, "o", &y);
|
||||
c = mrb_funcall(mrb, x, "<=>", 1, y);
|
||||
|
||||
if (mrb_cmpint(mrb, c, x, y) >= 0) return mrb_true_value();
|
||||
return mrb_false_value();
|
||||
}
|
||||
|
||||
static mrb_value
|
||||
cmp_lt(mrb_state *mrb, mrb_value x, mrb_value y)
|
||||
{
|
||||
mrb_value c;
|
||||
|
||||
c = mrb_funcall(mrb, x, "<=>", 1, y);
|
||||
|
||||
if (mrb_cmpint(mrb, c, x, y) < 0) return mrb_true_value();
|
||||
return mrb_false_value();
|
||||
}
|
||||
|
||||
static mrb_value
|
||||
cmp_lt_m(mrb_state *mrb, mrb_value x)
|
||||
{
|
||||
mrb_value y;
|
||||
|
||||
mrb_get_args(mrb, "o", &y);
|
||||
return cmp_lt(mrb, x, y);
|
||||
}
|
||||
|
||||
static mrb_value
|
||||
cmp_le_m(mrb_state *mrb, mrb_value x)
|
||||
{
|
||||
mrb_value y, c;
|
||||
|
||||
mrb_get_args(mrb, "o", &y);
|
||||
c = mrb_funcall(mrb, x, "<=>", 1, y);
|
||||
|
||||
if (mrb_cmpint(mrb, c, x, y) <= 0) return mrb_true_value();
|
||||
return mrb_false_value();
|
||||
}
|
||||
|
||||
static mrb_value
|
||||
cmp_between(mrb_state *mrb, mrb_value x)
|
||||
{
|
||||
mrb_value min, max;
|
||||
|
||||
mrb_get_args(mrb, "oo", &min, &max);
|
||||
|
||||
if (mrb_test(cmp_lt(mrb, x, min))) return mrb_false_value();
|
||||
if (mrb_test(cmp_gt(mrb, x, max))) return mrb_false_value();
|
||||
return mrb_true_value();
|
||||
}
|
||||
|
||||
void
|
||||
mrb_init_comparable(mrb_state *mrb)
|
||||
{
|
||||
struct RClass *comp;
|
||||
|
||||
comp = mrb_define_module(mrb, "Comparable");
|
||||
mrb_define_method(mrb, comp, "<", cmp_lt_m, ARGS_REQ(1)); /* 15.3.3.2.1 */
|
||||
mrb_define_method(mrb, comp, "<=", cmp_le_m, ARGS_REQ(1)); /* 15.3.3.2.2 */
|
||||
mrb_define_method(mrb, comp, "==", cmp_equal, ARGS_REQ(1)); /* 15.3.3.2.3 */
|
||||
mrb_define_method(mrb, comp, ">", cmp_gt_m, ARGS_REQ(1)); /* 15.3.3.2.4 */
|
||||
mrb_define_method(mrb, comp, ">=", cmp_ge_m, ARGS_REQ(1)); /* 15.3.3.2.5 */
|
||||
mrb_define_method(mrb, comp, "between?", cmp_between, ARGS_REQ(2)); /* 15.3.3.2.6 */
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
#include "mruby.h"
|
||||
#include <stdio.h>
|
||||
#include <setjmp.h>
|
||||
|
||||
typedef struct mrb_ast_node {
|
||||
struct mrb_ast_node *car, *cdr;
|
||||
} mrb_ast_node;
|
||||
|
||||
#include "node.h"
|
||||
#include "pool.h"
|
||||
#include <stdio.h>
|
||||
|
||||
enum mrb_lex_state_enum {
|
||||
EXPR_BEG, /* ignore newline, +/- is a sign. */
|
||||
EXPR_END, /* newline significant, +/- is an operator. */
|
||||
EXPR_ENDARG, /* ditto, and unbound braces. */
|
||||
EXPR_ENDFN, /* ditto, and unbound braces. */
|
||||
EXPR_ARG, /* newline significant, +/- is an operator. */
|
||||
EXPR_CMDARG, /* newline significant, +/- is an operator. */
|
||||
EXPR_MID, /* newline significant, +/- is an operator. */
|
||||
EXPR_FNAME, /* ignore newline, no reserved words. */
|
||||
EXPR_DOT, /* right after `.' or `::', no reserved words. */
|
||||
EXPR_CLASS, /* immediate after `class', no here document. */
|
||||
EXPR_VALUE, /* alike EXPR_BEG but label is disallowed. */
|
||||
EXPR_MAX_STATE
|
||||
};
|
||||
|
||||
struct mrb_parser_state {
|
||||
mrb_state *mrb;
|
||||
struct mrb_pool *pool;
|
||||
mrb_ast_node *cells;
|
||||
char *s, *send;
|
||||
FILE *f;
|
||||
int lineno;
|
||||
int column;
|
||||
const char *filename;
|
||||
|
||||
enum mrb_lex_state_enum lstate;
|
||||
int sterm;
|
||||
|
||||
unsigned int cond_stack;
|
||||
unsigned int cmdarg_stack;
|
||||
int paren_nest;
|
||||
int lpar_beg;
|
||||
|
||||
mrb_ast_node *pb;
|
||||
char buf[1024];
|
||||
int bidx;
|
||||
|
||||
mrb_ast_node *heredoc;
|
||||
|
||||
int in_def, in_single, cmd_start;
|
||||
mrb_ast_node *locals;
|
||||
|
||||
void *ylval;
|
||||
|
||||
int nerr;
|
||||
mrb_ast_node *tree, *begin_tree;
|
||||
|
||||
jmp_buf jmp;
|
||||
};
|
||||
|
||||
struct mrb_parser_state* mrb_parse_file(mrb_state*,FILE*);
|
||||
struct mrb_parser_state* mrb_parse_string(mrb_state*,char*);
|
||||
struct mrb_parser_state* mrb_parse_nstring(mrb_state*,char*,size_t);
|
||||
int mrb_generate_code(mrb_state*, mrb_ast_node*);
|
||||
|
||||
int mrb_compile_file(mrb_state*,FILE*);
|
||||
int mrb_compile_string(mrb_state*,char*);
|
||||
int mrb_compile_nstring(mrb_state*,char*,size_t);
|
||||
|
||||
const char *mrb_parser_filename(struct mrb_parser_state *p, const char *s);
|
||||
int mrb_parser_lineno(struct mrb_parser_state *p, int n);
|
||||
@@ -0,0 +1,28 @@
|
||||
#include <limits.h>
|
||||
#include <stdint.h>
|
||||
// Calculate CRC (CRC-16-CCITT)
|
||||
//
|
||||
// 0000_0000_0000_0000_0000_0000_0000_0000
|
||||
// ^|------- CRC -------|- work --|
|
||||
// carry
|
||||
#define CRC_16_CCITT 0x11021ul //x^16+x^12+x^5+1
|
||||
#define CRC_XOR_PATTERN (CRC_16_CCITT << 8)
|
||||
#define CRC_CARRY_BIT (1 << 24)
|
||||
|
||||
uint16_t
|
||||
calc_crc_16_ccitt(unsigned char *src, int nbytes)
|
||||
{
|
||||
uint32_t crcwk = 0ul;
|
||||
int ibyte, ibit;
|
||||
|
||||
for (ibyte = 0; ibyte < nbytes; ibyte++) {
|
||||
crcwk |= *src++;
|
||||
for (ibit = 0; ibit < CHAR_BIT; ibit++) {
|
||||
crcwk <<= 1;
|
||||
if (crcwk & CRC_CARRY_BIT) {
|
||||
crcwk ^= CRC_XOR_PATTERN;
|
||||
}
|
||||
}
|
||||
}
|
||||
return (uint16_t)(crcwk >> 8);
|
||||
}
|
||||
+697
@@ -0,0 +1,697 @@
|
||||
#include <string.h>
|
||||
#include "dump.h"
|
||||
|
||||
#include "mruby/string.h"
|
||||
#ifdef INCLUDE_REGEXP
|
||||
#include "re.h"
|
||||
#endif
|
||||
#include "irep.h"
|
||||
|
||||
static const unsigned char def_rite_binary_header[] =
|
||||
RITE_FILE_IDENFIFIER
|
||||
RITE_FILE_FORMAT_VER
|
||||
RITE_VM_VER
|
||||
RITE_COMPILER_TYPE
|
||||
RITE_COMPILER_VER
|
||||
"0000" //Binary data size
|
||||
"00" //Number of ireps
|
||||
"00" //Start index
|
||||
RITE_RESERVED
|
||||
;
|
||||
|
||||
static const unsigned char def_rite_file_header[] =
|
||||
RITE_FILE_IDENFIFIER
|
||||
RITE_FILE_FORMAT_VER
|
||||
RITE_VM_VER
|
||||
RITE_COMPILER_TYPE
|
||||
RITE_COMPILER_VER
|
||||
"00000000" //Binary data size
|
||||
"0000" //Number of ireps
|
||||
"0000" //Start index
|
||||
RITE_RESERVED
|
||||
"0000" //CRC
|
||||
;
|
||||
|
||||
const char bin2hex[] = {
|
||||
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
|
||||
};
|
||||
|
||||
#define DUMP_SIZE(size, type) ((type == DUMP_TYPE_BIN) ? size : size * RITE_FILE_HEX_SIZE)
|
||||
|
||||
enum {
|
||||
DUMP_IREP_HEADER = 0,
|
||||
DUMP_ISEQ_BLOCK,
|
||||
DUMP_POOL_BLOCK,
|
||||
DUMP_SYMS_BLOCK,
|
||||
DUMP_SECTION_NUM,
|
||||
};
|
||||
|
||||
uint16_t calc_crc_16_ccitt(unsigned char*,int);
|
||||
static inline int uint8_dump(uint8_t,char*,int);
|
||||
static inline int uint16_dump(uint16_t,char*,int);
|
||||
static inline int uint32_dump(uint32_t,char*,int);
|
||||
static char* str_dump(char*,char*,uint16_t,int);
|
||||
static uint16_t str_dump_len(char*,uint16_t, int);
|
||||
static uint32_t get_irep_header_size(mrb_state*,mrb_irep*,int);
|
||||
static uint32_t get_iseq_block_size(mrb_state*,mrb_irep*,int);
|
||||
static uint32_t get_pool_block_size(mrb_state*,mrb_irep*,int);
|
||||
static uint32_t get_syms_block_size(mrb_state*,mrb_irep*,int);
|
||||
static uint32_t get_irep_record_size(mrb_state*,int,int);
|
||||
static int write_irep_header(mrb_state*,mrb_irep*,char*,int);
|
||||
static int write_iseq_block(mrb_state*,mrb_irep*,char*,int);
|
||||
static int write_pool_block(mrb_state*,mrb_irep*,char*,int);
|
||||
static int write_syms_block(mrb_state*,mrb_irep*,char*,int);
|
||||
static int calc_crc_section(mrb_state*,mrb_irep*,uint16_t*,int);
|
||||
static int write_rite_header(mrb_state*,int,char*,uint32_t);
|
||||
static int dump_rite_header(mrb_state*,int,FILE*,uint32_t);
|
||||
static int write_irep_record(mrb_state*,int,char*,uint32_t*,int);
|
||||
static int dump_irep_record(mrb_state*,int,FILE*,uint32_t*);
|
||||
static int mrb_write_irep(mrb_state*,int,char*);
|
||||
|
||||
|
||||
static inline int
|
||||
uint8_dump(unsigned char bin, char *hex, int type)
|
||||
{
|
||||
if (type == DUMP_TYPE_BIN) {
|
||||
*hex = bin;
|
||||
} else {
|
||||
*hex++ = bin2hex[(bin >> 4) & 0x0f];
|
||||
*hex = bin2hex[bin & 0x0f];
|
||||
}
|
||||
return DUMP_SIZE(sizeof(char), type);
|
||||
}
|
||||
|
||||
static inline int
|
||||
uint16_dump(uint16_t bin, char *hex, int type)
|
||||
{
|
||||
if (type == DUMP_TYPE_BIN) {
|
||||
return (uint16_to_bin(bin, hex));
|
||||
} else {
|
||||
*hex++ = bin2hex[(bin >> 12)& 0x0f];
|
||||
*hex++ = bin2hex[(bin >> 8) & 0x0f];
|
||||
*hex++ = bin2hex[(bin >> 4) & 0x0f];
|
||||
*hex = bin2hex[bin & 0x0f];
|
||||
return DUMP_SIZE(MRB_DUMP_SIZE_OF_SHORT, type);
|
||||
}
|
||||
}
|
||||
|
||||
static inline int
|
||||
uint32_dump(uint32_t bin, char *hex, int type)
|
||||
{
|
||||
if (type == DUMP_TYPE_BIN) {
|
||||
return (uint32_to_bin(bin, hex));
|
||||
} else {
|
||||
*hex++ = bin2hex[(bin >> 28) & 0x0f];
|
||||
*hex++ = bin2hex[(bin >> 24) & 0x0f];
|
||||
*hex++ = bin2hex[(bin >> 20) & 0x0f];
|
||||
*hex++ = bin2hex[(bin >> 16) & 0x0f];
|
||||
*hex++ = bin2hex[(bin >> 12) & 0x0f];
|
||||
*hex++ = bin2hex[(bin >> 8) & 0x0f];
|
||||
*hex++ = bin2hex[(bin >> 4) & 0x0f];
|
||||
*hex = bin2hex[bin & 0x0f];
|
||||
return DUMP_SIZE(MRB_DUMP_SIZE_OF_LONG, type);
|
||||
}
|
||||
}
|
||||
|
||||
static char*
|
||||
str_dump(char *str, char *hex, uint16_t len, int type)
|
||||
{
|
||||
if (type == DUMP_TYPE_BIN)
|
||||
memcpy(hex, str, len);
|
||||
else {
|
||||
char *src, *dst;
|
||||
|
||||
for (src = str, dst = hex; len > 0; src++, dst++, len--) {
|
||||
switch (*src) {
|
||||
case 0x07:/* BEL */ *dst++ = '\\'; *dst = 'a'; break;
|
||||
case 0x08:/* BS */ *dst++ = '\\'; *dst = 'b'; break;
|
||||
case 0x09:/* HT */ *dst++ = '\\'; *dst = 't'; break;
|
||||
case 0x0A:/* LF */ *dst++ = '\\'; *dst = 'n'; break;
|
||||
case 0x0B:/* VT */ *dst++ = '\\'; *dst = 'v'; break;
|
||||
case 0x0C:/* FF */ *dst++ = '\\'; *dst = 'f'; break;
|
||||
case 0x0D:/* CR */ *dst++ = '\\'; *dst = 'r'; break;
|
||||
case 0x22:/* " */ /* fall through */
|
||||
case 0x27:/* ' */ /* fall through */
|
||||
// case 0x3F:/* ? */ /* fall through */
|
||||
case 0x5C:/* \ */ /* fall through */
|
||||
default: *dst = *src; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return hex;
|
||||
}
|
||||
|
||||
static uint16_t
|
||||
str_dump_len(char *str, uint16_t len, int type)
|
||||
{
|
||||
uint16_t dump_len = 0;
|
||||
|
||||
if (type == DUMP_TYPE_BIN)
|
||||
dump_len = len;
|
||||
else {
|
||||
char *src;
|
||||
|
||||
for (src = str; len > 0; src++, len--) {
|
||||
switch (*src) {
|
||||
case 0x07:/* BEL */ /* fall through */
|
||||
case 0x08:/* BS */ /* fall through */
|
||||
case 0x09:/* HT */ /* fall through */
|
||||
case 0x0A:/* LF */ /* fall through */
|
||||
case 0x0B:/* VT */ /* fall through */
|
||||
case 0x0C:/* FF */ /* fall through */
|
||||
case 0x0D:/* CR */ /* fall through */
|
||||
dump_len += 2;
|
||||
break;
|
||||
|
||||
case 0x22:/* " */ /* fall through */
|
||||
case 0x27:/* ' */ /* fall through */
|
||||
// case 0x3F:/* ? */ /* fall through */
|
||||
case 0x5C:/* \ */ /* fall through */
|
||||
default:
|
||||
dump_len++; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return dump_len;
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
get_irep_header_size(mrb_state *mrb, mrb_irep *irep, int type)
|
||||
{
|
||||
uint32_t size = 0;
|
||||
|
||||
size += sizeof(char) * 2;
|
||||
size += DUMP_SIZE(MRB_DUMP_SIZE_OF_SHORT, type) * 4;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
get_iseq_block_size(mrb_state *mrb, mrb_irep *irep, int type)
|
||||
{
|
||||
uint32_t size = 0;
|
||||
|
||||
size += MRB_DUMP_SIZE_OF_LONG; /* ilen */
|
||||
size += irep->ilen * MRB_DUMP_SIZE_OF_LONG; /* iseq(n) */
|
||||
size += MRB_DUMP_SIZE_OF_SHORT; /* crc */
|
||||
|
||||
return DUMP_SIZE(size, type);
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
get_pool_block_size(mrb_state *mrb, mrb_irep *irep, int type)
|
||||
{
|
||||
uint32_t size = 0;
|
||||
int pool_no;
|
||||
mrb_value str;
|
||||
char buf[32];
|
||||
|
||||
size += MRB_DUMP_SIZE_OF_LONG; /* plen */
|
||||
size += irep->plen * sizeof(char); /* tt(n) */
|
||||
size += irep->plen * MRB_DUMP_SIZE_OF_SHORT; /* len(n) */
|
||||
size += MRB_DUMP_SIZE_OF_SHORT; /* crc */
|
||||
size = DUMP_SIZE(size, type);
|
||||
|
||||
for (pool_no = 0; pool_no < irep->plen; pool_no++) {
|
||||
uint16_t nlen =0;
|
||||
|
||||
switch (irep->pool[pool_no].tt) {
|
||||
case MRB_TT_FIXNUM:
|
||||
sprintf( buf, "%d", irep->pool[pool_no].value.i);
|
||||
size += strlen(buf);
|
||||
break;
|
||||
case MRB_TT_FLOAT:
|
||||
sprintf( buf, "%.16e", irep->pool[pool_no].value.f);
|
||||
size += strlen(buf);
|
||||
break;
|
||||
case MRB_TT_STRING:
|
||||
str = mrb_string_value( mrb, &irep->pool[pool_no]);
|
||||
nlen = str_dump_len(RSTRING_PTR(str), RSTRING_LEN(str), type);
|
||||
size += nlen;
|
||||
break;
|
||||
#ifdef INCLUDE_REGEXP
|
||||
case MRB_TT_REGEX:
|
||||
str = mrb_reg_to_s(mrb, irep->pool[pool_no]);
|
||||
nlen = str_dump_len(RSTRING_PTR(str), RSTRING_LEN(str), type);
|
||||
size += nlen;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
get_syms_block_size(mrb_state *mrb, mrb_irep *irep, int type)
|
||||
{
|
||||
uint32_t size = 0;
|
||||
int sym_no;
|
||||
|
||||
size += MRB_DUMP_SIZE_OF_LONG; /* slen */
|
||||
size += MRB_DUMP_SIZE_OF_SHORT; /* crc */
|
||||
size = DUMP_SIZE(size, type);
|
||||
|
||||
for (sym_no = 0; sym_no < irep->slen; sym_no++) {
|
||||
const char * name;
|
||||
uint16_t nlen =0;
|
||||
|
||||
size += DUMP_SIZE(MRB_DUMP_SIZE_OF_SHORT, type); /* snl(n) */
|
||||
if (irep->syms[sym_no] != 0) {
|
||||
name = mrb_sym2name(mrb, irep->syms[sym_no]);
|
||||
nlen = str_dump_len((char*)name, strlen(name), type);
|
||||
size += nlen; /* sn(n) */
|
||||
}
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
get_irep_record_size(mrb_state *mrb, int irep_no, int type)
|
||||
{
|
||||
uint32_t size = 0;
|
||||
mrb_irep *irep = mrb->irep[irep_no];
|
||||
|
||||
size += DUMP_SIZE(MRB_DUMP_SIZE_OF_LONG, type); /* rlen */
|
||||
size += get_irep_header_size(mrb, irep, type);
|
||||
size += get_iseq_block_size(mrb, irep, type);
|
||||
size += get_pool_block_size(mrb, irep, type);
|
||||
size += get_syms_block_size(mrb, irep, type);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static int
|
||||
write_irep_header(mrb_state *mrb, mrb_irep *irep, char *buf, int type)
|
||||
{
|
||||
char *buf_top = buf;
|
||||
|
||||
*buf++ = RITE_IREP_IDENFIFIER; /* record identifier */
|
||||
*buf++ = RITE_IREP_TYPE_CLASS; /* class or module */
|
||||
buf += uint16_dump((uint16_t)irep->nlocals, buf, type); /* number of local variable */
|
||||
buf += uint16_dump((uint16_t)irep->nregs, buf, type); /* number of register variable */
|
||||
buf += uint16_dump(DUMP_SIZE(MRB_DUMP_SIZE_OF_SHORT, type)/* crc */, buf, type); /* offset of isec block */
|
||||
|
||||
return (int)(buf - buf_top);
|
||||
}
|
||||
|
||||
static int
|
||||
write_iseq_block(mrb_state *mrb, mrb_irep *irep, char *buf, int type)
|
||||
{
|
||||
char *buf_top = buf;
|
||||
int iseq_no;
|
||||
|
||||
buf += uint32_dump((uint32_t)irep->ilen, buf, type); /* number of opcode */
|
||||
|
||||
for (iseq_no = 0; iseq_no < irep->ilen; iseq_no++) {
|
||||
buf += uint32_dump((uint32_t)irep->iseq[iseq_no], buf, type); /* opcode */
|
||||
}
|
||||
|
||||
return (int)(buf - buf_top);
|
||||
}
|
||||
|
||||
static int
|
||||
write_pool_block(mrb_state *mrb, mrb_irep *irep, char *buf, int type)
|
||||
{
|
||||
int pool_no;
|
||||
mrb_value str;
|
||||
char *buf_top = buf;
|
||||
char *char_buf;
|
||||
uint16_t buf_size =0;
|
||||
|
||||
buf_size = MRB_DUMP_DEFAULT_STR_LEN;
|
||||
if ((char_buf = mrb_malloc(mrb, buf_size)) == 0)
|
||||
goto error_exit;
|
||||
|
||||
buf += uint32_dump((uint32_t)irep->plen, buf, type); /* number of pool */
|
||||
|
||||
for (pool_no = 0; pool_no < irep->plen; pool_no++) {
|
||||
uint16_t nlen =0;
|
||||
|
||||
buf += uint8_dump(irep->pool[pool_no].tt, buf, type); /* data type */
|
||||
memset(char_buf, 0, buf_size);
|
||||
|
||||
switch (irep->pool[pool_no].tt) {
|
||||
case MRB_TT_FIXNUM:
|
||||
sprintf(char_buf, "%d", irep->pool[pool_no].value.i);
|
||||
break;
|
||||
|
||||
case MRB_TT_FLOAT:
|
||||
sprintf(char_buf, "%.16e", irep->pool[pool_no].value.f);
|
||||
break;
|
||||
|
||||
case MRB_TT_STRING:
|
||||
str = mrb_string_value( mrb, &irep->pool[pool_no]);
|
||||
nlen = str_dump_len(RSTRING_PTR(str), RSTRING_LEN(str), type);
|
||||
if ( nlen > buf_size - 1) {
|
||||
buf_size = nlen + 1;
|
||||
if ((char_buf = mrb_realloc(mrb, char_buf, buf_size)) == 0)
|
||||
goto error_exit;
|
||||
memset(char_buf, 0, buf_size);
|
||||
}
|
||||
str_dump(RSTRING_PTR(str), char_buf, RSTRING_LEN(str), type);
|
||||
break;
|
||||
|
||||
#ifdef INCLUDE_REGEXP
|
||||
case MRB_TT_REGEX:
|
||||
str = mrb_reg_to_s(mrb, irep->pool[pool_no]);
|
||||
nlen = str_dump_len(RSTRING_PTR(str), RSTRING_LEN(str), type);
|
||||
if ( nlen > buf_size - 1) {
|
||||
buf_size = nlen + 1;
|
||||
if ((char_buf = mrb_realloc(mrb, char_buf, buf_size)) == 0)
|
||||
goto error_exit;
|
||||
memset(char_buf, 0, buf_size);
|
||||
}
|
||||
str_dump(RSTRING_PTR(str), char_buf, RSTRING_LEN(str), type);
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
buf += uint16_dump(0, buf, type); /* data length = 0 */
|
||||
continue;
|
||||
}
|
||||
|
||||
buf += uint16_dump((uint16_t)strlen(char_buf), buf, type); /* data length */
|
||||
|
||||
memcpy(buf, char_buf, strlen(char_buf));
|
||||
buf += strlen(char_buf);
|
||||
}
|
||||
|
||||
error_exit:
|
||||
if (char_buf)
|
||||
mrb_free(mrb, char_buf);
|
||||
return (int)(buf - buf_top);
|
||||
}
|
||||
|
||||
static int
|
||||
write_syms_block(mrb_state *mrb, mrb_irep *irep, char *buf, int type)
|
||||
{
|
||||
int sym_no;
|
||||
char *buf_top = buf;
|
||||
char *char_buf;
|
||||
uint16_t buf_size =0;
|
||||
|
||||
buf_size = MRB_DUMP_DEFAULT_STR_LEN;
|
||||
if ((char_buf = mrb_malloc(mrb, buf_size)) == 0)
|
||||
goto error_exit;
|
||||
|
||||
buf += uint32_dump((uint32_t)irep->slen, buf, type); /* number of symbol */
|
||||
|
||||
for (sym_no = 0; sym_no < irep->slen; sym_no++) {
|
||||
const char * name;
|
||||
uint16_t nlen =0;
|
||||
|
||||
if (irep->syms[sym_no] != 0) {
|
||||
name = mrb_sym2name(mrb, irep->syms[sym_no]);
|
||||
nlen = str_dump_len((char*)name, strlen(name), type);
|
||||
if ( nlen > buf_size - 1) {
|
||||
buf_size = nlen + 1;
|
||||
if ((char_buf = mrb_realloc(mrb, char_buf, buf_size)) == 0)
|
||||
goto error_exit;
|
||||
}
|
||||
memset(char_buf, 0, buf_size);
|
||||
str_dump((char*)name, char_buf, strlen(name), type);
|
||||
|
||||
buf += uint16_dump(nlen, buf, type); /* length of symbol name */
|
||||
memcpy(buf, char_buf, nlen); /* symbol name */
|
||||
buf += nlen;
|
||||
}
|
||||
else {
|
||||
buf += uint16_dump(MRB_DUMP_NULL_SYM_LEN, buf, type); /* length of symbol name */
|
||||
}
|
||||
}
|
||||
|
||||
error_exit:
|
||||
if (char_buf)
|
||||
mrb_free(mrb, char_buf);
|
||||
return (int)(buf - buf_top);
|
||||
}
|
||||
|
||||
static int
|
||||
calc_crc_section(mrb_state *mrb, mrb_irep *irep, uint16_t *crc, int section)
|
||||
{
|
||||
char *buf, *buf_top;
|
||||
uint32_t buf_size;
|
||||
int type = DUMP_TYPE_BIN;
|
||||
|
||||
switch (section) {
|
||||
case DUMP_IREP_HEADER: buf_size = get_irep_header_size(mrb, irep, type); break;
|
||||
case DUMP_ISEQ_BLOCK: buf_size = get_iseq_block_size(mrb, irep, type); break;
|
||||
case DUMP_POOL_BLOCK: buf_size = get_pool_block_size(mrb, irep, type); break;
|
||||
case DUMP_SYMS_BLOCK: buf_size = get_syms_block_size(mrb, irep, type); break;
|
||||
default: return MRB_DUMP_GENERAL_FAILURE;
|
||||
}
|
||||
|
||||
if ((buf = mrb_malloc(mrb, buf_size)) == 0)
|
||||
return MRB_DUMP_GENERAL_FAILURE;
|
||||
|
||||
buf_top = buf;
|
||||
memset(buf, 0, buf_size);
|
||||
|
||||
switch (section) {
|
||||
case DUMP_IREP_HEADER: buf += write_irep_header(mrb, irep, buf, type); break;
|
||||
case DUMP_ISEQ_BLOCK: buf += write_iseq_block(mrb, irep, buf, type); break;
|
||||
case DUMP_POOL_BLOCK: buf += write_pool_block(mrb, irep, buf, type); break;
|
||||
case DUMP_SYMS_BLOCK: buf += write_syms_block(mrb, irep, buf, type); break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
*crc = calc_crc_16_ccitt((unsigned char *)buf_top, (int)(buf - buf_top));
|
||||
|
||||
mrb_free(mrb, buf_top);
|
||||
|
||||
return MRB_DUMP_OK;
|
||||
}
|
||||
|
||||
static int
|
||||
write_rite_header(mrb_state *mrb, int top, char* bin, uint32_t rbds)
|
||||
{
|
||||
rite_binary_header *binary_header;
|
||||
uint16_t crc;
|
||||
int type = DUMP_TYPE_BIN;
|
||||
|
||||
binary_header = (rite_binary_header *)bin;
|
||||
|
||||
memcpy( binary_header, def_rite_binary_header, sizeof(*binary_header));
|
||||
|
||||
uint32_dump(rbds, (char *)binary_header->rbds, type);
|
||||
uint16_dump((uint16_t)mrb->irep_len, (char *)binary_header->nirep, type);
|
||||
uint16_dump((uint16_t)top, (char *)binary_header->sirep, type);
|
||||
|
||||
crc = calc_crc_16_ccitt((unsigned char *)binary_header, sizeof(*binary_header));
|
||||
bin += sizeof(*binary_header);
|
||||
uint16_dump(crc, bin, type);
|
||||
|
||||
return MRB_DUMP_OK;
|
||||
}
|
||||
|
||||
static int
|
||||
dump_rite_header(mrb_state *mrb, int top, FILE* fp, uint32_t rbds)
|
||||
{
|
||||
rite_binary_header binary_header;
|
||||
rite_file_header file_header;
|
||||
uint16_t crc;
|
||||
int type;
|
||||
|
||||
if (fseek(fp, 0, SEEK_SET) != 0)
|
||||
return MRB_DUMP_GENERAL_FAILURE;
|
||||
|
||||
/* calc crc */
|
||||
memcpy( &binary_header, def_rite_binary_header, sizeof(binary_header));
|
||||
|
||||
type = DUMP_TYPE_BIN;
|
||||
uint32_dump(rbds, (char *)&binary_header.rbds, type);
|
||||
uint16_dump((uint16_t)mrb->irep_len, (char *)&binary_header.nirep, type);
|
||||
uint16_dump((uint16_t)top, (char *)&binary_header.sirep, type);
|
||||
|
||||
crc = calc_crc_16_ccitt((unsigned char *)&binary_header, sizeof(binary_header));
|
||||
|
||||
/* dump rbc header */
|
||||
memcpy( &file_header, def_rite_file_header, sizeof(file_header));
|
||||
|
||||
type = DUMP_TYPE_HEX;
|
||||
uint32_dump(rbds, (char *)&file_header.rbds, type);
|
||||
uint16_dump((uint16_t)mrb->irep_len, (char *)&file_header.nirep, type);
|
||||
uint16_dump((uint16_t)top, (char *)&file_header.sirep, type);
|
||||
uint16_dump(crc, (char *)&file_header.hcrc, type);
|
||||
|
||||
if (fwrite(&file_header, sizeof(file_header), 1, fp) != 1)
|
||||
return MRB_DUMP_WRITE_FAULT;
|
||||
|
||||
return MRB_DUMP_OK;
|
||||
}
|
||||
|
||||
static int
|
||||
write_irep_record(mrb_state *mrb, int irep_no, char* bin, uint32_t *rlen, int type)
|
||||
{
|
||||
uint32_t irep_record_size;
|
||||
mrb_irep *irep = mrb->irep[irep_no];
|
||||
int section;
|
||||
|
||||
if (irep == 0)
|
||||
return MRB_DUMP_INVALID_IREP;
|
||||
|
||||
/* buf alloc */
|
||||
irep_record_size = get_irep_record_size(mrb, irep_no, type);
|
||||
if (irep_record_size == 0)
|
||||
return MRB_DUMP_GENERAL_FAILURE;
|
||||
|
||||
memset( bin, 0, irep_record_size);
|
||||
|
||||
/* rlen */
|
||||
*rlen = irep_record_size - DUMP_SIZE(MRB_DUMP_SIZE_OF_LONG, type);
|
||||
|
||||
bin += uint32_dump(*rlen, bin, type);
|
||||
|
||||
for (section = 0; section < DUMP_SECTION_NUM; section++) {
|
||||
int rc;
|
||||
uint16_t crc;
|
||||
|
||||
switch (section) {
|
||||
case DUMP_IREP_HEADER: bin += write_irep_header(mrb, irep, bin, type); break;
|
||||
case DUMP_ISEQ_BLOCK: bin += write_iseq_block(mrb, irep, bin, type); break;
|
||||
case DUMP_POOL_BLOCK: bin += write_pool_block(mrb, irep, bin, type); break;
|
||||
case DUMP_SYMS_BLOCK: bin += write_syms_block(mrb, irep, bin, type); break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
if ((rc = calc_crc_section(mrb, irep, &crc, section)) != 0)
|
||||
return rc;
|
||||
|
||||
bin += uint16_dump(crc, bin, type); /* crc */
|
||||
}
|
||||
|
||||
return MRB_DUMP_OK;
|
||||
}
|
||||
|
||||
static int
|
||||
dump_irep_record(mrb_state *mrb, int irep_no, FILE* fp, uint32_t *rlen)
|
||||
{
|
||||
int rc = MRB_DUMP_OK;
|
||||
uint32_t irep_record_size;
|
||||
char *buf;
|
||||
mrb_irep *irep = mrb->irep[irep_no];
|
||||
|
||||
if (irep == 0)
|
||||
return MRB_DUMP_INVALID_IREP;
|
||||
|
||||
/* buf alloc */
|
||||
irep_record_size = get_irep_record_size(mrb, irep_no, DUMP_TYPE_HEX);
|
||||
if (irep_record_size == 0)
|
||||
return MRB_DUMP_GENERAL_FAILURE;
|
||||
|
||||
if ((buf = mrb_malloc(mrb, irep_record_size)) == 0)
|
||||
return MRB_DUMP_GENERAL_FAILURE;
|
||||
|
||||
memset( buf, 0, irep_record_size);
|
||||
|
||||
if ((rc = write_irep_record(mrb, irep_no, buf, rlen, DUMP_TYPE_HEX)) != MRB_DUMP_OK)
|
||||
goto error_exit;
|
||||
|
||||
|
||||
if (fwrite(buf, irep_record_size, 1, fp) != 1)
|
||||
rc = MRB_DUMP_WRITE_FAULT;
|
||||
|
||||
error_exit:
|
||||
mrb_free(mrb, buf);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
mrb_write_irep(mrb_state *mrb, int top, char *bin)
|
||||
{
|
||||
int rc;
|
||||
uint32_t rlen=0; /* size of irep record */
|
||||
int irep_no;
|
||||
char *bin_top;
|
||||
|
||||
if (mrb == 0 || top < 0 || top >= mrb->irep_len || bin == 0)
|
||||
return MRB_DUMP_INVALID_ARGUMENT;
|
||||
|
||||
bin_top = bin;
|
||||
bin += sizeof(rite_binary_header) + MRB_DUMP_SIZE_OF_SHORT/* crc */;
|
||||
|
||||
for (irep_no=top; irep_no<mrb->irep_len; irep_no++) {
|
||||
if ((rc = write_irep_record(mrb, irep_no, bin, &rlen, DUMP_TYPE_BIN)) != 0)
|
||||
return rc;
|
||||
|
||||
bin += (rlen + DUMP_SIZE(MRB_DUMP_SIZE_OF_LONG, DUMP_TYPE_BIN));
|
||||
}
|
||||
|
||||
bin += uint32_dump(0, bin, DUMP_TYPE_BIN); /* end of file */
|
||||
|
||||
rc = write_rite_header(mrb, top, bin_top, (bin - bin_top)); //TODO: Remove top(SIREP)
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
mrb_dump_irep(mrb_state *mrb, int top, FILE* fp)
|
||||
{
|
||||
int rc;
|
||||
uint32_t rbds=0; /* size of Rite Binary Data */
|
||||
uint32_t rlen=0; /* size of irep record */
|
||||
int irep_no;
|
||||
|
||||
if (mrb == 0 || top < 0 || top >= mrb->irep_len || fp == 0)
|
||||
return MRB_DUMP_INVALID_ARGUMENT;
|
||||
|
||||
if (fwrite(&def_rite_file_header, sizeof(rite_file_header), 1, fp) != 1) /* dummy write */
|
||||
return MRB_DUMP_WRITE_FAULT;
|
||||
|
||||
for (irep_no=top; irep_no<mrb->irep_len; irep_no++) {
|
||||
if ((rc = dump_irep_record(mrb, irep_no, fp, &rlen)) != 0)
|
||||
return rc;
|
||||
|
||||
rbds += rlen;
|
||||
}
|
||||
|
||||
if (fwrite("00000000"/* end of file */, 8, 1, fp) != 1)
|
||||
return MRB_DUMP_WRITE_FAULT;
|
||||
|
||||
rc = dump_rite_header(mrb, top, fp, rbds); //TODO: Remove top(SIREP)
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
mrb_bdump_irep(mrb_state *mrb, int n, FILE *f,const char *initname)
|
||||
{
|
||||
int rc;
|
||||
int irep_no;
|
||||
char *buf;
|
||||
int buf_size = 0;
|
||||
int buf_idx = 0;
|
||||
|
||||
if (mrb == 0 || n < 0 || n >= mrb->irep_len || f == 0 || initname == 0)
|
||||
return -1;
|
||||
|
||||
buf_size = sizeof(rite_binary_header) + MRB_DUMP_SIZE_OF_SHORT/* crc */;
|
||||
for (irep_no=n; irep_no<mrb->irep_len; irep_no++)
|
||||
buf_size += get_irep_record_size(mrb, irep_no, DUMP_TYPE_BIN);
|
||||
buf_size += MRB_DUMP_SIZE_OF_LONG; /* end of file */
|
||||
|
||||
if ((buf = mrb_malloc(mrb, buf_size)) == 0)
|
||||
return MRB_DUMP_GENERAL_FAILURE;
|
||||
|
||||
rc = mrb_write_irep(mrb, n, buf);
|
||||
|
||||
if (rc == MRB_DUMP_OK) {
|
||||
fprintf(f, "const char %s[] = {", initname);
|
||||
while (buf_idx < buf_size ) {
|
||||
if (buf_idx % 16 == 0 ) fputs("\n", f);
|
||||
fprintf(f, "0x%02x,", (unsigned char)buf[buf_idx++]);
|
||||
}
|
||||
fputs("\n};\n", f);
|
||||
}
|
||||
|
||||
mrb_free(mrb, buf);
|
||||
|
||||
return rc;
|
||||
}
|
||||
+118
@@ -0,0 +1,118 @@
|
||||
#include "mruby.h"
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
int mrb_dump_irep(mrb_state*,int,FILE*);
|
||||
int mrb_load_irep(mrb_state*,FILE*);
|
||||
int mrb_load_irep_offset(mrb_state*,FILE*,long);
|
||||
int mrb_read_irep(mrb_state*,char*);
|
||||
|
||||
int mrb_bdump_irep(mrb_state *mrb, int n, FILE *f,const char *initname);
|
||||
|
||||
/* dump type */
|
||||
#define DUMP_TYPE_CODE 0
|
||||
#define DUMP_TYPE_BIN 1
|
||||
#define DUMP_TYPE_HEX 2
|
||||
|
||||
/* dump/load error code */
|
||||
#define MRB_DUMP_OK 0
|
||||
#define MRB_DUMP_GENERAL_FAILURE -1
|
||||
#define MRB_DUMP_WRITE_FAULT -2
|
||||
#define MRB_DUMP_READ_FAULT -3
|
||||
#define MRB_DUMP_CRC_ERROR -4
|
||||
#define MRB_DUMP_INVALID_FILE_HEADER -5
|
||||
#define MRB_DUMP_INVALID_IREP -6
|
||||
#define MRB_DUMP_INVALID_ARGUMENT -7
|
||||
|
||||
/* size of long/int/short value on dump/load */
|
||||
#define MRB_DUMP_SIZE_OF_LONG 4
|
||||
#define MRB_DUMP_SIZE_OF_INT 4
|
||||
#define MRB_DUMP_SIZE_OF_SHORT 2
|
||||
|
||||
/* null symbol length */
|
||||
#define MRB_DUMP_NULL_SYM_LEN 0xFFFF
|
||||
|
||||
/* Use HEX format string */
|
||||
#define RITE_FILE_IS_HEX
|
||||
|
||||
#ifdef RITE_FILE_IS_HEX
|
||||
#define RITE_FILE_HEX_SIZE 2
|
||||
#else
|
||||
#define RITE_FILE_HEX_SIZE 1
|
||||
#endif
|
||||
|
||||
/* Rite Binary File header */
|
||||
#define RITE_FILE_IDENFIFIER "RITE"
|
||||
#define RITE_FILE_FORMAT_VER "00090000"
|
||||
#define RITE_VM_VER "00090000"
|
||||
#define RITE_COMPILER_TYPE "MATZ "
|
||||
#define RITE_COMPILER_VER "00090000"
|
||||
#define RITE_RESERVED " "
|
||||
|
||||
/* irep header */
|
||||
#define RITE_IREP_IDENFIFIER 'S'
|
||||
#define RITE_IREP_TYPE_CLASS 'C'
|
||||
#define RITE_IREP_TYPE_MODULE 'M'
|
||||
|
||||
#define MRB_DUMP_DEFAULT_STR_LEN 128
|
||||
|
||||
//Rite Binary file_header
|
||||
typedef struct _rite_binary_header {
|
||||
unsigned char rbfi[4]; //Rite Binary File Identify
|
||||
unsigned char rbfv[8]; //Rite Binary File Format Version
|
||||
unsigned char risv[8]; //Rite Instruction Specification Version
|
||||
unsigned char rct[8]; //Rite Compiler Type
|
||||
unsigned char rcv[8]; //Rite Compiler Version
|
||||
unsigned char rbds[4]; //Rite Binary Data Size
|
||||
unsigned char nirep[2]; //Number of ireps
|
||||
unsigned char sirep[2]; //Start index
|
||||
unsigned char rsv[8]; //Reserved
|
||||
} rite_binary_header;
|
||||
|
||||
// Rite File file_header
|
||||
typedef struct _rite_file_header {
|
||||
unsigned char rbfi[4]; //Rite Binary File Identify
|
||||
unsigned char rbfv[8]; //Rite Binary File Format Version
|
||||
unsigned char risv[8]; //Rite Instruction Specification Version
|
||||
unsigned char rct[8]; //Rite Compiler Type
|
||||
unsigned char rcv[8]; //Rite Compiler Version
|
||||
unsigned char rbds[8]; //Rite Binary Data Size
|
||||
unsigned char nirep[4]; //Number of ireps
|
||||
unsigned char sirep[4]; //Start index
|
||||
unsigned char rsv[8]; //Reserved
|
||||
unsigned char hcrc[4]; //HCRC
|
||||
} rite_file_header;
|
||||
|
||||
static inline int
|
||||
uint16_to_bin(uint16_t s, char *bin)
|
||||
{
|
||||
*bin++ = (s >> 8) & 0xff;
|
||||
*bin = s & 0xff;
|
||||
return (MRB_DUMP_SIZE_OF_SHORT);
|
||||
}
|
||||
|
||||
static inline int
|
||||
uint32_to_bin(uint32_t l, char *bin)
|
||||
{
|
||||
*bin++ = (l >> 24) & 0xff;
|
||||
*bin++ = (l >> 16) & 0xff;
|
||||
*bin++ = (l >> 8) & 0xff;
|
||||
*bin = l & 0xff;
|
||||
return (MRB_DUMP_SIZE_OF_LONG);
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
bin_to_uint32(unsigned char bin[])
|
||||
{
|
||||
return (uint32_t)bin[0] << 24 |
|
||||
(uint32_t)bin[1] << 16 |
|
||||
(uint32_t)bin[2] << 8 |
|
||||
(uint32_t)bin[3];
|
||||
}
|
||||
|
||||
static inline uint16_t
|
||||
bin_to_uint16(unsigned char bin[])
|
||||
{
|
||||
return (uint16_t)bin[0] << 8 |
|
||||
(uint16_t)bin[1];
|
||||
}
|
||||
+1663
File diff suppressed because it is too large
Load Diff
+360
@@ -0,0 +1,360 @@
|
||||
/**********************************************************************
|
||||
|
||||
encoding.h -
|
||||
|
||||
$Author: matz $
|
||||
created at: Thu May 24 11:49:41 JST 2007
|
||||
|
||||
Copyright (C) 2007 Yukihiro Matsumoto
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef RUBY_ENCODING_H
|
||||
#define RUBY_ENCODING_H 1
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdarg.h>
|
||||
#include "oniguruma.h"
|
||||
#include "mdata.h"
|
||||
|
||||
int mrb_tolower(int c);
|
||||
int mrb_toupper(int c);
|
||||
#define TOUPPER(c) mrb_toupper((unsigned char)(c))
|
||||
#define TOLOWER(c) mrb_tolower((unsigned char)(c))
|
||||
|
||||
#define FL_USHIFT 12
|
||||
|
||||
#define FL_USER0 (((int)1)<<(FL_USHIFT+0))
|
||||
#define FL_USER1 (((int)1)<<(FL_USHIFT+1))
|
||||
#define FL_USER2 (((int)1)<<(FL_USHIFT+2))
|
||||
#define FL_USER3 (((int)1)<<(FL_USHIFT+3))
|
||||
#define FL_USER4 (((int)1)<<(FL_USHIFT+4))
|
||||
#define FL_USER5 (((int)1)<<(FL_USHIFT+5))
|
||||
#define FL_USER6 (((int)1)<<(FL_USHIFT+6))
|
||||
#define FL_USER7 (((int)1)<<(FL_USHIFT+7))
|
||||
#define FL_USER8 (((int)1)<<(FL_USHIFT+8))
|
||||
#define FL_USER9 (((int)1)<<(FL_USHIFT+9))
|
||||
|
||||
#define ENCODING_INLINE_MAX 1023
|
||||
/* 1023 = 0x03FF */
|
||||
/*#define ENCODING_SHIFT (FL_USHIFT+10)*/
|
||||
#define ENCODING_SHIFT (10)
|
||||
#define ENCODING_MASK (((unsigned int)ENCODING_INLINE_MAX)<<ENCODING_SHIFT)
|
||||
|
||||
#define ENCODING_SET_INLINED(obj,i) do {\
|
||||
RBASIC(obj)->flags &= ~ENCODING_MASK;\
|
||||
RBASIC(obj)->flags |= (unsigned int)(i) << ENCODING_SHIFT;\
|
||||
} while (0)
|
||||
#define ENCODING_SET(mrb, obj,i) do {\
|
||||
mrb_value mrb_encoding_set_obj = (obj); \
|
||||
int encoding_set_enc_index = (i); \
|
||||
if (encoding_set_enc_index < ENCODING_INLINE_MAX) \
|
||||
ENCODING_SET_INLINED(mrb_encoding_set_obj, encoding_set_enc_index); \
|
||||
else \
|
||||
mrb_enc_set_index(mrb, mrb_encoding_set_obj, encoding_set_enc_index); \
|
||||
} while (0)
|
||||
|
||||
#define ENCODING_GET_INLINED(obj) (unsigned int)((RSTRING(obj)->flags & ENCODING_MASK)>>ENCODING_SHIFT)
|
||||
#define ENCODING_GET(mrb, obj) \
|
||||
(ENCODING_GET_INLINED(obj) != ENCODING_INLINE_MAX ? \
|
||||
ENCODING_GET_INLINED(obj) : \
|
||||
mrb_enc_get_index(mrb, obj))
|
||||
|
||||
#define ENCODING_IS_ASCII8BIT(obj) (ENCODING_GET_INLINED(obj) == 0)
|
||||
|
||||
#define ENCODING_MAXNAMELEN 42
|
||||
|
||||
#define ENC_CODERANGE_MASK ((int)(FL_USER8|FL_USER9))
|
||||
#define ENC_CODERANGE_UNKNOWN 0
|
||||
#define ENC_CODERANGE_7BIT ((int)FL_USER8)
|
||||
#define ENC_CODERANGE_VALID ((int)FL_USER9)
|
||||
#define ENC_CODERANGE_BROKEN ((int)(FL_USER8|FL_USER9))
|
||||
#define ENC_CODERANGE(obj) ((int)(RSTRING(obj)->flags & ENC_CODERANGE_MASK))
|
||||
#define ENC_CODERANGE_ASCIIONLY(obj) (ENC_CODERANGE(obj) == ENC_CODERANGE_7BIT)
|
||||
#ifdef INCLUDE_ENCODING
|
||||
#define ENC_CODERANGE_SET(obj,cr) (RSTRING(obj)->flags = \
|
||||
(RSTRING(obj)->flags & ~ENC_CODERANGE_MASK) | (cr))
|
||||
#else
|
||||
#define ENC_CODERANGE_SET(obj,cr)
|
||||
#endif //INCLUDE_ENCODING
|
||||
#define ENC_CODERANGE_CLEAR(obj) ENC_CODERANGE_SET(obj,0)
|
||||
|
||||
/* assumed ASCII compatibility */
|
||||
#define ENC_CODERANGE_AND(a, b) \
|
||||
(a == ENC_CODERANGE_7BIT ? b : \
|
||||
a == ENC_CODERANGE_VALID ? (b == ENC_CODERANGE_7BIT ? ENC_CODERANGE_VALID : b) : \
|
||||
ENC_CODERANGE_UNKNOWN)
|
||||
|
||||
#define ENCODING_CODERANGE_SET(mrb, obj, encindex, cr) \
|
||||
do { \
|
||||
mrb_value mrb_encoding_coderange_obj = (obj); \
|
||||
ENCODING_SET(mrb, mrb_encoding_coderange_obj, (encindex)); \
|
||||
ENC_CODERANGE_SET(mrb_encoding_coderange_obj, (cr)); \
|
||||
} while (0)
|
||||
|
||||
typedef OnigEncodingType mrb_encoding;
|
||||
|
||||
mrb_encoding* mrb_enc_get(mrb_state *mrb, mrb_value obj);
|
||||
/* mrb_encoding * -> name */
|
||||
#define mrb_enc_name(enc) (enc)->name
|
||||
int mrb_enc_get_index(mrb_state *mrb, mrb_value obj);
|
||||
|
||||
int mrb_enc_replicate(mrb_state *, const char *, mrb_encoding *);
|
||||
int mrb_define_dummy_encoding(mrb_state *mrb, const char *);
|
||||
#define mrb_enc_to_index(enc) ((enc) ? ENC_TO_ENCINDEX(enc) : 0)
|
||||
void mrb_enc_set_index(mrb_state *mrb, mrb_value obj, int encindex);
|
||||
int mrb_enc_find_index(mrb_state *mrb, const char *name);
|
||||
int mrb_to_encoding_index(mrb_state *mrb, mrb_value);
|
||||
mrb_encoding* mrb_to_encoding(mrb_state *mrb, mrb_value);
|
||||
mrb_encoding* mrb_enc_get(mrb_state *, mrb_value);
|
||||
mrb_encoding* mrb_enc_compatible(mrb_state *, mrb_value, mrb_value);
|
||||
mrb_encoding* mrb_enc_check(mrb_state *, mrb_value, mrb_value);
|
||||
mrb_value mrb_enc_associate_index(mrb_state *mrb, mrb_value, int);
|
||||
#ifdef INCLUDE_ENCODING
|
||||
mrb_value mrb_enc_associate(mrb_state *mrb, mrb_value, mrb_encoding*);
|
||||
#else
|
||||
#define mrb_enc_associate(mrb,value,enc)
|
||||
#endif //INCLUDE_ENCODING
|
||||
void mrb_enc_copy(mrb_state *mrb, mrb_value dst, mrb_value src);
|
||||
|
||||
mrb_value mrb_enc_reg_new(const char*, long, mrb_encoding*, int);
|
||||
//PRINTF_ARGS(mrb_value rb_enc_sprintf(mrb_encoding *, const char*, ...), 2, 3);
|
||||
mrb_value mrb_enc_vsprintf(mrb_encoding *, const char*, va_list);
|
||||
long mrb_enc_strlen(const char*, const char*, mrb_encoding*);
|
||||
char* mrb_enc_nth(mrb_state *, const char*, const char*, long, mrb_encoding*);
|
||||
mrb_value mrb_obj_encoding(mrb_state *, mrb_value);
|
||||
mrb_value mrb_enc_str_buf_cat(mrb_state *mrb, mrb_value str, const char *ptr, long len, mrb_encoding *enc);
|
||||
mrb_value rb_enc_uint_chr(mrb_state *mrb, unsigned int code, mrb_encoding *enc);
|
||||
|
||||
mrb_value mrb_external_str_new_with_enc(mrb_state *mrb, const char *ptr, long len, mrb_encoding *);
|
||||
mrb_value mrb_str_export_to_enc(mrb_value, mrb_encoding *);
|
||||
|
||||
/* index -> mrb_encoding */
|
||||
mrb_encoding* mrb_enc_from_index(mrb_state *mrb, int idx);
|
||||
|
||||
/* name -> mrb_encoding */
|
||||
mrb_encoding * mrb_enc_find(mrb_state *mrb, const char *name);
|
||||
|
||||
/* mrb_encoding * -> name */
|
||||
#define mrb_enc_name(enc) (enc)->name
|
||||
|
||||
/* mrb_encoding * -> minlen/maxlen */
|
||||
#define mrb_enc_mbminlen(enc) (enc)->min_enc_len
|
||||
#define mrb_enc_mbmaxlen(enc) (enc)->max_enc_len
|
||||
|
||||
/* -> mbclen (no error notification: 0 < ret <= e-p, no exception) */
|
||||
int mrb_enc_mbclen(const char *p, const char *e, mrb_encoding *enc);
|
||||
|
||||
/* -> mbclen (only for valid encoding) */
|
||||
int mrb_enc_fast_mbclen(const char *p, const char *e, mrb_encoding *enc);
|
||||
|
||||
/* -> chlen, invalid or needmore */
|
||||
int mrb_enc_precise_mbclen(const char *p, const char *e, mrb_encoding *enc);
|
||||
#define MBCLEN_CHARFOUND_P(ret) ONIGENC_MBCLEN_CHARFOUND_P(ret)
|
||||
#define MBCLEN_CHARFOUND_LEN(ret) ONIGENC_MBCLEN_CHARFOUND_LEN(ret)
|
||||
#define MBCLEN_INVALID_P(ret) ONIGENC_MBCLEN_INVALID_P(ret)
|
||||
#define MBCLEN_NEEDMORE_P(ret) ONIGENC_MBCLEN_NEEDMORE_P(ret)
|
||||
#define MBCLEN_NEEDMORE_LEN(ret) ONIGENC_MBCLEN_NEEDMORE_LEN(ret)
|
||||
|
||||
/* -> 0x00..0x7f, -1 */
|
||||
int mrb_enc_ascget(mrb_state *mrb, const char *p, const char *e, int *len, mrb_encoding *enc);
|
||||
|
||||
|
||||
/* -> code (and len) or raise exception */
|
||||
unsigned int mrb_enc_codepoint_len(mrb_state *mrb, const char *p, const char *e, int *len, mrb_encoding *enc);
|
||||
|
||||
/* prototype for obsolete function */
|
||||
unsigned int mrb_enc_codepoint(mrb_state *mrb, const char *p, const char *e, mrb_encoding *enc);
|
||||
/* overriding macro */
|
||||
#define mrb_enc_codepoint(mrb,p,e,enc) mrb_enc_codepoint_len((mrb),(p),(e),0,(enc))
|
||||
#define mrb_enc_mbc_to_codepoint(p, e, enc) ONIGENC_MBC_TO_CODE(enc,(UChar*)(p),(UChar*)(e))
|
||||
|
||||
/* -> codelen>0 or raise exception */
|
||||
#ifdef INCLUDE_ENCODING
|
||||
int mrb_enc_codelen(mrb_state *mrb, int code, mrb_encoding *enc);
|
||||
#else
|
||||
#define mrb_enc_codelen(mrb,code,enc) 1
|
||||
#endif //INCLUDE_ENCODING
|
||||
|
||||
/* code,ptr,encoding -> write buf */
|
||||
#ifdef INCLUDE_ENCODING
|
||||
#define mrb_enc_mbcput(c,buf,enc) ONIGENC_CODE_TO_MBC(enc,c,(UChar*)(buf))
|
||||
#else
|
||||
#define mrb_enc_mbcput(c,buf,enc) *(buf) = (char)(c)
|
||||
#endif //INCLUDE_ENCODING
|
||||
|
||||
/* start, ptr, end, encoding -> prev_char */
|
||||
#define mrb_enc_prev_char(s,p,e,enc) (char *)onigenc_get_prev_char_head(enc,(UChar*)(s),(UChar*)(p),(UChar*)(e))
|
||||
/* start, ptr, end, encoding -> next_char */
|
||||
#define mrb_enc_left_char_head(s,p,e,enc) (char *)onigenc_get_left_adjust_char_head(enc,(UChar*)(s),(UChar*)(p),(UChar*)(e))
|
||||
#define mrb_enc_right_char_head(s,p,e,enc) (char *)onigenc_get_right_adjust_char_head(enc,(UChar*)(s),(UChar*)(p),(UChar*)(e))
|
||||
|
||||
/* ptr, ptr, encoding -> newline_or_not */
|
||||
#define mrb_enc_is_newline(p,end,enc) ONIGENC_IS_MBC_NEWLINE(enc,(UChar*)(p),(UChar*)(end))
|
||||
|
||||
#define mrb_enc_isctype(c,t,enc) ONIGENC_IS_CODE_CTYPE(enc,c,t)
|
||||
#define mrb_enc_isascii(c,enc) ONIGENC_IS_CODE_ASCII(c)
|
||||
#define mrb_enc_isalpha(c,enc) ONIGENC_IS_CODE_ALPHA(enc,c)
|
||||
#define mrb_enc_islower(c,enc) ONIGENC_IS_CODE_LOWER(enc,c)
|
||||
#define mrb_enc_isupper(c,enc) ONIGENC_IS_CODE_UPPER(enc,c)
|
||||
#define mrb_enc_ispunct(c,enc) ONIGENC_IS_CODE_PUNCT(enc,c)
|
||||
#define mrb_enc_isalnum(c,enc) ONIGENC_IS_CODE_ALNUM(enc,c)
|
||||
#define mrb_enc_isprint(c,enc) ONIGENC_IS_CODE_PRINT(enc,c)
|
||||
#define mrb_enc_isspace(c,enc) ONIGENC_IS_CODE_SPACE(enc,c)
|
||||
#define mrb_enc_isdigit(c,enc) ONIGENC_IS_CODE_DIGIT(enc,c)
|
||||
|
||||
#define mrb_enc_asciicompat(mrb, enc) (mrb_enc_mbminlen(enc)==1 && !mrb_enc_dummy_p(enc))
|
||||
|
||||
int mrb_enc_casefold(char *to, const char *p, const char *e, mrb_encoding *enc);
|
||||
int mrb_enc_toupper(int c, mrb_encoding *enc);
|
||||
int mrb_enc_tolower(int c, mrb_encoding *enc);
|
||||
//ID mrb_intern3(const char*, long, mrb_encoding*);
|
||||
//ID mrb_interned_id_p(const char *, long, mrb_encoding *);
|
||||
int mrb_enc_symname_p(const char*, mrb_encoding*);
|
||||
int mrb_enc_symname2_p(const char*, long, mrb_encoding*);
|
||||
int mrb_enc_str_coderange(mrb_state *mrb, mrb_value);
|
||||
long mrb_str_coderange_scan_restartable(const char*, const char*, mrb_encoding*, int*);
|
||||
int mrb_enc_str_asciionly_p(mrb_state *mrb, mrb_value);
|
||||
#define mrb_enc_str_asciicompat_p(mrb, str) mrb_enc_asciicompat(mrb, mrb_enc_get(mrb, str))
|
||||
mrb_value mrb_enc_from_encoding(mrb_state *mrb, mrb_encoding *enc);
|
||||
int mrb_enc_unicode_p(mrb_encoding *enc);
|
||||
mrb_encoding *mrb_ascii8bit_encoding(mrb_state *mrb);
|
||||
mrb_encoding *mrb_utf8_encoding(mrb_state *mrb);
|
||||
mrb_encoding *mrb_usascii_encoding(mrb_state *mrb);
|
||||
mrb_encoding *mrb_locale_encoding(mrb_state *mrb);
|
||||
mrb_encoding *mrb_filesystem_encoding(mrb_state *mrb);
|
||||
mrb_encoding *mrb_default_external_encoding(mrb_state *mrb);
|
||||
mrb_encoding *mrb_default_internal_encoding(mrb_state *mrb);
|
||||
int mrb_ascii8bit_encindex(void);
|
||||
int mrb_utf8_encindex(void);
|
||||
int mrb_usascii_encindex(void);
|
||||
int mrb_locale_encindex(mrb_state *mrb);
|
||||
int mrb_filesystem_encindex(void);
|
||||
mrb_value mrb_enc_default_external(mrb_state *mrb);
|
||||
mrb_value mrb_enc_default_internal(mrb_state *mrb);
|
||||
void mrb_enc_set_default_external(mrb_state *mrb, mrb_value encoding);
|
||||
void mrb_enc_set_default_internal(mrb_state *mrb, mrb_value encoding);
|
||||
mrb_value mrb_locale_charmap(mrb_state *mrb, mrb_value klass);
|
||||
#ifdef INCLUDE_ENCODING
|
||||
int mrb_memsearch(mrb_state *mrb, const void*,int,const void*,int,mrb_encoding*);
|
||||
#endif //INCLUDE_ENCODING
|
||||
mrb_value mrb_usascii_str_new_cstr(mrb_state *mrb, const char *ptr);
|
||||
int mrb_str_buf_cat_escaped_char(mrb_state *mrb, mrb_value result, unsigned int c, int unicode_p);
|
||||
|
||||
#define ENC_DUMMY_FLAG (1<<24)
|
||||
#define ENC_INDEX_MASK (~(~0U<<24))
|
||||
|
||||
#define ENC_TO_ENCINDEX(enc) (int)((enc)->ruby_encoding_index & ENC_INDEX_MASK)
|
||||
|
||||
#define ENC_DUMMY_P(enc) ((enc)->ruby_encoding_index & ENC_DUMMY_FLAG)
|
||||
#define ENC_SET_DUMMY(enc) ((enc)->ruby_encoding_index |= ENC_DUMMY_FLAG)
|
||||
|
||||
static inline int
|
||||
mrb_enc_dummy_p(mrb_encoding *enc)
|
||||
{
|
||||
return ENC_DUMMY_P(enc) != 0;
|
||||
}
|
||||
|
||||
/* econv stuff */
|
||||
|
||||
typedef enum {
|
||||
econv_invalid_byte_sequence,
|
||||
econv_undefined_conversion,
|
||||
econv_destination_buffer_full,
|
||||
econv_source_buffer_empty,
|
||||
econv_finished,
|
||||
econv_after_output,
|
||||
econv_incomplete_input
|
||||
} mrb_econv_result_t;
|
||||
|
||||
typedef struct mrb_econv_t mrb_econv_t;
|
||||
|
||||
mrb_value mrb_str_encode(mrb_state *mrb, mrb_value str, mrb_value to, int ecflags, mrb_value ecopts);
|
||||
int mrb_econv_has_convpath_p(mrb_state *mrb, const char* from_encoding, const char* to_encoding);
|
||||
|
||||
int mrb_econv_prepare_opts(mrb_state *mrb, mrb_value opthash, mrb_value *ecopts);
|
||||
|
||||
mrb_econv_t *mrb_econv_open(mrb_state *mrb, const char *source_encoding, const char *destination_encoding, int ecflags);
|
||||
mrb_econv_t *mrb_econv_open_opts(mrb_state *mrb, const char *source_encoding, const char *destination_encoding, int ecflags, mrb_value ecopts);
|
||||
|
||||
mrb_econv_result_t mrb_econv_convert(mrb_state *mrb, mrb_econv_t *ec,
|
||||
const unsigned char **source_buffer_ptr, const unsigned char *source_buffer_end,
|
||||
unsigned char **destination_buffer_ptr, unsigned char *destination_buffer_end,
|
||||
int flags);
|
||||
void mrb_econv_close(mrb_econv_t *ec);
|
||||
|
||||
/* result: 0:success -1:failure */
|
||||
int mrb_econv_set_replacement(mrb_state *mrb, mrb_econv_t *ec, const unsigned char *str, size_t len, const char *encname);
|
||||
|
||||
/* result: 0:success -1:failure */
|
||||
int mrb_econv_decorate_at_first(mrb_state *mrb, mrb_econv_t *ec, const char *decorator_name);
|
||||
int mrb_econv_decorate_at_last(mrb_state *mrb, mrb_econv_t *ec, const char *decorator_name);
|
||||
|
||||
mrb_value mrb_econv_open_exc(mrb_state *mrb, const char *senc, const char *denc, int ecflags);
|
||||
|
||||
/* result: 0:success -1:failure */
|
||||
int mrb_econv_insert_output(mrb_state *mrb, mrb_econv_t *ec,
|
||||
const unsigned char *str, size_t len, const char *str_encoding);
|
||||
|
||||
/* encoding that mrb_econv_insert_output doesn't need conversion */
|
||||
const char *mrb_econv_encoding_to_insert_output(mrb_econv_t *ec);
|
||||
|
||||
/* raise an error if the last mrb_econv_convert is error */
|
||||
void mrb_econv_check_error(mrb_state *mrb, mrb_econv_t *ec);
|
||||
|
||||
/* returns an exception object or nil */
|
||||
mrb_value mrb_econv_make_exception(mrb_state *mrb, mrb_econv_t *ec);
|
||||
|
||||
int mrb_econv_putbackable(mrb_econv_t *ec);
|
||||
void mrb_econv_putback(mrb_econv_t *ec, unsigned char *p, int n);
|
||||
|
||||
/* returns the corresponding ASCII compatible encoding for encname,
|
||||
* or NULL if encname is not ASCII incompatible encoding. */
|
||||
const char *mrb_econv_asciicompat_encoding(const char *encname);
|
||||
|
||||
mrb_value mrb_econv_str_convert(mrb_state *mrb, mrb_econv_t *ec, mrb_value src, int flags);
|
||||
mrb_value mrb_econv_substr_convert(mrb_state *mrb, mrb_econv_t *ec, mrb_value src, long byteoff, long bytesize, int flags);
|
||||
mrb_value mrb_econv_str_append(mrb_state *mrb, mrb_econv_t *ec, mrb_value src, mrb_value dst, int flags);
|
||||
mrb_value mrb_econv_substr_append(mrb_state *mrb, mrb_econv_t *ec, mrb_value src, long byteoff, long bytesize, mrb_value dst, int flags);
|
||||
|
||||
void mrb_econv_binmode(mrb_econv_t *ec);
|
||||
|
||||
/* flags for mrb_econv_open */
|
||||
|
||||
#define ECONV_ERROR_HANDLER_MASK 0x000000ff
|
||||
|
||||
#define ECONV_INVALID_MASK 0x0000000f
|
||||
#define ECONV_INVALID_REPLACE 0x00000002
|
||||
|
||||
#define ECONV_UNDEF_MASK 0x000000f0
|
||||
#define ECONV_UNDEF_REPLACE 0x00000020
|
||||
#define ECONV_UNDEF_HEX_CHARREF 0x00000030
|
||||
|
||||
#define ECONV_DECORATOR_MASK 0x0000ff00
|
||||
|
||||
#define ECONV_UNIVERSAL_NEWLINE_DECORATOR 0x00000100
|
||||
#define ECONV_CRLF_NEWLINE_DECORATOR 0x00001000
|
||||
#define ECONV_CR_NEWLINE_DECORATOR 0x00002000
|
||||
#define ECONV_XML_TEXT_DECORATOR 0x00004000
|
||||
#define ECONV_XML_ATTR_CONTENT_DECORATOR 0x00008000
|
||||
|
||||
#define ECONV_STATEFUL_DECORATOR_MASK 0x00f00000
|
||||
#define ECONV_XML_ATTR_QUOTE_DECORATOR 0x00100000
|
||||
|
||||
/* end of flags for mrb_econv_open */
|
||||
|
||||
/* flags for mrb_econv_convert */
|
||||
#define ECONV_PARTIAL_INPUT 0x00010000
|
||||
#define ECONV_AFTER_OUTPUT 0x00020000
|
||||
/* end of flags for mrb_econv_convert */
|
||||
|
||||
int mrb_isspace(int c);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
} /* extern "C" { */
|
||||
#endif
|
||||
|
||||
#endif /* RUBY_ENCODING_H */
|
||||
+1077
File diff suppressed because it is too large
Load Diff
+479
@@ -0,0 +1,479 @@
|
||||
#include "mruby.h"
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <setjmp.h>
|
||||
#include "error.h"
|
||||
#include "opcode.h"
|
||||
#include "irep.h"
|
||||
#include "mruby/proc.h"
|
||||
#include "mruby/numeric.h"
|
||||
#include "variable.h"
|
||||
#include "mruby/string.h"
|
||||
#include "eval_intern.h"
|
||||
#include "mruby/class.h"
|
||||
|
||||
#define warn_printf printf
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif
|
||||
|
||||
mrb_value
|
||||
mrb_exc_new(mrb_state *mrb, struct RClass *c, const char *ptr, long len)
|
||||
{
|
||||
return mrb_funcall(mrb, mrb_obj_value(c), "new", 1, mrb_str_new(mrb, ptr, len));
|
||||
}
|
||||
|
||||
mrb_value
|
||||
mrb_exc_new3(mrb_state *mrb, struct RClass* c, mrb_value str)
|
||||
{
|
||||
//StringValue(str);
|
||||
mrb_string_value(mrb, &str);
|
||||
return mrb_funcall(mrb, mrb_obj_value(c), "new", 1, str);
|
||||
}
|
||||
|
||||
//mrb_value make_exception(mrb_state *mrb, int argc, mrb_value *argv, int isstr);
|
||||
/*
|
||||
* call-seq:
|
||||
* Exception.new(msg = nil) -> exception
|
||||
*
|
||||
* Construct a new Exception object, optionally passing in
|
||||
* a message.
|
||||
*/
|
||||
|
||||
static mrb_value
|
||||
exc_initialize(mrb_state *mrb, mrb_value exc)
|
||||
{
|
||||
mrb_value mesg;
|
||||
|
||||
mrb_get_args(mrb, "o", &mesg);
|
||||
mrb_iv_set(mrb, exc, mrb_intern(mrb, "mesg"), mesg);
|
||||
|
||||
return exc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Document-method: exception
|
||||
*
|
||||
* call-seq:
|
||||
* exc.exception(string) -> an_exception or exc
|
||||
*
|
||||
* With no argument, or if the argument is the same as the receiver,
|
||||
* return the receiver. Otherwise, create a new
|
||||
* exception object of the same class as the receiver, but with a
|
||||
* message equal to <code>string.to_str</code>.
|
||||
*
|
||||
*/
|
||||
|
||||
static mrb_value
|
||||
exc_exception(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
mrb_value exc;
|
||||
mrb_value *argv;
|
||||
int argc;
|
||||
|
||||
mrb_get_args(mrb, "*", &argv, &argc);
|
||||
|
||||
if (argc == 0) return self;
|
||||
if (argc == 1 && mrb_obj_equal(mrb, self, argv[0])) return self;
|
||||
exc = mrb_obj_clone(mrb, self);
|
||||
exc_initialize(mrb, exc);
|
||||
|
||||
return exc;
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* exception.to_s -> string
|
||||
*
|
||||
* Returns exception's message (or the name of the exception if
|
||||
* no message is set).
|
||||
*/
|
||||
|
||||
static mrb_value
|
||||
exc_to_s(mrb_state *mrb, mrb_value exc)
|
||||
{
|
||||
mrb_value mesg = mrb_attr_get(mrb, exc, mrb_intern(mrb, "mesg"));
|
||||
|
||||
if (mrb_nil_p(mesg)) return mrb_str_new2(mrb, mrb_obj_classname(mrb, exc));
|
||||
return mesg;
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* exception.message -> string
|
||||
*
|
||||
* Returns the result of invoking <code>exception.to_s</code>.
|
||||
* Normally this returns the exception's message or name. By
|
||||
* supplying a to_str method, exceptions are agreeing to
|
||||
* be used where Strings are expected.
|
||||
*/
|
||||
|
||||
static mrb_value
|
||||
exc_message(mrb_state *mrb, mrb_value exc)
|
||||
{
|
||||
return mrb_funcall(mrb, exc, "to_s", 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* exception.inspect -> string
|
||||
*
|
||||
* Return this exception's class name an message
|
||||
*/
|
||||
|
||||
static mrb_value
|
||||
exc_inspect(mrb_state *mrb, mrb_value exc)
|
||||
{
|
||||
mrb_value str, klass;
|
||||
|
||||
klass = mrb_str_new2(mrb, mrb_obj_classname(mrb, exc));
|
||||
exc = mrb_obj_as_string(mrb, exc);
|
||||
if (RSTRING_LEN(exc) == 0) {
|
||||
return klass;
|
||||
}
|
||||
|
||||
str = mrb_str_new2(mrb, "#<");
|
||||
mrb_str_append(mrb, str, klass);
|
||||
mrb_str_cat2(mrb, str, ": ");
|
||||
mrb_str_append(mrb, str, exc);
|
||||
mrb_str_cat2(mrb, str, ">");
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
static mrb_value
|
||||
exc_equal(mrb_state *mrb, mrb_value exc)
|
||||
{
|
||||
mrb_value obj;
|
||||
mrb_value mesg;
|
||||
mrb_sym id_mesg = mrb_intern(mrb, "mesg");
|
||||
|
||||
mrb_get_args(mrb, "o", &obj);
|
||||
|
||||
if (mrb_obj_equal(mrb, exc, obj)) return mrb_true_value();
|
||||
|
||||
if (mrb_obj_class(mrb, exc) != mrb_obj_class(mrb, obj)) {
|
||||
if ( mrb_respond_to(mrb, obj, mrb_intern(mrb, "message")) ) {
|
||||
mesg = mrb_funcall(mrb, obj, "message", 0);
|
||||
}
|
||||
else
|
||||
return mrb_false_value();
|
||||
}
|
||||
else {
|
||||
mesg = mrb_attr_get(mrb, obj, id_mesg);
|
||||
}
|
||||
|
||||
if (!mrb_equal(mrb, mrb_attr_get(mrb, exc, id_mesg), mesg))
|
||||
return mrb_false_value();
|
||||
return mrb_true_value();
|
||||
}
|
||||
|
||||
void
|
||||
mrb_exc_raise(mrb_state *mrb, mrb_value exc)
|
||||
{
|
||||
mrb->exc = mrb_object(exc);
|
||||
longjmp(*(jmp_buf*)mrb->jmp, 1);
|
||||
}
|
||||
|
||||
void
|
||||
mrb_raise_va(mrb_state *mrb, struct RClass *c, const char *fmt, va_list args)
|
||||
{
|
||||
char buf[256];
|
||||
|
||||
vsnprintf(buf, 256, fmt, args);
|
||||
mrb_exc_raise(mrb, mrb_exc_new(mrb, c, buf, strlen(buf)));
|
||||
}
|
||||
|
||||
void
|
||||
mrb_raise(mrb_state *mrb, struct RClass *c, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
char buf[256];
|
||||
|
||||
va_start(args, fmt);
|
||||
vsnprintf(buf, 256, fmt, args);
|
||||
mrb_raise_va(mrb, c, fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void
|
||||
mrb_name_error(mrb_state *mrb, mrb_sym id, const char *fmt, ...)
|
||||
{
|
||||
mrb_value exc, argv[2];
|
||||
va_list args;
|
||||
char buf[256];
|
||||
|
||||
va_start(args, fmt);
|
||||
//argv[0] = mrb_vsprintf(fmt, args);
|
||||
vsnprintf(buf, 256, fmt, args);
|
||||
argv[0] = mrb_str_new(mrb, buf, strlen(buf));
|
||||
va_end(args);
|
||||
|
||||
argv[1] = mrb_str_new_cstr(mrb, mrb_sym2name(mrb, id));
|
||||
exc = mrb_class_new_instance(mrb, 2, argv, E_NAME_ERROR);
|
||||
mrb_exc_raise(mrb, exc);
|
||||
}
|
||||
mrb_value
|
||||
mrb_sprintf(mrb_state *mrb, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
char buf[256];
|
||||
|
||||
va_start(args, fmt);
|
||||
vsnprintf(buf, 256, fmt, args);
|
||||
va_end(args);
|
||||
return mrb_str_new(mrb, buf, strlen(buf));
|
||||
}
|
||||
|
||||
void
|
||||
mrb_warn(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
char buf[256];
|
||||
|
||||
va_start(args, fmt);
|
||||
snprintf(buf, 256, "warning: %s", fmt);
|
||||
printf(buf, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
mrb_warning(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
char buf[256];
|
||||
|
||||
va_start(args, fmt);
|
||||
snprintf(buf, 256, "warning: %s", fmt);
|
||||
printf(buf, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void
|
||||
mrb_bug(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
char buf[256];
|
||||
|
||||
va_start(args, fmt);
|
||||
snprintf(buf, 256, "bug: %s", fmt);
|
||||
printf(buf, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
static const char *
|
||||
mrb_strerrno(int err)
|
||||
{
|
||||
#define defined_error(name, num) if (err == num) return name;
|
||||
#define undefined_error(name)
|
||||
//#include "known_errors.inc"
|
||||
#undef defined_error
|
||||
#undef undefined_error
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
mrb_bug_errno(const char *mesg, int errno_arg)
|
||||
{
|
||||
if (errno_arg == 0)
|
||||
mrb_bug("%s: errno == 0 (NOERROR)", mesg);
|
||||
else {
|
||||
const char *errno_str = mrb_strerrno(errno_arg);
|
||||
if (errno_str)
|
||||
mrb_bug("%s: %s (%s)", mesg, strerror(errno_arg), errno_str);
|
||||
else
|
||||
mrb_bug("%s: %s (%d)", mesg, strerror(errno_arg), errno_arg);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
sysexit_status(mrb_state *mrb, mrb_value err)
|
||||
{
|
||||
mrb_value st = mrb_iv_get(mrb, err, mrb_intern(mrb, "status"));
|
||||
return mrb_fixnum(st);
|
||||
}
|
||||
|
||||
void
|
||||
error_pos(void)
|
||||
{
|
||||
#if 0
|
||||
const char *sourcefile = mrb_sourcefile();
|
||||
int sourceline = mrb_sourceline();
|
||||
|
||||
if (sourcefile) {
|
||||
if (sourceline == 0) {
|
||||
warn_printf("%s", sourcefile);
|
||||
}
|
||||
else if (mrb_frame_callee()) {
|
||||
warn_printf("%s:%d:in `%s'", sourcefile, sourceline,
|
||||
mrb_sym2name(mrb, mrb_frame_callee()));
|
||||
}
|
||||
else {
|
||||
warn_printf("%s:%d", sourcefile, sourceline);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
set_backtrace(mrb_state *mrb, mrb_value info, mrb_value bt)
|
||||
{
|
||||
mrb_funcall(mrb, info, "set_backtrace", 1, bt);
|
||||
}
|
||||
|
||||
mrb_value
|
||||
make_exception(mrb_state *mrb, int argc, mrb_value *argv, int isstr)
|
||||
{
|
||||
mrb_value mesg;
|
||||
int n;
|
||||
|
||||
mesg = mrb_nil_value();
|
||||
switch (argc) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
if (mrb_nil_p(argv[0]))
|
||||
break;
|
||||
if (isstr) {
|
||||
mesg = mrb_check_string_type(mrb, argv[0]);
|
||||
if (!mrb_nil_p(mesg)) {
|
||||
mesg = mrb_exc_new3(mrb, mrb->eRuntimeError_class, mesg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
n = 0;
|
||||
goto exception_call;
|
||||
|
||||
case 2:
|
||||
case 3:
|
||||
n = 1;
|
||||
exception_call:
|
||||
//if (argv[0] == sysstack_error) return argv[0];
|
||||
|
||||
//CONST_ID(mrb, exception, "exception");
|
||||
//mesg = mrb_check_funcall(mrb, argv[0], exception, n, argv+1);
|
||||
//if (mrb_nil_p(mesg)) {
|
||||
// /* undef */
|
||||
// mrb_raise(mrb, E_TYPE_ERROR, "exception class/object expected");
|
||||
//}
|
||||
if (mrb_respond_to(mrb, argv[0], mrb_intern(mrb, "exception"))) {
|
||||
mesg = mrb_funcall(mrb, argv[0], "exception", n, argv+1);
|
||||
}
|
||||
else {
|
||||
/* undef */
|
||||
mrb_raise(mrb, E_TYPE_ERROR, "exception class/object expected");
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
mrb_raise(mrb, E_ARGUMENT_ERROR, "wrong number of arguments (%d for 0..3)", argc);
|
||||
break;
|
||||
}
|
||||
if (argc > 0) {
|
||||
if (!mrb_obj_is_kind_of(mrb, mesg, mrb->eException_class))
|
||||
mrb_raise(mrb, E_TYPE_ERROR, "exception object expected");
|
||||
if (argc > 2)
|
||||
set_backtrace(mrb, mesg, argv[2]);
|
||||
}
|
||||
|
||||
return mesg;
|
||||
}
|
||||
|
||||
mrb_value
|
||||
mrb_make_exception(mrb_state *mrb, int argc, mrb_value *argv)
|
||||
{
|
||||
return make_exception(mrb, argc, argv, TRUE);
|
||||
}
|
||||
|
||||
void
|
||||
mrb_sys_fail(mrb_state *mrb, const char *mesg)
|
||||
{
|
||||
mrb_raise(mrb, mrb->eRuntimeError_class, "%s", mesg);
|
||||
}
|
||||
|
||||
static mrb_value
|
||||
mrb_exc_c_exception(mrb_state *mrb, mrb_value exc)
|
||||
{
|
||||
mrb_value *argv;
|
||||
int argc;
|
||||
|
||||
mrb_get_args(mrb, "*", &argv, &argc);
|
||||
return mrb_make_exception(mrb, argc, argv);
|
||||
}
|
||||
|
||||
static mrb_value
|
||||
mrb_exc_exception(mrb_state *mrb, mrb_value exc)
|
||||
{
|
||||
mrb_value *argv;
|
||||
int argc;
|
||||
mrb_value exclass;
|
||||
|
||||
mrb_get_args(mrb, "*", &argv, &argc);
|
||||
if (argc == 0) return exc;
|
||||
exclass = mrb_obj_value(mrb_class(mrb, exc));
|
||||
return mrb_funcall(mrb, exclass, mrb_intern(mrb, "exception"), argc, argv);
|
||||
}
|
||||
|
||||
void
|
||||
mrb_init_exception(mrb_state *mrb)
|
||||
{
|
||||
struct RClass *e;
|
||||
struct RClass *eTypeError_class;
|
||||
struct RClass *eArgumentError_class;
|
||||
struct RClass *eIndexError_class;
|
||||
struct RClass *eRangeError_class;
|
||||
struct RClass *eNameError_class;
|
||||
struct RClass *eNoMethodError_class;
|
||||
struct RClass *eScriptError_class;
|
||||
struct RClass *eSyntaxError_class;
|
||||
struct RClass *eLoadError_class;
|
||||
struct RClass *eSystemCallError_class;
|
||||
struct RClass *eLocalJumpError_class;
|
||||
struct RClass *eRegexpError_class;
|
||||
struct RClass *eZeroDivisionError_class;
|
||||
struct RClass *eEncodingError_class;
|
||||
struct RClass *eNotImpError_class;
|
||||
struct RClass *eFloatDomainError_class;
|
||||
struct RClass *eKeyError_class;
|
||||
|
||||
mrb->eException_class = e = mrb_define_class(mrb, "Exception", mrb->object_class); /* 15.2.22 */
|
||||
mrb_define_class_method(mrb, e, "exception", mrb_instance_new, ARGS_ANY());
|
||||
mrb_define_method(mrb, e, "exception", exc_exception, ARGS_ANY());
|
||||
mrb_define_method(mrb, e, "initialize", exc_initialize, ARGS_ANY());
|
||||
mrb_define_method(mrb, e, "==", exc_equal, ARGS_REQ(1));
|
||||
mrb_define_method(mrb, e, "to_s", exc_to_s, ARGS_NONE());
|
||||
mrb_define_method(mrb, e, "message", exc_message, ARGS_NONE());
|
||||
mrb_define_method(mrb, e, "inspect", exc_inspect, ARGS_NONE());
|
||||
|
||||
mrb->eStandardError_class = mrb_define_class(mrb, "StandardError", mrb->eException_class); /* 15.2.23 */
|
||||
mrb->eRuntimeError_class = mrb_define_class(mrb, "RuntimeError", mrb->eStandardError_class); /* 15.2.28 */
|
||||
|
||||
eTypeError_class = mrb_define_class(mrb, "TypeError", mrb->eStandardError_class); /* 15.2.29 */
|
||||
eArgumentError_class = mrb_define_class(mrb, "ArgumentError", mrb->eStandardError_class); /* 15.2.24 */
|
||||
eIndexError_class = mrb_define_class(mrb, "IndexError", mrb->eStandardError_class); /* 15.2.33 */
|
||||
eRangeError_class = mrb_define_class(mrb, "RangeError", mrb->eStandardError_class); /* 15.2.26 */
|
||||
eNameError_class = mrb_define_class(mrb, "NameError", mrb->eStandardError_class); /* 15.2.31 */
|
||||
|
||||
eNoMethodError_class = mrb_define_class(mrb, "NoMethodError", eNameError_class); /* 15.2.32 */
|
||||
eScriptError_class = mrb_define_class(mrb, "ScriptError", mrb->eException_class); /* 15.2.37 */
|
||||
eSyntaxError_class = mrb_define_class(mrb, "SyntaxError", eScriptError_class); /* 15.2.38 */
|
||||
eLoadError_class = mrb_define_class(mrb, "LoadError", eScriptError_class); /* 15.2.39 */
|
||||
eSystemCallError_class = mrb_define_class(mrb, "SystemCallError", mrb->eStandardError_class); /* 15.2.36 */
|
||||
eLocalJumpError_class = mrb_define_class(mrb, "LocalJumpError", mrb->eStandardError_class); /* 15.2.25 */
|
||||
eRegexpError_class = mrb_define_class(mrb, "RegexpError", mrb->eStandardError_class); /* 15.2.27 */
|
||||
eZeroDivisionError_class = mrb_define_class(mrb, "ZeroDivisionError", mrb->eStandardError_class); /* 15.2.30 */
|
||||
|
||||
eEncodingError_class = mrb_define_class(mrb, "EncodingError", mrb->eStandardError_class);
|
||||
eNotImpError_class = mrb_define_class(mrb, "NotImplementedError", eScriptError_class);
|
||||
|
||||
eFloatDomainError_class = mrb_define_class(mrb, "FloatDomainError", eRangeError_class);
|
||||
eKeyError_class = mrb_define_class(mrb, "KeyError", eIndexError_class);
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
#ifndef MRUBY_ERROR_H
|
||||
#define MRUBY_ERROR_H
|
||||
|
||||
struct RException {
|
||||
MRUBY_OBJECT_HEADER;
|
||||
};
|
||||
|
||||
void mrb_sys_fail(mrb_state *mrb, const char *mesg);
|
||||
void mrb_exc_raise(mrb_state *mrb, mrb_value mesg);
|
||||
void mrb_bug_errno(const char*, int);
|
||||
int sysexit_status(mrb_state *mrb, mrb_value err);
|
||||
void error_pos(void);
|
||||
mrb_value mrb_exc_new3(mrb_state *mrb, struct RClass* c, mrb_value str);
|
||||
mrb_value make_exception(mrb_state *mrb, int argc, mrb_value *argv, int isstr);
|
||||
mrb_value mrb_exc_new(mrb_state *mrb, struct RClass *c, const char *ptr, long len);
|
||||
mrb_value mrb_make_exception(mrb_state *mrb, int argc, mrb_value *argv);
|
||||
mrb_value mrb_sprintf(mrb_state *mrb, const char *fmt, ...);
|
||||
void mrb_name_error(mrb_state *mrb, mrb_sym id, const char *fmt, ...);
|
||||
void mrb_exc_print(mrb_state *mrb, struct RObject *exc);
|
||||
|
||||
#endif /* MRUBY_ERROR_H */
|
||||
@@ -0,0 +1,280 @@
|
||||
#include "mruby.h"
|
||||
#include "mdata.h"
|
||||
#include "mruby/string.h"
|
||||
#include "error.h"
|
||||
#include "mruby/numeric.h"
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif
|
||||
|
||||
void
|
||||
ruby_xfree(void *x)
|
||||
{
|
||||
//if (x)
|
||||
// vm_xfree(&mrb_objspace, x);
|
||||
}
|
||||
|
||||
struct RData*
|
||||
mrb_data_object_alloc(mrb_state *mrb, struct RClass *klass, void *ptr, const struct mrb_data_type *type)
|
||||
{
|
||||
struct RData *data;
|
||||
|
||||
data = mrb_obj_alloc(mrb, MRB_TT_DATA, klass);
|
||||
data->data = ptr;
|
||||
data->type = type;
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void *
|
||||
mrb_check_datatype(mrb_state *mrb, mrb_value obj, const struct mrb_data_type *type)
|
||||
{
|
||||
static const char mesg[] = "wrong argument type %s (expected %s)";
|
||||
|
||||
if (SPECIAL_CONST_P(obj) || (mrb_type(obj) != MRB_TT_DATA)) {
|
||||
mrb_check_type(mrb, obj, MRB_TT_DATA);
|
||||
}
|
||||
if (DATA_TYPE(obj) != type) {
|
||||
const char *etype = DATA_TYPE(obj)->struct_name;
|
||||
mrb_raise(mrb, E_TYPE_ERROR, mesg, etype, type->struct_name);
|
||||
}
|
||||
return DATA_PTR(obj);
|
||||
}
|
||||
|
||||
mrb_value
|
||||
mrb_lastline_get(mrb_state *mrb)
|
||||
{
|
||||
//mrb_value *var = mrb_svar(0);
|
||||
//if (var) {
|
||||
// return *var;
|
||||
//}
|
||||
//return mrb_nil_value();
|
||||
mrb_value *argv;
|
||||
int argc;
|
||||
mrb_get_args(mrb, "*", &argv, &argc);
|
||||
if (argc < 1) {
|
||||
return mrb_nil_value();
|
||||
}
|
||||
else
|
||||
{
|
||||
return argv[0];
|
||||
}
|
||||
}
|
||||
|
||||
mrb_value
|
||||
mrb_rescue2(mrb_state *mrb, mrb_value (* b_proc) (ANYARGS), mrb_value *data1,
|
||||
mrb_value (* r_proc) (ANYARGS), mrb_value *data2, ...)
|
||||
{
|
||||
mrb_value result = (*b_proc) (mrb, data1);
|
||||
return result;
|
||||
}
|
||||
|
||||
mrb_value
|
||||
mrb_rescue(mrb_state *mrb, mrb_value (* b_proc)(ANYARGS), mrb_value *data1,
|
||||
mrb_value (* r_proc)(ANYARGS), mrb_value *data2)
|
||||
{
|
||||
return mrb_rescue2(mrb, b_proc, data1, r_proc, data2, mrb->eStandardError_class,
|
||||
mrb_fixnum_value(0));
|
||||
}
|
||||
/* ------------------------------------------------ */
|
||||
/*
|
||||
* Calls func(obj, arg, recursive), where recursive is non-zero if the
|
||||
* current method is called recursively on obj
|
||||
*/
|
||||
|
||||
mrb_value
|
||||
mrb_exec_recursive(mrb_state *mrb, mrb_value (*func) (mrb_state *, mrb_value, mrb_value, int), mrb_value obj, void *arg)
|
||||
{
|
||||
// return mrb_exec_recursive(mrb, io_puts_ary, line, &out);
|
||||
return func(mrb, obj, *(mrb_value*)arg, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Calls func(obj, arg, recursive), where recursive is non-zero if the
|
||||
* current method is called recursively on the ordered pair <obj, paired_obj>
|
||||
*/
|
||||
|
||||
mrb_value
|
||||
mrb_exec_recursive_paired(mrb_state *mrb, mrb_value (*func) (mrb_state *, mrb_value, mrb_value, int),
|
||||
mrb_value obj, mrb_value paired_obj, void* arg)
|
||||
{
|
||||
// return mrb_exec_recursive_paired(mrb, recursive_eql, hash1, hash2, mrb_fixnum_value((int)&data));
|
||||
return func(mrb, obj, paired_obj, 0);
|
||||
}
|
||||
|
||||
mrb_sym
|
||||
mrb_to_id(mrb_state *mrb, mrb_value name)
|
||||
{
|
||||
mrb_value tmp;
|
||||
mrb_sym id;
|
||||
|
||||
switch (mrb_type(name)) {
|
||||
default:
|
||||
tmp = mrb_check_string_type(mrb, name);
|
||||
if (mrb_nil_p(tmp)) {
|
||||
tmp = mrb_inspect(mrb, name);
|
||||
mrb_raise(mrb, E_TYPE_ERROR, "%s is not a symbol",
|
||||
RSTRING_PTR(tmp));
|
||||
}
|
||||
name = tmp;
|
||||
/* fall through */
|
||||
case MRB_TT_STRING:
|
||||
name = mrb_str_intern(mrb, name);
|
||||
/* fall through */
|
||||
case MRB_TT_SYMBOL:
|
||||
return SYM2ID(name);
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* proc { |...| block } -> a_proc
|
||||
*
|
||||
* Equivalent to <code>Proc.new</code>.
|
||||
*/
|
||||
|
||||
mrb_value
|
||||
mrb_block_proc(void)
|
||||
{
|
||||
return mrb_nil_value();//proc_new(mrb_cProc, FALSE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Document-method: __id__
|
||||
* Document-method: object_id
|
||||
*
|
||||
* call-seq:
|
||||
* obj.__id__ -> fixnum
|
||||
* obj.object_id -> fixnum
|
||||
*
|
||||
* Returns an integer identifier for <i>obj</i>. The same number will
|
||||
* be returned on all calls to <code>id</code> for a given object, and
|
||||
* no two active objects will share an id.
|
||||
* <code>Object#object_id</code> is a different concept from the
|
||||
* <code>:name</code> notation, which returns the symbol id of
|
||||
* <code>name</code>. Replaces the deprecated <code>Object#id</code>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* obj.hash -> fixnum
|
||||
*
|
||||
* Generates a <code>Fixnum</code> hash value for this object. This
|
||||
* function must have the property that <code>a.eql?(b)</code> implies
|
||||
* <code>a.hash == b.hash</code>. The hash value is used by class
|
||||
* <code>Hash</code>. Any hash value that exceeds the capacity of a
|
||||
* <code>Fixnum</code> will be truncated before being used.
|
||||
*/
|
||||
|
||||
int
|
||||
mrb_obj_id(mrb_value obj)
|
||||
{
|
||||
/*
|
||||
* 32-bit mrb_value space
|
||||
* MSB ------------------------ LSB
|
||||
* false 00000000000000000000000000000000
|
||||
* true 00000000000000000000000000000010
|
||||
* nil 00000000000000000000000000000100
|
||||
* undef 00000000000000000000000000000110
|
||||
* symbol ssssssssssssssssssssssss00001110
|
||||
* object oooooooooooooooooooooooooooooo00 = 0 (mod sizeof(RVALUE))
|
||||
* fixnum fffffffffffffffffffffffffffffff1
|
||||
*
|
||||
* object_id space
|
||||
* LSB
|
||||
* false 00000000000000000000000000000000
|
||||
* true 00000000000000000000000000000010
|
||||
* nil 00000000000000000000000000000100
|
||||
* undef 00000000000000000000000000000110
|
||||
* symbol 000SSSSSSSSSSSSSSSSSSSSSSSSSSS0 S...S % A = 4 (S...S = s...s * A + 4)
|
||||
* object oooooooooooooooooooooooooooooo0 o...o % A = 0
|
||||
* fixnum fffffffffffffffffffffffffffffff1 bignum if required
|
||||
*
|
||||
* where A = sizeof(RVALUE)/4
|
||||
*
|
||||
* sizeof(RVALUE) is
|
||||
* 20 if 32-bit, double is 4-byte aligned
|
||||
* 24 if 32-bit, double is 8-byte aligned
|
||||
* 40 if 64-bit
|
||||
*/
|
||||
/*
|
||||
* 128-bit mrb_value space
|
||||
* MSB -------- LSB
|
||||
* x86 [0,1] [2,3] [4,5] [6,7] [8,9] [A,B] [C,D] [E,F]
|
||||
* 7 6 5 4 3 2 1 0
|
||||
* 0123456789ABCDEF 0123456789ABCDEF 0123456789ABCDEF 0123456789ABCDEF 0123456789ABCDEF 0123456789ABCDEF 0123456789ABCDEF 0123456789ABCDEF
|
||||
* FEDCBA9876543210 FEDCBA9876543210 FEDCBA9876543210 FEDCBA9876543210 FEDCBA9876543210 FEDCBA9876543210 FEDCBA9876543210 FEDCBA9876543210
|
||||
* false 0000000000000000 0000000000000000 xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx xxxxxxxx00000001 xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx
|
||||
* true 0000000000000001 0000000000000000 xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx xxxxxxxx00000010 xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx
|
||||
* nil 0000000000000001 0000000000000000 xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx xxxxxxxx00000001 xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx
|
||||
* undef 0000000000000000 0000000000000000 xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx xxxxxxxx00000101 xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx
|
||||
* symbol ssssssssssssssss ssssssssssssssss xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx xxxxxxxx00000100 xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx
|
||||
* object oooooooooooooooo oooooooooooooo00 = 0 (mod sizeof(RVALUE))
|
||||
(1)fixnum 0000000000000001 0000000000000000 xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx xxxxxxxx00000011 xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx
|
||||
* float 0000000000000001 0000000000000000 0000000000000000 0000000000000000 xxxxxxxx00000011 xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx
|
||||
* <-- mrb_float --> xxxxxxxx00001101 xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx
|
||||
*
|
||||
* object_id space
|
||||
* LSB
|
||||
* false 0000000000000000 0000000000000000
|
||||
* true 0000000000000000 0000000000000010
|
||||
* nil 0000000000000000 0000000000000100
|
||||
* undef 0000000000000000 0000000000000110
|
||||
* symbol 000SSSSSSSSSSSS SSSSSSSSSSSSSSS0 S...S % A = 4 (S...S = s...s * A + 4)
|
||||
* object ooooooooooooooo ooooooooooooooo0 o...o % A = 0
|
||||
* fixnum ffffffffffffffff fffffffffffffff1 bignum if required
|
||||
*
|
||||
* where A = sizeof(RVALUE)/4
|
||||
*
|
||||
* sizeof(RVALUE) is
|
||||
* 20 if 32-bit, double is 4-byte aligned
|
||||
* 24 if 32-bit, double is 8-byte aligned
|
||||
* 40 if 64-bit
|
||||
*/
|
||||
/* tt:0_27 */
|
||||
switch (mrb_type(obj)) {
|
||||
case MRB_TT_FREE:
|
||||
return 0; /* not define */
|
||||
case MRB_TT_FALSE:
|
||||
if (mrb_nil_p(obj))
|
||||
return 4;
|
||||
return 0;
|
||||
case MRB_TT_TRUE:
|
||||
return 2;
|
||||
case MRB_TT_FIXNUM:
|
||||
return mrb_fixnum(obj)*2+1; /* odd number */
|
||||
case MRB_TT_SYMBOL:
|
||||
return SYM2ID(obj) * 2;
|
||||
case MRB_TT_UNDEF:
|
||||
return 0; /* not define */
|
||||
case MRB_TT_FLOAT:
|
||||
return (int)mrb_float(obj)*2; /* even number */
|
||||
case MRB_TT_OBJECT:
|
||||
case MRB_TT_CLASS:
|
||||
case MRB_TT_MODULE:
|
||||
case MRB_TT_ICLASS:
|
||||
case MRB_TT_SCLASS:
|
||||
case MRB_TT_PROC:
|
||||
case MRB_TT_ARRAY:
|
||||
case MRB_TT_HASH:
|
||||
case MRB_TT_STRING:
|
||||
case MRB_TT_RANGE:
|
||||
case MRB_TT_REGEX:
|
||||
case MRB_TT_STRUCT:
|
||||
case MRB_TT_EXCEPTION:
|
||||
case MRB_TT_MATCH:
|
||||
case MRB_TT_FILE:
|
||||
case MRB_TT_DATA:
|
||||
case MRB_TT_THREAD:
|
||||
case MRB_TT_THREADGRP:
|
||||
default:
|
||||
return mrb_fixnum(obj); /* even number */
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,217 @@
|
||||
#ifndef RUBY_EVAL_INTERN_H
|
||||
#define RUBY_EVAL_INTERN_H
|
||||
|
||||
//#include "ruby/ruby.h"
|
||||
#include "mruby.h"
|
||||
#define HAVE_STRING_H
|
||||
//#include "vm_core.h"
|
||||
#include "node.h"
|
||||
|
||||
/* other frame flag */
|
||||
#define VM_FRAME_FLAG_PASSED 0x0100
|
||||
#define PASS_PASSED_BLOCK_TH(th) do { \
|
||||
(th)->passed_block = GC_GUARDED_PTR_REF((mrb_block_t *)(th)->cfp->lfp[0]); \
|
||||
(th)->cfp->flag |= VM_FRAME_FLAG_PASSED; \
|
||||
} while (0)
|
||||
|
||||
#define PASS_PASSED_BLOCK() do { \
|
||||
mrb_thread_t * const __th__ = GET_THREAD(); \
|
||||
PASS_PASSED_BLOCK_TH(__th__); \
|
||||
} while (0)
|
||||
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
#ifndef EXIT_SUCCESS
|
||||
#define EXIT_SUCCESS 0
|
||||
#endif
|
||||
#ifndef EXIT_FAILURE
|
||||
#define EXIT_FAILURE 1
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <setjmp.h>
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <crt_externs.h>
|
||||
#endif
|
||||
|
||||
/* Make alloca work the best possible way. */
|
||||
#ifdef __GNUC__
|
||||
# ifndef atarist
|
||||
# ifndef alloca
|
||||
# define alloca __builtin_alloca
|
||||
# endif
|
||||
# endif /* atarist */
|
||||
#else
|
||||
# ifdef HAVE_ALLOCA_H
|
||||
# include <alloca.h>
|
||||
# else
|
||||
# ifdef _AIX
|
||||
#pragma alloca
|
||||
# else
|
||||
# ifndef alloca /* predefined by HP cc +Olibcalls */
|
||||
void *alloca();
|
||||
# endif
|
||||
# endif /* AIX */
|
||||
# endif /* HAVE_ALLOCA_H */
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
#ifndef HAVE_STRING_H
|
||||
char *strrchr(const char *, const char);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_NET_SOCKET_H
|
||||
#include <net/socket.h>
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
|
||||
#ifdef HAVE_SYS_SELECT_H
|
||||
#include <sys/select.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
Solaris sys/select.h switches select to select_large_fdset to support larger
|
||||
file descriptors if FD_SETSIZE is larger than 1024 on 32bit environment.
|
||||
But Ruby doesn't change FD_SETSIZE because fd_set is allocated dynamically.
|
||||
So following definition is required to use select_large_fdset.
|
||||
*/
|
||||
#ifdef HAVE_SELECT_LARGE_FDSET
|
||||
#define select(n, r, w, e, t) select_large_fdset(n, r, w, e, t)
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_PARAM_H
|
||||
#include <sys/param.h>
|
||||
#endif
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
#define SAVE_ROOT_JMPBUF(th, stmt) do \
|
||||
if (ruby_setjmp((th)->root_jmpbuf) == 0) { \
|
||||
stmt; \
|
||||
} while (0)
|
||||
|
||||
#define TH_PUSH_TAG(th) do { \
|
||||
mrb_thread_t * const _th = th; \
|
||||
struct mrb_vm_tag _tag; \
|
||||
_tag.tag = 0; \
|
||||
_tag.prev = _th->tag; \
|
||||
_th->tag = &_tag;
|
||||
|
||||
#define TH_POP_TAG() \
|
||||
_th->tag = _tag.prev; \
|
||||
} while (0)
|
||||
|
||||
#define TH_POP_TAG2() \
|
||||
_th->tag = _tag.prev
|
||||
|
||||
#define PUSH_TAG() TH_PUSH_TAG(GET_THREAD())
|
||||
#define POP_TAG() TH_POP_TAG()
|
||||
|
||||
#define TH_EXEC_TAG() ruby_setjmp(_th->tag->buf)
|
||||
|
||||
#define EXEC_TAG() \
|
||||
TH_EXEC_TAG()
|
||||
|
||||
#define TH_JUMP_TAG(th, st) do { \
|
||||
ruby_longjmp(th->tag->buf,(st)); \
|
||||
} while (0)
|
||||
|
||||
//#define JUMP_TAG(st) TH_JUMP_TAG(GET_THREAD(), st)
|
||||
|
||||
enum ruby_tag_type {
|
||||
RUBY_TAG_RETURN = 0x1,
|
||||
RUBY_TAG_BREAK = 0x2,
|
||||
RUBY_TAG_NEXT = 0x3,
|
||||
RUBY_TAG_RETRY = 0x4,
|
||||
RUBY_TAG_REDO = 0x5,
|
||||
RUBY_TAG_RAISE = 0x6,
|
||||
RUBY_TAG_THROW = 0x7,
|
||||
RUBY_TAG_FATAL = 0x8,
|
||||
RUBY_TAG_MASK = 0xf
|
||||
};
|
||||
#define TAG_RETURN RUBY_TAG_RETURN
|
||||
#define TAG_BREAK RUBY_TAG_BREAK
|
||||
#define TAG_NEXT RUBY_TAG_NEXT
|
||||
#define TAG_RETRY RUBY_TAG_RETRY
|
||||
#define TAG_REDO RUBY_TAG_REDO
|
||||
#define TAG_RAISE RUBY_TAG_RAISE
|
||||
#define TAG_THROW RUBY_TAG_THROW
|
||||
#define TAG_FATAL RUBY_TAG_FATAL
|
||||
#define TAG_MASK RUBY_TAG_MASK
|
||||
|
||||
#define NEW_THROW_OBJECT(val, pt, st) \
|
||||
((mrb_value)mrb_node_newnode(NODE_LIT, (mrb_value)(val), (mrb_value)(pt), (mrb_value)(st)))
|
||||
//#define SET_THROWOBJ_CATCH_POINT(obj, val)
|
||||
// (RNODE((obj))->u2.value = (val))
|
||||
//#define SET_THROWOBJ_STATE(obj, val)
|
||||
// (RNODE((obj))->u3.value = (val))
|
||||
|
||||
#define GET_THROWOBJ_VAL(obj) ((mrb_value)RNODE((obj))->u1.value)
|
||||
#define GET_THROWOBJ_CATCH_POINT(obj) ((mrb_value*)RNODE((obj))->u2.value)
|
||||
#define GET_THROWOBJ_STATE(obj) ((int)RNODE((obj))->u3.value)
|
||||
|
||||
#define SCOPE_TEST(f) (mrb_vm_cref()->nd_visi & (f))
|
||||
#define SCOPE_CHECK(f) (mrb_vm_cref()->nd_visi == (f))
|
||||
#define SCOPE_SET(f) (mrb_vm_cref()->nd_visi = (f))
|
||||
|
||||
#define sysstack_error mrb_fixnum_value(0)
|
||||
|
||||
#define CHECK_STACK_OVERFLOW(mrb, cfp, margin) do \
|
||||
if ((mrb_value *)((char *)(((mrb_value *)(cfp)->sp) + (margin)) + sizeof(mrb_control_frame_t)) >= ((mrb_value *)cfp)) { \
|
||||
mrb_exc_raise(mrb, sysstack_error); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
void mrb_thread_cleanup(void);
|
||||
void mrb_thread_wait_other_threads(void);
|
||||
|
||||
enum {
|
||||
RAISED_EXCEPTION = 1,
|
||||
RAISED_STACKOVERFLOW = 2,
|
||||
RAISED_NOMEMORY = 4
|
||||
};
|
||||
//int rb_threadptr_set_raised(mrb_thread_t *th);
|
||||
//int rb_threadptr_reset_raised(mrb_thread_t *th);
|
||||
#define mrb_thread_raised_set(th, f) ((th)->raised_flag |= (f))
|
||||
#define mrb_thread_raised_reset(th, f) ((th)->raised_flag &= ~(f))
|
||||
#define mrb_thread_raised_p(th, f) (((th)->raised_flag & (f)) != 0)
|
||||
#define mrb_thread_raised_clear(th) ((th)->raised_flag = 0)
|
||||
|
||||
//mrb_value mrb_f_eval(int argc, mrb_value *argv, mrb_value self);
|
||||
//mrb_value mrb_make_exception(int argc, mrb_value *argv);
|
||||
#ifndef NORETURN
|
||||
# define NORETURN(x) x
|
||||
#endif
|
||||
#ifndef DEPRECATED
|
||||
# define DEPRECATED(x) x
|
||||
#endif
|
||||
|
||||
NORETURN(void mrb_fiber_start(void));
|
||||
|
||||
NORETURN(void rb_print_undef(mrb_value, mrb_sym, int));
|
||||
NORETURN(void rb_vm_localjump_error(const char *,mrb_value, int));
|
||||
NORETURN(void rb_vm_jump_tag_but_local_jump(int, mrb_value));
|
||||
//NORETURN(void mrb_raise_method_missing(mrb_thread_t *th, int argc, mrb_value *argv,
|
||||
// mrb_value obj, int call_status));
|
||||
|
||||
mrb_value mrb_vm_make_jump_tag_but_local_jump(int state, mrb_value val);
|
||||
NODE *mrb_vm_cref(void);
|
||||
//mrb_value rb_vm_call_cfunc(mrb_value recv, mrb_value (*func)(mrb_value), mrb_value arg, const mrb_block_t *blockptr, mrb_value filename, mrb_value filepath);
|
||||
void mrb_vm_set_progname(mrb_value filename);
|
||||
void mrb_thread_terminate_all(mrb_state *mrb);
|
||||
//mrb_value mrb_vm_top_self();
|
||||
mrb_value mrb_vm_cbase(void);
|
||||
//int mrb_vm_get_sourceline(const mrb_control_frame_t *);
|
||||
void mrb_trap_restore_mask(void);
|
||||
|
||||
#endif /* RUBY_EVAL_INTERN_H */
|
||||
@@ -0,0 +1,26 @@
|
||||
#ifndef MRUBY_GC_H
|
||||
#define MRUBY_GC_H
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
struct free_obj {
|
||||
MRUBY_OBJECT_HEADER;
|
||||
struct RBasic *next;
|
||||
} free;
|
||||
struct RBasic basic;
|
||||
struct RObject object;
|
||||
struct RClass klass;
|
||||
struct RString string;
|
||||
struct RArray array;
|
||||
struct RHash hash;
|
||||
struct RRange range;
|
||||
struct RStruct structdata;
|
||||
struct RProc procdata;
|
||||
#ifdef INCLUDE_REGEXP
|
||||
struct RMatch match;
|
||||
struct RRegexp regexp;
|
||||
#endif
|
||||
} as;
|
||||
} RVALUE;
|
||||
|
||||
#endif /* MRUBY_GC_H */
|
||||
+1436
File diff suppressed because it is too large
Load Diff
+105
@@ -0,0 +1,105 @@
|
||||
#include "mruby.h"
|
||||
|
||||
void mrb_init_class(mrb_state*);
|
||||
void mrb_init_symtbl(mrb_state*);
|
||||
void mrb_init_symbols(mrb_state*);
|
||||
void mrb_init_object(mrb_state*);
|
||||
void mrb_init_kernel(mrb_state*);
|
||||
void mrb_init_enumerable(mrb_state*);
|
||||
void mrb_init_comparable(mrb_state*);
|
||||
void mrb_init_array(mrb_state*);
|
||||
void mrb_init_hash(mrb_state*);
|
||||
void mrb_init_numeric(mrb_state*);
|
||||
void mrb_init_proc(mrb_state*);
|
||||
void mrb_init_range(mrb_state*);
|
||||
void mrb_init_string(mrb_state*);
|
||||
void mrb_init_regexp(mrb_state*);
|
||||
void mrb_init_encoding(mrb_state*);
|
||||
void mrb_init_exception(mrb_state*);
|
||||
void mrb_init_time(mrb_state *);
|
||||
void mrb_init_io(mrb_state *);
|
||||
void mrb_init_file(mrb_state *);
|
||||
void mrb_init_thread(mrb_state *);
|
||||
void mrb_init_struct(mrb_state *);
|
||||
void mrb_init_gc(mrb_state *);
|
||||
void Init_var_tables(mrb_state *mrb);
|
||||
void Init_version(mrb_state *mrb);
|
||||
void mrb_init_print(mrb_state *mrb);
|
||||
void mrb_init_mrblib(mrb_state *mrb);
|
||||
|
||||
#define MANDEL
|
||||
#ifdef MANDEL
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
static mrb_value
|
||||
mpow(mrb_state *mrb, mrb_value obj)
|
||||
{
|
||||
mrb_float x, y;
|
||||
|
||||
mrb_get_args(mrb, "ff", &x, &y);
|
||||
x = pow(x, y);
|
||||
|
||||
return mrb_float_value(x);
|
||||
}
|
||||
|
||||
static mrb_value
|
||||
msqrt(mrb_state *mrb, mrb_value obj)
|
||||
{
|
||||
mrb_float x;
|
||||
|
||||
mrb_get_args(mrb, "f", &x);
|
||||
x = sqrt(x);
|
||||
|
||||
return mrb_float_value(x);
|
||||
}
|
||||
|
||||
static mrb_value
|
||||
mputc(mrb_state *mrb, mrb_value obj)
|
||||
{
|
||||
int x;
|
||||
|
||||
mrb_get_args(mrb, "i", &x);
|
||||
putc(x, stdout);
|
||||
|
||||
return mrb_nil_value();
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
mrb_init_core(mrb_state *mrb)
|
||||
{
|
||||
mrb_init_symtbl(mrb);
|
||||
|
||||
mrb_init_class(mrb);
|
||||
mrb_init_object(mrb);
|
||||
mrb_init_kernel(mrb);
|
||||
mrb_init_comparable(mrb);
|
||||
mrb_init_enumerable(mrb);
|
||||
|
||||
mrb_init_symbols(mrb);
|
||||
mrb_init_proc(mrb);
|
||||
mrb_init_string(mrb);
|
||||
Init_version(mrb); /* after init_string */
|
||||
mrb_init_array(mrb);
|
||||
mrb_init_hash(mrb);
|
||||
mrb_init_numeric(mrb);
|
||||
mrb_init_range(mrb);
|
||||
mrb_init_struct(mrb);
|
||||
mrb_init_gc(mrb);
|
||||
#ifdef INCLUDE_REGEXP
|
||||
mrb_init_regexp(mrb);
|
||||
mrb_init_encoding(mrb);
|
||||
#endif
|
||||
mrb_init_exception(mrb);
|
||||
mrb_init_print(mrb);
|
||||
|
||||
#ifdef MANDEL
|
||||
mrb_define_method(mrb, mrb->kernel_module, "pow", mpow, ARGS_REQ(2));
|
||||
mrb_define_method(mrb, mrb->kernel_module, "sqrt", msqrt, ARGS_REQ(1));
|
||||
mrb_define_method(mrb, mrb->kernel_module, "putc", mputc, ARGS_REQ(1));
|
||||
#endif
|
||||
|
||||
mrb_init_mrblib(mrb);
|
||||
|
||||
mrb_gc_arena_restore(mrb, 0);
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
#include "mruby.h"
|
||||
|
||||
void
|
||||
mrb_init_ext(mrb_state *mrb)
|
||||
{
|
||||
#ifdef INCLUDE_SOCKET
|
||||
extern void mrb_init_socket(mrb_state *mrb);
|
||||
mrb_init_socket(mrb);
|
||||
#endif
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
#ifndef MRUBY_IREP_H
|
||||
#define MRUBY_IREP_H
|
||||
|
||||
typedef struct mrb_irep {
|
||||
int idx;
|
||||
|
||||
int flags;
|
||||
int nlocals;
|
||||
int nregs;
|
||||
|
||||
mrb_code *iseq;
|
||||
mrb_value *pool;
|
||||
int *syms;
|
||||
|
||||
int ilen, plen, slen;
|
||||
} mrb_irep;
|
||||
|
||||
#define MRB_IREP_NOFREE 3
|
||||
#define MRB_ISEQ_NOFREE 1
|
||||
|
||||
void mrb_add_irep(mrb_state *mrb, int n);
|
||||
|
||||
#endif /* MRUBY_IREP_H */
|
||||
+1530
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,50 @@
|
||||
%{
|
||||
struct kwtable {const char *name; int id[2]; enum mrb_lex_state_enum state;};
|
||||
const struct kwtable *mrb_reserved_word(const char *, unsigned int);
|
||||
static const struct kwtable *reserved_word(const char *, unsigned int);
|
||||
#define mrb_reserved_word(str, len) reserved_word(str, len)
|
||||
%}
|
||||
|
||||
struct kwtable;
|
||||
%%
|
||||
__ENCODING__, {keyword__ENCODING__, keyword__ENCODING__}, EXPR_END
|
||||
__LINE__, {keyword__LINE__, keyword__LINE__}, EXPR_END
|
||||
__FILE__, {keyword__FILE__, keyword__FILE__}, EXPR_END
|
||||
BEGIN, {keyword_BEGIN, keyword_BEGIN}, EXPR_END
|
||||
END, {keyword_END, keyword_END}, EXPR_END
|
||||
alias, {keyword_alias, keyword_alias}, EXPR_FNAME
|
||||
and, {keyword_and, keyword_and}, EXPR_VALUE
|
||||
begin, {keyword_begin, keyword_begin}, EXPR_BEG
|
||||
break, {keyword_break, keyword_break}, EXPR_MID
|
||||
case, {keyword_case, keyword_case}, EXPR_VALUE
|
||||
class, {keyword_class, keyword_class}, EXPR_CLASS
|
||||
def, {keyword_def, keyword_def}, EXPR_FNAME
|
||||
do, {keyword_do, keyword_do}, EXPR_BEG
|
||||
else, {keyword_else, keyword_else}, EXPR_BEG
|
||||
elsif, {keyword_elsif, keyword_elsif}, EXPR_VALUE
|
||||
end, {keyword_end, keyword_end}, EXPR_END
|
||||
ensure, {keyword_ensure, keyword_ensure}, EXPR_BEG
|
||||
false, {keyword_false, keyword_false}, EXPR_END
|
||||
for, {keyword_for, keyword_for}, EXPR_VALUE
|
||||
if, {keyword_if, modifier_if}, EXPR_VALUE
|
||||
in, {keyword_in, keyword_in}, EXPR_VALUE
|
||||
module, {keyword_module, keyword_module}, EXPR_VALUE
|
||||
next, {keyword_next, keyword_next}, EXPR_MID
|
||||
nil, {keyword_nil, keyword_nil}, EXPR_END
|
||||
not, {keyword_not, keyword_not}, EXPR_ARG
|
||||
or, {keyword_or, keyword_or}, EXPR_VALUE
|
||||
redo, {keyword_redo, keyword_redo}, EXPR_END
|
||||
rescue, {keyword_rescue, modifier_rescue}, EXPR_MID
|
||||
retry, {keyword_retry, keyword_retry}, EXPR_END
|
||||
return, {keyword_return, keyword_return}, EXPR_MID
|
||||
self, {keyword_self, keyword_self}, EXPR_END
|
||||
super, {keyword_super, keyword_super}, EXPR_ARG
|
||||
then, {keyword_then, keyword_then}, EXPR_BEG
|
||||
true, {keyword_true, keyword_true}, EXPR_END
|
||||
undef, {keyword_undef, keyword_undef}, EXPR_FNAME
|
||||
unless, {keyword_unless, modifier_unless}, EXPR_VALUE
|
||||
until, {keyword_until, modifier_until}, EXPR_VALUE
|
||||
when, {keyword_when, keyword_when}, EXPR_VALUE
|
||||
while, {keyword_while, modifier_while}, EXPR_VALUE
|
||||
yield, {keyword_yield, keyword_yield}, EXPR_ARG
|
||||
%%
|
||||
+216
@@ -0,0 +1,216 @@
|
||||
/* C code produced by gperf version 3.0.3 */
|
||||
/* Command-line: gperf -C -p -j1 -i 1 -g -o -t -N mrb_reserved_word -k'1,3,$' keywords */
|
||||
|
||||
#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
|
||||
&& ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \
|
||||
&& (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \
|
||||
&& ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \
|
||||
&& ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \
|
||||
&& ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \
|
||||
&& ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \
|
||||
&& ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \
|
||||
&& ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \
|
||||
&& ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \
|
||||
&& ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \
|
||||
&& ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \
|
||||
&& ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \
|
||||
&& ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \
|
||||
&& ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \
|
||||
&& ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \
|
||||
&& ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \
|
||||
&& ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \
|
||||
&& ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \
|
||||
&& ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \
|
||||
&& ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \
|
||||
&& ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \
|
||||
&& ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126))
|
||||
/* The character set is not based on ISO-646. */
|
||||
error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gnu-gperf@gnu.org>."
|
||||
#endif
|
||||
|
||||
#line 1 "keywords"
|
||||
|
||||
struct kwtable {const char *name; int id[2]; enum mrb_lex_state_enum state;};
|
||||
const struct kwtable *mrb_reserved_word(const char *, unsigned int);
|
||||
static const struct kwtable *reserved_word(const char *, unsigned int);
|
||||
#define mrb_reserved_word(str, len) reserved_word(str, len)
|
||||
#line 8 "keywords"
|
||||
struct kwtable;
|
||||
|
||||
#define TOTAL_KEYWORDS 40
|
||||
#define MIN_WORD_LENGTH 2
|
||||
#define MAX_WORD_LENGTH 12
|
||||
#define MIN_HASH_VALUE 8
|
||||
#define MAX_HASH_VALUE 50
|
||||
/* maximum key range = 43, duplicates = 0 */
|
||||
|
||||
#ifdef __GNUC__
|
||||
__inline
|
||||
#else
|
||||
#ifdef __cplusplus
|
||||
inline
|
||||
#endif
|
||||
#endif
|
||||
static unsigned int
|
||||
hash (str, len)
|
||||
register const char *str;
|
||||
register unsigned int len;
|
||||
{
|
||||
static const unsigned char asso_values[] =
|
||||
{
|
||||
51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
|
||||
51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
|
||||
51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
|
||||
51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
|
||||
51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
|
||||
51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
|
||||
51, 51, 51, 51, 51, 51, 14, 51, 16, 8,
|
||||
11, 13, 51, 51, 51, 51, 10, 51, 13, 51,
|
||||
51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
|
||||
51, 51, 51, 51, 51, 11, 51, 13, 1, 26,
|
||||
4, 1, 8, 28, 51, 23, 51, 1, 1, 27,
|
||||
5, 19, 21, 51, 8, 3, 3, 11, 51, 21,
|
||||
24, 16, 51, 51, 51, 51, 51, 51, 51, 51,
|
||||
51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
|
||||
51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
|
||||
51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
|
||||
51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
|
||||
51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
|
||||
51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
|
||||
51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
|
||||
51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
|
||||
51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
|
||||
51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
|
||||
51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
|
||||
51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
|
||||
51, 51, 51, 51, 51, 51
|
||||
};
|
||||
register int hval = len;
|
||||
|
||||
switch (hval)
|
||||
{
|
||||
default:
|
||||
hval += asso_values[(unsigned char)str[2]];
|
||||
/*FALLTHROUGH*/
|
||||
case 2:
|
||||
case 1:
|
||||
hval += asso_values[(unsigned char)str[0]];
|
||||
break;
|
||||
}
|
||||
return hval + asso_values[(unsigned char)str[len - 1]];
|
||||
}
|
||||
|
||||
#ifdef __GNUC__
|
||||
__inline
|
||||
#ifdef __GNUC_STDC_INLINE__
|
||||
__attribute__ ((__gnu_inline__))
|
||||
#endif
|
||||
#endif
|
||||
const struct kwtable *
|
||||
mrb_reserved_word (str, len)
|
||||
register const char *str;
|
||||
register unsigned int len;
|
||||
{
|
||||
static const struct kwtable wordlist[] =
|
||||
{
|
||||
{""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
|
||||
#line 18 "keywords"
|
||||
{"break", {keyword_break, keyword_break}, EXPR_MID},
|
||||
#line 23 "keywords"
|
||||
{"else", {keyword_else, keyword_else}, EXPR_BEG},
|
||||
#line 33 "keywords"
|
||||
{"nil", {keyword_nil, keyword_nil}, EXPR_END},
|
||||
#line 26 "keywords"
|
||||
{"ensure", {keyword_ensure, keyword_ensure}, EXPR_BEG},
|
||||
#line 25 "keywords"
|
||||
{"end", {keyword_end, keyword_end}, EXPR_END},
|
||||
#line 42 "keywords"
|
||||
{"then", {keyword_then, keyword_then}, EXPR_BEG},
|
||||
#line 34 "keywords"
|
||||
{"not", {keyword_not, keyword_not}, EXPR_ARG},
|
||||
#line 27 "keywords"
|
||||
{"false", {keyword_false, keyword_false}, EXPR_END},
|
||||
#line 40 "keywords"
|
||||
{"self", {keyword_self, keyword_self}, EXPR_END},
|
||||
#line 24 "keywords"
|
||||
{"elsif", {keyword_elsif, keyword_elsif}, EXPR_VALUE},
|
||||
#line 37 "keywords"
|
||||
{"rescue", {keyword_rescue, modifier_rescue}, EXPR_MID},
|
||||
#line 43 "keywords"
|
||||
{"true", {keyword_true, keyword_true}, EXPR_END},
|
||||
#line 46 "keywords"
|
||||
{"until", {keyword_until, modifier_until}, EXPR_VALUE},
|
||||
#line 45 "keywords"
|
||||
{"unless", {keyword_unless, modifier_unless}, EXPR_VALUE},
|
||||
#line 39 "keywords"
|
||||
{"return", {keyword_return, keyword_return}, EXPR_MID},
|
||||
#line 21 "keywords"
|
||||
{"def", {keyword_def, keyword_def}, EXPR_FNAME},
|
||||
#line 16 "keywords"
|
||||
{"and", {keyword_and, keyword_and}, EXPR_VALUE},
|
||||
#line 22 "keywords"
|
||||
{"do", {keyword_do, keyword_do}, EXPR_BEG},
|
||||
#line 49 "keywords"
|
||||
{"yield", {keyword_yield, keyword_yield}, EXPR_ARG},
|
||||
#line 28 "keywords"
|
||||
{"for", {keyword_for, keyword_for}, EXPR_VALUE},
|
||||
#line 44 "keywords"
|
||||
{"undef", {keyword_undef, keyword_undef}, EXPR_FNAME},
|
||||
#line 35 "keywords"
|
||||
{"or", {keyword_or, keyword_or}, EXPR_VALUE},
|
||||
#line 30 "keywords"
|
||||
{"in", {keyword_in, keyword_in}, EXPR_VALUE},
|
||||
#line 47 "keywords"
|
||||
{"when", {keyword_when, keyword_when}, EXPR_VALUE},
|
||||
#line 38 "keywords"
|
||||
{"retry", {keyword_retry, keyword_retry}, EXPR_END},
|
||||
#line 29 "keywords"
|
||||
{"if", {keyword_if, modifier_if}, EXPR_VALUE},
|
||||
#line 19 "keywords"
|
||||
{"case", {keyword_case, keyword_case}, EXPR_VALUE},
|
||||
#line 36 "keywords"
|
||||
{"redo", {keyword_redo, keyword_redo}, EXPR_END},
|
||||
#line 32 "keywords"
|
||||
{"next", {keyword_next, keyword_next}, EXPR_MID},
|
||||
#line 41 "keywords"
|
||||
{"super", {keyword_super, keyword_super}, EXPR_ARG},
|
||||
#line 31 "keywords"
|
||||
{"module", {keyword_module, keyword_module}, EXPR_VALUE},
|
||||
#line 17 "keywords"
|
||||
{"begin", {keyword_begin, keyword_begin}, EXPR_BEG},
|
||||
#line 11 "keywords"
|
||||
{"__LINE__", {keyword__LINE__, keyword__LINE__}, EXPR_END},
|
||||
#line 12 "keywords"
|
||||
{"__FILE__", {keyword__FILE__, keyword__FILE__}, EXPR_END},
|
||||
#line 10 "keywords"
|
||||
{"__ENCODING__", {keyword__ENCODING__, keyword__ENCODING__}, EXPR_END},
|
||||
#line 14 "keywords"
|
||||
{"END", {keyword_END, keyword_END}, EXPR_END},
|
||||
#line 15 "keywords"
|
||||
{"alias", {keyword_alias, keyword_alias}, EXPR_FNAME},
|
||||
#line 13 "keywords"
|
||||
{"BEGIN", {keyword_BEGIN, keyword_BEGIN}, EXPR_END},
|
||||
{""},
|
||||
#line 20 "keywords"
|
||||
{"class", {keyword_class, keyword_class}, EXPR_CLASS},
|
||||
{""}, {""},
|
||||
#line 48 "keywords"
|
||||
{"while", {keyword_while, modifier_while}, EXPR_VALUE}
|
||||
};
|
||||
|
||||
if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
|
||||
{
|
||||
register int key = hash (str, len);
|
||||
|
||||
if (key <= MAX_HASH_VALUE && key >= 0)
|
||||
{
|
||||
register const char *s = wordlist[key].name;
|
||||
|
||||
if (*str == *s && !strcmp (str + 1, s + 1))
|
||||
return &wordlist[key];
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#line 50 "keywords"
|
||||
|
||||
+642
@@ -0,0 +1,642 @@
|
||||
#include <string.h>
|
||||
#include "dump.h"
|
||||
|
||||
#include "mruby/string.h"
|
||||
#ifdef INCLUDE_REGEXP
|
||||
#include "re.h"
|
||||
#endif
|
||||
#include "irep.h"
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif
|
||||
|
||||
typedef struct _RiteFILE
|
||||
{
|
||||
FILE* fp;
|
||||
unsigned char buf[256];
|
||||
int cnt;
|
||||
int readlen;
|
||||
} RiteFILE;
|
||||
|
||||
const char hex2bin[256] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //00-0f
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //10-1f
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //20-2f
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, //30-3f
|
||||
0, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, //40-4f
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //50-5f
|
||||
0, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0 //60-6f
|
||||
//70-ff
|
||||
};
|
||||
|
||||
static uint16_t hex_to_bin8(unsigned char*,unsigned char*);
|
||||
static uint16_t hex_to_bin16(unsigned char*,unsigned char*);
|
||||
static uint16_t hex_to_bin32(unsigned char*,unsigned char*);
|
||||
static uint8_t hex_to_uint8(unsigned char*);
|
||||
static uint16_t hex_to_uint16(unsigned char*);
|
||||
static uint32_t hex_to_uint32(unsigned char*);
|
||||
static char* hex_to_str(char*,char*,uint16_t*);
|
||||
uint16_t calc_crc_16_ccitt(unsigned char*,int);
|
||||
static unsigned char rite_fgetcSub(RiteFILE*);
|
||||
static unsigned char rite_fgetc(RiteFILE*,int);
|
||||
static unsigned char* rite_fgets(RiteFILE*,unsigned char*,int,int);
|
||||
static int load_rite_header(FILE*,rite_binary_header*,unsigned char*);
|
||||
static int load_rite_irep_record(mrb_state*, RiteFILE*,unsigned char*,uint32_t*);
|
||||
static int read_rite_header(mrb_state*,unsigned char*,rite_binary_header*);
|
||||
static int read_rite_irep_record(mrb_state*,unsigned char*,mrb_irep*,uint32_t*);
|
||||
|
||||
|
||||
static unsigned char
|
||||
rite_fgetcSub(RiteFILE* rfp)
|
||||
{
|
||||
//only first call
|
||||
if (rfp->buf[0] == '\0') {
|
||||
rfp->readlen = fread(rfp->buf, 1, sizeof(rfp->buf), rfp->fp);
|
||||
rfp->cnt = 0;
|
||||
}
|
||||
|
||||
if (rfp->readlen == rfp->cnt) {
|
||||
rfp->readlen = fread(rfp->buf, 1, sizeof(rfp->buf), rfp->fp);
|
||||
rfp->cnt = 0;
|
||||
if (rfp->readlen == 0) {
|
||||
return '\0';
|
||||
}
|
||||
}
|
||||
return rfp->buf[(rfp->cnt)++];
|
||||
}
|
||||
|
||||
static unsigned char
|
||||
rite_fgetc(RiteFILE* rfp, int ignorecomment)
|
||||
{
|
||||
unsigned char tmp;
|
||||
|
||||
for (;;) {
|
||||
tmp = rite_fgetcSub(rfp);
|
||||
if (tmp == '\n' || tmp == '\r') {
|
||||
continue;
|
||||
}
|
||||
else if (ignorecomment && tmp == '#') {
|
||||
while (tmp != '\n' && tmp != '\r' && tmp != '\0')
|
||||
tmp = rite_fgetcSub(rfp);
|
||||
if (tmp == '\0')
|
||||
return '\0';
|
||||
}
|
||||
else {
|
||||
return tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned char*
|
||||
rite_fgets(RiteFILE* rfp, unsigned char* dst, int len, int ignorecomment)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i<len; i++) {
|
||||
if ('\0' == (dst[i] = rite_fgetc(rfp, ignorecomment))) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
|
||||
static int
|
||||
load_rite_header(FILE* fp, rite_binary_header* bin_header, unsigned char* hcrc)
|
||||
{
|
||||
rite_file_header file_header;
|
||||
|
||||
fread(&file_header, 1, sizeof(file_header), fp);
|
||||
memcpy(bin_header->rbfi, file_header.rbfi, sizeof(file_header.rbfi));
|
||||
if (memcmp(bin_header->rbfi, RITE_FILE_IDENFIFIER, sizeof(bin_header->rbfi)) != 0) {
|
||||
return MRB_DUMP_INVALID_FILE_HEADER; //File identifier error
|
||||
}
|
||||
memcpy(bin_header->rbfv, file_header.rbfv, sizeof(file_header.rbfv));
|
||||
if (memcmp(bin_header->rbfv, RITE_FILE_FORMAT_VER, sizeof(bin_header->rbfv)) != 0) {
|
||||
return MRB_DUMP_INVALID_FILE_HEADER; //File format version error
|
||||
}
|
||||
memcpy(bin_header->risv, file_header.risv, sizeof(file_header.risv));
|
||||
memcpy(bin_header->rct, file_header.rct, sizeof(file_header.rct));
|
||||
memcpy(bin_header->rcv, file_header.rcv, sizeof(file_header.rcv));
|
||||
hex_to_bin32(bin_header->rbds, file_header.rbds);
|
||||
hex_to_bin16(bin_header->nirep, file_header.nirep);
|
||||
hex_to_bin16(bin_header->sirep, file_header.sirep);
|
||||
memcpy(bin_header->rsv, file_header.rsv, sizeof(file_header.rsv));
|
||||
memcpy(hcrc, file_header.hcrc, sizeof(file_header.hcrc));
|
||||
|
||||
return MRB_DUMP_OK;
|
||||
}
|
||||
|
||||
static int
|
||||
load_rite_irep_record(mrb_state *mrb, RiteFILE* rfp, unsigned char* dst, uint32_t* len)
|
||||
{
|
||||
int i;
|
||||
uint32_t blocklen;
|
||||
uint16_t offset, tt, pdl, snl, clen;
|
||||
unsigned char hex2[2], hex4[4], hex8[8], hcrc[4];
|
||||
unsigned char *pStart;
|
||||
char *char_buf;
|
||||
uint16_t buf_size =0;
|
||||
|
||||
buf_size = MRB_DUMP_DEFAULT_STR_LEN;
|
||||
if ((char_buf = mrb_malloc(mrb, buf_size)) == 0)
|
||||
goto error_exit;
|
||||
|
||||
pStart = dst;
|
||||
|
||||
//IREP HEADER BLOCK
|
||||
*dst = rite_fgetc(rfp, TRUE); //record identifier
|
||||
if (*dst != RITE_IREP_IDENFIFIER)
|
||||
return MRB_DUMP_INVALID_IREP;
|
||||
dst += sizeof(unsigned char);
|
||||
*dst = rite_fgetc(rfp, TRUE); //class or module
|
||||
dst += sizeof(unsigned char);
|
||||
rite_fgets(rfp, hex4, sizeof(hex4), TRUE); //number of local variable
|
||||
dst += hex_to_bin16(dst, hex4);
|
||||
rite_fgets(rfp, hex4, sizeof(hex4), TRUE); //number of register variable
|
||||
dst += hex_to_bin16(dst, hex4);
|
||||
rite_fgets(rfp, hex4, sizeof(hex4), TRUE); //offset of isec block
|
||||
offset = hex_to_uint16(hex4);
|
||||
rite_fgets(rfp, hcrc, sizeof(hcrc), TRUE); //header CRC
|
||||
memset( char_buf, '\0', buf_size);
|
||||
rite_fgets(rfp, (unsigned char*)char_buf, (offset - (MRB_DUMP_SIZE_OF_SHORT * RITE_FILE_HEX_SIZE)), TRUE); //class or module name
|
||||
hex_to_str(char_buf, (char*)(dst + MRB_DUMP_SIZE_OF_SHORT + MRB_DUMP_SIZE_OF_SHORT), &clen); //class or module name
|
||||
dst += uint16_to_bin((MRB_DUMP_SIZE_OF_SHORT/*crc*/ + clen), (char*)dst); //offset of isec block
|
||||
dst += hex_to_bin16(dst, hcrc); //header CRC
|
||||
dst += clen;
|
||||
|
||||
//ISEQ BLOCK
|
||||
rite_fgets(rfp, hex8, sizeof(hex8), TRUE); //iseq length
|
||||
dst += hex_to_bin32(dst, hex8);
|
||||
blocklen = hex_to_uint32(hex8);
|
||||
for (i=0; i<blocklen; i++) {
|
||||
rite_fgets(rfp, hex8, sizeof(hex8), TRUE); //iseq
|
||||
dst += hex_to_bin32(dst, hex8);
|
||||
}
|
||||
rite_fgets(rfp, hcrc, sizeof(hcrc), TRUE); //iseq CRC
|
||||
dst += hex_to_bin16(dst, hcrc);
|
||||
|
||||
//POOL BLOCK
|
||||
rite_fgets(rfp, hex8, sizeof(hex8), TRUE); //pool length
|
||||
dst += hex_to_bin32(dst, hex8);
|
||||
blocklen = hex_to_uint32(hex8);
|
||||
for (i=0; i<blocklen; i++) {
|
||||
rite_fgets(rfp, hex2, sizeof(hex2), TRUE); //TT
|
||||
dst += hex_to_bin8(dst, hex2);
|
||||
tt = hex_to_uint8(hex2);
|
||||
rite_fgets(rfp, hex4, sizeof(hex4), TRUE); //pool data length
|
||||
pdl = hex_to_uint16(hex4);
|
||||
|
||||
if ( pdl > buf_size - 1) {
|
||||
buf_size = pdl + 1;
|
||||
if ((char_buf = mrb_realloc(mrb, char_buf, buf_size)) == 0)
|
||||
goto error_exit;
|
||||
}
|
||||
memset(char_buf, '\0', buf_size);
|
||||
rite_fgets(rfp, (unsigned char*)char_buf, pdl, FALSE); //pool
|
||||
hex_to_str(char_buf, (char*)(dst + MRB_DUMP_SIZE_OF_SHORT), &clen);
|
||||
dst += uint16_to_bin(clen, (char*)dst);
|
||||
dst += clen;
|
||||
}
|
||||
rite_fgets(rfp, hcrc, sizeof(hcrc), TRUE); //pool CRC
|
||||
dst += hex_to_bin16(dst, hcrc);
|
||||
|
||||
//SYMS BLOCK
|
||||
rite_fgets(rfp, hex8, sizeof(hex8), TRUE); //syms length
|
||||
dst += hex_to_bin32(dst, hex8);
|
||||
blocklen = hex_to_uint32(hex8);
|
||||
for (i=0; i<blocklen; i++) {
|
||||
rite_fgets(rfp, hex4, sizeof(hex4), TRUE); //symbol name length
|
||||
snl = hex_to_uint16(hex4);
|
||||
|
||||
if (snl == MRB_DUMP_NULL_SYM_LEN) {
|
||||
dst += uint16_to_bin(snl, (char*)dst);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( snl > buf_size - 1) {
|
||||
buf_size = snl + 1;
|
||||
if ((char_buf = mrb_realloc(mrb, char_buf, buf_size)) == 0)
|
||||
goto error_exit;
|
||||
}
|
||||
memset(char_buf, '\0', buf_size);
|
||||
rite_fgets(rfp, (unsigned char*)char_buf, snl, FALSE); //symbol name
|
||||
hex_to_str(char_buf, (char*)(dst + MRB_DUMP_SIZE_OF_SHORT), &clen);
|
||||
dst += uint16_to_bin(clen, (char*)dst);
|
||||
dst += clen;
|
||||
}
|
||||
rite_fgets(rfp, hcrc, sizeof(hcrc), TRUE); //syms CRC
|
||||
dst += hex_to_bin16(dst, hcrc);
|
||||
|
||||
*len = dst - pStart;
|
||||
|
||||
error_exit:
|
||||
if (char_buf)
|
||||
mrb_free(mrb, char_buf);
|
||||
|
||||
return MRB_DUMP_OK;
|
||||
}
|
||||
|
||||
int
|
||||
mrb_load_irep(mrb_state *mrb, FILE* fp)
|
||||
{
|
||||
int ret, i;
|
||||
uint32_t len, rlen;
|
||||
unsigned char hex8[8], hcrc[4];
|
||||
unsigned char *dst, *rite_dst = NULL;
|
||||
rite_binary_header bin_header;
|
||||
RiteFILE ritefp, *rfp;
|
||||
|
||||
if ((mrb == NULL) || (fp == NULL)) {
|
||||
return MRB_DUMP_INVALID_ARGUMENT;
|
||||
}
|
||||
memset(&ritefp, 0, sizeof(ritefp));
|
||||
ritefp.fp = fp;
|
||||
rfp = &ritefp;
|
||||
|
||||
//Read File Header Section
|
||||
if ((ret = load_rite_header(fp, &bin_header, hcrc)) != MRB_DUMP_OK)
|
||||
return ret;
|
||||
|
||||
len = sizeof(rite_binary_header) + bin_to_uint32(bin_header.rbds);
|
||||
if ((rite_dst = mrb_malloc(mrb, len)) == NULL)
|
||||
return MRB_DUMP_GENERAL_FAILURE;
|
||||
|
||||
dst = rite_dst;
|
||||
memset(dst, 0x00, len);
|
||||
memcpy(dst, &bin_header, sizeof(rite_binary_header));
|
||||
dst += sizeof(rite_binary_header);
|
||||
dst += hex_to_bin16(dst, hcrc);
|
||||
|
||||
//Read Binary Data Section
|
||||
len = bin_to_uint16(bin_header.nirep);
|
||||
for (i=0; i<len; i++) {
|
||||
rite_fgets(rfp, hex8, sizeof(hex8), TRUE); //record len
|
||||
dst += hex_to_bin32(dst, hex8);
|
||||
if ((ret = load_rite_irep_record(mrb, rfp, dst, &rlen)) != MRB_DUMP_OK) //irep info
|
||||
goto error_exit;
|
||||
dst += rlen;
|
||||
}
|
||||
rite_fgets(rfp, hex8, sizeof(hex8), TRUE); //dummy record len
|
||||
dst += hex_to_bin32(dst, hex8);
|
||||
if (0 != hex_to_uint32(hex8)) {
|
||||
ret = MRB_DUMP_INVALID_IREP;
|
||||
goto error_exit;
|
||||
}
|
||||
|
||||
if (ret == MRB_DUMP_OK)
|
||||
ret = mrb_read_irep(mrb, (char*)rite_dst);
|
||||
|
||||
error_exit:
|
||||
if (rite_dst)
|
||||
mrb_free(mrb, rite_dst);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
read_rite_header(mrb_state *mrb, unsigned char *bin, rite_binary_header* bin_header)
|
||||
{
|
||||
uint16_t crc;
|
||||
|
||||
memcpy(bin_header, bin, sizeof(rite_binary_header));
|
||||
bin += sizeof(rite_binary_header);
|
||||
if (memcmp(bin_header->rbfi, RITE_FILE_IDENFIFIER, sizeof(bin_header->rbfi)) != 0) {
|
||||
return MRB_DUMP_INVALID_FILE_HEADER; //File identifier error
|
||||
}
|
||||
if (memcmp(bin_header->risv, RITE_VM_VER, sizeof(bin_header->risv)) != 0) {
|
||||
return MRB_DUMP_INVALID_FILE_HEADER; //Instruction set version check
|
||||
}
|
||||
|
||||
crc = calc_crc_16_ccitt((unsigned char *)bin_header, sizeof(*bin_header)); //Calculate CRC
|
||||
if (crc != bin_to_uint16(bin)) {
|
||||
return MRB_DUMP_INVALID_FILE_HEADER; //CRC error
|
||||
}
|
||||
|
||||
return bin_to_uint16(bin_header->nirep);
|
||||
}
|
||||
|
||||
static int
|
||||
read_rite_irep_record(mrb_state *mrb, unsigned char *src, mrb_irep *irep, uint32_t* len)
|
||||
{
|
||||
int i, ret = MRB_DUMP_OK;
|
||||
char *buf;
|
||||
unsigned char *recordStart, *pStart;
|
||||
uint16_t crc, tt, pdl, snl, offset, bufsize=MRB_DUMP_DEFAULT_STR_LEN;
|
||||
mrb_int fix_num;
|
||||
mrb_float f;
|
||||
mrb_value str;
|
||||
|
||||
recordStart = src;
|
||||
buf = mrb_malloc(mrb, bufsize);
|
||||
if (buf == NULL) {
|
||||
ret = MRB_DUMP_INVALID_IREP;
|
||||
goto error_exit;
|
||||
}
|
||||
|
||||
//Header Section
|
||||
pStart = src;
|
||||
if (*src != RITE_IREP_IDENFIFIER)
|
||||
return MRB_DUMP_INVALID_IREP;
|
||||
src += (sizeof(unsigned char) * 2);
|
||||
irep->nlocals = bin_to_uint16(src); //number of local variable
|
||||
src += MRB_DUMP_SIZE_OF_SHORT;
|
||||
irep->nregs = bin_to_uint16(src); //number of register variable
|
||||
src += MRB_DUMP_SIZE_OF_SHORT;
|
||||
offset = bin_to_uint16(src); //offset of isec block
|
||||
src += MRB_DUMP_SIZE_OF_SHORT;
|
||||
crc = calc_crc_16_ccitt(pStart, src - pStart); //Calculate CRC
|
||||
if (crc != bin_to_uint16(src)) //header CRC
|
||||
return MRB_DUMP_INVALID_IREP;
|
||||
src += offset;
|
||||
|
||||
//Binary Data Section
|
||||
//ISEQ BLOCK
|
||||
pStart = src;
|
||||
irep->ilen = bin_to_uint32(src); //iseq length
|
||||
src += MRB_DUMP_SIZE_OF_LONG;
|
||||
if (irep->ilen > 0) {
|
||||
if ((irep->iseq = mrb_malloc(mrb, sizeof(mrb_code) * irep->ilen)) == NULL) {
|
||||
ret = MRB_DUMP_GENERAL_FAILURE;
|
||||
goto error_exit;
|
||||
}
|
||||
for (i=0; i<irep->ilen; i++) {
|
||||
irep->iseq[i] = bin_to_uint32(src); //iseq
|
||||
src += MRB_DUMP_SIZE_OF_LONG;
|
||||
}
|
||||
}
|
||||
crc = calc_crc_16_ccitt((unsigned char *)pStart, src - pStart); //Calculate CRC
|
||||
if (crc != bin_to_uint16(src)) { //iseq CRC
|
||||
ret = MRB_DUMP_INVALID_IREP;
|
||||
goto error_exit;
|
||||
}
|
||||
src += MRB_DUMP_SIZE_OF_SHORT;
|
||||
|
||||
//POOL BLOCK
|
||||
pStart = src;
|
||||
irep->plen = bin_to_uint32(src); //pool length
|
||||
src += MRB_DUMP_SIZE_OF_LONG;
|
||||
if (irep->plen > 0) {
|
||||
irep->pool = mrb_malloc(mrb, sizeof(mrb_value) * irep->plen);
|
||||
if (irep->pool == NULL) {
|
||||
ret = MRB_DUMP_INVALID_IREP;
|
||||
goto error_exit;
|
||||
}
|
||||
|
||||
for (i=0; i<irep->plen; i++) {
|
||||
tt = *src; //pool TT
|
||||
src += sizeof(unsigned char);
|
||||
pdl = bin_to_uint16(src); //pool data length
|
||||
src += MRB_DUMP_SIZE_OF_SHORT;
|
||||
if (pdl > bufsize - 1) {
|
||||
mrb_free(mrb, buf);
|
||||
bufsize = pdl + 1;
|
||||
if ((buf = mrb_malloc(mrb, bufsize)) == NULL) {
|
||||
ret = MRB_DUMP_GENERAL_FAILURE;
|
||||
goto error_exit;
|
||||
}
|
||||
}
|
||||
memcpy(buf, src, pdl);
|
||||
src += pdl;
|
||||
buf[pdl] = '\0';
|
||||
|
||||
switch (tt) { //pool data
|
||||
case MRB_TT_FIXNUM:
|
||||
sscanf(buf, "%d", &fix_num);
|
||||
irep->pool[i] = mrb_fixnum_value(fix_num);
|
||||
break;
|
||||
|
||||
case MRB_TT_FLOAT:
|
||||
sscanf(buf, "%le", &f);
|
||||
irep->pool[i] = mrb_float_value(f);
|
||||
break;
|
||||
|
||||
case MRB_TT_STRING:
|
||||
irep->pool[i] = mrb_str_new(mrb, buf, pdl);
|
||||
break;
|
||||
|
||||
#ifdef INCLUDE_REGEXP
|
||||
case MRB_TT_REGEX:
|
||||
str = mrb_str_new(mrb, buf, pdl);
|
||||
irep->pool[i] = mrb_reg_quote(mrb, str);
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
irep->pool[i] = mrb_nil_value();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
crc = calc_crc_16_ccitt((unsigned char *)pStart, src - pStart); //Calculate CRC
|
||||
if (crc != bin_to_uint16(src)) { //pool CRC
|
||||
ret = MRB_DUMP_INVALID_IREP;
|
||||
goto error_exit;
|
||||
}
|
||||
src += MRB_DUMP_SIZE_OF_SHORT;
|
||||
|
||||
//SYMS BLOCK
|
||||
pStart = src;
|
||||
irep->slen = bin_to_uint32(src); //syms length
|
||||
src += MRB_DUMP_SIZE_OF_LONG;
|
||||
if (irep->slen > 0) {
|
||||
if ((irep->syms = mrb_malloc(mrb, MRB_DUMP_SIZE_OF_INT * irep->slen)) == NULL) {
|
||||
ret = MRB_DUMP_INVALID_IREP;
|
||||
goto error_exit;
|
||||
}
|
||||
|
||||
memset(irep->syms, 0, sizeof(mrb_sym)*(irep->slen));
|
||||
for (i=0; i<irep->slen; i++) {
|
||||
snl = bin_to_uint16(src); //symbol name length
|
||||
src += MRB_DUMP_SIZE_OF_SHORT;
|
||||
|
||||
if (snl == MRB_DUMP_NULL_SYM_LEN) {
|
||||
irep->syms[i] = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (snl > bufsize - 1) {
|
||||
mrb_free(mrb, buf);
|
||||
bufsize = snl + 1;
|
||||
if ((buf = mrb_malloc(mrb, bufsize)) == NULL) {
|
||||
ret = MRB_DUMP_GENERAL_FAILURE;
|
||||
goto error_exit;
|
||||
}
|
||||
}
|
||||
memcpy(buf, src, snl); //symbol name
|
||||
src += snl;
|
||||
buf[snl] = '\0';
|
||||
irep->syms[i] = mrb_intern(mrb, buf);
|
||||
}
|
||||
}
|
||||
crc = calc_crc_16_ccitt((unsigned char *)pStart, src - pStart); //Calculate CRC
|
||||
if (crc != bin_to_uint16(src)) { //syms CRC
|
||||
ret = MRB_DUMP_INVALID_IREP;
|
||||
goto error_exit;
|
||||
}
|
||||
src += MRB_DUMP_SIZE_OF_SHORT;
|
||||
|
||||
*len = src - recordStart;
|
||||
error_exit:
|
||||
if (buf)
|
||||
mrb_free(mrb, buf);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
mrb_read_irep(mrb_state *mrb, char *bin)
|
||||
{
|
||||
int ret = MRB_DUMP_OK, i, n, nirep, sirep;
|
||||
uint32_t len;
|
||||
unsigned char *src;
|
||||
rite_binary_header bin_header;
|
||||
|
||||
if ((mrb == NULL) || (bin == NULL)) {
|
||||
return MRB_DUMP_INVALID_ARGUMENT;
|
||||
}
|
||||
src = (unsigned char*)bin;
|
||||
sirep = mrb->irep_len;
|
||||
|
||||
//Read File Header Section
|
||||
if ((nirep = read_rite_header(mrb, src, &bin_header)) < 0)
|
||||
return nirep;
|
||||
|
||||
mrb_add_irep(mrb, sirep + nirep);
|
||||
|
||||
for (n=0,i=sirep; n<nirep; n++,i++) {
|
||||
if ((mrb->irep[i] = mrb_malloc(mrb, sizeof(mrb_irep))) == NULL) {
|
||||
ret = MRB_DUMP_GENERAL_FAILURE;
|
||||
goto error_exit;
|
||||
}
|
||||
memset(mrb->irep[i], 0, sizeof(mrb_irep));
|
||||
}
|
||||
src += sizeof(bin_header) + MRB_DUMP_SIZE_OF_SHORT; //header + crc
|
||||
|
||||
//Read Binary Data Section
|
||||
for (n=0,i=sirep; n<nirep; n++,i++) {
|
||||
src += MRB_DUMP_SIZE_OF_LONG; //record ren
|
||||
if ((ret = read_rite_irep_record(mrb, src, mrb->irep[i], &len)) != MRB_DUMP_OK)
|
||||
goto error_exit;
|
||||
mrb->irep[i]->idx = i;
|
||||
src += len;
|
||||
}
|
||||
if (0 != bin_to_uint32(src)) { //dummy record len
|
||||
ret = MRB_DUMP_GENERAL_FAILURE;
|
||||
}
|
||||
|
||||
mrb->irep_len += nirep;
|
||||
|
||||
error_exit:
|
||||
if (ret != MRB_DUMP_OK) {
|
||||
for (n=0,i=sirep; n<nirep; n++,i++) {
|
||||
if (mrb->irep[i]) {
|
||||
if (mrb->irep[i]->iseq)
|
||||
mrb_free(mrb, mrb->irep[i]->iseq);
|
||||
|
||||
if (mrb->irep[i]->pool)
|
||||
mrb_free(mrb, mrb->irep[i]->pool);
|
||||
|
||||
if (mrb->irep[i]->syms)
|
||||
mrb_free(mrb, mrb->irep[i]->syms);
|
||||
|
||||
mrb_free(mrb, mrb->irep[i]);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
return sirep + hex_to_uint8(bin_header.sirep);
|
||||
}
|
||||
|
||||
static uint16_t
|
||||
hex_to_bin8(unsigned char *dst, unsigned char *src)
|
||||
{
|
||||
dst[0] = (hex2bin[src[0]] << 4) | (hex2bin[src[1]]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static uint16_t
|
||||
hex_to_bin16(unsigned char *dst, unsigned char *src)
|
||||
{
|
||||
dst[0] = (hex2bin[src[0]] << 4) | (hex2bin[src[1]]);
|
||||
dst[1] = (hex2bin[src[2]] << 4) | (hex2bin[src[3]]);
|
||||
return 2;
|
||||
}
|
||||
|
||||
static uint16_t
|
||||
hex_to_bin32(unsigned char *dst, unsigned char *src)
|
||||
{
|
||||
dst[0] = (hex2bin[src[0]] << 4) | (hex2bin[src[1]]);
|
||||
dst[1] = (hex2bin[src[2]] << 4) | (hex2bin[src[3]]);
|
||||
dst[2] = (hex2bin[src[4]] << 4) | (hex2bin[src[5]]);
|
||||
dst[3] = (hex2bin[src[6]] << 4) | (hex2bin[src[7]]);
|
||||
return 4;
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
hex_to_uint8(unsigned char *hex)
|
||||
{
|
||||
return (unsigned char)hex2bin[hex[0]] << 4 |
|
||||
(unsigned char)hex2bin[hex[1]];
|
||||
}
|
||||
|
||||
static uint16_t
|
||||
hex_to_uint16(unsigned char *hex)
|
||||
{
|
||||
return (uint16_t)hex2bin[hex[0]] << 12 |
|
||||
(uint16_t)hex2bin[hex[1]] << 8 |
|
||||
(uint16_t)hex2bin[hex[2]] << 4 |
|
||||
(uint16_t)hex2bin[hex[3]];
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
hex_to_uint32(unsigned char *hex)
|
||||
{
|
||||
return (uint32_t)hex2bin[hex[0]] << 28 |
|
||||
(uint32_t)hex2bin[hex[1]] << 24 |
|
||||
(uint32_t)hex2bin[hex[2]] << 20 |
|
||||
(uint32_t)hex2bin[hex[3]] << 16 |
|
||||
(uint32_t)hex2bin[hex[4]] << 12 |
|
||||
(uint32_t)hex2bin[hex[5]] << 8 |
|
||||
(uint32_t)hex2bin[hex[6]] << 4 |
|
||||
(uint32_t)hex2bin[hex[7]];
|
||||
}
|
||||
|
||||
static char*
|
||||
hex_to_str(char *hex, char *str, uint16_t *str_len)
|
||||
{
|
||||
char *src, *dst;
|
||||
uint16_t hex_len = strlen(hex);
|
||||
|
||||
*str_len = 0;
|
||||
|
||||
for (src = hex, dst = str; hex_len > 0; (*str_len)++, hex_len--) {
|
||||
if (*src == '\\' && hex_len > 1) {
|
||||
src++; hex_len--;
|
||||
switch(*src) {
|
||||
case 'a': *dst++ = '\a'/* BEL */; break;
|
||||
case 'b': *dst++ = '\b'/* BS */; break;
|
||||
case 't': *dst++ = '\t'/* HT */; break;
|
||||
case 'n': *dst++ = '\n'/* LF */; break;
|
||||
case 'v': *dst++ = '\v'/* VT */; break;
|
||||
case 'f': *dst++ = '\f'/* FF */; break;
|
||||
case 'r': *dst++ = '\r'/* CR */; break;
|
||||
case '\"': /* fall through */
|
||||
case '\'': /* fall through */
|
||||
case '\?': /* fall through */
|
||||
case '\\': *dst++ = *src; break;
|
||||
default:break;
|
||||
}
|
||||
src++;
|
||||
} else {
|
||||
*dst++ = *src++;
|
||||
}
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
/**********************************************************************
|
||||
|
||||
mdata.h -
|
||||
|
||||
|
||||
Copyright (C) 2007 Yukihiro Matsumoto
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef RUBY_DATA_H
|
||||
#define RUBY_DATA_H 1
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
struct mrb_data_type {
|
||||
const char *struct_name;
|
||||
void (*dfree)(mrb_state *mrb, void*);
|
||||
};
|
||||
|
||||
struct RData {
|
||||
MRUBY_OBJECT_HEADER;
|
||||
struct kh_iv *iv;
|
||||
struct mrb_data_type *type;
|
||||
void *data;
|
||||
};
|
||||
|
||||
struct RData *mrb_data_object_alloc(mrb_state *mrb, struct RClass* klass, void *datap, const struct mrb_data_type *type);
|
||||
|
||||
#define Data_Wrap_Struct(mrb,klass,type,ptr)\
|
||||
mrb_data_object_alloc(mrb,klass,ptr,type)
|
||||
|
||||
#define Data_Make_Struct(mrb,klass,strct,type,sval) (\
|
||||
sval = mrb_malloc(mrb, sizeof(strct)),\
|
||||
memset(sval, 0, sizeof(strct)),\
|
||||
Data_Wrap_Struct(mrb,klass,type,sval)\
|
||||
)
|
||||
|
||||
#define RDATA(obj) ((struct RData *)((obj).value.p))
|
||||
#define DATA_PTR(d) (RDATA(d)->data)
|
||||
#define DATA_TYPE(d) (RDATA(d)->type)
|
||||
void *mrb_check_datatype(mrb_state *mrb, mrb_value, const struct mrb_data_type*);
|
||||
#define Data_Get_Struct(mrb,obj,type,sval) do {\
|
||||
sval = mrb_check_datatype(mrb, obj, type); \
|
||||
} while (0)
|
||||
|
||||
#if defined(__cplusplus)
|
||||
} /* extern "C" { */
|
||||
#endif
|
||||
|
||||
#endif /* RUBY_DATA_H */
|
||||
+103
@@ -0,0 +1,103 @@
|
||||
/**********************************************************************
|
||||
|
||||
method.h -
|
||||
|
||||
$Author: ko1 $
|
||||
created at: Wed Jul 15 20:02:33 2009
|
||||
|
||||
Copyright (C) 2009 Koichi Sasada
|
||||
|
||||
**********************************************************************/
|
||||
#ifndef METHOD_H
|
||||
#define METHOD_H
|
||||
|
||||
typedef enum {
|
||||
NOEX_PUBLIC = 0x00,
|
||||
NOEX_NOSUPER = 0x01,
|
||||
NOEX_PRIVATE = 0x02,
|
||||
NOEX_PROTECTED = 0x04,
|
||||
NOEX_MASK = 0x06,
|
||||
NOEX_BASIC = 0x08,
|
||||
NOEX_UNDEF = NOEX_NOSUPER,
|
||||
NOEX_MODFUNC = 0x12,
|
||||
NOEX_SUPER = 0x20,
|
||||
NOEX_VCALL = 0x40,
|
||||
NOEX_RESPONDS = 0x80
|
||||
} mrb_method_flag_t;
|
||||
|
||||
#define NOEX_SAFE(n) ((int)((n) >> 8) & 0x0F)
|
||||
#define NOEX_WITH(n, s) ((s << 8) | (n) | (ruby_running ? 0 : NOEX_BASIC))
|
||||
#define NOEX_WITH_SAFE(n) NOEX_WITH(n, mrb_safe_level())
|
||||
|
||||
/* method data type */
|
||||
|
||||
typedef enum {
|
||||
VM_METHOD_TYPE_ISEQ,
|
||||
VM_METHOD_TYPE_CFUNC,
|
||||
VM_METHOD_TYPE_ATTRSET,
|
||||
VM_METHOD_TYPE_IVAR,
|
||||
VM_METHOD_TYPE_BMETHOD,
|
||||
VM_METHOD_TYPE_ZSUPER,
|
||||
VM_METHOD_TYPE_UNDEF,
|
||||
VM_METHOD_TYPE_NOTIMPLEMENTED,
|
||||
VM_METHOD_TYPE_OPTIMIZED, /* Kernel#send, Proc#call, etc */
|
||||
VM_METHOD_TYPE_MISSING /* wrapper for method_missing(id) */
|
||||
} mrb_method_type_t;
|
||||
|
||||
typedef struct mrb_method_cfunc_struct {
|
||||
mrb_value (*func)(ANYARGS);
|
||||
int argc;
|
||||
} mrb_method_cfunc_t;
|
||||
|
||||
typedef struct mrb_method_attr_struct {
|
||||
mrb_sym id;
|
||||
mrb_value location;
|
||||
} mrb_method_attr_t;
|
||||
|
||||
typedef struct mrb_iseq_struct mrb_iseq_t;
|
||||
|
||||
typedef struct mrb_method_definition_struct {
|
||||
mrb_method_type_t type; /* method type */
|
||||
mrb_sym original_id;
|
||||
union {
|
||||
mrb_iseq_t *iseq; /* should be mark */
|
||||
mrb_method_cfunc_t cfunc;
|
||||
mrb_method_attr_t attr;
|
||||
mrb_value proc; /* should be mark */
|
||||
enum method_optimized_type {
|
||||
OPTIMIZED_METHOD_TYPE_SEND,
|
||||
OPTIMIZED_METHOD_TYPE_CALL
|
||||
} optimize_type;
|
||||
} body;
|
||||
int alias_count;
|
||||
} mrb_method_definition_t;
|
||||
|
||||
typedef struct mrb_method_entry_struct {
|
||||
mrb_method_flag_t flag;
|
||||
char mark;
|
||||
mrb_method_definition_t *def;
|
||||
mrb_sym called_id;
|
||||
mrb_value klass; /* should be mark */
|
||||
} mrb_method_entry_t;
|
||||
|
||||
struct unlinked_method_entry_list_entry {
|
||||
struct unlinked_method_entry_list_entry *next;
|
||||
mrb_method_entry_t *me;
|
||||
};
|
||||
|
||||
#define UNDEFINED_METHOD_ENTRY_P(me) (!(me) || !(me)->def || (me)->def->type == VM_METHOD_TYPE_UNDEF)
|
||||
|
||||
void mrb_add_method_cfunc(mrb_value klass, mrb_sym mid, mrb_value (*func)(ANYARGS), int argc, mrb_method_flag_t noex);
|
||||
mrb_method_entry_t *mrb_add_method(mrb_value klass, mrb_sym mid, mrb_method_type_t type, void *option, mrb_method_flag_t noex);
|
||||
mrb_method_entry_t *mrb_method_entry(mrb_state *mrb, mrb_value klass, mrb_sym id);
|
||||
|
||||
mrb_method_entry_t *mrb_method_entry_get_without_cache(mrb_value klass, mrb_sym id);
|
||||
mrb_method_entry_t *mrb_method_entry_set(mrb_value klass, mrb_sym mid, const mrb_method_entry_t *, mrb_method_flag_t noex);
|
||||
|
||||
int mrb_method_entry_arity(const mrb_method_entry_t *me);
|
||||
|
||||
void mrb_mark_method_entry(const mrb_method_entry_t *me);
|
||||
void mrb_free_method_entry(mrb_method_entry_t *me);
|
||||
void mrb_sweep_method_entry(void *vm);
|
||||
|
||||
#endif /* METHOD_H */
|
||||
+117
@@ -0,0 +1,117 @@
|
||||
#include "mruby.h"
|
||||
#include "mruby/proc.h"
|
||||
|
||||
#if 0
|
||||
#include "opcode.h"
|
||||
|
||||
mrb_code fib_iseq[256];
|
||||
|
||||
int fib_syms[4];
|
||||
|
||||
mrb_irep fib_irep = {
|
||||
1,
|
||||
MRB_IREP_NOFREE,
|
||||
2,
|
||||
5,
|
||||
fib_iseq,
|
||||
NULL,
|
||||
fib_syms,
|
||||
|
||||
256, 0, 4,
|
||||
};
|
||||
|
||||
mrb_code main_iseq[256];
|
||||
|
||||
int main_syms[2];
|
||||
|
||||
mrb_irep main_irep = {
|
||||
0,
|
||||
MRB_IREP_NOFREE,
|
||||
1,
|
||||
3,
|
||||
main_iseq,
|
||||
NULL,
|
||||
main_syms,
|
||||
|
||||
256, 0, 2,
|
||||
};
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
mrb_state *mrb = mrb_open();
|
||||
int sirep = mrb->irep_len;
|
||||
int n;
|
||||
|
||||
main_syms[0] = mrb_intern(mrb, "fib");
|
||||
main_syms[1] = mrb_intern(mrb, "p");
|
||||
n = 0;
|
||||
|
||||
main_iseq[n++] = MKOP_AB(OP_LAMBDA, 1, 1); /* r1 := lambda(1) */
|
||||
main_iseq[n++] = MKOP_AB(OP_METHOD, 1, 0); /* defmethod(r1) */
|
||||
main_iseq[n++] = MKOP_AB(OP_MOVE, 1, 0); /* r1 := r0 */
|
||||
main_iseq[n++] = MKOP_AB(OP_MOVE, 2, 0); /* r2 := r0 */
|
||||
main_iseq[n++] = MKOP_AsBx(OP_LOADI, 3, 35); /* r3 := 20 */
|
||||
main_iseq[n++] = MKOP_ABC(OP_SEND, 2, 0, 1); /* r2 .fib r3 */
|
||||
main_iseq[n++] = MKOP_ABC(OP_SEND, 1, 1, 1); /* r1 .p r2 */
|
||||
main_iseq[n++] = MKOP_ABC(OP_STOP, 1, 1, 2); /* stop */
|
||||
main_irep.ilen = n;
|
||||
main_irep.idx = sirep;
|
||||
|
||||
fib_syms[0] = mrb_intern(mrb, "<");
|
||||
fib_syms[1] = mrb_intern(mrb, "-");
|
||||
fib_syms[2] = mrb_intern(mrb, "+");
|
||||
fib_syms[3] = mrb_intern(mrb, "fib");
|
||||
n = 0;
|
||||
|
||||
fib_iseq[n++] = MKOP_AB(OP_MOVE, 2, 1); /* r2 := r1 */
|
||||
fib_iseq[n++] = MKOP_AsBx(OP_LOADI, 3, 3); /* r3 := 2 */
|
||||
fib_iseq[n++] = MKOP_ABC(OP_LT, 2, 0, 2); /* r2 .< r3 */
|
||||
fib_iseq[n++] = MKOP_AsBx(OP_JMPNOT, 2, 2); /* ifnot r2 :else */
|
||||
fib_iseq[n++] = MKOP_AsBx(OP_LOADI, 2, 1); /* r6 := 1 */
|
||||
fib_iseq[n++] = MKOP_A(OP_RETURN, 2); /* return r2 */
|
||||
fib_iseq[n++] = MKOP_AB(OP_MOVE, 3, 0); /* r3 := r0 :else */
|
||||
fib_iseq[n++] = MKOP_AB(OP_MOVE, 4, 1); /* r4 := r1 */
|
||||
fib_iseq[n++] = MKOP_ABC(OP_SUBI, 4, 1, 2); /* r4 .- 2 */
|
||||
fib_iseq[n++] = MKOP_ABC(OP_SEND, 3, 3, 1); /* r3 .fib r4 */
|
||||
fib_iseq[n++] = MKOP_AB(OP_MOVE, 4, 0); /* r4 := r0 */
|
||||
fib_iseq[n++] = MKOP_AB(OP_MOVE, 5, 1); /* r5 := r1 */
|
||||
fib_iseq[n++] = MKOP_ABC(OP_SUBI, 5, 1, 1); /* r5 .- 1 */
|
||||
fib_iseq[n++] = MKOP_ABC(OP_SEND, 4, 3, 1); /* r4 .fib :r5 */
|
||||
fib_iseq[n++] = MKOP_ABC(OP_ADD, 3, 2, 1); /* r3 .+ r4 */
|
||||
fib_iseq[n++] = MKOP_A(OP_RETURN, 3); /* return r3 */
|
||||
fib_irep.ilen = n;
|
||||
fib_irep.idx = sirep+1;
|
||||
|
||||
mrb_add_irep(mrb, sirep+2);
|
||||
mrb->irep[sirep ] = &main_irep;
|
||||
mrb->irep[sirep+1] = &fib_irep;
|
||||
|
||||
mrb_run(mrb, mrb_proc_new(mrb, &main_irep), mrb_nil_value());
|
||||
}
|
||||
|
||||
#else
|
||||
#include "compile.h"
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
mrb_state *mrb = mrb_open();
|
||||
int n;
|
||||
|
||||
n = mrb_compile_string(mrb, "\
|
||||
def fib(n)\n\
|
||||
if n<2\n\
|
||||
n\n\
|
||||
else\n\
|
||||
fib(n-2)+fib(n-1)\n\
|
||||
end\n\
|
||||
end\n\
|
||||
p(fib(30), \"\\n\")\n\
|
||||
");
|
||||
mrb_run(mrb, mrb_proc_new(mrb, mrb->irep[n]), mrb_nil_value());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
+17985
File diff suppressed because it is too large
Load Diff
+125
@@ -0,0 +1,125 @@
|
||||
enum node_type {
|
||||
NODE_METHOD,
|
||||
NODE_FBODY,
|
||||
NODE_CFUNC,
|
||||
NODE_SCOPE,
|
||||
NODE_BLOCK,
|
||||
NODE_IF,
|
||||
NODE_CASE,
|
||||
NODE_WHEN,
|
||||
NODE_OPT_N,
|
||||
NODE_WHILE,
|
||||
NODE_UNTIL,
|
||||
NODE_ITER,
|
||||
NODE_FOR,
|
||||
NODE_BREAK,
|
||||
NODE_NEXT,
|
||||
NODE_REDO,
|
||||
NODE_RETRY,
|
||||
NODE_BEGIN,
|
||||
NODE_RESCUE,
|
||||
NODE_ENSURE,
|
||||
NODE_AND,
|
||||
NODE_OR,
|
||||
NODE_NOT,
|
||||
NODE_MASGN,
|
||||
NODE_ASGN,
|
||||
NODE_CDECL,
|
||||
NODE_CVASGN,
|
||||
NODE_CVDECL,
|
||||
NODE_OP_ASGN,
|
||||
NODE_CALL,
|
||||
NODE_FCALL,
|
||||
NODE_VCALL,
|
||||
NODE_SUPER,
|
||||
NODE_ZSUPER,
|
||||
NODE_ARRAY,
|
||||
NODE_ZARRAY,
|
||||
NODE_HASH,
|
||||
NODE_RETURN,
|
||||
NODE_YIELD,
|
||||
NODE_LVAR,
|
||||
NODE_DVAR,
|
||||
NODE_GVAR,
|
||||
NODE_IVAR,
|
||||
NODE_CONST,
|
||||
NODE_CVAR,
|
||||
NODE_NTH_REF,
|
||||
NODE_BACK_REF,
|
||||
NODE_MATCH,
|
||||
NODE_MATCH2,
|
||||
NODE_MATCH3,
|
||||
NODE_INT,
|
||||
NODE_FLOAT,
|
||||
NODE_NEGATE,
|
||||
NODE_LAMBDA,
|
||||
NODE_SYM,
|
||||
NODE_STR,
|
||||
NODE_DSTR,
|
||||
NODE_DREGX,
|
||||
NODE_DREGX_ONCE,
|
||||
NODE_LIST,
|
||||
NODE_ARG,
|
||||
NODE_ARGSCAT,
|
||||
NODE_ARGSPUSH,
|
||||
NODE_SPLAT,
|
||||
NODE_TO_ARY,
|
||||
NODE_SVALUE,
|
||||
NODE_BLOCK_ARG,
|
||||
NODE_DEF,
|
||||
NODE_SDEF,
|
||||
NODE_ALIAS,
|
||||
NODE_UNDEF,
|
||||
NODE_CLASS,
|
||||
NODE_MODULE,
|
||||
NODE_SCLASS,
|
||||
NODE_COLON2,
|
||||
NODE_COLON3,
|
||||
NODE_CREF,
|
||||
NODE_DOT2,
|
||||
NODE_DOT3,
|
||||
NODE_FLIP2,
|
||||
NODE_FLIP3,
|
||||
NODE_ATTRSET,
|
||||
NODE_SELF,
|
||||
NODE_NIL,
|
||||
NODE_TRUE,
|
||||
NODE_FALSE,
|
||||
NODE_DEFINED,
|
||||
NODE_NEWLINE,
|
||||
NODE_POSTEXE,
|
||||
NODE_ALLOCA,
|
||||
NODE_DMETHOD,
|
||||
NODE_BMETHOD,
|
||||
NODE_MEMO,
|
||||
NODE_IFUNC,
|
||||
NODE_DSYM,
|
||||
NODE_ATTRASGN,
|
||||
NODE_LAST
|
||||
};
|
||||
|
||||
typedef struct RNode {
|
||||
unsigned long flags;
|
||||
char *nd_file;
|
||||
union {
|
||||
struct RNode *node;
|
||||
mrb_sym id;
|
||||
mrb_value value;
|
||||
//mrb_value (*cfunc)((ARGS_ANY()));
|
||||
mrb_sym *tbl;
|
||||
} u1;
|
||||
union {
|
||||
struct RNode *node;
|
||||
mrb_sym id;
|
||||
long argc;
|
||||
mrb_value value;
|
||||
} u2;
|
||||
union {
|
||||
struct RNode *node;
|
||||
mrb_sym id;
|
||||
long state;
|
||||
struct global_entry *entry;
|
||||
long cnt;
|
||||
mrb_value value;
|
||||
} u3;
|
||||
} NODE;
|
||||
+2018
File diff suppressed because it is too large
Load Diff
+632
@@ -0,0 +1,632 @@
|
||||
#include "mruby.h"
|
||||
#include <string.h>
|
||||
#include "mruby/string.h"
|
||||
#include <stdio.h>
|
||||
#include "mruby/class.h"
|
||||
#include "method.h"
|
||||
#include "mruby/numeric.h"
|
||||
#include "mdata.h"
|
||||
|
||||
#ifdef INCLUDE_REGEXP
|
||||
#define mrb_usascii_str_new2 mrb_usascii_str_new_cstr
|
||||
#else
|
||||
#define mrb_usascii_str_new2 mrb_str_new_cstr
|
||||
#define mrb_usascii_str_new mrb_str_new
|
||||
#endif
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif
|
||||
|
||||
int
|
||||
mrb_obj_eq(mrb_state *mrb, mrb_value v1, mrb_value v2)
|
||||
{
|
||||
if (v1.tt != v2.tt) return 0;
|
||||
switch (v1.tt) {
|
||||
case MRB_TT_TRUE:
|
||||
return 1;
|
||||
|
||||
case MRB_TT_FALSE:
|
||||
case MRB_TT_FIXNUM:
|
||||
return (v1.value.i == v2.value.i);
|
||||
case MRB_TT_SYMBOL:
|
||||
return (v1.value.sym == v2.value.sym);
|
||||
|
||||
case MRB_TT_FLOAT:
|
||||
return (v1.value.f == v2.value.f);
|
||||
|
||||
default:
|
||||
return (v1.value.p == v2.value.p);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
mrb_obj_equal(mrb_state *mrb, mrb_value v1, mrb_value v2)
|
||||
{
|
||||
/* temporary definition */
|
||||
return mrb_obj_eq(mrb, v1, v2);
|
||||
}
|
||||
|
||||
int
|
||||
mrb_equal(mrb_state *mrb, mrb_value obj1, mrb_value obj2)
|
||||
{
|
||||
mrb_value result;
|
||||
|
||||
if (mrb_obj_eq(mrb, obj1, obj2)) return TRUE;
|
||||
result = mrb_funcall(mrb, obj1, "==", 1, obj2);
|
||||
if (mrb_nil_p(result)) {
|
||||
return FALSE;
|
||||
}
|
||||
else {
|
||||
if (mrb_type(result) == MRB_TT_TRUE) {
|
||||
return TRUE;
|
||||
}
|
||||
else {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Document-class: NilClass
|
||||
*
|
||||
* The class of the singleton object <code>nil</code>.
|
||||
*/
|
||||
|
||||
/* 15.2.4.3.4 */
|
||||
/*
|
||||
* call_seq:
|
||||
* nil.nil? -> true
|
||||
*
|
||||
* Only the object <i>nil</i> responds <code>true</code> to <code>nil?</code>.
|
||||
*/
|
||||
|
||||
static mrb_value
|
||||
mrb_true(mrb_state *mrb, mrb_value obj)
|
||||
{
|
||||
return mrb_true_value();
|
||||
}
|
||||
|
||||
/* 15.2.4.3.5 */
|
||||
/*
|
||||
* call-seq:
|
||||
* nil.to_s -> ""
|
||||
*
|
||||
* Always returns the empty string.
|
||||
*/
|
||||
|
||||
static mrb_value
|
||||
nil_to_s(mrb_state *mrb, mrb_value obj)
|
||||
{
|
||||
return mrb_usascii_str_new(mrb, 0, 0);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* Document-class: TrueClass
|
||||
*
|
||||
* The global value <code>true</code> is the only instance of class
|
||||
* <code>TrueClass</code> and represents a logically true value in
|
||||
* boolean expressions. The class provides operators allowing
|
||||
* <code>true</code> to be used in logical expressions.
|
||||
*/
|
||||
|
||||
/* 15.2.5.3.1 */
|
||||
/*
|
||||
* call-seq:
|
||||
* true & obj -> true or false
|
||||
*
|
||||
* And---Returns <code>false</code> if <i>obj</i> is
|
||||
* <code>nil</code> or <code>false</code>, <code>true</code> otherwise.
|
||||
*/
|
||||
|
||||
static mrb_value
|
||||
true_and(mrb_state *mrb, mrb_value obj)
|
||||
{
|
||||
mrb_value obj2;
|
||||
|
||||
mrb_get_args(mrb, "o", &obj2);
|
||||
return mrb_test(obj2)?mrb_true_value():mrb_false_value();
|
||||
}
|
||||
|
||||
/* 15.2.5.3.2 */
|
||||
/*
|
||||
* call-seq:
|
||||
* true ^ obj -> !obj
|
||||
*
|
||||
* Exclusive Or---Returns <code>true</code> if <i>obj</i> is
|
||||
* <code>nil</code> or <code>false</code>, <code>false</code>
|
||||
* otherwise.
|
||||
*/
|
||||
|
||||
static mrb_value
|
||||
true_xor(mrb_state *mrb, mrb_value obj)
|
||||
{
|
||||
mrb_value obj2;
|
||||
|
||||
mrb_get_args(mrb, "o", &obj2);
|
||||
return mrb_test(obj2)?mrb_false_value():mrb_true_value();
|
||||
}
|
||||
|
||||
/* 15.2.5.3.3 */
|
||||
/*
|
||||
* call-seq:
|
||||
* true.to_s -> "true"
|
||||
*
|
||||
* The string representation of <code>true</code> is "true".
|
||||
*/
|
||||
|
||||
static mrb_value
|
||||
true_to_s(mrb_state *mrb, mrb_value obj)
|
||||
{
|
||||
return mrb_usascii_str_new2(mrb, "true");
|
||||
}
|
||||
|
||||
/* 15.2.5.3.4 */
|
||||
/*
|
||||
* call-seq:
|
||||
* true | obj -> true
|
||||
*
|
||||
* Or---Returns <code>true</code>. As <i>anObject</i> is an argument to
|
||||
* a method call, it is always evaluated; there is no short-circuit
|
||||
* evaluation in this case.
|
||||
*
|
||||
* true | puts("or")
|
||||
* true || puts("logical or")
|
||||
*
|
||||
* <em>produces:</em>
|
||||
*
|
||||
* or
|
||||
*/
|
||||
|
||||
static mrb_value
|
||||
true_or(mrb_state *mrb, mrb_value obj)
|
||||
{
|
||||
mrb_value obj2;
|
||||
|
||||
mrb_get_args(mrb, "o", &obj2);
|
||||
return mrb_true_value();
|
||||
}
|
||||
|
||||
/*
|
||||
* Document-class: FalseClass
|
||||
*
|
||||
* The global value <code>false</code> is the only instance of class
|
||||
* <code>FalseClass</code> and represents a logically false value in
|
||||
* boolean expressions. The class provides operators allowing
|
||||
* <code>false</code> to participate correctly in logical expressions.
|
||||
*
|
||||
*/
|
||||
|
||||
/* 15.2.4.3.1 */
|
||||
/* 15.2.6.3.1 */
|
||||
/*
|
||||
* call-seq:
|
||||
* false & obj -> false
|
||||
* nil & obj -> false
|
||||
*
|
||||
* And---Returns <code>false</code>. <i>obj</i> is always
|
||||
* evaluated as it is the argument to a method call---there is no
|
||||
* short-circuit evaluation in this case.
|
||||
*/
|
||||
|
||||
static mrb_value
|
||||
false_and(mrb_state *mrb, mrb_value obj)
|
||||
{
|
||||
mrb_value obj2;
|
||||
|
||||
mrb_get_args(mrb, "o", &obj2);
|
||||
return mrb_false_value();
|
||||
}
|
||||
|
||||
/* 15.2.4.3.2 */
|
||||
/* 15.2.6.3.2 */
|
||||
/*
|
||||
* call-seq:
|
||||
* false ^ obj -> true or false
|
||||
* nil ^ obj -> true or false
|
||||
*
|
||||
* Exclusive Or---If <i>obj</i> is <code>nil</code> or
|
||||
* <code>false</code>, returns <code>false</code>; otherwise, returns
|
||||
* <code>true</code>.
|
||||
*
|
||||
*/
|
||||
|
||||
static mrb_value
|
||||
false_xor(mrb_state *mrb, mrb_value obj)
|
||||
{
|
||||
mrb_value obj2;
|
||||
|
||||
mrb_get_args(mrb, "o", &obj2);
|
||||
return mrb_test(obj2)?mrb_true_value():mrb_false_value();
|
||||
}
|
||||
|
||||
/* 15.2.4.3.3 */
|
||||
/* 15.2.6.3.4 */
|
||||
/*
|
||||
* call-seq:
|
||||
* false | obj -> true or false
|
||||
* nil | obj -> true or false
|
||||
*
|
||||
* Or---Returns <code>false</code> if <i>obj</i> is
|
||||
* <code>nil</code> or <code>false</code>; <code>true</code> otherwise.
|
||||
*/
|
||||
|
||||
static mrb_value
|
||||
false_or(mrb_state *mrb, mrb_value obj)
|
||||
{
|
||||
mrb_value obj2;
|
||||
|
||||
mrb_get_args(mrb, "o", &obj2);
|
||||
return mrb_test(obj2)?mrb_true_value():mrb_false_value();
|
||||
}
|
||||
|
||||
/* 15.2.6.3.3 */
|
||||
/*
|
||||
* call-seq:
|
||||
* false.to_s -> "false"
|
||||
*
|
||||
* 'nuf said...
|
||||
*/
|
||||
|
||||
static mrb_value
|
||||
false_to_s(mrb_state *mrb, mrb_value obj)
|
||||
{
|
||||
return mrb_usascii_str_new2(mrb, "false");
|
||||
}
|
||||
|
||||
void
|
||||
mrb_init_object(mrb_state *mrb)
|
||||
{
|
||||
struct RClass *n;
|
||||
struct RClass *t;
|
||||
struct RClass *f;
|
||||
|
||||
n = mrb->nil_class = mrb_define_class(mrb, "NilClass", mrb->object_class);
|
||||
mrb_define_method(mrb, n, "&", false_and, ARGS_REQ(1)); /* 15.2.4.3.1 */
|
||||
mrb_define_method(mrb, n, "^", false_xor, ARGS_REQ(1)); /* 15.2.4.3.2 */
|
||||
mrb_define_method(mrb, n, "|", false_or, ARGS_REQ(1)); /* 15.2.4.3.3 */
|
||||
mrb_define_method(mrb, n, "nil?", mrb_true, ARGS_NONE()); /* 15.2.4.3.4 */
|
||||
mrb_define_method(mrb, n, "to_s", nil_to_s, ARGS_NONE()); /* 15.2.4.3.5 */
|
||||
|
||||
t = mrb->true_class = mrb_define_class(mrb, "TrueClass", mrb->object_class);
|
||||
mrb_define_method(mrb, t, "&", true_and, ARGS_REQ(1)); /* 15.2.5.3.1 */
|
||||
mrb_define_method(mrb, t, "^", true_xor, ARGS_REQ(1)); /* 15.2.5.3.2 */
|
||||
mrb_define_method(mrb, t, "to_s", true_to_s, ARGS_NONE()); /* 15.2.5.3.3 */
|
||||
mrb_define_method(mrb, t, "|", true_or, ARGS_REQ(1)); /* 15.2.5.3.4 */
|
||||
|
||||
f = mrb->false_class = mrb_define_class(mrb, "FalseClass", mrb->object_class);
|
||||
mrb_define_method(mrb, f, "&", false_and, ARGS_REQ(1)); /* 15.2.6.3.1 */
|
||||
mrb_define_method(mrb, f, "^", false_xor, ARGS_REQ(1)); /* 15.2.6.3.2 */
|
||||
mrb_define_method(mrb, f, "to_s", false_to_s, ARGS_NONE()); /* 15.2.6.3.3 */
|
||||
mrb_define_method(mrb, f, "|", false_or, ARGS_REQ(1)); /* 15.2.6.3.4 */
|
||||
}
|
||||
|
||||
mrb_value
|
||||
convert_type(mrb_state *mrb, mrb_value val, const char *tname, const char *method, int raise)
|
||||
{
|
||||
mrb_sym m = 0;
|
||||
|
||||
m = mrb_intern(mrb, method);
|
||||
if (!mrb_respond_to(mrb, val, m)) {
|
||||
if (raise) {
|
||||
mrb_raise(mrb, E_TYPE_ERROR, "can't convert %s into %s",
|
||||
mrb_nil_p(val) ? "nil" :
|
||||
(mrb_type(val) == MRB_TT_TRUE) ? "true" :
|
||||
(mrb_type(val) == MRB_TT_FALSE) ? "false" :
|
||||
mrb_obj_classname(mrb, val),
|
||||
tname);
|
||||
return mrb_nil_value();
|
||||
}
|
||||
else {
|
||||
return mrb_nil_value();
|
||||
}
|
||||
}
|
||||
return mrb_funcall(mrb, val, method, 0);
|
||||
}
|
||||
|
||||
mrb_value
|
||||
mrb_check_to_integer(mrb_state *mrb, mrb_value val, const char *method)
|
||||
{
|
||||
mrb_value v;
|
||||
|
||||
if (mrb_type(val) == MRB_TT_FIXNUM) return val;
|
||||
v = convert_type(mrb, val, "Integer", method, FALSE);
|
||||
if (mrb_nil_p(v)) return (v);
|
||||
if (!mrb_obj_is_kind_of(mrb, v, mrb_obj_class(mrb, v))) {
|
||||
return mrb_nil_value();
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
mrb_value
|
||||
mrb_convert_type(mrb_state *mrb, mrb_value val, mrb_int type, const char *tname, const char *method)
|
||||
{
|
||||
mrb_value v;
|
||||
|
||||
if (mrb_type(val) == type) return val;
|
||||
v = convert_type(mrb, val, tname, method, 1/*Qtrue*/);
|
||||
if (mrb_type(v) != type) {
|
||||
mrb_raise(mrb, E_TYPE_ERROR, "%s#%s should return %s",
|
||||
mrb_obj_classname(mrb, val), method, tname);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
mrb_value
|
||||
mrb_check_convert_type(mrb_state *mrb, mrb_value val, mrb_int type, const char *tname, const char *method)
|
||||
{
|
||||
mrb_value v;
|
||||
|
||||
/* always convert T_DATA */
|
||||
if (mrb_type(val) == type && type != MRB_TT_DATA) return val;
|
||||
v = convert_type(mrb, val, tname, method, 0/*Qfalse*/);
|
||||
if (mrb_nil_p(v)) return mrb_nil_value();
|
||||
if (mrb_type(v) != type) {
|
||||
mrb_raise(mrb, E_TYPE_ERROR, "%s#%s should return %s",
|
||||
mrb_obj_classname(mrb, val), method, tname);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
static const struct types {
|
||||
unsigned char type;
|
||||
const char *name;
|
||||
} builtin_types[] = {
|
||||
// {MRB_TT_NIL, "nil"},
|
||||
{MRB_TT_FALSE, "false"},
|
||||
{MRB_TT_TRUE, "true"},
|
||||
{MRB_TT_FIXNUM, "Fixnum"},
|
||||
{MRB_TT_SYMBOL, "Symbol"}, /* :symbol */
|
||||
{MRB_TT_MODULE, "Module"},
|
||||
{MRB_TT_OBJECT, "Object"},
|
||||
{MRB_TT_CLASS, "Class"},
|
||||
{MRB_TT_ICLASS, "iClass"}, /* internal use: mixed-in module holder */
|
||||
{MRB_TT_SCLASS, "SClass"},
|
||||
{MRB_TT_PROC, "Proc"},
|
||||
{MRB_TT_FLOAT, "Float"},
|
||||
{MRB_TT_ARRAY, "Array"},
|
||||
{MRB_TT_HASH, "Hash"},
|
||||
{MRB_TT_STRING, "String"},
|
||||
{MRB_TT_RANGE, "Range"},
|
||||
{MRB_TT_REGEX, "Regexp"},
|
||||
{MRB_TT_STRUCT, "Struct"},
|
||||
// {MRB_TT_BIGNUM, "Bignum"},
|
||||
{MRB_TT_FILE, "File"},
|
||||
{MRB_TT_DATA, "Data"}, /* internal use: wrapped C pointers */
|
||||
{MRB_TT_MATCH, "MatchData"}, /* data of $~ */
|
||||
// {MRB_TT_VARMAP, "Varmap"}, /* internal use: dynamic variables */
|
||||
// {MRB_TT_NODE, "Node"}, /* internal use: syntax tree node */
|
||||
// {MRB_TT_UNDEF, "undef"}, /* internal use: #undef; should not happen */
|
||||
{-1, 0}
|
||||
};
|
||||
|
||||
void
|
||||
mrb_check_type(mrb_state *mrb, mrb_value x, enum mrb_vtype t)
|
||||
{
|
||||
const struct types *type = builtin_types;
|
||||
struct RString *s;
|
||||
int xt;
|
||||
|
||||
/*if (x == Qundef) {
|
||||
//mrb_bug("undef leaked to the Ruby space");
|
||||
printf ("undef leaked to the Ruby space\n");
|
||||
}*/
|
||||
|
||||
xt = mrb_type(x);
|
||||
if ((xt != t) || (xt == MRB_TT_DATA)) {
|
||||
while (type->type < MRB_TT_MAXDEFINE) {
|
||||
if (type->type == t) {
|
||||
const char *etype;
|
||||
|
||||
if (mrb_nil_p(x)) {
|
||||
etype = "nil";
|
||||
}
|
||||
else if (mrb_type(x) == MRB_TT_FIXNUM) {
|
||||
etype = "Fixnum";
|
||||
}
|
||||
else if (mrb_type(x) == MRB_TT_SYMBOL) {
|
||||
etype = "Symbol";
|
||||
}
|
||||
else if (mrb_special_const_p(x)) {
|
||||
s = mrb_str_ptr(mrb_obj_as_string(mrb, x));
|
||||
etype = s->buf;
|
||||
}
|
||||
else {
|
||||
etype = mrb_obj_classname(mrb, x);
|
||||
}
|
||||
mrb_raise(mrb, E_TYPE_ERROR, "wrong argument type %s (expected %s)",
|
||||
etype, type->name);
|
||||
}
|
||||
type++;
|
||||
}
|
||||
/*mrb_bug("unknown type 0x%x", t);*/
|
||||
printf ("unknown type 0x%x (0x%x given)", t, mrb_type(x));
|
||||
}
|
||||
}
|
||||
|
||||
/* 15.3.1.3.46 */
|
||||
/*
|
||||
* call-seq:
|
||||
* obj.to_s => string
|
||||
*
|
||||
* Returns a string representing <i>obj</i>. The default
|
||||
* <code>to_s</code> prints the object's class and an encoding of the
|
||||
* object id. As a special case, the top-level object that is the
|
||||
* initial execution context of Ruby programs returns ``main.''
|
||||
*/
|
||||
|
||||
mrb_value
|
||||
mrb_any_to_s(mrb_state *mrb, mrb_value obj)
|
||||
{
|
||||
const char *cname = mrb_obj_classname(mrb, obj);
|
||||
size_t len;
|
||||
mrb_value str;
|
||||
struct RString *s;
|
||||
|
||||
len = strlen(cname)+6+16;
|
||||
str = mrb_str_new(mrb, 0, len); /* 6:tags 16:addr */
|
||||
s = mrb_str_ptr(str);
|
||||
// snprintf(RSTRING(str)->ptr, len+1, "#<%s:0x%lx>", cname, obj);
|
||||
sprintf(s->buf, "#<%s:0x%lx>", cname, (unsigned long)(obj.value.p));
|
||||
s->len = strlen(s->buf);
|
||||
/*if (OBJ_TAINTED(obj)) OBJ_TAINT(str);*/
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* obj.is_a?(class) => true or false
|
||||
* obj.kind_of?(class) => true or false
|
||||
*
|
||||
* Returns <code>true</code> if <i>class</i> is the class of
|
||||
* <i>obj</i>, or if <i>class</i> is one of the superclasses of
|
||||
* <i>obj</i> or modules included in <i>obj</i>.
|
||||
*
|
||||
* module M; end
|
||||
* class A
|
||||
* include M
|
||||
* end
|
||||
* class B < A; end
|
||||
* class C < B; end
|
||||
* b = B.new
|
||||
* b.instance_of? A #=> false
|
||||
* b.instance_of? B #=> true
|
||||
* b.instance_of? C #=> false
|
||||
* b.instance_of? M #=> false
|
||||
* b.kind_of? A #=> true
|
||||
* b.kind_of? B #=> true
|
||||
* b.kind_of? C #=> false
|
||||
* b.kind_of? M #=> true
|
||||
*/
|
||||
|
||||
int
|
||||
mrb_obj_is_kind_of(mrb_state *mrb, mrb_value obj, struct RClass *c)
|
||||
{
|
||||
struct RClass *cl = mrb_class(mrb, obj);
|
||||
|
||||
switch (c->tt) {
|
||||
case MRB_TT_MODULE:
|
||||
case MRB_TT_CLASS:
|
||||
case MRB_TT_ICLASS:
|
||||
break;
|
||||
|
||||
default:
|
||||
mrb_raise(mrb, E_TYPE_ERROR, "class or module required");
|
||||
}
|
||||
|
||||
while (cl) {
|
||||
if (cl == c || cl->mt == c->mt)
|
||||
return 1/* TRUE */;
|
||||
cl = cl->super;
|
||||
}
|
||||
return 0/* FALSE */;
|
||||
}
|
||||
|
||||
static mrb_value
|
||||
mrb_to_integer(mrb_state *mrb, mrb_value val, const char *method)
|
||||
{
|
||||
mrb_value v;
|
||||
|
||||
if (FIXNUM_P(val)) return val;
|
||||
//if (TYPE(val) == T_BIGNUM) return val;
|
||||
v = convert_type(mrb, val, "Integer", method, TRUE);
|
||||
if (!mrb_obj_is_kind_of(mrb, v, mrb->fixnum_class)) {
|
||||
const char *cname = mrb_obj_classname(mrb, val);
|
||||
mrb_raise(mrb, E_TYPE_ERROR, "can't convert %s to Integer (%s#%s gives %s)",
|
||||
cname, cname, method, mrb_obj_classname(mrb, v));
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
mrb_value
|
||||
mrb_to_int(mrb_state *mrb, mrb_value val)
|
||||
{
|
||||
return mrb_to_integer(mrb, val, "to_int");
|
||||
}
|
||||
|
||||
static mrb_value
|
||||
mrb_convert_to_integer(mrb_state *mrb, mrb_value val, int base)
|
||||
{
|
||||
mrb_value tmp;
|
||||
|
||||
if (mrb_nil_p(val)) {
|
||||
if (base != 0) goto arg_error;
|
||||
mrb_raise(mrb, E_TYPE_ERROR, "can't convert nil into Integer");
|
||||
}
|
||||
switch (mrb_type(val)) {
|
||||
case MRB_TT_FLOAT:
|
||||
if (base != 0) goto arg_error;
|
||||
if (mrb_float(val) <= (double)FIXNUM_MAX
|
||||
&& mrb_float(val) >= (double)FIXNUM_MIN) {
|
||||
break;
|
||||
}
|
||||
return mrb_dbl2big(mrb, mrb_float(val));
|
||||
|
||||
case MRB_TT_FIXNUM:
|
||||
if (base != 0) goto arg_error;
|
||||
return val;
|
||||
|
||||
case MRB_TT_STRING:
|
||||
string_conv:
|
||||
return mrb_str_to_inum(mrb, val, base, TRUE);
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (base != 0) {
|
||||
tmp = mrb_check_string_type(mrb, val);
|
||||
if (!mrb_nil_p(tmp)) goto string_conv;
|
||||
arg_error:
|
||||
mrb_raise(mrb, E_ARGUMENT_ERROR, "base specified for non string value");
|
||||
}
|
||||
tmp = convert_type(mrb, val, "Integer", "to_int", FALSE);
|
||||
if (mrb_nil_p(tmp)) {
|
||||
return mrb_to_integer(mrb, val, "to_i");
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
|
||||
mrb_value
|
||||
mrb_Integer(mrb_state *mrb, mrb_value val)
|
||||
{
|
||||
return mrb_convert_to_integer(mrb, val, 0);
|
||||
}
|
||||
|
||||
mrb_value
|
||||
mrb_Float(mrb_state *mrb, mrb_value val)
|
||||
{
|
||||
if (mrb_nil_p(val)) {
|
||||
mrb_raise(mrb, E_TYPE_ERROR, "can't convert nil into Float");
|
||||
}
|
||||
switch (mrb_type(val)) {
|
||||
case MRB_TT_FIXNUM:
|
||||
return mrb_float_value((mrb_float)mrb_fixnum(val));
|
||||
|
||||
case MRB_TT_FLOAT:
|
||||
return val;
|
||||
|
||||
case MRB_TT_STRING:
|
||||
return mrb_float_value(mrb_str_to_dbl(mrb, val, TRUE));
|
||||
|
||||
default:
|
||||
return mrb_convert_type(mrb, val, MRB_TT_FLOAT, "Float", "to_f");
|
||||
}
|
||||
}
|
||||
|
||||
mrb_value
|
||||
mrb_inspect(mrb_state *mrb, mrb_value obj)
|
||||
{
|
||||
return mrb_obj_as_string(mrb, mrb_funcall(mrb, obj, "inspect", 0, 0));
|
||||
}
|
||||
|
||||
int
|
||||
mrb_eql(mrb_state *mrb, mrb_value obj1, mrb_value obj2)
|
||||
{
|
||||
return RTEST(mrb_funcall(mrb, obj1, "eql?", 1, obj2));
|
||||
}
|
||||
|
||||
+771
@@ -0,0 +1,771 @@
|
||||
#ifndef ONIGURUMA_H
|
||||
#define ONIGURUMA_H
|
||||
/**********************************************************************
|
||||
oniguruma.h - Oniguruma (regular expression library)
|
||||
**********************************************************************/
|
||||
/*-
|
||||
* Copyright (c) 2002-2008 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define ONIGURUMA
|
||||
#define ONIGURUMA_VERSION_MAJOR 5
|
||||
#define ONIGURUMA_VERSION_MINOR 9
|
||||
#define ONIGURUMA_VERSION_TEENY 2
|
||||
|
||||
#ifdef __cplusplus
|
||||
# ifndef HAVE_PROTOTYPES
|
||||
# define HAVE_PROTOTYPES 1
|
||||
# endif
|
||||
# ifndef HAVE_STDARG_PROTOTYPES
|
||||
# define HAVE_STDARG_PROTOTYPES 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* escape Mac OS X/Xcode 2.4/gcc 4.0.1 problem */
|
||||
#if defined(__APPLE__) && defined(__GNUC__) && __GNUC__ >= 4
|
||||
# ifndef HAVE_STDARG_PROTOTYPES
|
||||
# define HAVE_STDARG_PROTOTYPES 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef ONIG_EXTERN
|
||||
#ifdef RUBY_EXTERN
|
||||
#define ONIG_EXTERN RUBY_EXTERN
|
||||
#else
|
||||
#if defined(_WIN32) && !defined(__GNUC__)
|
||||
#if defined(EXPORT) || defined(RUBY_EXPORT)
|
||||
#define ONIG_EXTERN extern __declspec(dllexport)
|
||||
#else
|
||||
#define ONIG_EXTERN extern __declspec(dllimport)
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef ONIG_EXTERN
|
||||
#define ONIG_EXTERN extern
|
||||
#endif
|
||||
|
||||
/* PART: character encoding */
|
||||
|
||||
#ifndef ONIG_ESCAPE_UCHAR_COLLISION
|
||||
#define UChar OnigUChar
|
||||
#endif
|
||||
|
||||
typedef unsigned char OnigUChar;
|
||||
typedef unsigned int OnigCodePoint;
|
||||
typedef unsigned int OnigCtype;
|
||||
typedef size_t OnigDistance;
|
||||
|
||||
#define ONIG_INFINITE_DISTANCE ~((OnigDistance )0)
|
||||
|
||||
typedef unsigned int OnigCaseFoldType; /* case fold flag */
|
||||
|
||||
ONIG_EXTERN OnigCaseFoldType OnigDefaultCaseFoldFlag;
|
||||
|
||||
/* #define ONIGENC_CASE_FOLD_HIRAGANA_KATAKANA (1<<1) */
|
||||
/* #define ONIGENC_CASE_FOLD_KATAKANA_WIDTH (1<<2) */
|
||||
#define ONIGENC_CASE_FOLD_TURKISH_AZERI (1<<20)
|
||||
#define INTERNAL_ONIGENC_CASE_FOLD_MULTI_CHAR (1<<30)
|
||||
|
||||
#define ONIGENC_CASE_FOLD_MIN INTERNAL_ONIGENC_CASE_FOLD_MULTI_CHAR
|
||||
#define ONIGENC_CASE_FOLD_DEFAULT OnigDefaultCaseFoldFlag
|
||||
|
||||
|
||||
#define ONIGENC_MAX_COMP_CASE_FOLD_CODE_LEN 3
|
||||
#define ONIGENC_GET_CASE_FOLD_CODES_MAX_NUM 13
|
||||
/* 13 => Unicode:0x1ffc */
|
||||
|
||||
/* code range */
|
||||
#define ONIGENC_CODE_RANGE_NUM(range) ((int )range[0])
|
||||
#define ONIGENC_CODE_RANGE_FROM(range,i) range[((i)*2) + 1]
|
||||
#define ONIGENC_CODE_RANGE_TO(range,i) range[((i)*2) + 2]
|
||||
|
||||
typedef struct {
|
||||
int byte_len; /* argument(original) character(s) byte length */
|
||||
int code_len; /* number of code */
|
||||
OnigCodePoint code[ONIGENC_MAX_COMP_CASE_FOLD_CODE_LEN];
|
||||
} OnigCaseFoldCodeItem;
|
||||
|
||||
typedef struct {
|
||||
OnigCodePoint esc;
|
||||
OnigCodePoint anychar;
|
||||
OnigCodePoint anytime;
|
||||
OnigCodePoint zero_or_one_time;
|
||||
OnigCodePoint one_or_more_time;
|
||||
OnigCodePoint anychar_anytime;
|
||||
} OnigMetaCharTableType;
|
||||
|
||||
typedef int (*OnigApplyAllCaseFoldFunc)(OnigCodePoint from, OnigCodePoint* to, int to_len, void* arg);
|
||||
|
||||
typedef struct OnigEncodingTypeST {
|
||||
int (*precise_mbc_enc_len)(const OnigUChar* p,const OnigUChar* e, struct OnigEncodingTypeST* enc);
|
||||
const char* name;
|
||||
int max_enc_len;
|
||||
int min_enc_len;
|
||||
int (*is_mbc_newline)(const OnigUChar* p, const OnigUChar* end, struct OnigEncodingTypeST* enc);
|
||||
OnigCodePoint (*mbc_to_code)(const OnigUChar* p, const OnigUChar* end, struct OnigEncodingTypeST* enc);
|
||||
int (*code_to_mbclen)(OnigCodePoint code, struct OnigEncodingTypeST* enc);
|
||||
int (*code_to_mbc)(OnigCodePoint code, OnigUChar *buf, struct OnigEncodingTypeST* enc);
|
||||
int (*mbc_case_fold)(OnigCaseFoldType flag, const OnigUChar** pp, const OnigUChar* end, OnigUChar* to, struct OnigEncodingTypeST* enc);
|
||||
int (*apply_all_case_fold)(OnigCaseFoldType flag, OnigApplyAllCaseFoldFunc f, void* arg, struct OnigEncodingTypeST* enc);
|
||||
int (*get_case_fold_codes_by_str)(OnigCaseFoldType flag, const OnigUChar* p, const OnigUChar* end, OnigCaseFoldCodeItem acs[], struct OnigEncodingTypeST* enc);
|
||||
int (*property_name_to_ctype)(struct OnigEncodingTypeST* enc, OnigUChar* p, OnigUChar* end);
|
||||
int (*is_code_ctype)(OnigCodePoint code, OnigCtype ctype, struct OnigEncodingTypeST* enc);
|
||||
int (*get_ctype_code_range)(OnigCtype ctype, OnigCodePoint* sb_out, const OnigCodePoint* ranges[], struct OnigEncodingTypeST* enc);
|
||||
OnigUChar* (*left_adjust_char_head)(const OnigUChar* start, const OnigUChar* p, const OnigUChar* end, struct OnigEncodingTypeST* enc);
|
||||
int (*is_allowed_reverse_match)(const OnigUChar* p, const OnigUChar* end, struct OnigEncodingTypeST* enc);
|
||||
int ruby_encoding_index;
|
||||
} OnigEncodingType;
|
||||
|
||||
typedef OnigEncodingType* OnigEncoding;
|
||||
|
||||
ONIG_EXTERN OnigEncodingType OnigEncodingASCII;
|
||||
|
||||
#define ONIG_ENCODING_ASCII (&OnigEncodingASCII)
|
||||
|
||||
#define ONIG_ENCODING_UNDEF ((OnigEncoding )0)
|
||||
|
||||
|
||||
/* work size */
|
||||
#define ONIGENC_CODE_TO_MBC_MAXLEN 7
|
||||
#define ONIGENC_MBC_CASE_FOLD_MAXLEN 18
|
||||
/* 18: 6(max-byte) * 3(case-fold chars) */
|
||||
|
||||
/* character types */
|
||||
#define ONIGENC_CTYPE_NEWLINE 0
|
||||
#define ONIGENC_CTYPE_ALPHA 1
|
||||
#define ONIGENC_CTYPE_BLANK 2
|
||||
#define ONIGENC_CTYPE_CNTRL 3
|
||||
#define ONIGENC_CTYPE_DIGIT 4
|
||||
#define ONIGENC_CTYPE_GRAPH 5
|
||||
#define ONIGENC_CTYPE_LOWER 6
|
||||
#define ONIGENC_CTYPE_PRINT 7
|
||||
#define ONIGENC_CTYPE_PUNCT 8
|
||||
#define ONIGENC_CTYPE_SPACE 9
|
||||
#define ONIGENC_CTYPE_UPPER 10
|
||||
#define ONIGENC_CTYPE_XDIGIT 11
|
||||
#define ONIGENC_CTYPE_WORD 12
|
||||
#define ONIGENC_CTYPE_ALNUM 13 /* alpha || digit */
|
||||
#define ONIGENC_CTYPE_ASCII 14
|
||||
#define ONIGENC_MAX_STD_CTYPE ONIGENC_CTYPE_ASCII
|
||||
#define ONIGENC_CTYPE_SPECIAL_MASK 128
|
||||
#define ONIGENC_CTYPE_S /* [\t\n\v\f\r\s] */ \
|
||||
ONIGENC_CTYPE_SPECIAL_MASK | ONIGENC_CTYPE_SPACE
|
||||
#define ONIGENC_CTYPE_D /* [0-9] */ \
|
||||
ONIGENC_CTYPE_SPECIAL_MASK | ONIGENC_CTYPE_DIGIT
|
||||
#define ONIGENC_CTYPE_W /* [0-9A-Za-z_] */ \
|
||||
ONIGENC_CTYPE_SPECIAL_MASK | ONIGENC_CTYPE_WORD
|
||||
#define ONIGENC_CTYPE_SPECIAL_P(ctype) ((ctype) & ONIGENC_CTYPE_SPECIAL_MASK)
|
||||
|
||||
|
||||
#define onig_enc_len(enc,p,e) ONIGENC_MBC_ENC_LEN(enc, p, e)
|
||||
|
||||
#define ONIGENC_IS_UNDEF(enc) ((enc) == ONIG_ENCODING_UNDEF)
|
||||
#define ONIGENC_IS_SINGLEBYTE(enc) (ONIGENC_MBC_MAXLEN(enc) == 1)
|
||||
#define ONIGENC_IS_MBC_HEAD(enc,p,e) (ONIGENC_MBC_ENC_LEN(enc,p,e) != 1)
|
||||
#define ONIGENC_IS_MBC_ASCII(p) (*(p) < 128)
|
||||
#define ONIGENC_IS_CODE_ASCII(code) ((code) < 128)
|
||||
#define ONIGENC_IS_MBC_WORD(enc,s,end) \
|
||||
ONIGENC_IS_CODE_WORD(enc,ONIGENC_MBC_TO_CODE(enc,s,end))
|
||||
|
||||
|
||||
#define ONIGENC_NAME(enc) ((enc)->name)
|
||||
|
||||
#define ONIGENC_MBC_CASE_FOLD(enc,flag,pp,end,buf) \
|
||||
(enc)->mbc_case_fold(flag,(const OnigUChar** )pp,end,buf,enc)
|
||||
#define ONIGENC_IS_ALLOWED_REVERSE_MATCH(enc,s,end) \
|
||||
(enc)->is_allowed_reverse_match(s,end,enc)
|
||||
#define ONIGENC_LEFT_ADJUST_CHAR_HEAD(enc,start,s,end) \
|
||||
(enc)->left_adjust_char_head(start, s, end, enc)
|
||||
#define ONIGENC_APPLY_ALL_CASE_FOLD(enc,case_fold_flag,f,arg) \
|
||||
(enc)->apply_all_case_fold(case_fold_flag,f,arg,enc)
|
||||
#define ONIGENC_GET_CASE_FOLD_CODES_BY_STR(enc,case_fold_flag,p,end,acs) \
|
||||
(enc)->get_case_fold_codes_by_str(case_fold_flag,p,end,acs,enc)
|
||||
#define ONIGENC_STEP_BACK(enc,start,s,end,n) \
|
||||
onigenc_step_back((enc),(start),(s),(end),(n))
|
||||
|
||||
#define ONIGENC_CONSTRUCT_MBCLEN_CHARFOUND(n) (n)
|
||||
#define ONIGENC_MBCLEN_CHARFOUND_P(r) (0 < (r))
|
||||
#define ONIGENC_MBCLEN_CHARFOUND_LEN(r) (r)
|
||||
|
||||
#define ONIGENC_CONSTRUCT_MBCLEN_INVALID() (-1)
|
||||
#define ONIGENC_MBCLEN_INVALID_P(r) ((r) == -1)
|
||||
|
||||
#define ONIGENC_CONSTRUCT_MBCLEN_NEEDMORE(n) (-1-(n))
|
||||
#define ONIGENC_MBCLEN_NEEDMORE_P(r) ((r) < -1)
|
||||
#define ONIGENC_MBCLEN_NEEDMORE_LEN(r) (-1-(r))
|
||||
|
||||
#define ONIGENC_PRECISE_MBC_ENC_LEN(enc,p,e) (enc)->precise_mbc_enc_len(p,e,enc)
|
||||
|
||||
ONIG_EXTERN
|
||||
int onigenc_mbclen_approximate(const OnigUChar* p,const OnigUChar* e, struct OnigEncodingTypeST* enc);
|
||||
|
||||
#define ONIGENC_MBC_ENC_LEN(enc,p,e) onigenc_mbclen_approximate(p,e,enc)
|
||||
#define ONIGENC_MBC_MAXLEN(enc) ((enc)->max_enc_len)
|
||||
#define ONIGENC_MBC_MAXLEN_DIST(enc) ONIGENC_MBC_MAXLEN(enc)
|
||||
#define ONIGENC_MBC_MINLEN(enc) ((enc)->min_enc_len)
|
||||
#define ONIGENC_IS_MBC_NEWLINE(enc,p,end) (enc)->is_mbc_newline((p),(end),enc)
|
||||
#define ONIGENC_MBC_TO_CODE(enc,p,end) (enc)->mbc_to_code((p),(end),enc)
|
||||
#define ONIGENC_CODE_TO_MBCLEN(enc,code) (enc)->code_to_mbclen(code,enc)
|
||||
#define ONIGENC_CODE_TO_MBC(enc,code,buf) (enc)->code_to_mbc(code,buf,enc)
|
||||
#define ONIGENC_PROPERTY_NAME_TO_CTYPE(enc,p,end) \
|
||||
(enc)->property_name_to_ctype(enc,p,end)
|
||||
|
||||
#define ONIGENC_IS_CODE_CTYPE(enc,code,ctype) (enc)->is_code_ctype(code,ctype,enc)
|
||||
|
||||
#define ONIGENC_IS_CODE_NEWLINE(enc,code) \
|
||||
ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_NEWLINE)
|
||||
#define ONIGENC_IS_CODE_GRAPH(enc,code) \
|
||||
ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_GRAPH)
|
||||
#define ONIGENC_IS_CODE_PRINT(enc,code) \
|
||||
ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_PRINT)
|
||||
#define ONIGENC_IS_CODE_ALNUM(enc,code) \
|
||||
ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_ALNUM)
|
||||
#define ONIGENC_IS_CODE_ALPHA(enc,code) \
|
||||
ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_ALPHA)
|
||||
#define ONIGENC_IS_CODE_LOWER(enc,code) \
|
||||
ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_LOWER)
|
||||
#define ONIGENC_IS_CODE_UPPER(enc,code) \
|
||||
ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_UPPER)
|
||||
#define ONIGENC_IS_CODE_CNTRL(enc,code) \
|
||||
ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_CNTRL)
|
||||
#define ONIGENC_IS_CODE_PUNCT(enc,code) \
|
||||
ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_PUNCT)
|
||||
#define ONIGENC_IS_CODE_SPACE(enc,code) \
|
||||
ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_SPACE)
|
||||
#define ONIGENC_IS_CODE_BLANK(enc,code) \
|
||||
ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_BLANK)
|
||||
#define ONIGENC_IS_CODE_DIGIT(enc,code) \
|
||||
ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_DIGIT)
|
||||
#define ONIGENC_IS_CODE_XDIGIT(enc,code) \
|
||||
ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_XDIGIT)
|
||||
#define ONIGENC_IS_CODE_WORD(enc,code) \
|
||||
ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_WORD)
|
||||
|
||||
#define ONIGENC_GET_CTYPE_CODE_RANGE(enc,ctype,sbout,ranges) \
|
||||
(enc)->get_ctype_code_range(ctype,sbout,ranges,enc)
|
||||
|
||||
ONIG_EXTERN
|
||||
OnigUChar* onigenc_step_back(OnigEncoding enc, const OnigUChar* start, const OnigUChar* s, const OnigUChar* end, int n);
|
||||
|
||||
|
||||
/* encoding API */
|
||||
ONIG_EXTERN
|
||||
int onigenc_init(void);
|
||||
ONIG_EXTERN
|
||||
int onigenc_set_default_encoding(OnigEncoding enc);
|
||||
ONIG_EXTERN
|
||||
OnigEncoding onigenc_get_default_encoding(void);
|
||||
ONIG_EXTERN
|
||||
void onigenc_set_default_caseconv_table(const OnigUChar* table);
|
||||
ONIG_EXTERN
|
||||
OnigUChar* onigenc_get_right_adjust_char_head_with_prev(OnigEncoding enc, const OnigUChar* start, const OnigUChar* s, const OnigUChar* end, const OnigUChar** prev);
|
||||
ONIG_EXTERN
|
||||
OnigUChar* onigenc_get_prev_char_head(OnigEncoding enc, const OnigUChar* start, const OnigUChar* s, const OnigUChar* end);
|
||||
ONIG_EXTERN
|
||||
OnigUChar* onigenc_get_left_adjust_char_head(OnigEncoding enc, const OnigUChar* start, const OnigUChar* s, const OnigUChar* end);
|
||||
ONIG_EXTERN
|
||||
OnigUChar* onigenc_get_right_adjust_char_head(OnigEncoding enc, const OnigUChar* start, const OnigUChar* s, const OnigUChar* end);
|
||||
ONIG_EXTERN
|
||||
int onigenc_strlen(OnigEncoding enc, const OnigUChar* p, const OnigUChar* end);
|
||||
ONIG_EXTERN
|
||||
int onigenc_strlen_null(OnigEncoding enc, const OnigUChar* p);
|
||||
ONIG_EXTERN
|
||||
int onigenc_str_bytelen_null(OnigEncoding enc, const OnigUChar* p);
|
||||
|
||||
|
||||
|
||||
/* PART: regular expression */
|
||||
|
||||
/* config parameters */
|
||||
#define ONIG_NREGION 10
|
||||
#define ONIG_MAX_BACKREF_NUM 1000
|
||||
#define ONIG_MAX_REPEAT_NUM 100000
|
||||
#define ONIG_MAX_MULTI_BYTE_RANGES_NUM 10000
|
||||
/* constants */
|
||||
#define ONIG_MAX_ERROR_MESSAGE_LEN 90
|
||||
|
||||
typedef unsigned int OnigOptionType;
|
||||
|
||||
#define ONIG_OPTION_DEFAULT ONIG_OPTION_NONE
|
||||
|
||||
/* options */
|
||||
#define ONIG_OPTION_NONE 0U
|
||||
#define ONIG_OPTION_IGNORECASE 1U
|
||||
#define ONIG_OPTION_EXTEND (ONIG_OPTION_IGNORECASE << 1)
|
||||
#define ONIG_OPTION_MULTILINE (ONIG_OPTION_EXTEND << 1)
|
||||
#define ONIG_OPTION_SINGLELINE (ONIG_OPTION_MULTILINE << 1)
|
||||
#define ONIG_OPTION_FIND_LONGEST (ONIG_OPTION_SINGLELINE << 1)
|
||||
#define ONIG_OPTION_FIND_NOT_EMPTY (ONIG_OPTION_FIND_LONGEST << 1)
|
||||
#define ONIG_OPTION_NEGATE_SINGLELINE (ONIG_OPTION_FIND_NOT_EMPTY << 1)
|
||||
#define ONIG_OPTION_DONT_CAPTURE_GROUP (ONIG_OPTION_NEGATE_SINGLELINE << 1)
|
||||
#define ONIG_OPTION_CAPTURE_GROUP (ONIG_OPTION_DONT_CAPTURE_GROUP << 1)
|
||||
/* options (search time) */
|
||||
#define ONIG_OPTION_NOTBOL (ONIG_OPTION_CAPTURE_GROUP << 1)
|
||||
#define ONIG_OPTION_NOTEOL (ONIG_OPTION_NOTBOL << 1)
|
||||
#define ONIG_OPTION_POSIX_REGION (ONIG_OPTION_NOTEOL << 1)
|
||||
#define ONIG_OPTION_MAXBIT ONIG_OPTION_POSIX_REGION /* limit */
|
||||
|
||||
#define ONIG_OPTION_ON(options,regopt) ((options) |= (regopt))
|
||||
#define ONIG_OPTION_OFF(options,regopt) ((options) &= ~(regopt))
|
||||
#define ONIG_IS_OPTION_ON(options,option) ((options) & (option))
|
||||
|
||||
/* syntax */
|
||||
typedef struct {
|
||||
unsigned int op;
|
||||
unsigned int op2;
|
||||
unsigned int behavior;
|
||||
OnigOptionType options; /* default option */
|
||||
OnigMetaCharTableType meta_char_table;
|
||||
} OnigSyntaxType;
|
||||
|
||||
ONIG_EXTERN const OnigSyntaxType OnigSyntaxASIS;
|
||||
ONIG_EXTERN const OnigSyntaxType OnigSyntaxPosixBasic;
|
||||
ONIG_EXTERN const OnigSyntaxType OnigSyntaxPosixExtended;
|
||||
ONIG_EXTERN const OnigSyntaxType OnigSyntaxEmacs;
|
||||
ONIG_EXTERN const OnigSyntaxType OnigSyntaxGrep;
|
||||
ONIG_EXTERN const OnigSyntaxType OnigSyntaxGnuRegex;
|
||||
ONIG_EXTERN const OnigSyntaxType OnigSyntaxJava;
|
||||
ONIG_EXTERN const OnigSyntaxType OnigSyntaxPerl;
|
||||
ONIG_EXTERN const OnigSyntaxType OnigSyntaxPerl_NG;
|
||||
ONIG_EXTERN const OnigSyntaxType OnigSyntaxRuby;
|
||||
|
||||
/* predefined syntaxes (see regsyntax.c) */
|
||||
#define ONIG_SYNTAX_ASIS (&OnigSyntaxASIS)
|
||||
#define ONIG_SYNTAX_POSIX_BASIC (&OnigSyntaxPosixBasic)
|
||||
#define ONIG_SYNTAX_POSIX_EXTENDED (&OnigSyntaxPosixExtended)
|
||||
#define ONIG_SYNTAX_EMACS (&OnigSyntaxEmacs)
|
||||
#define ONIG_SYNTAX_GREP (&OnigSyntaxGrep)
|
||||
#define ONIG_SYNTAX_GNU_REGEX (&OnigSyntaxGnuRegex)
|
||||
#define ONIG_SYNTAX_JAVA (&OnigSyntaxJava)
|
||||
#define ONIG_SYNTAX_PERL (&OnigSyntaxPerl)
|
||||
#define ONIG_SYNTAX_PERL_NG (&OnigSyntaxPerl_NG)
|
||||
#define ONIG_SYNTAX_RUBY (&OnigSyntaxRuby)
|
||||
|
||||
/* default syntax */
|
||||
ONIG_EXTERN const OnigSyntaxType* OnigDefaultSyntax;
|
||||
#define ONIG_SYNTAX_DEFAULT OnigDefaultSyntax
|
||||
|
||||
/* syntax (operators) */
|
||||
#define ONIG_SYN_OP_VARIABLE_META_CHARACTERS (1U<<0)
|
||||
#define ONIG_SYN_OP_DOT_ANYCHAR (1U<<1) /* . */
|
||||
#define ONIG_SYN_OP_ASTERISK_ZERO_INF (1U<<2) /* * */
|
||||
#define ONIG_SYN_OP_ESC_ASTERISK_ZERO_INF (1U<<3)
|
||||
#define ONIG_SYN_OP_PLUS_ONE_INF (1U<<4) /* + */
|
||||
#define ONIG_SYN_OP_ESC_PLUS_ONE_INF (1U<<5)
|
||||
#define ONIG_SYN_OP_QMARK_ZERO_ONE (1U<<6) /* ? */
|
||||
#define ONIG_SYN_OP_ESC_QMARK_ZERO_ONE (1U<<7)
|
||||
#define ONIG_SYN_OP_BRACE_INTERVAL (1U<<8) /* {lower,upper} */
|
||||
#define ONIG_SYN_OP_ESC_BRACE_INTERVAL (1U<<9) /* \{lower,upper\} */
|
||||
#define ONIG_SYN_OP_VBAR_ALT (1U<<10) /* | */
|
||||
#define ONIG_SYN_OP_ESC_VBAR_ALT (1U<<11) /* \| */
|
||||
#define ONIG_SYN_OP_LPAREN_SUBEXP (1U<<12) /* (...) */
|
||||
#define ONIG_SYN_OP_ESC_LPAREN_SUBEXP (1U<<13) /* \(...\) */
|
||||
#define ONIG_SYN_OP_ESC_AZ_BUF_ANCHOR (1U<<14) /* \A, \Z, \z */
|
||||
#define ONIG_SYN_OP_ESC_CAPITAL_G_BEGIN_ANCHOR (1U<<15) /* \G */
|
||||
#define ONIG_SYN_OP_DECIMAL_BACKREF (1U<<16) /* \num */
|
||||
#define ONIG_SYN_OP_BRACKET_CC (1U<<17) /* [...] */
|
||||
#define ONIG_SYN_OP_ESC_W_WORD (1U<<18) /* \w, \W */
|
||||
#define ONIG_SYN_OP_ESC_LTGT_WORD_BEGIN_END (1U<<19) /* \<. \> */
|
||||
#define ONIG_SYN_OP_ESC_B_WORD_BOUND (1U<<20) /* \b, \B */
|
||||
#define ONIG_SYN_OP_ESC_S_WHITE_SPACE (1U<<21) /* \s, \S */
|
||||
#define ONIG_SYN_OP_ESC_D_DIGIT (1U<<22) /* \d, \D */
|
||||
#define ONIG_SYN_OP_LINE_ANCHOR (1U<<23) /* ^, $ */
|
||||
#define ONIG_SYN_OP_POSIX_BRACKET (1U<<24) /* [:xxxx:] */
|
||||
#define ONIG_SYN_OP_QMARK_NON_GREEDY (1U<<25) /* ??,*?,+?,{n,m}? */
|
||||
#define ONIG_SYN_OP_ESC_CONTROL_CHARS (1U<<26) /* \n,\r,\t,\a ... */
|
||||
#define ONIG_SYN_OP_ESC_C_CONTROL (1U<<27) /* \cx */
|
||||
#define ONIG_SYN_OP_ESC_OCTAL3 (1U<<28) /* \OOO */
|
||||
#define ONIG_SYN_OP_ESC_X_HEX2 (1U<<29) /* \xHH */
|
||||
#define ONIG_SYN_OP_ESC_X_BRACE_HEX8 (1U<<30) /* \x{7HHHHHHH} */
|
||||
|
||||
#define ONIG_SYN_OP2_ESC_CAPITAL_Q_QUOTE (1U<<0) /* \Q...\E */
|
||||
#define ONIG_SYN_OP2_QMARK_GROUP_EFFECT (1U<<1) /* (?...) */
|
||||
#define ONIG_SYN_OP2_OPTION_PERL (1U<<2) /* (?imsx),(?-imsx) */
|
||||
#define ONIG_SYN_OP2_OPTION_RUBY (1U<<3) /* (?imx), (?-imx) */
|
||||
#define ONIG_SYN_OP2_PLUS_POSSESSIVE_REPEAT (1U<<4) /* ?+,*+,++ */
|
||||
#define ONIG_SYN_OP2_PLUS_POSSESSIVE_INTERVAL (1U<<5) /* {n,m}+ */
|
||||
#define ONIG_SYN_OP2_CCLASS_SET_OP (1U<<6) /* [...&&..[..]..] */
|
||||
#define ONIG_SYN_OP2_QMARK_LT_NAMED_GROUP (1U<<7) /* (?<name>...) */
|
||||
#define ONIG_SYN_OP2_ESC_K_NAMED_BACKREF (1U<<8) /* \k<name> */
|
||||
#define ONIG_SYN_OP2_ESC_G_SUBEXP_CALL (1U<<9) /* \g<name>, \g<n> */
|
||||
#define ONIG_SYN_OP2_ATMARK_CAPTURE_HISTORY (1U<<10) /* (?@..),(?@<x>..) */
|
||||
#define ONIG_SYN_OP2_ESC_CAPITAL_C_BAR_CONTROL (1U<<11) /* \C-x */
|
||||
#define ONIG_SYN_OP2_ESC_CAPITAL_M_BAR_META (1U<<12) /* \M-x */
|
||||
#define ONIG_SYN_OP2_ESC_V_VTAB (1U<<13) /* \v as VTAB */
|
||||
#define ONIG_SYN_OP2_ESC_U_HEX4 (1U<<14) /* \uHHHH */
|
||||
#define ONIG_SYN_OP2_ESC_GNU_BUF_ANCHOR (1U<<15) /* \`, \' */
|
||||
#define ONIG_SYN_OP2_ESC_P_BRACE_CHAR_PROPERTY (1U<<16) /* \p{...}, \P{...} */
|
||||
#define ONIG_SYN_OP2_ESC_P_BRACE_CIRCUMFLEX_NOT (1U<<17) /* \p{^..}, \P{^..} */
|
||||
/* #define ONIG_SYN_OP2_CHAR_PROPERTY_PREFIX_IS (1U<<18) */
|
||||
#define ONIG_SYN_OP2_ESC_H_XDIGIT (1U<<19) /* \h, \H */
|
||||
#define ONIG_SYN_OP2_INEFFECTIVE_ESCAPE (1U<<20) /* \ */
|
||||
|
||||
/* syntax (behavior) */
|
||||
#define ONIG_SYN_CONTEXT_INDEP_ANCHORS (1U<<31) /* not implemented */
|
||||
#define ONIG_SYN_CONTEXT_INDEP_REPEAT_OPS (1U<<0) /* ?, *, +, {n,m} */
|
||||
#define ONIG_SYN_CONTEXT_INVALID_REPEAT_OPS (1U<<1) /* error or ignore */
|
||||
#define ONIG_SYN_ALLOW_UNMATCHED_CLOSE_SUBEXP (1U<<2) /* ...)... */
|
||||
#define ONIG_SYN_ALLOW_INVALID_INTERVAL (1U<<3) /* {??? */
|
||||
#define ONIG_SYN_ALLOW_INTERVAL_LOW_ABBREV (1U<<4) /* {,n} => {0,n} */
|
||||
#define ONIG_SYN_STRICT_CHECK_BACKREF (1U<<5) /* /(\1)/,/\1()/ ..*/
|
||||
#define ONIG_SYN_DIFFERENT_LEN_ALT_LOOK_BEHIND (1U<<6) /* (?<=a|bc) */
|
||||
#define ONIG_SYN_CAPTURE_ONLY_NAMED_GROUP (1U<<7) /* see doc/RE */
|
||||
#define ONIG_SYN_ALLOW_MULTIPLEX_DEFINITION_NAME (1U<<8) /* (?<x>)(?<x>) */
|
||||
#define ONIG_SYN_FIXED_INTERVAL_IS_GREEDY_ONLY (1U<<9) /* a{n}?=(?:a{n})? */
|
||||
|
||||
/* syntax (behavior) in char class [...] */
|
||||
#define ONIG_SYN_NOT_NEWLINE_IN_NEGATIVE_CC (1U<<20) /* [^...] */
|
||||
#define ONIG_SYN_BACKSLASH_ESCAPE_IN_CC (1U<<21) /* [..\w..] etc.. */
|
||||
#define ONIG_SYN_ALLOW_EMPTY_RANGE_IN_CC (1U<<22)
|
||||
#define ONIG_SYN_ALLOW_DOUBLE_RANGE_OP_IN_CC (1U<<23) /* [0-9-a]=[0-9\-a] */
|
||||
/* syntax (behavior) warning */
|
||||
#define ONIG_SYN_WARN_CC_OP_NOT_ESCAPED (1U<<24) /* [,-,] */
|
||||
#define ONIG_SYN_WARN_REDUNDANT_NESTED_REPEAT (1U<<25) /* (?:a*)+ */
|
||||
#define ONIG_SYN_WARN_CC_DUP (1U<<26) /* [aa] */
|
||||
|
||||
/* meta character specifiers (onig_set_meta_char()) */
|
||||
#define ONIG_META_CHAR_ESCAPE 0
|
||||
#define ONIG_META_CHAR_ANYCHAR 1
|
||||
#define ONIG_META_CHAR_ANYTIME 2
|
||||
#define ONIG_META_CHAR_ZERO_OR_ONE_TIME 3
|
||||
#define ONIG_META_CHAR_ONE_OR_MORE_TIME 4
|
||||
#define ONIG_META_CHAR_ANYCHAR_ANYTIME 5
|
||||
|
||||
#define ONIG_INEFFECTIVE_META_CHAR 0
|
||||
|
||||
/* error codes */
|
||||
#define ONIG_IS_PATTERN_ERROR(ecode) ((ecode) <= -100 && (ecode) > -1000)
|
||||
/* normal return */
|
||||
#define ONIG_NORMAL 0
|
||||
#define ONIG_MISMATCH -1
|
||||
#define ONIG_NO_SUPPORT_CONFIG -2
|
||||
|
||||
/* internal error */
|
||||
#define ONIGERR_MEMORY -5
|
||||
#define ONIGERR_TYPE_BUG -6
|
||||
#define ONIGERR_PARSER_BUG -11
|
||||
#define ONIGERR_STACK_BUG -12
|
||||
#define ONIGERR_UNDEFINED_BYTECODE -13
|
||||
#define ONIGERR_UNEXPECTED_BYTECODE -14
|
||||
#define ONIGERR_MATCH_STACK_LIMIT_OVER -15
|
||||
#define ONIGERR_DEFAULT_ENCODING_IS_NOT_SETTED -21
|
||||
#define ONIGERR_SPECIFIED_ENCODING_CANT_CONVERT_TO_WIDE_CHAR -22
|
||||
/* general error */
|
||||
#define ONIGERR_INVALID_ARGUMENT -30
|
||||
/* syntax error */
|
||||
#define ONIGERR_END_PATTERN_AT_LEFT_BRACE -100
|
||||
#define ONIGERR_END_PATTERN_AT_LEFT_BRACKET -101
|
||||
#define ONIGERR_EMPTY_CHAR_CLASS -102
|
||||
#define ONIGERR_PREMATURE_END_OF_CHAR_CLASS -103
|
||||
#define ONIGERR_END_PATTERN_AT_ESCAPE -104
|
||||
#define ONIGERR_END_PATTERN_AT_META -105
|
||||
#define ONIGERR_END_PATTERN_AT_CONTROL -106
|
||||
#define ONIGERR_META_CODE_SYNTAX -108
|
||||
#define ONIGERR_CONTROL_CODE_SYNTAX -109
|
||||
#define ONIGERR_CHAR_CLASS_VALUE_AT_END_OF_RANGE -110
|
||||
#define ONIGERR_CHAR_CLASS_VALUE_AT_START_OF_RANGE -111
|
||||
#define ONIGERR_UNMATCHED_RANGE_SPECIFIER_IN_CHAR_CLASS -112
|
||||
#define ONIGERR_TARGET_OF_REPEAT_OPERATOR_NOT_SPECIFIED -113
|
||||
#define ONIGERR_TARGET_OF_REPEAT_OPERATOR_INVALID -114
|
||||
#define ONIGERR_NESTED_REPEAT_OPERATOR -115
|
||||
#define ONIGERR_UNMATCHED_CLOSE_PARENTHESIS -116
|
||||
#define ONIGERR_END_PATTERN_WITH_UNMATCHED_PARENTHESIS -117
|
||||
#define ONIGERR_END_PATTERN_IN_GROUP -118
|
||||
#define ONIGERR_UNDEFINED_GROUP_OPTION -119
|
||||
#define ONIGERR_INVALID_POSIX_BRACKET_TYPE -121
|
||||
#define ONIGERR_INVALID_LOOK_BEHIND_PATTERN -122
|
||||
#define ONIGERR_INVALID_REPEAT_RANGE_PATTERN -123
|
||||
/* values error (syntax error) */
|
||||
#define ONIGERR_TOO_BIG_NUMBER -200
|
||||
#define ONIGERR_TOO_BIG_NUMBER_FOR_REPEAT_RANGE -201
|
||||
#define ONIGERR_UPPER_SMALLER_THAN_LOWER_IN_REPEAT_RANGE -202
|
||||
#define ONIGERR_EMPTY_RANGE_IN_CHAR_CLASS -203
|
||||
#define ONIGERR_MISMATCH_CODE_LENGTH_IN_CLASS_RANGE -204
|
||||
#define ONIGERR_TOO_MANY_MULTI_BYTE_RANGES -205
|
||||
#define ONIGERR_TOO_SHORT_MULTI_BYTE_STRING -206
|
||||
#define ONIGERR_TOO_BIG_BACKREF_NUMBER -207
|
||||
#define ONIGERR_INVALID_BACKREF -208
|
||||
#define ONIGERR_NUMBERED_BACKREF_OR_CALL_NOT_ALLOWED -209
|
||||
#define ONIGERR_TOO_LONG_WIDE_CHAR_VALUE -212
|
||||
#define ONIGERR_EMPTY_GROUP_NAME -214
|
||||
#define ONIGERR_INVALID_GROUP_NAME -215
|
||||
#define ONIGERR_INVALID_CHAR_IN_GROUP_NAME -216
|
||||
#define ONIGERR_UNDEFINED_NAME_REFERENCE -217
|
||||
#define ONIGERR_UNDEFINED_GROUP_REFERENCE -218
|
||||
#define ONIGERR_MULTIPLEX_DEFINED_NAME -219
|
||||
#define ONIGERR_MULTIPLEX_DEFINITION_NAME_CALL -220
|
||||
#define ONIGERR_NEVER_ENDING_RECURSION -221
|
||||
#define ONIGERR_GROUP_NUMBER_OVER_FOR_CAPTURE_HISTORY -222
|
||||
#define ONIGERR_INVALID_CHAR_PROPERTY_NAME -223
|
||||
#define ONIGERR_INVALID_CODE_POINT_VALUE -400
|
||||
#define ONIGERR_INVALID_WIDE_CHAR_VALUE -400
|
||||
#define ONIGERR_TOO_BIG_WIDE_CHAR_VALUE -401
|
||||
#define ONIGERR_NOT_SUPPORTED_ENCODING_COMBINATION -402
|
||||
#define ONIGERR_INVALID_COMBINATION_OF_OPTIONS -403
|
||||
|
||||
/* errors related to thread */
|
||||
#define ONIGERR_OVER_THREAD_PASS_LIMIT_COUNT -1001
|
||||
|
||||
|
||||
/* must be smaller than BIT_STATUS_BITS_NUM (unsigned int * 8) */
|
||||
#define ONIG_MAX_CAPTURE_HISTORY_GROUP 31
|
||||
#define ONIG_IS_CAPTURE_HISTORY_GROUP(r, i) \
|
||||
((i) <= ONIG_MAX_CAPTURE_HISTORY_GROUP && (r)->list && (r)->list[i])
|
||||
|
||||
typedef struct OnigCaptureTreeNodeStruct {
|
||||
int group; /* group number */
|
||||
int beg;
|
||||
int end;
|
||||
int allocated;
|
||||
int num_childs;
|
||||
struct OnigCaptureTreeNodeStruct** childs;
|
||||
} OnigCaptureTreeNode;
|
||||
|
||||
/* match result region type */
|
||||
struct re_registers {
|
||||
int allocated;
|
||||
int num_regs;
|
||||
int* beg;
|
||||
int* end;
|
||||
/* extended */
|
||||
OnigCaptureTreeNode* history_root; /* capture history tree root */
|
||||
};
|
||||
|
||||
/* capture tree traverse */
|
||||
#define ONIG_TRAVERSE_CALLBACK_AT_FIRST 1
|
||||
#define ONIG_TRAVERSE_CALLBACK_AT_LAST 2
|
||||
#define ONIG_TRAVERSE_CALLBACK_AT_BOTH \
|
||||
( ONIG_TRAVERSE_CALLBACK_AT_FIRST | ONIG_TRAVERSE_CALLBACK_AT_LAST )
|
||||
|
||||
|
||||
#define ONIG_REGION_NOTPOS -1
|
||||
|
||||
typedef struct re_registers OnigRegion;
|
||||
|
||||
typedef struct {
|
||||
OnigEncoding enc;
|
||||
OnigUChar* par;
|
||||
OnigUChar* par_end;
|
||||
} OnigErrorInfo;
|
||||
|
||||
typedef struct {
|
||||
int lower;
|
||||
int upper;
|
||||
} OnigRepeatRange;
|
||||
|
||||
typedef void (*OnigWarnFunc)(const char* s);
|
||||
extern void onig_null_warn(const char* s);
|
||||
#define ONIG_NULL_WARN onig_null_warn
|
||||
|
||||
#define ONIG_CHAR_TABLE_SIZE 256
|
||||
|
||||
/* regex_t state */
|
||||
#define ONIG_STATE_NORMAL 0
|
||||
#define ONIG_STATE_SEARCHING 1
|
||||
#define ONIG_STATE_COMPILING -1
|
||||
#define ONIG_STATE_MODIFY -2
|
||||
|
||||
#define ONIG_STATE(reg) \
|
||||
((reg)->state > 0 ? ONIG_STATE_SEARCHING : (reg)->state)
|
||||
|
||||
typedef struct re_pattern_buffer {
|
||||
/* common members of BBuf(bytes-buffer) */
|
||||
unsigned char* p; /* compiled pattern */
|
||||
unsigned int used; /* used space for p */
|
||||
unsigned int alloc; /* allocated space for p */
|
||||
|
||||
int state; /* normal, searching, compiling */
|
||||
int num_mem; /* used memory(...) num counted from 1 */
|
||||
int num_repeat; /* OP_REPEAT/OP_REPEAT_NG id-counter */
|
||||
int num_null_check; /* OP_NULL_CHECK_START/END id counter */
|
||||
int num_comb_exp_check; /* combination explosion check */
|
||||
int num_call; /* number of subexp call */
|
||||
unsigned int capture_history; /* (?@...) flag (1-31) */
|
||||
unsigned int bt_mem_start; /* need backtrack flag */
|
||||
unsigned int bt_mem_end; /* need backtrack flag */
|
||||
int stack_pop_level;
|
||||
int repeat_range_alloc;
|
||||
OnigRepeatRange* repeat_range;
|
||||
|
||||
OnigEncoding enc;
|
||||
OnigOptionType options;
|
||||
const OnigSyntaxType* syntax;
|
||||
OnigCaseFoldType case_fold_flag;
|
||||
void* name_table;
|
||||
|
||||
/* optimization info (string search, char-map and anchors) */
|
||||
int optimize; /* optimize flag */
|
||||
int threshold_len; /* search str-length for apply optimize */
|
||||
int anchor; /* BEGIN_BUF, BEGIN_POS, (SEMI_)END_BUF */
|
||||
OnigDistance anchor_dmin; /* (SEMI_)END_BUF anchor distance */
|
||||
OnigDistance anchor_dmax; /* (SEMI_)END_BUF anchor distance */
|
||||
int sub_anchor; /* start-anchor for exact or map */
|
||||
unsigned char *exact;
|
||||
unsigned char *exact_end;
|
||||
unsigned char map[ONIG_CHAR_TABLE_SIZE]; /* used as BM skip or char-map */
|
||||
int *int_map; /* BM skip for exact_len > 255 */
|
||||
int *int_map_backward; /* BM skip for backward search */
|
||||
OnigDistance dmin; /* min-distance of exact or map */
|
||||
OnigDistance dmax; /* max-distance of exact or map */
|
||||
|
||||
/* regex_t link chain */
|
||||
struct re_pattern_buffer* chain; /* escape compile-conflict */
|
||||
} OnigRegexType;
|
||||
|
||||
typedef OnigRegexType* OnigRegex;
|
||||
|
||||
#ifndef ONIG_ESCAPE_REGEX_T_COLLISION
|
||||
typedef OnigRegexType regex_t;
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct {
|
||||
int num_of_elements;
|
||||
OnigEncoding pattern_enc;
|
||||
OnigEncoding target_enc;
|
||||
OnigSyntaxType* syntax;
|
||||
OnigOptionType option;
|
||||
OnigCaseFoldType case_fold_flag;
|
||||
} OnigCompileInfo;
|
||||
|
||||
/* Oniguruma Native API */
|
||||
ONIG_EXTERN
|
||||
int onig_init(void);
|
||||
ONIG_EXTERN
|
||||
int onig_error_code_to_str(OnigUChar* s, int err_code, ...);
|
||||
ONIG_EXTERN
|
||||
void onig_set_warn_func(OnigWarnFunc f);
|
||||
ONIG_EXTERN
|
||||
void onig_set_verb_warn_func(OnigWarnFunc f);
|
||||
ONIG_EXTERN
|
||||
int onig_new(OnigRegex*, const OnigUChar* pattern, const OnigUChar* pattern_end, OnigOptionType option, OnigEncoding enc, const OnigSyntaxType* syntax, OnigErrorInfo* einfo);
|
||||
ONIG_EXTERN
|
||||
int onig_reg_init(regex_t* reg, OnigOptionType option, OnigCaseFoldType case_fold_flag, OnigEncoding enc, const OnigSyntaxType* syntax);
|
||||
ONIG_EXTERN
|
||||
int onig_new_without_alloc(OnigRegex, const OnigUChar* pattern, const OnigUChar* pattern_end, OnigOptionType option, OnigEncoding enc, OnigSyntaxType* syntax, OnigErrorInfo* einfo);
|
||||
ONIG_EXTERN
|
||||
int onig_new_deluxe(OnigRegex* reg, const OnigUChar* pattern, const OnigUChar* pattern_end, OnigCompileInfo* ci, OnigErrorInfo* einfo);
|
||||
ONIG_EXTERN
|
||||
void onig_free(OnigRegex);
|
||||
ONIG_EXTERN
|
||||
void onig_free_body(OnigRegex);
|
||||
ONIG_EXTERN
|
||||
int onig_recompile(OnigRegex, const OnigUChar* pattern, const OnigUChar* pattern_end, OnigOptionType option, OnigEncoding enc, OnigSyntaxType* syntax, OnigErrorInfo* einfo);
|
||||
ONIG_EXTERN
|
||||
int onig_recompile_deluxe(OnigRegex reg, const OnigUChar* pattern, const OnigUChar* pattern_end, OnigCompileInfo* ci, OnigErrorInfo* einfo);
|
||||
ONIG_EXTERN
|
||||
long onig_search(OnigRegex, const OnigUChar* str, const OnigUChar* end, const OnigUChar* start, const OnigUChar* range, OnigRegion* region, OnigOptionType option);
|
||||
ONIG_EXTERN
|
||||
long onig_match(OnigRegex, const OnigUChar* str, const OnigUChar* end, const OnigUChar* at, OnigRegion* region, OnigOptionType option);
|
||||
ONIG_EXTERN
|
||||
OnigRegion* onig_region_new(void);
|
||||
ONIG_EXTERN
|
||||
void onig_region_init(OnigRegion* region);
|
||||
ONIG_EXTERN
|
||||
void onig_region_free(OnigRegion* region, int free_self);
|
||||
ONIG_EXTERN
|
||||
void onig_region_copy(OnigRegion* to, OnigRegion* from);
|
||||
ONIG_EXTERN
|
||||
void onig_region_clear(OnigRegion* region);
|
||||
ONIG_EXTERN
|
||||
int onig_region_resize(OnigRegion* region, int n);
|
||||
ONIG_EXTERN
|
||||
int onig_region_set(OnigRegion* region, int at, int beg, int end);
|
||||
ONIG_EXTERN
|
||||
int onig_name_to_group_numbers(OnigRegex reg, const OnigUChar* name, const OnigUChar* name_end, int** nums);
|
||||
ONIG_EXTERN
|
||||
int onig_name_to_backref_number(OnigRegex reg, const OnigUChar* name, const OnigUChar* name_end, OnigRegion *region);
|
||||
ONIG_EXTERN
|
||||
int onig_foreach_name(OnigRegex reg, int (*func)(const OnigUChar*, const OnigUChar*,int,int*,OnigRegex,void*), void* arg);
|
||||
ONIG_EXTERN
|
||||
int onig_number_of_names(OnigRegex reg);
|
||||
ONIG_EXTERN
|
||||
int onig_number_of_captures(OnigRegex reg);
|
||||
ONIG_EXTERN
|
||||
int onig_number_of_capture_histories(OnigRegex reg);
|
||||
ONIG_EXTERN
|
||||
OnigCaptureTreeNode* onig_get_capture_tree(OnigRegion* region);
|
||||
ONIG_EXTERN
|
||||
int onig_capture_tree_traverse(OnigRegion* region, int at, int(*callback_func)(int,int,int,int,int,void*), void* arg);
|
||||
ONIG_EXTERN
|
||||
int onig_noname_group_capture_is_active(OnigRegex reg);
|
||||
ONIG_EXTERN
|
||||
OnigEncoding onig_get_encoding(OnigRegex reg);
|
||||
ONIG_EXTERN
|
||||
OnigOptionType onig_get_options(OnigRegex reg);
|
||||
ONIG_EXTERN
|
||||
OnigCaseFoldType onig_get_case_fold_flag(OnigRegex reg);
|
||||
ONIG_EXTERN
|
||||
const OnigSyntaxType* onig_get_syntax(OnigRegex reg);
|
||||
ONIG_EXTERN
|
||||
int onig_set_default_syntax(const OnigSyntaxType* syntax);
|
||||
ONIG_EXTERN
|
||||
void onig_copy_syntax(OnigSyntaxType* to, const OnigSyntaxType* from);
|
||||
ONIG_EXTERN
|
||||
unsigned int onig_get_syntax_op(OnigSyntaxType* syntax);
|
||||
ONIG_EXTERN
|
||||
unsigned int onig_get_syntax_op2(OnigSyntaxType* syntax);
|
||||
ONIG_EXTERN
|
||||
unsigned int onig_get_syntax_behavior(OnigSyntaxType* syntax);
|
||||
ONIG_EXTERN
|
||||
OnigOptionType onig_get_syntax_options(OnigSyntaxType* syntax);
|
||||
ONIG_EXTERN
|
||||
void onig_set_syntax_op(OnigSyntaxType* syntax, unsigned int op);
|
||||
ONIG_EXTERN
|
||||
void onig_set_syntax_op2(OnigSyntaxType* syntax, unsigned int op2);
|
||||
ONIG_EXTERN
|
||||
void onig_set_syntax_behavior(OnigSyntaxType* syntax, unsigned int behavior);
|
||||
ONIG_EXTERN
|
||||
void onig_set_syntax_options(OnigSyntaxType* syntax, OnigOptionType options);
|
||||
ONIG_EXTERN
|
||||
int onig_set_meta_char(OnigSyntaxType* syntax, unsigned int what, OnigCodePoint code);
|
||||
ONIG_EXTERN
|
||||
void onig_copy_encoding(OnigEncoding to, OnigEncoding from);
|
||||
ONIG_EXTERN
|
||||
OnigCaseFoldType onig_get_default_case_fold_flag(void);
|
||||
ONIG_EXTERN
|
||||
int onig_set_default_case_fold_flag(OnigCaseFoldType case_fold_flag);
|
||||
ONIG_EXTERN
|
||||
unsigned int onig_get_match_stack_limit_size(void);
|
||||
ONIG_EXTERN
|
||||
int onig_set_match_stack_limit_size(unsigned int size);
|
||||
ONIG_EXTERN
|
||||
int onig_end(void);
|
||||
ONIG_EXTERN
|
||||
const char* onig_version(void);
|
||||
ONIG_EXTERN
|
||||
const char* onig_copyright(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ONIGURUMA_H */
|
||||
+148
@@ -0,0 +1,148 @@
|
||||
#ifndef OPCODE_H
|
||||
#define OPCODE_H
|
||||
|
||||
#define MAXARG_Bx ((1<<16)-1)
|
||||
#define MAXARG_sBx (MAXARG_Bx>>1) /* `sBx' is signed */
|
||||
|
||||
/* instructions OP:A:B:C = 7:9:9:7 (32 bits) */
|
||||
/* OP:A:Bx = 7:9:16 */
|
||||
/* OP:Ax = 7:25 */
|
||||
|
||||
#define GET_OPCODE(i) (((mrb_code)(i)) & 0x7f)
|
||||
#define GETARG_A(i) ((((mrb_code)(i)) >> 23) & 0x1ff)
|
||||
#define GETARG_B(i) ((((mrb_code)(i)) >> 14) & 0x1ff)
|
||||
#define GETARG_C(i) ((((mrb_code)(i)) >> 7) & 0x7f)
|
||||
#define GETARG_Bx(i) ((((mrb_code)(i)) >> 7) & 0xffff)
|
||||
#define GETARG_sBx(i) (GETARG_Bx(i)-MAXARG_sBx)
|
||||
#define GETARG_Ax(i) ((((mrb_code)(i)) >> 7) & 0x1ffffff)
|
||||
#define GETARG_UNPACK_b(i,n1,n2) ((((mrb_code)(i)) >> (7+n2)) & (((1<<n1)-1)))
|
||||
#define GETARG_UNPACK_c(i,n1,n2) ((((mrb_code)(i)) >> 7) & (((1<<n2)-1)))
|
||||
#define GETARG_b(i) GETARG_UNPACK_b(i,14,2)
|
||||
#define GETARG_c(i) GETARG_UNPACK_c(i,14,2)
|
||||
|
||||
#define MKOPCODE(op) ((op) & 0x7f)
|
||||
#define MKARG_A(c) (((c) & 0x1ff) << 23)
|
||||
#define MKARG_B(c) (((c) & 0x1ff) << 14)
|
||||
#define MKARG_C(c) (((c) & 0x7f) << 7)
|
||||
#define MKARG_Bx(v) (((v) & 0xffff) << 7)
|
||||
#define MKARG_sBx(v) MKARG_Bx((v)+MAXARG_sBx)
|
||||
#define MKARG_Ax(v) (((v) & 0x1ffffff) << 7)
|
||||
#define MKARG_PACK(b,n1,c,n2) ((((b) & ((1<<n1)-1)) << (7+n2))|(((c) & ((1<<n2)-1)) << 7))
|
||||
#define MKARG_bc(b,c) MKARG_PACK(b,14,c,2)
|
||||
|
||||
#define MKOP_A(op,a) (MKOPCODE(op)|MKARG_A(a))
|
||||
#define MKOP_AB(op,a,b) (MKOP_A(op,a)|MKARG_B(b))
|
||||
#define MKOP_ABC(op,a,b,c) (MKOP_AB(op,a,b)|MKARG_C(c))
|
||||
#define MKOP_ABx(op,a,bx) (MKOP_A(op,a)|MKARG_Bx(bx))
|
||||
#define MKOP_Bx(op,bx) (MKOPCODE(op)|MKARG_Bx(bx))
|
||||
#define MKOP_sBx(op,sbx) (MKOPCODE(op)|MKARG_sBx(sbx))
|
||||
#define MKOP_AsBx(op,a,sbx) (MKOP_A(op,a)|MKARG_sBx(sbx))
|
||||
#define MKOP_Ax(op,ax) (MKOPCODE(op)|MKARG_Ax(ax))
|
||||
#define MKOP_Abc(op,a,b,c) (MKOP_A(op,a)|MKARG_bc(b,c))
|
||||
|
||||
enum {
|
||||
OP_NOP=0,/* */
|
||||
OP_MOVE,/* A B R(A) := R(B) */
|
||||
OP_LOADL,/* A Bx R(A) := Lit(Bx) */
|
||||
OP_LOADI,/* A sBx R(A) := sBx */
|
||||
OP_LOADSYM,/* A Bx R(A) := Sym(Bx) */
|
||||
OP_LOADNIL,/* A R(A) := nil */
|
||||
OP_LOADSELF,/* A R(A) := self */
|
||||
OP_LOADT,/* A R(A) := true */
|
||||
OP_LOADF,/* A R(A) := false */
|
||||
|
||||
OP_GETGLOBAL,/* A Bx R(A) := getglobal(Sym(Bx)) */
|
||||
OP_SETGLOBAL,/* A Bx setglobal(Sym(Bx), R(A)) */
|
||||
OP_GETSPECIAL,/*A Bx R(A) := Special[Bx] */
|
||||
OP_SETSPECIAL,/*A Bx Special[Bx] := R(A) */
|
||||
OP_GETIV,/* A Bx R(A) := ivget(Sym(Bx)) */
|
||||
OP_SETIV,/* A Bx ivset(Sym(Bx),R(A)) */
|
||||
OP_GETCV,/* A Bx R(A) := cvget(Sym(Bx)) */
|
||||
OP_SETCV,/* A Bx cvset(Sym(Bx),R(A)) */
|
||||
OP_GETCONST,/* A Bx R(A) := constget(Sym(Bx)) */
|
||||
OP_SETCONST,/* A Bx constset(Sym(Bx),R(A)) */
|
||||
OP_GETMCNST,/* A Bx R(A) := R(A)::Sym(B) */
|
||||
OP_SETMCNST,/* A Bx R(A+1)::Sym(B) := R(A) */
|
||||
OP_GETUPVAR,/* A B C R(A) := uvget(B,C) */
|
||||
OP_SETUPVAR,/* A B C uvset(B,C,R(A)) */
|
||||
|
||||
OP_JMP,/* sBx pc+=sBx */
|
||||
OP_JMPIF,/* A sBx if R(A) pc+=sBx */
|
||||
OP_JMPNOT,/* A sBx if !R(A) pc+=sBx */
|
||||
OP_ONERR,/* sBx rescue_push(pc+sBx) */
|
||||
OP_RESCUE,/* A clear(exc); R(A) := exception (ignore when A=0) */
|
||||
OP_POPERR,/* A A.times{rescue_pop()} */
|
||||
OP_RAISE,/* A raise(R(A)) */
|
||||
OP_EPUSH,/* Bx ensure_push(SEQ[Bx]) */
|
||||
OP_EPOP,/* A A.times{ensure_pop().call} */
|
||||
|
||||
OP_SEND,/* A B C R(A) := call(R(A),mSym(B),R(A+1),...,R(A+C)) */
|
||||
OP_FSEND,/* A B C R(A) := fcall(R(A),mSym(B),R(A+1),...,R(A+C-1)) */
|
||||
OP_VSEND,/* A B R(A) := vcall(R(A),mSym(B)) */
|
||||
OP_CALL,/* A B C R(A) := self.call(R(A),.., R(A+C)) */
|
||||
OP_SUPER,/* A B C R(A) := super(R(A+1),... ,R(A+C-1)) */
|
||||
OP_ARGARY,/* A Bx R(A) := argument array (16=6:1:5:4) */
|
||||
OP_ENTER,/* Ax arg setup according to flags (24=5:5:1:5:5:1:1) */
|
||||
OP_KARG,/* A B C R(A) := kdict[mSym(B)]; if C kdict.rm(mSym(B)) */
|
||||
OP_KDICT,/* A C R(A) := kdict */
|
||||
|
||||
OP_RETURN,/* A B return R(A) (B=normal,in-block return/break) */
|
||||
OP_TAILCALL,/* A B C return call(R(A),mSym(B),*R(C)) */
|
||||
OP_BLKPUSH,/* A Bx R(A) := block (16=6:1:5:4) */
|
||||
|
||||
OP_ADD,/* A B C R(A) := R(A)+R(A+1) (mSyms[B]=:+,C=1) */
|
||||
OP_ADDI,/* A B C R(A) := R(A)+C (mSyms[B]=:+) */
|
||||
OP_SUB,/* A B C R(A) := R(A)-R(A+1) (mSyms[B]=:-,C=1) */
|
||||
OP_SUBI,/* A B C R(A) := R(A)-C (mSyms[B]=:-) */
|
||||
OP_MUL,/* A B C R(A) := R(A)*R(A+1) (mSyms[B]=:*,C=1) */
|
||||
OP_DIV,/* A B C R(A) := R(A)/R(A+1) (mSyms[B]=:/,C=1) */
|
||||
OP_EQ,/* A B C R(A) := R(A)==R(A+1) (mSyms[B]=:==,C=1) */
|
||||
OP_LT,/* A B C R(A) := R(A)<R(A+1) (mSyms[B]=:<,C=1) */
|
||||
OP_LE,/* A B C R(A) := R(A)<=R(A+1) (mSyms[B]=:<=,C=1) */
|
||||
OP_GT,/* A B C R(A) := R(A)>R(A+1) (mSyms[B]=:>,C=1) */
|
||||
OP_GE,/* A B C R(A) := R(A)>=R(A+1) (mSyms[B]=:>=,C=1) */
|
||||
|
||||
OP_ARRAY,/* A B C R(A) := ary_new(R(B),R(B+1)..R(B+C)) */
|
||||
OP_ARYCAT,/* A B ary_cat(R(A),R(B)) */
|
||||
OP_ARYPUSH,/* A B ary_push(R(A),R(B)) */
|
||||
OP_AREF,/* A B C R(A) := R(B)[C] */
|
||||
OP_ASET,/* A B C R(B)[C] := R(A) */
|
||||
OP_APOST,/* A B C *R(A),R(A+1)..R(A+C) := R(A) */
|
||||
|
||||
OP_STRING,/* A Bx R(A) := str_dup(Lit(Bx)) */
|
||||
OP_STRCAT,/* A B str_cat(R(A),R(B)) */
|
||||
|
||||
OP_HASH,/* A B C R(A) := hash_new(R(B),R(B+1)..R(B+C)) */
|
||||
OP_LAMBDA,/* A Bz Cz R(A) := lambda(SEQ[Bz],Cm) */
|
||||
OP_RANGE,/* A B C R(A) := range_new(R(B),R(B+1),C) */
|
||||
|
||||
OP_OCLASS,/* A R(A) := ::Object */
|
||||
OP_CLASS,/* A B R(A) := newclass(R(A),mSym(B),R(A+1)) */
|
||||
OP_MODULE,/* A B R(A) := newmodule(R(A),mSym(B)) */
|
||||
OP_EXEC,/* A Bx R(A) := blockexec(R(A),SEQ[Bx]) */
|
||||
OP_METHOD,/* A B R(A).newmethod(mSym(B),R(A+1)) */
|
||||
OP_SCLASS,/* A B R(A) := R(B).singleton_class */
|
||||
OP_TCLASS,/* A R(A) := target_class */
|
||||
|
||||
OP_DEBUG,/* A print R(A) */
|
||||
OP_STOP,/* stop VM */
|
||||
OP_ERR,/* Bx raise RuntimeError with message Lit(Bx) */
|
||||
|
||||
OP_RSVD1,/* reserved instruction #1 */
|
||||
OP_RSVD2,/* reserved instruction #2 */
|
||||
OP_RSVD3,/* reserved instruction #3 */
|
||||
OP_RSVD4,/* reserved instruction #4 */
|
||||
OP_RSVD5,/* reserved instruction #5 */
|
||||
};
|
||||
|
||||
#define OP_L_STRICT 1
|
||||
#define OP_L_CAPTURE 2
|
||||
#define OP_L_METHOD OP_L_STRICT
|
||||
#define OP_L_LAMBDA (OP_L_STRICT|OP_L_CAPTURE)
|
||||
#define OP_L_BLOCK OP_L_CAPTURE
|
||||
|
||||
#define OP_R_NORMAL 0
|
||||
#define OP_R_BREAK 1
|
||||
#define OP_R_RETURN 2
|
||||
|
||||
#endif /* OPCODE_H */
|
||||
+5435
File diff suppressed because it is too large
Load Diff
+152
@@ -0,0 +1,152 @@
|
||||
#include "pool.h"
|
||||
#include <string.h>
|
||||
|
||||
#undef TEST_POOL
|
||||
#ifdef TEST_POOL
|
||||
#include <stdio.h>
|
||||
|
||||
#define mrb_malloc(m,s) malloc(s)
|
||||
#define mrb_free(m,p) free(p)
|
||||
#endif
|
||||
|
||||
#define POOL_PAGE_SIZE 16000
|
||||
|
||||
mrb_pool*
|
||||
mrb_pool_open(mrb_state *mrb)
|
||||
{
|
||||
mrb_pool *pool = mrb_malloc(mrb, sizeof(mrb_pool));
|
||||
|
||||
if (pool) {
|
||||
pool->mrb = mrb;
|
||||
pool->pages = 0;
|
||||
}
|
||||
|
||||
return pool;
|
||||
}
|
||||
|
||||
void
|
||||
mrb_pool_close(mrb_pool *pool)
|
||||
{
|
||||
struct mrb_pool_page *page, *tmp;
|
||||
|
||||
if (!pool) return;
|
||||
page = pool->pages;
|
||||
while (page) {
|
||||
tmp = page;
|
||||
page = page->next;
|
||||
mrb_free(pool->mrb, tmp);
|
||||
}
|
||||
mrb_free(pool->mrb, pool);
|
||||
}
|
||||
|
||||
static struct mrb_pool_page*
|
||||
page_alloc(mrb_pool *pool, size_t len)
|
||||
{
|
||||
struct mrb_pool_page *page;
|
||||
|
||||
if (len < POOL_PAGE_SIZE)
|
||||
len = POOL_PAGE_SIZE;
|
||||
page = mrb_malloc(pool->mrb, sizeof(struct mrb_pool_page)+len-1);
|
||||
if (page) {
|
||||
page->offset = 0;
|
||||
page->len = len;
|
||||
}
|
||||
|
||||
return page;
|
||||
}
|
||||
|
||||
void*
|
||||
mrb_pool_alloc(mrb_pool *pool, size_t len)
|
||||
{
|
||||
struct mrb_pool_page *page;
|
||||
size_t n;
|
||||
|
||||
if (!pool) return 0;
|
||||
|
||||
page = pool->pages;
|
||||
while (page) {
|
||||
if (page->offset + len <= page->len) {
|
||||
n = page->offset;
|
||||
page->offset += len;
|
||||
page->last = (void*)page->page+n;
|
||||
return page->last;
|
||||
}
|
||||
page = page->next;
|
||||
}
|
||||
page = page_alloc(pool, len);
|
||||
if (!page) return 0;
|
||||
page->offset = len;
|
||||
page->next = pool->pages;
|
||||
pool->pages = page;
|
||||
|
||||
page->last = (void*)page->page;
|
||||
return page->last;
|
||||
}
|
||||
|
||||
int
|
||||
mrb_pool_can_realloc(mrb_pool *pool, void *p, size_t len)
|
||||
{
|
||||
struct mrb_pool_page *page;
|
||||
|
||||
if (!pool) return 0;
|
||||
page = pool->pages;
|
||||
while (page) {
|
||||
if (page->last == p) {
|
||||
size_t beg;
|
||||
|
||||
beg = (char*)p - page->page;
|
||||
if (beg + len > page->len) return 0;
|
||||
return 1;
|
||||
}
|
||||
page = page->next;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void*
|
||||
mrb_pool_realloc(mrb_pool *pool, void *p, size_t oldlen, size_t newlen)
|
||||
{
|
||||
struct mrb_pool_page *page;
|
||||
void *np;
|
||||
|
||||
if (!pool) return 0;
|
||||
page = pool->pages;
|
||||
while (page) {
|
||||
if (page->last == p) {
|
||||
size_t beg;
|
||||
|
||||
beg = (char*)p - page->page;
|
||||
if (beg + oldlen != page->offset) break;
|
||||
if (beg + newlen > page->len) {
|
||||
page->offset = beg;
|
||||
break;
|
||||
}
|
||||
page->offset = beg + newlen;
|
||||
return p;
|
||||
}
|
||||
page = page->next;
|
||||
}
|
||||
np = mrb_pool_alloc(pool, newlen);
|
||||
memcpy(np, p, oldlen);
|
||||
return np;
|
||||
}
|
||||
|
||||
#ifdef TEST_POOL
|
||||
int
|
||||
main()
|
||||
{
|
||||
int i, len = 250;
|
||||
mrb_pool *pool;
|
||||
void *p;
|
||||
|
||||
pool = mrb_pool_open(0);
|
||||
p = mrb_pool_alloc(pool, len);
|
||||
for (i=1; i<20; i++) {
|
||||
printf("%p (len=%d) %d\n", p, len, mrb_pool_can_realloc(pool, p, len*2));
|
||||
p = mrb_pool_realloc(pool, p, len, len*2);
|
||||
len *= 2;
|
||||
}
|
||||
mrb_pool_close(pool);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
#include "mruby.h"
|
||||
#include <stddef.h>
|
||||
|
||||
typedef struct mrb_pool {
|
||||
mrb_state *mrb;
|
||||
struct mrb_pool_page {
|
||||
struct mrb_pool_page *next;
|
||||
size_t offset;
|
||||
size_t len;
|
||||
void *last;
|
||||
char page[1];
|
||||
} *pages;
|
||||
} mrb_pool;
|
||||
|
||||
mrb_pool* mrb_pool_open(mrb_state*);
|
||||
void mrb_pool_close(mrb_pool*);
|
||||
void* mrb_pool_alloc(mrb_pool*, size_t);
|
||||
void* mrb_pool_realloc(mrb_pool*, void*, size_t oldlen, size_t newlen);
|
||||
int mrb_pool_can_realloc(mrb_pool*, void*, size_t);
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
#include "mruby.h"
|
||||
#include "mruby/string.h"
|
||||
#include <stdio.h>
|
||||
|
||||
mrb_value
|
||||
printstr(mrb_state *mrb, mrb_value obj)
|
||||
{
|
||||
struct RString *str;
|
||||
char *s;
|
||||
size_t len;
|
||||
|
||||
if (mrb_type(obj) == MRB_TT_STRING) {
|
||||
str = mrb_str_ptr(obj);
|
||||
s = str->buf;
|
||||
len = str->len;
|
||||
while (len--) {
|
||||
putc(*s, stdout);
|
||||
s++;
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
mrb_value
|
||||
mrb_p(mrb_state *mrb, mrb_value obj)
|
||||
{
|
||||
obj = mrb_funcall(mrb, obj, "inspect", 0);
|
||||
printstr(mrb, obj);
|
||||
putc('\n', stdout);
|
||||
return obj;
|
||||
}
|
||||
|
||||
/* 15.3.1.2.9 */
|
||||
/* 15.3.1.3.34 */
|
||||
static mrb_value
|
||||
p_m(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
int argc, i;
|
||||
mrb_value *argv;
|
||||
|
||||
mrb_get_args(mrb, "*", &argv, &argc);
|
||||
for (i=0; i<argc; i++) {
|
||||
mrb_p(mrb, argv[i]);
|
||||
}
|
||||
|
||||
return argv[0];
|
||||
}
|
||||
|
||||
mrb_value
|
||||
mrb_printstr(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
mrb_value argv;
|
||||
|
||||
mrb_get_args(mrb, "o", &argv);
|
||||
printstr(mrb, argv);
|
||||
|
||||
return argv;
|
||||
}
|
||||
|
||||
void
|
||||
mrb_init_print(mrb_state *mrb)
|
||||
{
|
||||
struct RClass *krn;
|
||||
|
||||
krn = mrb->kernel_module;
|
||||
|
||||
mrb_define_method(mrb, krn, "__printstr__", mrb_printstr, ARGS_REQ(1));
|
||||
mrb_define_method(mrb, krn, "p", p_m, ARGS_ANY()); /* 15.3.1.3.34 */
|
||||
}
|
||||
+92
@@ -0,0 +1,92 @@
|
||||
#include "mruby.h"
|
||||
#include "mruby/proc.h"
|
||||
#include "mruby/array.h"
|
||||
#include "mruby/class.h"
|
||||
#include "opcode.h"
|
||||
|
||||
struct RProc *
|
||||
mrb_proc_new(mrb_state *mrb, mrb_irep *irep)
|
||||
{
|
||||
struct RProc *p;
|
||||
|
||||
p = mrb_obj_alloc(mrb, MRB_TT_PROC, mrb->proc_class);
|
||||
p->body.irep = irep;
|
||||
p->target_class = (mrb->ci) ? mrb->ci->target_class : 0;
|
||||
p->env = 0;
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
struct RProc *
|
||||
mrb_closure_new(mrb_state *mrb, mrb_irep *irep)
|
||||
{
|
||||
struct RProc *p = mrb_proc_new(mrb, irep);
|
||||
struct REnv *e;
|
||||
|
||||
if (!mrb->ci->env) {
|
||||
e = mrb_obj_alloc(mrb, MRB_TT_ENV, mrb->ci->proc->env);
|
||||
e->flags= (unsigned int)irep->nlocals;
|
||||
e->mid = mrb->ci->mid;
|
||||
e->cioff = mrb->ci - mrb->cibase;
|
||||
e->stack = mrb->stack;
|
||||
mrb->ci->env = e;
|
||||
}
|
||||
else {
|
||||
e = mrb->ci->env;
|
||||
}
|
||||
p->env = e;
|
||||
return p;
|
||||
}
|
||||
|
||||
struct RProc *
|
||||
mrb_proc_new_cfunc(mrb_state *mrb, mrb_func_t func)
|
||||
{
|
||||
struct RProc *p;
|
||||
|
||||
p = mrb_obj_alloc(mrb, MRB_TT_PROC, mrb->proc_class);
|
||||
p->body.func = func;
|
||||
p->flags |= MRB_PROC_CFUNC;
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
int
|
||||
mrb_proc_cfunc_p(struct RProc *p)
|
||||
{
|
||||
return MRB_PROC_CFUNC_P(p);
|
||||
}
|
||||
|
||||
mrb_value
|
||||
mrb_proc_call_cfunc(mrb_state *mrb, struct RProc *p, mrb_value self)
|
||||
{
|
||||
return (p->body.func)(mrb, self);
|
||||
}
|
||||
|
||||
mrb_code*
|
||||
mrb_proc_iseq(mrb_state *mrb, struct RProc *p)
|
||||
{
|
||||
return p->body.irep->iseq;
|
||||
}
|
||||
|
||||
void
|
||||
mrb_init_proc(mrb_state *mrb)
|
||||
{
|
||||
struct RProc *m;
|
||||
mrb_code *call_iseq = mrb_malloc(mrb, sizeof(mrb_code));
|
||||
mrb_irep *call_irep = mrb_calloc(mrb, sizeof(mrb_irep), 1);
|
||||
|
||||
if ( call_iseq == NULL || call_irep == NULL )
|
||||
return;
|
||||
|
||||
*call_iseq = MKOP_A(OP_CALL, 0);
|
||||
call_irep->idx = -1;
|
||||
call_irep->flags = MRB_IREP_NOFREE;
|
||||
call_irep->iseq = call_iseq;
|
||||
call_irep->ilen = 1;
|
||||
|
||||
mrb->proc_class = mrb_define_class(mrb, "Proc", mrb->object_class);
|
||||
|
||||
m = mrb_proc_new(mrb, call_irep);
|
||||
mrb_define_method_raw(mrb, mrb->proc_class, mrb_intern(mrb, "call"), m);
|
||||
mrb_define_method_raw(mrb, mrb->proc_class, mrb_intern(mrb, "[]"), m);
|
||||
}
|
||||
+499
@@ -0,0 +1,499 @@
|
||||
#include "mruby.h"
|
||||
#include "mruby/class.h"
|
||||
#include "mruby/range.h"
|
||||
#include "variable.h"
|
||||
#include "error.h"
|
||||
#include "mruby/numeric.h"
|
||||
#include "mruby/string.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif
|
||||
|
||||
#ifndef OTHER
|
||||
#define OTHER 2
|
||||
#endif
|
||||
|
||||
mrb_value mrb_exec_recursive_paired(mrb_state *mrb, mrb_value (*func) (mrb_state *, mrb_value, mrb_value, int),
|
||||
mrb_value obj, mrb_value paired_obj, void* arg);
|
||||
|
||||
int printf (const char*, ...);
|
||||
/*--------- <1.8.7>object.c ---------> */
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* obj.instance_of?(class) => true or false
|
||||
*
|
||||
* Returns <code>true</code> if <i>obj</i> is an instance of the given
|
||||
* class. See also <code>Object#kind_of?</code>.
|
||||
*/
|
||||
|
||||
int
|
||||
mrb_obj_is_instance_of(mrb_state *mrb, mrb_value obj, struct RClass* c)
|
||||
{
|
||||
if (mrb_obj_class(mrb, obj) == c) return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
/*--------- <1.8.7>object.c ---------< */
|
||||
|
||||
mrb_value
|
||||
mrb_range_new(mrb_state *mrb, mrb_value beg, mrb_value end, int excl)
|
||||
{
|
||||
struct RRange *r;
|
||||
|
||||
r = mrb_obj_alloc(mrb, MRB_TT_RANGE, mrb->range_class);
|
||||
r->edges = mrb_malloc(mrb, sizeof(struct mrb_range_edges));
|
||||
r->edges->beg = beg;
|
||||
r->edges->end = end;
|
||||
r->excl = excl;
|
||||
return mrb_range_value(r);
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* rng.first => obj
|
||||
* rng.begin => obj
|
||||
*
|
||||
* Returns the first object in <i>rng</i>.
|
||||
*/
|
||||
mrb_value
|
||||
mrb_range_beg(mrb_state *mrb, mrb_value range)
|
||||
{
|
||||
struct RRange *r = mrb_range_ptr(range);
|
||||
|
||||
return r->edges->beg;
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* rng.end => obj
|
||||
* rng.last => obj
|
||||
*
|
||||
* Returns the object that defines the end of <i>rng</i>.
|
||||
*
|
||||
* (1..10).end #=> 10
|
||||
* (1...10).end #=> 10
|
||||
*/
|
||||
|
||||
mrb_value
|
||||
mrb_range_end(mrb_state *mrb, mrb_value range)
|
||||
{
|
||||
struct RRange *r = mrb_range_ptr(range);
|
||||
|
||||
return r->edges->end;
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* range.exclude_end? => true or false
|
||||
*
|
||||
* Returns <code>true</code> if <i>range</i> excludes its end value.
|
||||
*/
|
||||
mrb_value
|
||||
mrb_range_excl(mrb_state *mrb, mrb_value range)
|
||||
{
|
||||
struct RRange *r = mrb_range_ptr(range);
|
||||
|
||||
return r->excl ? mrb_true_value() : mrb_false_value();
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* beg end
|
||||
* args[0] <= args[1] => true
|
||||
* args[0] > args[1] => false
|
||||
*/
|
||||
static int
|
||||
range_check(mrb_state *mrb, mrb_value *args)
|
||||
{
|
||||
mrb_value ans = mrb_funcall(mrb, args[0], "<=>", 1, args[1]);
|
||||
/* beg end
|
||||
ans :args[0] < args[1] => -1
|
||||
args[0] = args[1] => 0
|
||||
args[0] > args[1] => +1 */
|
||||
if (mrb_nil_p(ans)) return FALSE;
|
||||
//if (mrb_obj_equal(mrb, ans, mrb_fixnum_value(1))) return FALSE;
|
||||
if (mrb_fixnum(ans) == 1) return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
range_init(mrb_state *mrb, mrb_value range, mrb_value beg, mrb_value end, mrb_int exclude_end)
|
||||
{
|
||||
mrb_value args[2];
|
||||
struct RRange *r = mrb_range_ptr(range);
|
||||
|
||||
if ((mrb_type(beg) != MRB_TT_FIXNUM) || (mrb_type(end) != MRB_TT_FIXNUM)) {
|
||||
args[0] = beg;
|
||||
args[1] = end;
|
||||
/* eroor.c v = mrb_rescue(range_check, (mrb_value)args, range_failed, 0);
|
||||
if (mrb_nil_p(v)) range_failed(); */
|
||||
if (!range_check(mrb, args)) {
|
||||
printf("range_failed()\n");
|
||||
}
|
||||
}
|
||||
r->excl = exclude_end;
|
||||
r->edges->beg = beg;
|
||||
r->edges->end = end;
|
||||
}
|
||||
/*
|
||||
* call-seq:
|
||||
* Range.new(start, end, exclusive=false) => range
|
||||
*
|
||||
* Constructs a range using the given <i>start</i> and <i>end</i>. If the third
|
||||
* parameter is omitted or is <code>false</code>, the <i>range</i> will include
|
||||
* the end object; otherwise, it will be excluded.
|
||||
*/
|
||||
|
||||
mrb_value
|
||||
mrb_range_initialize(mrb_state *mrb, mrb_value range)
|
||||
{
|
||||
mrb_value beg, end;
|
||||
mrb_value flags;
|
||||
|
||||
mrb_get_args(mrb, "ooo", &beg, &end, &flags);
|
||||
/* Ranges are immutable, so that they should be initialized only once. */
|
||||
range_init(mrb, range, beg, end, mrb_test(flags));
|
||||
return range;
|
||||
}
|
||||
/*
|
||||
* call-seq:
|
||||
* range == obj => true or false
|
||||
*
|
||||
* Returns <code>true</code> only if
|
||||
* 1) <i>obj</i> is a Range,
|
||||
* 2) <i>obj</i> has equivalent beginning and end items (by comparing them with <code>==</code>),
|
||||
* 3) <i>obj</i> has the same #exclude_end? setting as <i>rng</t>.
|
||||
*
|
||||
* (0..2) == (0..2) #=> true
|
||||
* (0..2) == Range.new(0,2) #=> true
|
||||
* (0..2) == (0...2) #=> false
|
||||
*
|
||||
*/
|
||||
|
||||
mrb_value
|
||||
mrb_range_eq(mrb_state *mrb, mrb_value range)
|
||||
{
|
||||
struct RRange *rr;
|
||||
struct RRange *ro;
|
||||
mrb_value obj;
|
||||
|
||||
mrb_get_args(mrb, "o", &obj);
|
||||
|
||||
if (mrb_obj_equal(mrb, range, obj)) return mrb_true_value();
|
||||
|
||||
/* same class? */
|
||||
// if (!rb_obj_is_instance_of(obj, rb_obj_class(range)))
|
||||
if (!mrb_obj_is_instance_of(mrb, obj, mrb_obj_class(mrb, range)))
|
||||
return mrb_false_value();
|
||||
|
||||
rr = mrb_range_ptr(range);
|
||||
ro = mrb_range_ptr(obj);
|
||||
if (!mrb_obj_equal(mrb, rr->edges->beg, ro->edges->beg))
|
||||
return mrb_false_value();
|
||||
if (!mrb_obj_equal(mrb, rr->edges->end, ro->edges->end))
|
||||
return mrb_false_value();
|
||||
if (rr->excl != ro->excl)
|
||||
return mrb_false_value();
|
||||
|
||||
return mrb_true_value();
|
||||
}
|
||||
|
||||
static int
|
||||
r_le(mrb_state *mrb, mrb_value a, mrb_value b)
|
||||
{
|
||||
//int c;
|
||||
mrb_value r = mrb_funcall(mrb, a, "<=>", 1, b); /* compare result */
|
||||
/* output :a < b => -1, a = b => 0, a > b => +1 */
|
||||
|
||||
if (mrb_nil_p(r)) return FALSE;
|
||||
|
||||
/* mrb_value -> int */
|
||||
//c = mrb_cmpint(mrb, r, a, b);
|
||||
//if (c == 0) return TRUE;
|
||||
//if (c < 0) return TRUE;
|
||||
//return FALSE;
|
||||
if (mrb_obj_equal(mrb, r, mrb_fixnum_value(0))) return TRUE;
|
||||
if (mrb_obj_equal(mrb, r, mrb_fixnum_value(-1))) return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static int
|
||||
r_gt(mrb_state *mrb, mrb_value a, mrb_value b)
|
||||
{
|
||||
//int c;
|
||||
mrb_value r = mrb_funcall(mrb, a, "<=>", 1, b);
|
||||
/* output :a < b => -1, a = b => 0, a > b => +1 */
|
||||
|
||||
if (mrb_nil_p(r)) return FALSE;
|
||||
|
||||
/* mrb_value -> int */
|
||||
//c = mrb_cmpint(mrb, r);
|
||||
//if (c > 0) return TRUE;
|
||||
//return FALSE;
|
||||
if (mrb_obj_equal(mrb, r, mrb_fixnum_value(1))) return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static int
|
||||
r_ge(mrb_state *mrb, mrb_value a, mrb_value b)
|
||||
{
|
||||
//int c;
|
||||
mrb_value r = mrb_funcall(mrb, a, "<=>", 1, b); /* compare result */
|
||||
/* output :a < b => -1, a = b => 0, a > b => +1 */
|
||||
|
||||
if (mrb_nil_p(r)) return FALSE;
|
||||
|
||||
/* mrb_value -> int */
|
||||
//c = mrb_cmpint(mrb, r);
|
||||
//if (c == 0) return TRUE;
|
||||
//if (c > 0) return TRUE;
|
||||
//return FALSE;
|
||||
if (mrb_obj_equal(mrb, r, mrb_fixnum_value(0))) return TRUE;
|
||||
if (mrb_obj_equal(mrb, r, mrb_fixnum_value(1))) return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* range === obj => true or false
|
||||
* range.member?(val) => true or false
|
||||
* range.include?(val) => true or false
|
||||
*
|
||||
*/
|
||||
mrb_value
|
||||
mrb_range_include(mrb_state *mrb, mrb_value range)
|
||||
{
|
||||
mrb_value val;
|
||||
struct RRange *r = mrb_range_ptr(range);
|
||||
mrb_value beg, end;
|
||||
|
||||
mrb_get_args(mrb, "o", &val);
|
||||
|
||||
beg = r->edges->beg;
|
||||
end = r->edges->end;
|
||||
if (r_le(mrb, beg, val)) {
|
||||
/* beg <= val */
|
||||
if (r->excl) {
|
||||
if (r_gt(mrb, end, val)) return mrb_true_value(); /* end > val */
|
||||
}
|
||||
else {
|
||||
if (r_ge(mrb, end, val)) return mrb_true_value(); /* end >= val */
|
||||
}
|
||||
}
|
||||
return mrb_false_value();
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* rng.each {| i | block } => rng
|
||||
*
|
||||
* Iterates over the elements <i>rng</i>, passing each in turn to the
|
||||
* block. You can only iterate if the start object of the range
|
||||
* supports the +succ+ method (which means that you can't iterate over
|
||||
* ranges of +Float+ objects).
|
||||
*
|
||||
* (10..15).each do |n|
|
||||
* print n, ' '
|
||||
* end
|
||||
*
|
||||
* <em>produces:</em>
|
||||
*
|
||||
* 10 11 12 13 14 15
|
||||
*/
|
||||
|
||||
mrb_value
|
||||
mrb_range_each(mrb_state *mrb, mrb_value range)
|
||||
{
|
||||
return range;
|
||||
}
|
||||
|
||||
mrb_int
|
||||
mrb_range_beg_len(mrb_state *mrb, mrb_value range, mrb_int *begp, mrb_int *lenp, mrb_int len, mrb_int err)
|
||||
{
|
||||
mrb_int beg, end, b, e;
|
||||
struct RRange *r = mrb_range_ptr(range);
|
||||
|
||||
//if (!mrb_obj_is_kind_of(mrb, range, mrb->range_class)) return FALSE;
|
||||
if (mrb_type(range) != MRB_TT_RANGE) return FALSE;
|
||||
|
||||
beg = b = mrb_fixnum(r->edges->beg);
|
||||
end = e = mrb_fixnum(r->edges->end);
|
||||
|
||||
if (beg < 0) {
|
||||
beg += len;
|
||||
if (beg < 0) goto out_of_range;
|
||||
}
|
||||
if (err == 0 || err == 2) {
|
||||
if (beg > len) goto out_of_range;
|
||||
if (end > len) end = len;
|
||||
}
|
||||
if (end < 0) end += len;
|
||||
if (!r->excl) end++; /* include end point */
|
||||
len = end - beg;
|
||||
if (len < 0) len = 0;
|
||||
|
||||
*begp = beg;
|
||||
*lenp = len;
|
||||
return TRUE;
|
||||
|
||||
out_of_range:
|
||||
if (err) {
|
||||
mrb_raise(mrb, E_RANGE_ERROR, "%ld..%s%ld out of range",
|
||||
b, r->excl? "." : "", e);
|
||||
}
|
||||
return OTHER;
|
||||
}
|
||||
|
||||
/* 15.2.14.4.12(x) */
|
||||
/*
|
||||
* call-seq:
|
||||
* rng.to_s -> string
|
||||
*
|
||||
* Convert this range object to a printable form.
|
||||
*/
|
||||
|
||||
static mrb_value
|
||||
range_to_s(mrb_state *mrb, mrb_value range)
|
||||
{
|
||||
mrb_value str, str2;
|
||||
struct RRange *r = mrb_range_ptr(range);
|
||||
|
||||
str = mrb_obj_as_string(mrb, r->edges->beg);
|
||||
str2 = mrb_obj_as_string(mrb, r->edges->end);
|
||||
str = mrb_str_dup(mrb, str);
|
||||
mrb_str_cat(mrb, str, "...", r->excl ? 3 : 2);
|
||||
mrb_str_append(mrb, str, str2);
|
||||
//OBJ_INFECT(str, str2);
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
static mrb_value
|
||||
inspect_range(mrb_state *mrb, mrb_value range, mrb_value dummy, int recur)
|
||||
{
|
||||
mrb_value str, str2;
|
||||
struct RRange *r = mrb_range_ptr(range);
|
||||
|
||||
if (recur) {
|
||||
return mrb_str_new2(mrb, r->excl ? "(... ... ...)" : "(... .. ...)");
|
||||
}
|
||||
str = mrb_inspect(mrb, r->edges->beg);
|
||||
str2 = mrb_inspect(mrb, r->edges->end);
|
||||
str = mrb_str_dup(mrb, str);
|
||||
mrb_str_cat(mrb, str, "...", r->excl ? 3 : 2);
|
||||
mrb_str_append(mrb, str, str2);
|
||||
// OBJ_INFECT(str, str2);
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
/* 15.2.14.4.13(x) */
|
||||
/*
|
||||
* call-seq:
|
||||
* rng.inspect -> string
|
||||
*
|
||||
* Convert this range object to a printable form (using
|
||||
* <code>inspect</code> to convert the start and end
|
||||
* objects).
|
||||
*/
|
||||
|
||||
static mrb_value
|
||||
range_inspect(mrb_state *mrb, mrb_value range)
|
||||
{
|
||||
return inspect_range(mrb, range, range, 0);
|
||||
}
|
||||
|
||||
static mrb_value
|
||||
recursive_eql(mrb_state *mrb, mrb_value range, mrb_value obj, int recur)
|
||||
{
|
||||
struct RRange *r = mrb_range_ptr(range);
|
||||
struct RRange *o = mrb_range_ptr(obj);
|
||||
|
||||
if (recur) return mrb_true_value(); /* Subtle! */
|
||||
if (!mrb_eql(mrb, r->edges->beg, o->edges->beg))
|
||||
return mrb_false_value();
|
||||
if (!mrb_eql(mrb, r->edges->end, o->edges->end))
|
||||
return mrb_false_value();
|
||||
|
||||
if (r->excl != o->excl)
|
||||
return mrb_false_value();
|
||||
return mrb_true_value();
|
||||
}
|
||||
|
||||
/* 15.2.14.4.14(x) */
|
||||
/*
|
||||
* call-seq:
|
||||
* rng.eql?(obj) -> true or false
|
||||
*
|
||||
* Returns <code>true</code> only if <i>obj</i> is a Range, has equivalent
|
||||
* beginning and end items (by comparing them with #eql?), and has the same
|
||||
* #exclude_end? setting as <i>rng</i>.
|
||||
*
|
||||
* (0..2).eql?(0..2) #=> true
|
||||
* (0..2).eql?(Range.new(0,2)) #=> true
|
||||
* (0..2).eql?(0...2) #=> false
|
||||
*
|
||||
*/
|
||||
|
||||
static mrb_value
|
||||
range_eql(mrb_state *mrb, mrb_value range)
|
||||
{
|
||||
mrb_value obj;
|
||||
mrb_get_args(mrb, "o", &obj);
|
||||
|
||||
if (mrb_obj_equal(mrb, range, obj))
|
||||
return mrb_true_value();
|
||||
if (!mrb_obj_is_kind_of(mrb, obj, mrb->range_class))
|
||||
return mrb_false_value();
|
||||
return mrb_exec_recursive_paired(mrb, recursive_eql, range, obj, &obj);
|
||||
}
|
||||
|
||||
/* 15.2.14.4.15(x) */
|
||||
mrb_value
|
||||
range_initialize_copy(mrb_state *mrb, mrb_value copy)
|
||||
{
|
||||
mrb_value src;
|
||||
mrb_get_args(mrb, "o", &src);
|
||||
|
||||
if (mrb_obj_equal(mrb, copy, src)) return copy;
|
||||
//mrb_check_frozen(copy);
|
||||
if (!mrb_obj_is_instance_of(mrb, src, mrb_obj_class(mrb, copy))) {
|
||||
mrb_raise(mrb, E_TYPE_ERROR, "wrong argument class");
|
||||
}
|
||||
memcpy(mrb_range_ptr(copy), mrb_range_ptr(src), sizeof(struct RRange));
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
void
|
||||
mrb_init_range(mrb_state *mrb)
|
||||
{
|
||||
struct RClass *r;
|
||||
r = mrb->range_class = mrb_define_class(mrb, "Range", mrb->object_class);
|
||||
mrb_include_module(mrb, r, mrb_class_get(mrb, "Enumerable"));
|
||||
|
||||
mrb_define_method(mrb, r, "begin", mrb_range_beg, ARGS_NONE()); /* 15.2.14.4.3 */
|
||||
mrb_define_method(mrb, r, "end", mrb_range_end, ARGS_NONE()); /* 15.2.14.4.5 */
|
||||
mrb_define_method(mrb, r, "==", mrb_range_eq, ARGS_REQ(1)); /* 15.2.14.4.1 */
|
||||
mrb_define_method(mrb, r, "===", mrb_range_include, ARGS_REQ(1)); /* 15.2.14.4.2 */
|
||||
mrb_define_method(mrb, r, "each", mrb_range_each, ARGS_NONE()); /* 15.2.14.4.4 */
|
||||
mrb_define_method(mrb, r, "exclude_end?", mrb_range_excl, ARGS_NONE()); /* 15.2.14.4.6 */
|
||||
mrb_define_method(mrb, r, "first", mrb_range_beg, ARGS_NONE()); /* 15.2.14.4.7 */
|
||||
mrb_define_method(mrb, r, "include?", mrb_range_include, ARGS_REQ(1)); /* 15.2.14.4.8 */
|
||||
mrb_define_method(mrb, r, "initialize", mrb_range_initialize, ARGS_REQ(4)); /* 15.2.14.4.9 */
|
||||
mrb_define_method(mrb, r, "last", mrb_range_end, ARGS_NONE()); /* 15.2.14.4.10 */
|
||||
mrb_define_method(mrb, r, "member?", mrb_range_include, ARGS_REQ(1)); /* 15.2.14.4.11 */
|
||||
|
||||
mrb_define_method(mrb, r, "to_s", range_to_s, ARGS_NONE()); /* 15.2.14.4.12(x) */
|
||||
mrb_define_method(mrb, r, "inspect", range_inspect, ARGS_NONE()); /* 15.2.14.4.13(x) */
|
||||
mrb_define_method(mrb, r, "eql?", range_eql, ARGS_REQ(1)); /* 15.2.14.4.14(x) */
|
||||
mrb_define_method(mrb, r, "initialize_copy", range_initialize_copy, ARGS_REQ(1)); /* 15.2.14.4.15(x) */
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
/**********************************************************************
|
||||
|
||||
re.h -
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef RE_H
|
||||
#define RE_H
|
||||
|
||||
//#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "node.h"
|
||||
#include "regex.h"
|
||||
#include "encoding.h"
|
||||
|
||||
#define BEG(no) regs->beg[no]
|
||||
#define END(no) regs->end[no]
|
||||
|
||||
struct rmatch_offset {
|
||||
long beg;
|
||||
long end;
|
||||
};
|
||||
|
||||
struct rmatch {
|
||||
struct re_registers regs;
|
||||
|
||||
int char_offset_updated;
|
||||
int char_offset_num_allocated;
|
||||
struct rmatch_offset *char_offset;
|
||||
};
|
||||
|
||||
//struct RMatch {
|
||||
// MRUBY_OBJECT_HEADER;
|
||||
// mrb_value str;
|
||||
// struct re_registers *regs;
|
||||
//};
|
||||
struct RMatch {
|
||||
MRUBY_OBJECT_HEADER;
|
||||
mrb_value str;
|
||||
struct rmatch *rmatch;
|
||||
mrb_value regexp; /* RRegexp */
|
||||
};
|
||||
|
||||
struct RRegexp {
|
||||
MRUBY_OBJECT_HEADER;
|
||||
struct re_pattern_buffer *ptr;
|
||||
mrb_value src;
|
||||
unsigned long usecnt;
|
||||
};
|
||||
|
||||
#define mrb_regex_ptr(r) ((struct RRegexp*)((r).value.p))
|
||||
#define RREGEXP(r) ((struct RRegexp*)((r).value.p))
|
||||
#define RREGEXP_SRC(r) (RREGEXP(r)->src)
|
||||
#define RREGEXP_SRC_PTR(r) (((struct RString*)(RREGEXP_SRC(r).value.p))->buf)
|
||||
#define RREGEXP_SRC_LEN(r) RSTRING_LEN(RREGEXP(r)->src)
|
||||
int re_adjust_startpos(struct re_pattern_buffer *bufp, const char *string, int size, int startpos, int range);
|
||||
|
||||
typedef struct re_pattern_buffer Regexp;
|
||||
|
||||
//#define RMATCH(obj) (R_CAST(RMatch)(obj))
|
||||
#define RMATCH_REGS(v) (&((struct RMatch*)((v).value.p))->rmatch->regs)
|
||||
#define RMATCH(v) ((struct RMatch*)((v).value.p))
|
||||
#define mrb_match_ptr(v) ((struct RMatch*)((v).value.p))
|
||||
|
||||
int mrb_memcmp(const void *p1, const void *p2, int len);
|
||||
|
||||
mrb_int mrb_reg_search (mrb_state *mrb, mrb_value, mrb_value, mrb_int, mrb_int);
|
||||
mrb_value mrb_reg_regsub (mrb_state *mrb, mrb_value, mrb_value, struct re_registers *, mrb_value);
|
||||
//mrb_value mrb_reg_regsub(mrb_value, mrb_value, struct re_registers *, mrb_value);
|
||||
mrb_int mrb_reg_adjust_startpos(mrb_state *mrb, mrb_value re, mrb_value str, mrb_int pos, mrb_int reverse);
|
||||
void mrb_match_busy (mrb_value);
|
||||
|
||||
mrb_value mrb_reg_quote(mrb_state *mrb, mrb_value str);
|
||||
mrb_value mrb_reg_regcomp(mrb_state *mrb, mrb_value str);
|
||||
mrb_value mrb_reg_match_str(mrb_state *mrb, mrb_value re, mrb_value str);
|
||||
mrb_value mrb_reg_nth_match(mrb_state *mrb, mrb_int nth, mrb_value match);
|
||||
mrb_value mrb_backref_get(mrb_state *mrb);
|
||||
//mrb_int mrb_memsearch(const void *x0, mrb_int m, const void *y0, mrb_int n);
|
||||
mrb_value mrb_reg_to_s(mrb_state *mrb, mrb_value re);
|
||||
void mrb_backref_set(mrb_state *mrb, mrb_value val);
|
||||
mrb_value match_alloc(mrb_state *mrb);
|
||||
int mrb_reg_backref_number(mrb_state *mrb, mrb_value match, mrb_value backref);
|
||||
|
||||
#endif
|
||||
+6286
File diff suppressed because it is too large
Load Diff
+909
@@ -0,0 +1,909 @@
|
||||
/**********************************************************************
|
||||
regenc.c - Oniguruma (regular expression library)
|
||||
**********************************************************************/
|
||||
/*-
|
||||
* Copyright (c) 2002-2007 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "mruby.h"
|
||||
#ifdef INCLUDE_ENCODING
|
||||
#include <string.h>
|
||||
#include "regint.h"
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif
|
||||
|
||||
OnigEncoding OnigEncDefaultCharEncoding = ONIG_ENCODING_INIT_DEFAULT;
|
||||
|
||||
extern int
|
||||
onigenc_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern OnigEncoding
|
||||
onigenc_get_default_encoding(void)
|
||||
{
|
||||
return OnigEncDefaultCharEncoding;
|
||||
}
|
||||
|
||||
extern int
|
||||
onigenc_set_default_encoding(OnigEncoding enc)
|
||||
{
|
||||
OnigEncDefaultCharEncoding = enc;
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern int
|
||||
onigenc_mbclen_approximate(const OnigUChar* p,const OnigUChar* e, struct OnigEncodingTypeST* enc)
|
||||
{
|
||||
int ret = ONIGENC_PRECISE_MBC_ENC_LEN(enc,p,e);
|
||||
if (ONIGENC_MBCLEN_CHARFOUND_P(ret))
|
||||
return ONIGENC_MBCLEN_CHARFOUND_LEN(ret);
|
||||
else if (ONIGENC_MBCLEN_NEEDMORE_P(ret))
|
||||
return (int)(e-p)+ONIGENC_MBCLEN_NEEDMORE_LEN(ret);
|
||||
return 1;
|
||||
}
|
||||
|
||||
extern UChar*
|
||||
onigenc_get_right_adjust_char_head(OnigEncoding enc, const UChar* start, const UChar* s, const UChar* end)
|
||||
{
|
||||
UChar* p = ONIGENC_LEFT_ADJUST_CHAR_HEAD(enc, start, s, end);
|
||||
if (p < s) {
|
||||
p += enclen(enc, p, end);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
extern UChar*
|
||||
onigenc_get_right_adjust_char_head_with_prev(OnigEncoding enc,
|
||||
const UChar* start, const UChar* s, const UChar* end, const UChar** prev)
|
||||
{
|
||||
UChar* p = ONIGENC_LEFT_ADJUST_CHAR_HEAD(enc, start, s, end);
|
||||
|
||||
if (p < s) {
|
||||
if (prev) *prev = (const UChar* )p;
|
||||
p += enclen(enc, p, end);
|
||||
}
|
||||
else {
|
||||
if (prev) *prev = (const UChar* )NULL; /* Sorry */
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
extern UChar*
|
||||
onigenc_get_prev_char_head(OnigEncoding enc, const UChar* start, const UChar* s, const UChar* end)
|
||||
{
|
||||
if (s <= start)
|
||||
return (UChar* )NULL;
|
||||
|
||||
return ONIGENC_LEFT_ADJUST_CHAR_HEAD(enc, start, s - 1, end);
|
||||
}
|
||||
|
||||
extern UChar*
|
||||
onigenc_step_back(OnigEncoding enc, const UChar* start, const UChar* s, const UChar* end, int n)
|
||||
{
|
||||
while (ONIG_IS_NOT_NULL(s) && n-- > 0) {
|
||||
if (s <= start)
|
||||
return (UChar* )NULL;
|
||||
|
||||
s = ONIGENC_LEFT_ADJUST_CHAR_HEAD(enc, start, s - 1, end);
|
||||
}
|
||||
return (UChar* )s;
|
||||
}
|
||||
|
||||
extern UChar*
|
||||
onigenc_step(OnigEncoding enc, const UChar* p, const UChar* end, int n)
|
||||
{
|
||||
UChar* q = (UChar* )p;
|
||||
while (n-- > 0) {
|
||||
q += ONIGENC_MBC_ENC_LEN(enc, q, end);
|
||||
}
|
||||
return (q <= end ? q : NULL);
|
||||
}
|
||||
|
||||
extern int
|
||||
onigenc_strlen(OnigEncoding enc, const UChar* p, const UChar* end)
|
||||
{
|
||||
int n = 0;
|
||||
UChar* q = (UChar* )p;
|
||||
|
||||
while (q < end) {
|
||||
q += ONIGENC_MBC_ENC_LEN(enc, q, end);
|
||||
n++;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
extern int
|
||||
onigenc_strlen_null(OnigEncoding enc, const UChar* s)
|
||||
{
|
||||
int n = 0;
|
||||
UChar* p = (UChar* )s;
|
||||
UChar* e;
|
||||
|
||||
while (1) {
|
||||
if (*p == '\0') {
|
||||
UChar* q;
|
||||
int len = ONIGENC_MBC_MINLEN(enc);
|
||||
|
||||
if (len == 1) return n;
|
||||
q = p + 1;
|
||||
while (len > 1) {
|
||||
if (*q != '\0') break;
|
||||
q++;
|
||||
len--;
|
||||
}
|
||||
if (len == 1) return n;
|
||||
}
|
||||
e = p + ONIGENC_MBC_MAXLEN(enc);
|
||||
p += ONIGENC_MBC_ENC_LEN(enc, p, e);
|
||||
n++;
|
||||
}
|
||||
}
|
||||
|
||||
extern int
|
||||
onigenc_str_bytelen_null(OnigEncoding enc, const UChar* s)
|
||||
{
|
||||
UChar* start = (UChar* )s;
|
||||
UChar* p = (UChar* )s;
|
||||
UChar* e;
|
||||
|
||||
while (1) {
|
||||
if (*p == '\0') {
|
||||
UChar* q;
|
||||
int len = ONIGENC_MBC_MINLEN(enc);
|
||||
|
||||
if (len == 1) return (int )(p - start);
|
||||
q = p + 1;
|
||||
while (len > 1) {
|
||||
if (*q != '\0') break;
|
||||
q++;
|
||||
len--;
|
||||
}
|
||||
if (len == 1) return (int )(p - start);
|
||||
}
|
||||
e = p + ONIGENC_MBC_MAXLEN(enc);
|
||||
p += ONIGENC_MBC_ENC_LEN(enc, p, e);
|
||||
}
|
||||
}
|
||||
|
||||
const UChar OnigEncAsciiToLowerCaseTable[] = {
|
||||
'\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
|
||||
'\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017',
|
||||
'\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027',
|
||||
'\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037',
|
||||
'\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047',
|
||||
'\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057',
|
||||
'\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067',
|
||||
'\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077',
|
||||
'\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
|
||||
'\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
|
||||
'\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
|
||||
'\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137',
|
||||
'\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
|
||||
'\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
|
||||
'\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
|
||||
'\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177',
|
||||
'\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207',
|
||||
'\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217',
|
||||
'\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227',
|
||||
'\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237',
|
||||
'\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247',
|
||||
'\250', '\251', '\252', '\253', '\254', '\255', '\256', '\257',
|
||||
'\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267',
|
||||
'\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277',
|
||||
'\300', '\301', '\302', '\303', '\304', '\305', '\306', '\307',
|
||||
'\310', '\311', '\312', '\313', '\314', '\315', '\316', '\317',
|
||||
'\320', '\321', '\322', '\323', '\324', '\325', '\326', '\327',
|
||||
'\330', '\331', '\332', '\333', '\334', '\335', '\336', '\337',
|
||||
'\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
|
||||
'\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
|
||||
'\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
|
||||
'\370', '\371', '\372', '\373', '\374', '\375', '\376', '\377',
|
||||
};
|
||||
|
||||
#ifdef USE_UPPER_CASE_TABLE
|
||||
const UChar OnigEncAsciiToUpperCaseTable[256] = {
|
||||
'\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
|
||||
'\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017',
|
||||
'\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027',
|
||||
'\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037',
|
||||
'\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047',
|
||||
'\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057',
|
||||
'\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067',
|
||||
'\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077',
|
||||
'\100', '\101', '\102', '\103', '\104', '\105', '\106', '\107',
|
||||
'\110', '\111', '\112', '\113', '\114', '\115', '\116', '\117',
|
||||
'\120', '\121', '\122', '\123', '\124', '\125', '\126', '\127',
|
||||
'\130', '\131', '\132', '\133', '\134', '\135', '\136', '\137',
|
||||
'\140', '\101', '\102', '\103', '\104', '\105', '\106', '\107',
|
||||
'\110', '\111', '\112', '\113', '\114', '\115', '\116', '\117',
|
||||
'\120', '\121', '\122', '\123', '\124', '\125', '\126', '\127',
|
||||
'\130', '\131', '\132', '\173', '\174', '\175', '\176', '\177',
|
||||
'\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207',
|
||||
'\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217',
|
||||
'\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227',
|
||||
'\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237',
|
||||
'\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247',
|
||||
'\250', '\251', '\252', '\253', '\254', '\255', '\256', '\257',
|
||||
'\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267',
|
||||
'\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277',
|
||||
'\300', '\301', '\302', '\303', '\304', '\305', '\306', '\307',
|
||||
'\310', '\311', '\312', '\313', '\314', '\315', '\316', '\317',
|
||||
'\320', '\321', '\322', '\323', '\324', '\325', '\326', '\327',
|
||||
'\330', '\331', '\332', '\333', '\334', '\335', '\336', '\337',
|
||||
'\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
|
||||
'\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
|
||||
'\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
|
||||
'\370', '\371', '\372', '\373', '\374', '\375', '\376', '\377',
|
||||
};
|
||||
#endif
|
||||
|
||||
const unsigned short OnigEncAsciiCtypeTable[256] = {
|
||||
0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
|
||||
0x4008, 0x420c, 0x4209, 0x4208, 0x4208, 0x4208, 0x4008, 0x4008,
|
||||
0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
|
||||
0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
|
||||
0x4284, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
|
||||
0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
|
||||
0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0,
|
||||
0x78b0, 0x78b0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
|
||||
0x41a0, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x74a2,
|
||||
0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2,
|
||||
0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2,
|
||||
0x74a2, 0x74a2, 0x74a2, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x51a0,
|
||||
0x41a0, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x70e2,
|
||||
0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2,
|
||||
0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2,
|
||||
0x70e2, 0x70e2, 0x70e2, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x4008,
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
|
||||
};
|
||||
|
||||
const UChar OnigEncISO_8859_1_ToLowerCaseTable[256] = {
|
||||
'\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
|
||||
'\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017',
|
||||
'\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027',
|
||||
'\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037',
|
||||
'\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047',
|
||||
'\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057',
|
||||
'\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067',
|
||||
'\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077',
|
||||
'\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
|
||||
'\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
|
||||
'\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
|
||||
'\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137',
|
||||
'\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
|
||||
'\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
|
||||
'\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
|
||||
'\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177',
|
||||
'\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207',
|
||||
'\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217',
|
||||
'\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227',
|
||||
'\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237',
|
||||
'\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247',
|
||||
'\250', '\251', '\252', '\253', '\254', '\255', '\256', '\257',
|
||||
'\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267',
|
||||
'\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277',
|
||||
'\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
|
||||
'\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
|
||||
'\360', '\361', '\362', '\363', '\364', '\365', '\366', '\327',
|
||||
'\370', '\371', '\372', '\373', '\374', '\375', '\376', '\337',
|
||||
'\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
|
||||
'\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
|
||||
'\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
|
||||
'\370', '\371', '\372', '\373', '\374', '\375', '\376', '\377'
|
||||
};
|
||||
|
||||
#ifdef USE_UPPER_CASE_TABLE
|
||||
const UChar OnigEncISO_8859_1_ToUpperCaseTable[256] = {
|
||||
'\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
|
||||
'\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017',
|
||||
'\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027',
|
||||
'\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037',
|
||||
'\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047',
|
||||
'\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057',
|
||||
'\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067',
|
||||
'\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077',
|
||||
'\100', '\101', '\102', '\103', '\104', '\105', '\106', '\107',
|
||||
'\110', '\111', '\112', '\113', '\114', '\115', '\116', '\117',
|
||||
'\120', '\121', '\122', '\123', '\124', '\125', '\126', '\127',
|
||||
'\130', '\131', '\132', '\133', '\134', '\135', '\136', '\137',
|
||||
'\140', '\101', '\102', '\103', '\104', '\105', '\106', '\107',
|
||||
'\110', '\111', '\112', '\113', '\114', '\115', '\116', '\117',
|
||||
'\120', '\121', '\122', '\123', '\124', '\125', '\126', '\127',
|
||||
'\130', '\131', '\132', '\173', '\174', '\175', '\176', '\177',
|
||||
'\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207',
|
||||
'\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217',
|
||||
'\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227',
|
||||
'\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237',
|
||||
'\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247',
|
||||
'\250', '\251', '\252', '\253', '\254', '\255', '\256', '\257',
|
||||
'\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267',
|
||||
'\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277',
|
||||
'\300', '\301', '\302', '\303', '\304', '\305', '\306', '\307',
|
||||
'\310', '\311', '\312', '\313', '\314', '\315', '\316', '\317',
|
||||
'\320', '\321', '\322', '\323', '\324', '\325', '\326', '\327',
|
||||
'\330', '\331', '\332', '\333', '\334', '\335', '\336', '\337',
|
||||
'\300', '\301', '\302', '\303', '\304', '\305', '\306', '\307',
|
||||
'\310', '\311', '\312', '\313', '\314', '\315', '\316', '\317',
|
||||
'\320', '\321', '\322', '\323', '\324', '\325', '\326', '\367',
|
||||
'\330', '\331', '\332', '\333', '\334', '\335', '\336', '\377',
|
||||
};
|
||||
#endif
|
||||
|
||||
extern void
|
||||
onigenc_set_default_caseconv_table(const UChar* table ARG_UNUSED)
|
||||
{
|
||||
/* nothing */
|
||||
/* obsoleted. */
|
||||
}
|
||||
|
||||
extern UChar*
|
||||
onigenc_get_left_adjust_char_head(OnigEncoding enc, const UChar* start, const UChar* s, const UChar* end)
|
||||
{
|
||||
return ONIGENC_LEFT_ADJUST_CHAR_HEAD(enc, start, s, end);
|
||||
}
|
||||
|
||||
const OnigPairCaseFoldCodes OnigAsciiLowerMap[] = {
|
||||
{ 0x41, 0x61 },
|
||||
{ 0x42, 0x62 },
|
||||
{ 0x43, 0x63 },
|
||||
{ 0x44, 0x64 },
|
||||
{ 0x45, 0x65 },
|
||||
{ 0x46, 0x66 },
|
||||
{ 0x47, 0x67 },
|
||||
{ 0x48, 0x68 },
|
||||
{ 0x49, 0x69 },
|
||||
{ 0x4a, 0x6a },
|
||||
{ 0x4b, 0x6b },
|
||||
{ 0x4c, 0x6c },
|
||||
{ 0x4d, 0x6d },
|
||||
{ 0x4e, 0x6e },
|
||||
{ 0x4f, 0x6f },
|
||||
{ 0x50, 0x70 },
|
||||
{ 0x51, 0x71 },
|
||||
{ 0x52, 0x72 },
|
||||
{ 0x53, 0x73 },
|
||||
{ 0x54, 0x74 },
|
||||
{ 0x55, 0x75 },
|
||||
{ 0x56, 0x76 },
|
||||
{ 0x57, 0x77 },
|
||||
{ 0x58, 0x78 },
|
||||
{ 0x59, 0x79 },
|
||||
{ 0x5a, 0x7a }
|
||||
};
|
||||
|
||||
extern int
|
||||
onigenc_ascii_apply_all_case_fold(OnigCaseFoldType flag ARG_UNUSED,
|
||||
OnigApplyAllCaseFoldFunc f, void* arg,
|
||||
OnigEncoding enc ARG_UNUSED)
|
||||
{
|
||||
OnigCodePoint code;
|
||||
int i, r;
|
||||
|
||||
for (i = 0;
|
||||
i < (int )(sizeof(OnigAsciiLowerMap)/sizeof(OnigPairCaseFoldCodes));
|
||||
i++) {
|
||||
code = OnigAsciiLowerMap[i].to;
|
||||
r = (*f)(OnigAsciiLowerMap[i].from, &code, 1, arg);
|
||||
if (r != 0) return r;
|
||||
|
||||
code = OnigAsciiLowerMap[i].from;
|
||||
r = (*f)(OnigAsciiLowerMap[i].to, &code, 1, arg);
|
||||
if (r != 0) return r;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern int
|
||||
onigenc_ascii_get_case_fold_codes_by_str(OnigCaseFoldType flag ARG_UNUSED,
|
||||
const OnigUChar* p, const OnigUChar* end ARG_UNUSED, OnigCaseFoldCodeItem items[],
|
||||
OnigEncoding enc ARG_UNUSED)
|
||||
{
|
||||
if (0x41 <= *p && *p <= 0x5a) {
|
||||
items[0].byte_len = 1;
|
||||
items[0].code_len = 1;
|
||||
items[0].code[0] = (OnigCodePoint )(*p + 0x20);
|
||||
return 1;
|
||||
}
|
||||
else if (0x61 <= *p && *p <= 0x7a) {
|
||||
items[0].byte_len = 1;
|
||||
items[0].code_len = 1;
|
||||
items[0].code[0] = (OnigCodePoint )(*p - 0x20);
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
ss_apply_all_case_fold(OnigCaseFoldType flag ARG_UNUSED,
|
||||
OnigApplyAllCaseFoldFunc f, void* arg)
|
||||
{
|
||||
OnigCodePoint ss[] = { 0x73, 0x73 };
|
||||
|
||||
return (*f)((OnigCodePoint )0xdf, ss, 2, arg);
|
||||
}
|
||||
|
||||
extern int
|
||||
onigenc_apply_all_case_fold_with_map(int map_size,
|
||||
const OnigPairCaseFoldCodes map[],
|
||||
int ess_tsett_flag, OnigCaseFoldType flag,
|
||||
OnigApplyAllCaseFoldFunc f, void* arg)
|
||||
{
|
||||
OnigCodePoint code;
|
||||
int i, r;
|
||||
|
||||
r = onigenc_ascii_apply_all_case_fold(flag, f, arg, 0);
|
||||
if (r != 0) return r;
|
||||
|
||||
for (i = 0; i < map_size; i++) {
|
||||
code = map[i].to;
|
||||
r = (*f)(map[i].from, &code, 1, arg);
|
||||
if (r != 0) return r;
|
||||
|
||||
code = map[i].from;
|
||||
r = (*f)(map[i].to, &code, 1, arg);
|
||||
if (r != 0) return r;
|
||||
}
|
||||
|
||||
if (ess_tsett_flag != 0)
|
||||
return ss_apply_all_case_fold(flag, f, arg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern int
|
||||
onigenc_get_case_fold_codes_by_str_with_map(int map_size,
|
||||
const OnigPairCaseFoldCodes map[],
|
||||
int ess_tsett_flag, OnigCaseFoldType flag ARG_UNUSED,
|
||||
const OnigUChar* p, const OnigUChar* end, OnigCaseFoldCodeItem items[])
|
||||
{
|
||||
if (0x41 <= *p && *p <= 0x5a) {
|
||||
items[0].byte_len = 1;
|
||||
items[0].code_len = 1;
|
||||
items[0].code[0] = (OnigCodePoint )(*p + 0x20);
|
||||
if (*p == 0x53 && ess_tsett_flag != 0 && end > p + 1
|
||||
&& (*(p+1) == 0x53 || *(p+1) == 0x73)) {
|
||||
/* SS */
|
||||
items[1].byte_len = 2;
|
||||
items[1].code_len = 1;
|
||||
items[1].code[0] = (OnigCodePoint )0xdf;
|
||||
return 2;
|
||||
}
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
else if (0x61 <= *p && *p <= 0x7a) {
|
||||
items[0].byte_len = 1;
|
||||
items[0].code_len = 1;
|
||||
items[0].code[0] = (OnigCodePoint )(*p - 0x20);
|
||||
if (*p == 0x73 && ess_tsett_flag != 0 && end > p + 1
|
||||
&& (*(p+1) == 0x73 || *(p+1) == 0x53)) {
|
||||
/* ss */
|
||||
items[1].byte_len = 2;
|
||||
items[1].code_len = 1;
|
||||
items[1].code[0] = (OnigCodePoint )0xdf;
|
||||
return 2;
|
||||
}
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
else if (*p == 0xdf && ess_tsett_flag != 0) {
|
||||
items[0].byte_len = 1;
|
||||
items[0].code_len = 2;
|
||||
items[0].code[0] = (OnigCodePoint )'s';
|
||||
items[0].code[1] = (OnigCodePoint )'s';
|
||||
|
||||
items[1].byte_len = 1;
|
||||
items[1].code_len = 2;
|
||||
items[1].code[0] = (OnigCodePoint )'S';
|
||||
items[1].code[1] = (OnigCodePoint )'S';
|
||||
|
||||
items[2].byte_len = 1;
|
||||
items[2].code_len = 2;
|
||||
items[2].code[0] = (OnigCodePoint )'s';
|
||||
items[2].code[1] = (OnigCodePoint )'S';
|
||||
|
||||
items[3].byte_len = 1;
|
||||
items[3].code_len = 2;
|
||||
items[3].code[0] = (OnigCodePoint )'S';
|
||||
items[3].code[1] = (OnigCodePoint )'s';
|
||||
|
||||
return 4;
|
||||
}
|
||||
else {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < map_size; i++) {
|
||||
if (*p == map[i].from) {
|
||||
items[0].byte_len = 1;
|
||||
items[0].code_len = 1;
|
||||
items[0].code[0] = map[i].to;
|
||||
return 1;
|
||||
}
|
||||
else if (*p == map[i].to) {
|
||||
items[0].byte_len = 1;
|
||||
items[0].code_len = 1;
|
||||
items[0].code[0] = map[i].from;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
extern int
|
||||
onigenc_not_support_get_ctype_code_range(OnigCtype ctype,
|
||||
OnigCodePoint* sb_out, const OnigCodePoint* ranges[],
|
||||
OnigEncoding enc)
|
||||
{
|
||||
return ONIG_NO_SUPPORT_CONFIG;
|
||||
}
|
||||
|
||||
extern int
|
||||
onigenc_is_mbc_newline_0x0a(const UChar* p, const UChar* end, OnigEncoding enc ARG_UNUSED)
|
||||
{
|
||||
if (p < end) {
|
||||
if (*p == 0x0a) return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* for single byte encodings */
|
||||
extern int
|
||||
onigenc_ascii_mbc_case_fold(OnigCaseFoldType flag ARG_UNUSED, const UChar** p,
|
||||
const UChar*end, UChar* lower, OnigEncoding enc ARG_UNUSED)
|
||||
{
|
||||
*lower = ONIGENC_ASCII_CODE_TO_LOWER_CASE(**p);
|
||||
|
||||
(*p)++;
|
||||
return 1; /* return byte length of converted char to lower */
|
||||
}
|
||||
|
||||
extern int
|
||||
onigenc_single_byte_mbc_enc_len(const UChar* p ARG_UNUSED, const UChar* e ARG_UNUSED,
|
||||
OnigEncoding enc ARG_UNUSED)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
extern OnigCodePoint
|
||||
onigenc_single_byte_mbc_to_code(const UChar* p, const UChar* end ARG_UNUSED,
|
||||
OnigEncoding enc ARG_UNUSED)
|
||||
{
|
||||
return (OnigCodePoint )(*p);
|
||||
}
|
||||
|
||||
extern int
|
||||
onigenc_single_byte_code_to_mbclen(OnigCodePoint code ARG_UNUSED, OnigEncoding enc ARG_UNUSED)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
extern int
|
||||
onigenc_single_byte_code_to_mbc(OnigCodePoint code, UChar *buf, OnigEncoding enc ARG_UNUSED)
|
||||
{
|
||||
*buf = (UChar )(code & 0xff);
|
||||
return 1;
|
||||
}
|
||||
|
||||
extern UChar*
|
||||
onigenc_single_byte_left_adjust_char_head(const UChar* start ARG_UNUSED, const UChar* s,
|
||||
const UChar* end,
|
||||
OnigEncoding enc ARG_UNUSED)
|
||||
{
|
||||
return (UChar* )s;
|
||||
}
|
||||
|
||||
extern int
|
||||
onigenc_always_true_is_allowed_reverse_match(const UChar* s ARG_UNUSED, const UChar* end ARG_UNUSED,
|
||||
OnigEncoding enc ARG_UNUSED)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
extern int
|
||||
onigenc_always_false_is_allowed_reverse_match(const UChar* s ARG_UNUSED, const UChar* end ARG_UNUSED,
|
||||
OnigEncoding enc ARG_UNUSED)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
extern int
|
||||
onigenc_ascii_is_code_ctype(OnigCodePoint code, unsigned int ctype,
|
||||
OnigEncoding enc ARG_UNUSED)
|
||||
{
|
||||
if (code < 128)
|
||||
return ONIGENC_IS_ASCII_CODE_CTYPE(code, ctype);
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
extern OnigCodePoint
|
||||
onigenc_mbn_mbc_to_code(OnigEncoding enc, const UChar* p, const UChar* end)
|
||||
{
|
||||
int c, i, len;
|
||||
OnigCodePoint n;
|
||||
|
||||
len = enclen(enc, p, end);
|
||||
n = (OnigCodePoint )(*p++);
|
||||
if (len == 1) return n;
|
||||
|
||||
for (i = 1; i < len; i++) {
|
||||
if (p >= end) break;
|
||||
c = *p++;
|
||||
n <<= 8; n += c;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
extern int
|
||||
onigenc_mbn_mbc_case_fold(OnigEncoding enc, OnigCaseFoldType flag ARG_UNUSED,
|
||||
const UChar** pp, const UChar* end ARG_UNUSED,
|
||||
UChar* lower)
|
||||
{
|
||||
int len;
|
||||
const UChar *p = *pp;
|
||||
|
||||
if (ONIGENC_IS_MBC_ASCII(p)) {
|
||||
*lower = ONIGENC_ASCII_CODE_TO_LOWER_CASE(*p);
|
||||
(*pp)++;
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
int i;
|
||||
|
||||
len = enclen(enc, p, end);
|
||||
for (i = 0; i < len; i++) {
|
||||
*lower++ = *p++;
|
||||
}
|
||||
(*pp) += len;
|
||||
return len; /* return byte length of converted to lower char */
|
||||
}
|
||||
}
|
||||
|
||||
extern int
|
||||
onigenc_mb2_code_to_mbclen(OnigCodePoint code, OnigEncoding enc ARG_UNUSED)
|
||||
{
|
||||
if ((code & 0xff00) != 0) return 2;
|
||||
else return 1;
|
||||
}
|
||||
|
||||
extern int
|
||||
onigenc_mb4_code_to_mbclen(OnigCodePoint code, OnigEncoding enc ARG_UNUSED)
|
||||
{
|
||||
if ((code & 0xff000000) != 0) return 4;
|
||||
else if ((code & 0xff0000) != 0) return 3;
|
||||
else if ((code & 0xff00) != 0) return 2;
|
||||
else return 1;
|
||||
}
|
||||
|
||||
extern int
|
||||
onigenc_mb2_code_to_mbc(OnigEncoding enc, OnigCodePoint code, UChar *buf)
|
||||
{
|
||||
UChar *p = buf;
|
||||
|
||||
if ((code & 0xff00) != 0) {
|
||||
*p++ = (UChar )((code >> 8) & 0xff);
|
||||
}
|
||||
*p++ = (UChar )(code & 0xff);
|
||||
|
||||
if (enclen(enc, buf, p) != (p - buf))
|
||||
return ONIGERR_INVALID_CODE_POINT_VALUE;
|
||||
return (int)(p - buf);
|
||||
}
|
||||
|
||||
extern int
|
||||
onigenc_mb4_code_to_mbc(OnigEncoding enc, OnigCodePoint code, UChar *buf)
|
||||
{
|
||||
UChar *p = buf;
|
||||
|
||||
if ((code & 0xff000000) != 0) {
|
||||
*p++ = (UChar )((code >> 24) & 0xff);
|
||||
}
|
||||
if ((code & 0xff0000) != 0 || p != buf) {
|
||||
*p++ = (UChar )((code >> 16) & 0xff);
|
||||
}
|
||||
if ((code & 0xff00) != 0 || p != buf) {
|
||||
*p++ = (UChar )((code >> 8) & 0xff);
|
||||
}
|
||||
*p++ = (UChar )(code & 0xff);
|
||||
|
||||
if (enclen(enc, buf, p) != (p - buf))
|
||||
return ONIGERR_INVALID_CODE_POINT_VALUE;
|
||||
return (int)(p - buf);
|
||||
}
|
||||
|
||||
extern int
|
||||
onigenc_minimum_property_name_to_ctype(OnigEncoding enc, UChar* p, UChar* end)
|
||||
{
|
||||
static const PosixBracketEntryType PBS[] = {
|
||||
PosixBracketEntryInit("Alnum", ONIGENC_CTYPE_ALNUM),
|
||||
PosixBracketEntryInit("Alpha", ONIGENC_CTYPE_ALPHA),
|
||||
PosixBracketEntryInit("Blank", ONIGENC_CTYPE_BLANK),
|
||||
PosixBracketEntryInit("Cntrl", ONIGENC_CTYPE_CNTRL),
|
||||
PosixBracketEntryInit("Digit", ONIGENC_CTYPE_DIGIT),
|
||||
PosixBracketEntryInit("Graph", ONIGENC_CTYPE_GRAPH),
|
||||
PosixBracketEntryInit("Lower", ONIGENC_CTYPE_LOWER),
|
||||
PosixBracketEntryInit("Print", ONIGENC_CTYPE_PRINT),
|
||||
PosixBracketEntryInit("Punct", ONIGENC_CTYPE_PUNCT),
|
||||
PosixBracketEntryInit("Space", ONIGENC_CTYPE_SPACE),
|
||||
PosixBracketEntryInit("Upper", ONIGENC_CTYPE_UPPER),
|
||||
PosixBracketEntryInit("XDigit", ONIGENC_CTYPE_XDIGIT),
|
||||
PosixBracketEntryInit("ASCII", ONIGENC_CTYPE_ASCII),
|
||||
PosixBracketEntryInit("Word", ONIGENC_CTYPE_WORD),
|
||||
};
|
||||
|
||||
const PosixBracketEntryType *pb, *pbe;
|
||||
int len;
|
||||
|
||||
len = onigenc_strlen(enc, p, end);
|
||||
for (pbe = (pb = PBS) + sizeof(PBS)/sizeof(PBS[0]); pb < pbe; ++pb) {
|
||||
if (len == pb->len &&
|
||||
onigenc_with_ascii_strncmp(enc, p, end, pb->name, pb->len) == 0)
|
||||
return pb->ctype;
|
||||
}
|
||||
|
||||
return ONIGERR_INVALID_CHAR_PROPERTY_NAME;
|
||||
}
|
||||
|
||||
extern int
|
||||
onigenc_mb2_is_code_ctype(OnigEncoding enc, OnigCodePoint code,
|
||||
unsigned int ctype)
|
||||
{
|
||||
if (code < 128)
|
||||
return ONIGENC_IS_ASCII_CODE_CTYPE(code, ctype);
|
||||
else {
|
||||
if (CTYPE_IS_WORD_GRAPH_PRINT(ctype)) {
|
||||
return (ONIGENC_CODE_TO_MBCLEN(enc, code) > 1 ? TRUE : FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
extern int
|
||||
onigenc_mb4_is_code_ctype(OnigEncoding enc, OnigCodePoint code,
|
||||
unsigned int ctype)
|
||||
{
|
||||
if (code < 128)
|
||||
return ONIGENC_IS_ASCII_CODE_CTYPE(code, ctype);
|
||||
else {
|
||||
if (CTYPE_IS_WORD_GRAPH_PRINT(ctype)) {
|
||||
return (ONIGENC_CODE_TO_MBCLEN(enc, code) > 1 ? TRUE : FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
extern int
|
||||
onigenc_with_ascii_strncmp(OnigEncoding enc, const UChar* p, const UChar* end,
|
||||
const UChar* sascii /* ascii */, int n)
|
||||
{
|
||||
int x, c;
|
||||
|
||||
while (n-- > 0) {
|
||||
if (p >= end) return (int )(*sascii);
|
||||
|
||||
c = (int )ONIGENC_MBC_TO_CODE(enc, p, end);
|
||||
x = *sascii - c;
|
||||
if (x) return x;
|
||||
|
||||
sascii++;
|
||||
p += enclen(enc, p, end);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Property management */
|
||||
static int
|
||||
resize_property_list(int new_size, const OnigCodePoint*** plist, int* psize)
|
||||
{
|
||||
size_t size;
|
||||
const OnigCodePoint **list = *plist;
|
||||
|
||||
size = sizeof(OnigCodePoint*) * new_size;
|
||||
if (IS_NULL(list)) {
|
||||
list = (const OnigCodePoint** )xmalloc(size);
|
||||
}
|
||||
else {
|
||||
list = (const OnigCodePoint** )xrealloc((void* )list, size);
|
||||
}
|
||||
|
||||
if (IS_NULL(list)) return ONIGERR_MEMORY;
|
||||
|
||||
*plist = list;
|
||||
*psize = new_size;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern int
|
||||
onigenc_property_list_add_property(UChar* name, const OnigCodePoint* prop,
|
||||
hash_table_type **table, const OnigCodePoint*** plist, int *pnum,
|
||||
int *psize)
|
||||
{
|
||||
#define PROP_INIT_SIZE 16
|
||||
|
||||
int r;
|
||||
|
||||
if (*psize <= *pnum) {
|
||||
int new_size = (*psize == 0 ? PROP_INIT_SIZE : *psize * 2);
|
||||
r = resize_property_list(new_size, plist, psize);
|
||||
if (r != 0) return r;
|
||||
}
|
||||
|
||||
(*plist)[*pnum] = prop;
|
||||
|
||||
if (ONIG_IS_NULL(*table)) {
|
||||
*table = onig_st_init_strend_table_with_size(PROP_INIT_SIZE);
|
||||
if (ONIG_IS_NULL(*table)) return ONIGERR_MEMORY;
|
||||
}
|
||||
|
||||
*pnum = *pnum + 1;
|
||||
onig_st_insert_strend(*table, name, name + strlen((char* )name),
|
||||
(hash_data_type )(*pnum + ONIGENC_MAX_STD_CTYPE));
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern int
|
||||
onigenc_property_list_init(int (*f)(void))
|
||||
{
|
||||
int r;
|
||||
|
||||
THREAD_ATOMIC_START;
|
||||
|
||||
r = f();
|
||||
|
||||
THREAD_ATOMIC_END;
|
||||
return r;
|
||||
}
|
||||
#endif //INCLUDE_ENCODING
|
||||
+203
@@ -0,0 +1,203 @@
|
||||
#ifndef ONIGURUMA_REGENC_H
|
||||
#define ONIGURUMA_REGENC_H
|
||||
/**********************************************************************
|
||||
regenc.h - Oniguruma (regular expression library)
|
||||
**********************************************************************/
|
||||
/*-
|
||||
* Copyright (c) 2002-2008 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#define RUBY
|
||||
|
||||
#ifndef mrb_compile_warn
|
||||
#define mrb_compile_warn(a,b,c,d) printf(c,d)
|
||||
#endif
|
||||
|
||||
#ifndef REGINT_H
|
||||
#ifdef ONIG_ESCAPE_UCHAR_COLLISION
|
||||
#undef ONIG_ESCAPE_UCHAR_COLLISION
|
||||
#endif
|
||||
#endif
|
||||
#include "oniguruma.h"
|
||||
|
||||
typedef struct {
|
||||
OnigCodePoint from;
|
||||
OnigCodePoint to;
|
||||
} OnigPairCaseFoldCodes;
|
||||
|
||||
|
||||
#ifndef ARG_UNUSED
|
||||
#if defined(__GNUC__)
|
||||
# define ARG_UNUSED __attribute__ ((unused))
|
||||
#else
|
||||
# define ARG_UNUSED
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define ONIG_IS_NULL(p) (((void*)(p)) == (void*)0)
|
||||
#define ONIG_IS_NOT_NULL(p) (((void*)(p)) != (void*)0)
|
||||
#define ONIG_CHECK_NULL_RETURN(p) if (ONIG_IS_NULL(p)) return NULL
|
||||
#define ONIG_CHECK_NULL_RETURN_VAL(p,val) if (ONIG_IS_NULL(p)) return (val)
|
||||
|
||||
#define enclen(enc,p,e) ((enc->max_enc_len == enc->min_enc_len) ? enc->min_enc_len : ONIGENC_MBC_ENC_LEN(enc,p,e))
|
||||
|
||||
/* character types bit flag */
|
||||
#define BIT_CTYPE_NEWLINE (1<< ONIGENC_CTYPE_NEWLINE)
|
||||
#define BIT_CTYPE_ALPHA (1<< ONIGENC_CTYPE_ALPHA)
|
||||
#define BIT_CTYPE_BLANK (1<< ONIGENC_CTYPE_BLANK)
|
||||
#define BIT_CTYPE_CNTRL (1<< ONIGENC_CTYPE_CNTRL)
|
||||
#define BIT_CTYPE_DIGIT (1<< ONIGENC_CTYPE_DIGIT)
|
||||
#define BIT_CTYPE_GRAPH (1<< ONIGENC_CTYPE_GRAPH)
|
||||
#define BIT_CTYPE_LOWER (1<< ONIGENC_CTYPE_LOWER)
|
||||
#define BIT_CTYPE_PRINT (1<< ONIGENC_CTYPE_PRINT)
|
||||
#define BIT_CTYPE_PUNCT (1<< ONIGENC_CTYPE_PUNCT)
|
||||
#define BIT_CTYPE_SPACE (1<< ONIGENC_CTYPE_SPACE)
|
||||
#define BIT_CTYPE_UPPER (1<< ONIGENC_CTYPE_UPPER)
|
||||
#define BIT_CTYPE_XDIGIT (1<< ONIGENC_CTYPE_XDIGIT)
|
||||
#define BIT_CTYPE_WORD (1<< ONIGENC_CTYPE_WORD)
|
||||
#define BIT_CTYPE_ALNUM (1<< ONIGENC_CTYPE_ALNUM)
|
||||
#define BIT_CTYPE_ASCII (1<< ONIGENC_CTYPE_ASCII)
|
||||
|
||||
#define CTYPE_TO_BIT(ctype) (1<<(ctype))
|
||||
#define CTYPE_IS_WORD_GRAPH_PRINT(ctype) \
|
||||
((ctype) == ONIGENC_CTYPE_WORD || (ctype) == ONIGENC_CTYPE_GRAPH ||\
|
||||
(ctype) == ONIGENC_CTYPE_PRINT)
|
||||
|
||||
|
||||
typedef struct {
|
||||
const UChar *name;
|
||||
int ctype;
|
||||
short int len;
|
||||
} PosixBracketEntryType;
|
||||
|
||||
#define PosixBracketEntryInit(name, ctype) {(const UChar *)name, ctype, (short int)(sizeof(name) - 1)}
|
||||
|
||||
/* #define USE_CRNL_AS_LINE_TERMINATOR */
|
||||
#define USE_UNICODE_PROPERTIES
|
||||
/* #define USE_UNICODE_CASE_FOLD_TURKISH_AZERI */
|
||||
/* #define USE_UNICODE_ALL_LINE_TERMINATORS */ /* see Unicode.org UTF#18 */
|
||||
|
||||
|
||||
#define ONIG_ENCODING_INIT_DEFAULT ONIG_ENCODING_ASCII
|
||||
|
||||
/* for encoding system implementation (internal) */
|
||||
ONIG_EXTERN int onigenc_ascii_apply_all_case_fold(OnigCaseFoldType flag, OnigApplyAllCaseFoldFunc f, void* arg, OnigEncoding enc);
|
||||
ONIG_EXTERN int onigenc_ascii_get_case_fold_codes_by_str(OnigCaseFoldType flag, const OnigUChar* p, const OnigUChar* end, OnigCaseFoldCodeItem items[], OnigEncoding enc);
|
||||
ONIG_EXTERN int onigenc_apply_all_case_fold_with_map(int map_size, const OnigPairCaseFoldCodes map[], int ess_tsett_flag, OnigCaseFoldType flag, OnigApplyAllCaseFoldFunc f, void* arg);
|
||||
ONIG_EXTERN int onigenc_get_case_fold_codes_by_str_with_map(int map_size, const OnigPairCaseFoldCodes map[], int ess_tsett_flag, OnigCaseFoldType flag, const OnigUChar* p, const OnigUChar* end, OnigCaseFoldCodeItem items[]);
|
||||
ONIG_EXTERN int onigenc_not_support_get_ctype_code_range(OnigCtype ctype, OnigCodePoint* sb_out, const OnigCodePoint* ranges[], OnigEncoding enc);
|
||||
ONIG_EXTERN int onigenc_is_mbc_newline_0x0a(const UChar* p, const UChar* end, OnigEncoding enc);
|
||||
|
||||
/* methods for single byte encoding */
|
||||
ONIG_EXTERN int onigenc_ascii_mbc_case_fold(OnigCaseFoldType flag, const UChar** p, const UChar* end, UChar* lower, OnigEncoding enc);
|
||||
ONIG_EXTERN int onigenc_single_byte_mbc_enc_len(const UChar* p, const UChar* e, OnigEncoding enc);
|
||||
ONIG_EXTERN OnigCodePoint onigenc_single_byte_mbc_to_code(const UChar* p, const UChar* end, OnigEncoding enc);
|
||||
ONIG_EXTERN int onigenc_single_byte_code_to_mbclen(OnigCodePoint code, OnigEncoding enc);
|
||||
ONIG_EXTERN int onigenc_single_byte_code_to_mbc(OnigCodePoint code, UChar *buf, OnigEncoding enc);
|
||||
ONIG_EXTERN UChar* onigenc_single_byte_left_adjust_char_head(const UChar* start, const UChar* s, const OnigUChar* end, OnigEncoding enc);
|
||||
ONIG_EXTERN int onigenc_always_true_is_allowed_reverse_match(const UChar* s, const UChar* end, OnigEncoding enc);
|
||||
ONIG_EXTERN int onigenc_always_false_is_allowed_reverse_match(const UChar* s, const UChar* end, OnigEncoding enc);
|
||||
ONIG_EXTERN int onigenc_ascii_is_code_ctype(OnigCodePoint code, unsigned int ctype, OnigEncoding enc);
|
||||
|
||||
/* methods for multi byte encoding */
|
||||
ONIG_EXTERN OnigCodePoint onigenc_mbn_mbc_to_code(OnigEncoding enc, const UChar* p, const UChar* end);
|
||||
ONIG_EXTERN int onigenc_mbn_mbc_case_fold(OnigEncoding enc, OnigCaseFoldType flag, const UChar** p, const UChar* end, UChar* lower);
|
||||
ONIG_EXTERN int onigenc_mb2_code_to_mbclen(OnigCodePoint code, OnigEncoding enc);
|
||||
ONIG_EXTERN int onigenc_mb2_code_to_mbc(OnigEncoding enc, OnigCodePoint code, UChar *buf);
|
||||
ONIG_EXTERN int onigenc_minimum_property_name_to_ctype(OnigEncoding enc, UChar* p, UChar* end);
|
||||
ONIG_EXTERN int onigenc_unicode_property_name_to_ctype(OnigEncoding enc, UChar* p, UChar* end);
|
||||
ONIG_EXTERN int onigenc_mb2_is_code_ctype(OnigEncoding enc, OnigCodePoint code, unsigned int ctype);
|
||||
ONIG_EXTERN int onigenc_mb4_code_to_mbclen(OnigCodePoint code, OnigEncoding enc);
|
||||
ONIG_EXTERN int onigenc_mb4_code_to_mbc(OnigEncoding enc, OnigCodePoint code, UChar *buf);
|
||||
ONIG_EXTERN int onigenc_mb4_is_code_ctype(OnigEncoding enc, OnigCodePoint code, unsigned int ctype);
|
||||
|
||||
|
||||
/* in enc/unicode.c */
|
||||
ONIG_EXTERN int onigenc_unicode_is_code_ctype(OnigCodePoint code, unsigned int ctype, OnigEncoding enc);
|
||||
ONIG_EXTERN int onigenc_utf16_32_get_ctype_code_range(OnigCtype ctype, OnigCodePoint *sb_out, const OnigCodePoint* ranges[], OnigEncoding enc);
|
||||
ONIG_EXTERN int onigenc_unicode_ctype_code_range(int ctype, const OnigCodePoint* ranges[]);
|
||||
ONIG_EXTERN int onigenc_unicode_get_case_fold_codes_by_str(OnigEncoding enc, OnigCaseFoldType flag, const OnigUChar* p, const OnigUChar* end, OnigCaseFoldCodeItem items[]);
|
||||
ONIG_EXTERN int onigenc_unicode_mbc_case_fold(OnigEncoding enc, OnigCaseFoldType flag, const UChar** pp, const UChar* end, UChar* fold);
|
||||
ONIG_EXTERN int onigenc_unicode_apply_all_case_fold(OnigCaseFoldType flag, OnigApplyAllCaseFoldFunc f, void* arg, OnigEncoding enc);
|
||||
|
||||
|
||||
#define UTF16_IS_SURROGATE_FIRST(c) (((c) & 0xfc) == 0xd8)
|
||||
#define UTF16_IS_SURROGATE_SECOND(c) (((c) & 0xfc) == 0xdc)
|
||||
|
||||
#define ONIGENC_ISO_8859_1_TO_LOWER_CASE(c) \
|
||||
OnigEncISO_8859_1_ToLowerCaseTable[c]
|
||||
#define ONIGENC_ISO_8859_1_TO_UPPER_CASE(c) \
|
||||
OnigEncISO_8859_1_ToUpperCaseTable[c]
|
||||
|
||||
ONIG_EXTERN const UChar OnigEncISO_8859_1_ToLowerCaseTable[];
|
||||
ONIG_EXTERN const UChar OnigEncISO_8859_1_ToUpperCaseTable[];
|
||||
|
||||
ONIG_EXTERN int
|
||||
onigenc_with_ascii_strncmp(OnigEncoding enc, const UChar* p, const UChar* end, const UChar* sascii /* ascii */, int n);
|
||||
ONIG_EXTERN UChar*
|
||||
onigenc_step(OnigEncoding enc, const UChar* p, const UChar* end, int n);
|
||||
|
||||
/* defined in regexec.c, but used in enc/xxx.c */
|
||||
extern int onig_is_in_code_range (const UChar* p, OnigCodePoint code);
|
||||
|
||||
ONIG_EXTERN OnigEncoding OnigEncDefaultCharEncoding;
|
||||
ONIG_EXTERN const UChar OnigEncAsciiToLowerCaseTable[];
|
||||
ONIG_EXTERN const UChar OnigEncAsciiToUpperCaseTable[];
|
||||
ONIG_EXTERN const unsigned short OnigEncAsciiCtypeTable[];
|
||||
|
||||
#define ONIGENC_IS_ASCII_CODE(code) ((code) < 0x80)
|
||||
#define ONIGENC_ASCII_CODE_TO_LOWER_CASE(c) OnigEncAsciiToLowerCaseTable[c]
|
||||
#define ONIGENC_ASCII_CODE_TO_UPPER_CASE(c) OnigEncAsciiToUpperCaseTable[c]
|
||||
#define ONIGENC_IS_ASCII_CODE_CTYPE(code,ctype) \
|
||||
((OnigEncAsciiCtypeTable[code] & CTYPE_TO_BIT(ctype)) != 0)
|
||||
#define ONIGENC_IS_ASCII_CODE_CASE_AMBIG(code) \
|
||||
(ONIGENC_IS_ASCII_CODE_CTYPE(code, ONIGENC_CTYPE_UPPER) ||\
|
||||
ONIGENC_IS_ASCII_CODE_CTYPE(code, ONIGENC_CTYPE_LOWER))
|
||||
|
||||
#ifdef ONIG_ENC_REGISTER
|
||||
extern int ONIG_ENC_REGISTER(const char *, OnigEncodingType*);
|
||||
#define OnigEncodingName(n) encoding_##n
|
||||
#define OnigEncodingDeclare(n) static OnigEncodingType OnigEncodingName(n)
|
||||
#define OnigEncodingDefine(f,n) \
|
||||
OnigEncodingDeclare(n); \
|
||||
void Init_##f(void) { \
|
||||
ONIG_ENC_REGISTER(OnigEncodingName(n).name, \
|
||||
&OnigEncodingName(n)); \
|
||||
} \
|
||||
OnigEncodingDeclare(n)
|
||||
#else
|
||||
#define OnigEncodingName(n) OnigEncoding##n
|
||||
#define OnigEncodingDeclare(n) OnigEncodingType OnigEncodingName(n)
|
||||
#define OnigEncodingDefine(f,n) OnigEncodingDeclare(n)
|
||||
#endif
|
||||
|
||||
/* macros for define replica encoding and encoding alias */
|
||||
#define ENC_REPLICATE(name, orig)
|
||||
#define ENC_ALIAS(name, orig)
|
||||
#define ENC_DUMMY(name)
|
||||
|
||||
#endif /* ONIGURUMA_REGENC_H */
|
||||
+375
@@ -0,0 +1,375 @@
|
||||
/**********************************************************************
|
||||
regerror.c - Oniguruma (regular expression library)
|
||||
**********************************************************************/
|
||||
/*-
|
||||
* Copyright (c) 2002-2007 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "mruby.h"
|
||||
#ifdef INCLUDE_REGEXP
|
||||
#include <string.h>
|
||||
#include "regint.h"
|
||||
#include <stdio.h> /* for vsnprintf() */
|
||||
#include <stdarg.h>
|
||||
|
||||
extern UChar*
|
||||
onig_error_code_to_format(int code)
|
||||
{
|
||||
const char *p;
|
||||
|
||||
if (code >= 0) return (UChar* )0;
|
||||
|
||||
switch (code) {
|
||||
case ONIG_MISMATCH:
|
||||
p = "mismatch"; break;
|
||||
case ONIG_NO_SUPPORT_CONFIG:
|
||||
p = "no support in this configuration"; break;
|
||||
case ONIGERR_MEMORY:
|
||||
p = "failed to allocate memory"; break;
|
||||
case ONIGERR_MATCH_STACK_LIMIT_OVER:
|
||||
p = "match-stack limit over"; break;
|
||||
case ONIGERR_TYPE_BUG:
|
||||
p = "undefined type (bug)"; break;
|
||||
case ONIGERR_PARSER_BUG:
|
||||
p = "internal parser error (bug)"; break;
|
||||
case ONIGERR_STACK_BUG:
|
||||
p = "stack error (bug)"; break;
|
||||
case ONIGERR_UNDEFINED_BYTECODE:
|
||||
p = "undefined bytecode (bug)"; break;
|
||||
case ONIGERR_UNEXPECTED_BYTECODE:
|
||||
p = "unexpected bytecode (bug)"; break;
|
||||
case ONIGERR_DEFAULT_ENCODING_IS_NOT_SETTED:
|
||||
p = "default multibyte-encoding is not setted"; break;
|
||||
case ONIGERR_SPECIFIED_ENCODING_CANT_CONVERT_TO_WIDE_CHAR:
|
||||
p = "can't convert to wide-char on specified multibyte-encoding"; break;
|
||||
case ONIGERR_INVALID_ARGUMENT:
|
||||
p = "invalid argument"; break;
|
||||
case ONIGERR_END_PATTERN_AT_LEFT_BRACE:
|
||||
p = "end pattern at left brace"; break;
|
||||
case ONIGERR_END_PATTERN_AT_LEFT_BRACKET:
|
||||
p = "end pattern at left bracket"; break;
|
||||
case ONIGERR_EMPTY_CHAR_CLASS:
|
||||
p = "empty char-class"; break;
|
||||
case ONIGERR_PREMATURE_END_OF_CHAR_CLASS:
|
||||
p = "premature end of char-class"; break;
|
||||
case ONIGERR_END_PATTERN_AT_ESCAPE:
|
||||
p = "end pattern at escape"; break;
|
||||
case ONIGERR_END_PATTERN_AT_META:
|
||||
p = "end pattern at meta"; break;
|
||||
case ONIGERR_END_PATTERN_AT_CONTROL:
|
||||
p = "end pattern at control"; break;
|
||||
case ONIGERR_META_CODE_SYNTAX:
|
||||
p = "invalid meta-code syntax"; break;
|
||||
case ONIGERR_CONTROL_CODE_SYNTAX:
|
||||
p = "invalid control-code syntax"; break;
|
||||
case ONIGERR_CHAR_CLASS_VALUE_AT_END_OF_RANGE:
|
||||
p = "char-class value at end of range"; break;
|
||||
case ONIGERR_CHAR_CLASS_VALUE_AT_START_OF_RANGE:
|
||||
p = "char-class value at start of range"; break;
|
||||
case ONIGERR_UNMATCHED_RANGE_SPECIFIER_IN_CHAR_CLASS:
|
||||
p = "unmatched range specifier in char-class"; break;
|
||||
case ONIGERR_TARGET_OF_REPEAT_OPERATOR_NOT_SPECIFIED:
|
||||
p = "target of repeat operator is not specified"; break;
|
||||
case ONIGERR_TARGET_OF_REPEAT_OPERATOR_INVALID:
|
||||
p = "target of repeat operator is invalid"; break;
|
||||
case ONIGERR_NESTED_REPEAT_OPERATOR:
|
||||
p = "nested repeat operator"; break;
|
||||
case ONIGERR_UNMATCHED_CLOSE_PARENTHESIS:
|
||||
p = "unmatched close parenthesis"; break;
|
||||
case ONIGERR_END_PATTERN_WITH_UNMATCHED_PARENTHESIS:
|
||||
p = "end pattern with unmatched parenthesis"; break;
|
||||
case ONIGERR_END_PATTERN_IN_GROUP:
|
||||
p = "end pattern in group"; break;
|
||||
case ONIGERR_UNDEFINED_GROUP_OPTION:
|
||||
p = "undefined group option"; break;
|
||||
case ONIGERR_INVALID_POSIX_BRACKET_TYPE:
|
||||
p = "invalid POSIX bracket type"; break;
|
||||
case ONIGERR_INVALID_LOOK_BEHIND_PATTERN:
|
||||
p = "invalid pattern in look-behind"; break;
|
||||
case ONIGERR_INVALID_REPEAT_RANGE_PATTERN:
|
||||
p = "invalid repeat range {lower,upper}"; break;
|
||||
case ONIGERR_TOO_BIG_NUMBER:
|
||||
p = "too big number"; break;
|
||||
case ONIGERR_TOO_BIG_NUMBER_FOR_REPEAT_RANGE:
|
||||
p = "too big number for repeat range"; break;
|
||||
case ONIGERR_UPPER_SMALLER_THAN_LOWER_IN_REPEAT_RANGE:
|
||||
p = "upper is smaller than lower in repeat range"; break;
|
||||
case ONIGERR_EMPTY_RANGE_IN_CHAR_CLASS:
|
||||
p = "empty range in char class"; break;
|
||||
case ONIGERR_MISMATCH_CODE_LENGTH_IN_CLASS_RANGE:
|
||||
p = "mismatch multibyte code length in char-class range"; break;
|
||||
case ONIGERR_TOO_MANY_MULTI_BYTE_RANGES:
|
||||
p = "too many multibyte code ranges are specified"; break;
|
||||
case ONIGERR_TOO_SHORT_MULTI_BYTE_STRING:
|
||||
p = "too short multibyte code string"; break;
|
||||
case ONIGERR_TOO_BIG_BACKREF_NUMBER:
|
||||
p = "too big backref number"; break;
|
||||
case ONIGERR_INVALID_BACKREF:
|
||||
#ifdef USE_NAMED_GROUP
|
||||
p = "invalid backref number/name"; break;
|
||||
#else
|
||||
p = "invalid backref number"; break;
|
||||
#endif
|
||||
case ONIGERR_NUMBERED_BACKREF_OR_CALL_NOT_ALLOWED:
|
||||
p = "numbered backref/call is not allowed. (use name)"; break;
|
||||
case ONIGERR_TOO_BIG_WIDE_CHAR_VALUE:
|
||||
p = "too big wide-char value"; break;
|
||||
case ONIGERR_TOO_LONG_WIDE_CHAR_VALUE:
|
||||
p = "too long wide-char value"; break;
|
||||
case ONIGERR_INVALID_CODE_POINT_VALUE:
|
||||
p = "invalid code point value"; break;
|
||||
case ONIGERR_EMPTY_GROUP_NAME:
|
||||
p = "group name is empty"; break;
|
||||
case ONIGERR_INVALID_GROUP_NAME:
|
||||
p = "invalid group name <%n>"; break;
|
||||
case ONIGERR_INVALID_CHAR_IN_GROUP_NAME:
|
||||
#ifdef USE_NAMED_GROUP
|
||||
p = "invalid char in group name <%n>"; break;
|
||||
#else
|
||||
p = "invalid char in group number <%n>"; break;
|
||||
#endif
|
||||
case ONIGERR_UNDEFINED_NAME_REFERENCE:
|
||||
p = "undefined name <%n> reference"; break;
|
||||
case ONIGERR_UNDEFINED_GROUP_REFERENCE:
|
||||
p = "undefined group <%n> reference"; break;
|
||||
case ONIGERR_MULTIPLEX_DEFINED_NAME:
|
||||
p = "multiplex defined name <%n>"; break;
|
||||
case ONIGERR_MULTIPLEX_DEFINITION_NAME_CALL:
|
||||
p = "multiplex definition name <%n> call"; break;
|
||||
case ONIGERR_NEVER_ENDING_RECURSION:
|
||||
p = "never ending recursion"; break;
|
||||
case ONIGERR_GROUP_NUMBER_OVER_FOR_CAPTURE_HISTORY:
|
||||
p = "group number is too big for capture history"; break;
|
||||
case ONIGERR_INVALID_CHAR_PROPERTY_NAME:
|
||||
p = "invalid character property name {%n}"; break;
|
||||
case ONIGERR_NOT_SUPPORTED_ENCODING_COMBINATION:
|
||||
p = "not supported encoding combination"; break;
|
||||
case ONIGERR_INVALID_COMBINATION_OF_OPTIONS:
|
||||
p = "invalid combination of options"; break;
|
||||
case ONIGERR_OVER_THREAD_PASS_LIMIT_COUNT:
|
||||
p = "over thread pass limit count"; break;
|
||||
|
||||
default:
|
||||
p = "undefined error code"; break;
|
||||
}
|
||||
|
||||
return (UChar* )p;
|
||||
}
|
||||
|
||||
static void sprint_byte(char* s, unsigned int v)
|
||||
{
|
||||
sprintf(s, "%02x", (v & 0377));
|
||||
}
|
||||
|
||||
static void sprint_byte_with_x(char* s, unsigned int v)
|
||||
{
|
||||
sprintf(s, "\\x%02x", (v & 0377));
|
||||
}
|
||||
|
||||
static int to_ascii(OnigEncoding enc, UChar *s, UChar *end,
|
||||
UChar buf[], int buf_size, int *is_over)
|
||||
{
|
||||
int len;
|
||||
UChar *p;
|
||||
OnigCodePoint code;
|
||||
|
||||
if (ONIGENC_MBC_MINLEN(enc) > 1) {
|
||||
p = s;
|
||||
len = 0;
|
||||
while (p < end) {
|
||||
code = ONIGENC_MBC_TO_CODE(enc, p, end);
|
||||
if (code >= 0x80) {
|
||||
if (code > 0xffff && len + 10 <= buf_size) {
|
||||
sprint_byte_with_x((char*)(&(buf[len])), (unsigned int)(code >> 24));
|
||||
sprint_byte((char*)(&(buf[len+4])), (unsigned int)(code >> 16));
|
||||
sprint_byte((char*)(&(buf[len+6])), (unsigned int)(code >> 8));
|
||||
sprint_byte((char*)(&(buf[len+8])), (unsigned int)code);
|
||||
len += 10;
|
||||
}
|
||||
else if (len + 6 <= buf_size) {
|
||||
sprint_byte_with_x((char*)(&(buf[len])), (unsigned int)(code >> 8));
|
||||
sprint_byte((char*)(&(buf[len+4])), (unsigned int)code);
|
||||
len += 6;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
buf[len++] = (UChar )code;
|
||||
}
|
||||
|
||||
p += enclen(enc, p, end);
|
||||
if (len >= buf_size) break;
|
||||
}
|
||||
|
||||
*is_over = ((p < end) ? 1 : 0);
|
||||
}
|
||||
else {
|
||||
len = (int)MIN((end - s), buf_size);
|
||||
xmemcpy(buf, s, (size_t )len);
|
||||
*is_over = ((buf_size < (end - s)) ? 1 : 0);
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
/* for ONIG_MAX_ERROR_MESSAGE_LEN */
|
||||
#define MAX_ERROR_PAR_LEN 30
|
||||
|
||||
extern int
|
||||
onig_error_code_to_str(UChar* s, int code, ...)
|
||||
{
|
||||
UChar *p, *q;
|
||||
OnigErrorInfo* einfo;
|
||||
size_t len;
|
||||
int is_over;
|
||||
UChar parbuf[MAX_ERROR_PAR_LEN];
|
||||
va_list vargs;
|
||||
|
||||
va_start(vargs, code);
|
||||
|
||||
switch (code) {
|
||||
case ONIGERR_UNDEFINED_NAME_REFERENCE:
|
||||
case ONIGERR_UNDEFINED_GROUP_REFERENCE:
|
||||
case ONIGERR_MULTIPLEX_DEFINED_NAME:
|
||||
case ONIGERR_MULTIPLEX_DEFINITION_NAME_CALL:
|
||||
case ONIGERR_INVALID_GROUP_NAME:
|
||||
case ONIGERR_INVALID_CHAR_IN_GROUP_NAME:
|
||||
case ONIGERR_INVALID_CHAR_PROPERTY_NAME:
|
||||
einfo = va_arg(vargs, OnigErrorInfo*);
|
||||
len = to_ascii(einfo->enc, einfo->par, einfo->par_end,
|
||||
parbuf, MAX_ERROR_PAR_LEN - 3, &is_over);
|
||||
q = onig_error_code_to_format(code);
|
||||
p = s;
|
||||
while (*q != '\0') {
|
||||
if (*q == '%') {
|
||||
q++;
|
||||
if (*q == 'n') { /* '%n': name */
|
||||
xmemcpy(p, parbuf, len);
|
||||
p += len;
|
||||
if (is_over != 0) {
|
||||
xmemcpy(p, "...", 3);
|
||||
p += 3;
|
||||
}
|
||||
q++;
|
||||
}
|
||||
else
|
||||
goto normal_char;
|
||||
}
|
||||
else {
|
||||
normal_char:
|
||||
*p++ = *q++;
|
||||
}
|
||||
}
|
||||
*p = '\0';
|
||||
len = p - s;
|
||||
break;
|
||||
|
||||
default:
|
||||
q = onig_error_code_to_format(code);
|
||||
len = onigenc_str_bytelen_null(ONIG_ENCODING_ASCII, q);
|
||||
xmemcpy(s, q, len);
|
||||
s[len] = '\0';
|
||||
break;
|
||||
}
|
||||
|
||||
va_end(vargs);
|
||||
return (int)len;
|
||||
}
|
||||
|
||||
void
|
||||
onig_vsnprintf_with_pattern(UChar buf[], int bufsize, OnigEncoding enc,
|
||||
UChar* pat, UChar* pat_end, const UChar *fmt, va_list args)
|
||||
{
|
||||
size_t need;
|
||||
int n, len;
|
||||
UChar *p, *s, *bp;
|
||||
UChar bs[6];
|
||||
|
||||
n = xvsnprintf((char* )buf, bufsize, (const char* )fmt, args);
|
||||
|
||||
need = (pat_end - pat) * 4 + 4;
|
||||
|
||||
if (n + need < (size_t)bufsize) {
|
||||
strcat((char* )buf, ": /");
|
||||
s = buf + onigenc_str_bytelen_null(ONIG_ENCODING_ASCII, buf);
|
||||
|
||||
p = pat;
|
||||
while (p < pat_end) {
|
||||
if (*p == '\\') {
|
||||
*s++ = *p++;
|
||||
len = enclen(enc, p, pat_end);
|
||||
while (len-- > 0) *s++ = *p++;
|
||||
}
|
||||
else if (*p == '/') {
|
||||
*s++ = (unsigned char )'\\';
|
||||
*s++ = *p++;
|
||||
}
|
||||
else if (ONIGENC_IS_MBC_HEAD(enc, p, pat_end)) {
|
||||
len = enclen(enc, p, pat_end);
|
||||
if (ONIGENC_MBC_MINLEN(enc) == 1) {
|
||||
while (len-- > 0) *s++ = *p++;
|
||||
}
|
||||
else { /* for UTF16 */
|
||||
int blen;
|
||||
|
||||
while (len-- > 0) {
|
||||
sprint_byte_with_x((char* )bs, (unsigned int )(*p++));
|
||||
blen = onigenc_str_bytelen_null(ONIG_ENCODING_ASCII, bs);
|
||||
bp = bs;
|
||||
while (blen-- > 0) *s++ = *bp++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!ONIGENC_IS_CODE_PRINT(enc, *p) &&
|
||||
!ONIGENC_IS_CODE_SPACE(enc, *p)) {
|
||||
sprint_byte_with_x((char* )bs, (unsigned int )(*p++));
|
||||
len = onigenc_str_bytelen_null(ONIG_ENCODING_ASCII, bs);
|
||||
bp = bs;
|
||||
while (len-- > 0) *s++ = *bp++;
|
||||
}
|
||||
else {
|
||||
*s++ = *p++;
|
||||
}
|
||||
}
|
||||
|
||||
*s++ = '/';
|
||||
*s = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
onig_snprintf_with_pattern(UChar buf[], int bufsize, OnigEncoding enc,
|
||||
UChar* pat, UChar* pat_end, const UChar *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
onig_vsnprintf_with_pattern(buf, bufsize, enc,
|
||||
pat, pat_end, fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
#endif //INCLUDE_REGEXP
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
/**********************************************************************
|
||||
|
||||
regex.h -
|
||||
|
||||
$Author: akr $
|
||||
|
||||
Copyright (C) 1993-2007 Yukihiro Matsumoto
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef ONIGURUMA_REGEX_H
|
||||
#define ONIGURUMA_REGEX_H 1
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "oniguruma.h"
|
||||
|
||||
#ifndef ONIG_RUBY_M17N
|
||||
|
||||
ONIG_EXTERN OnigEncoding OnigEncDefaultCharEncoding;
|
||||
|
||||
#define mbclen(p,e,enc) mrb_enc_mbclen((p),(e),(enc))
|
||||
|
||||
#endif /* ifndef ONIG_RUBY_M17N */
|
||||
|
||||
#if defined(__cplusplus)
|
||||
} /* extern "C" { */
|
||||
#endif
|
||||
|
||||
#endif /* ONIGURUMA_REGEX_H */
|
||||
+3757
File diff suppressed because it is too large
Load Diff
+833
@@ -0,0 +1,833 @@
|
||||
#ifndef ONIGURUMA_REGINT_H
|
||||
#define ONIGURUMA_REGINT_H
|
||||
/**********************************************************************
|
||||
regint.h - Oniguruma (regular expression library)
|
||||
**********************************************************************/
|
||||
/*-
|
||||
* Copyright (c) 2002-2008 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* for debug */
|
||||
/* #define ONIG_DEBUG_PARSE_TREE */
|
||||
/* #define ONIG_DEBUG_COMPILE */
|
||||
/* #define ONIG_DEBUG_SEARCH */
|
||||
/* #define ONIG_DEBUG_MATCH */
|
||||
/* #define ONIG_DONT_OPTIMIZE */
|
||||
|
||||
/* for byte-code statistical data. */
|
||||
/* #define ONIG_DEBUG_STATISTICS */
|
||||
|
||||
#ifndef RUBY
|
||||
#define RUBY
|
||||
#endif
|
||||
|
||||
#include <stddef.h> //typedef unsigned int ptrdiff_t;
|
||||
|
||||
#if defined(ONIG_DEBUG_PARSE_TREE) || defined(ONIG_DEBUG_MATCH) || \
|
||||
defined(ONIG_DEBUG_SEARCH) || defined(ONIG_DEBUG_COMPILE) || \
|
||||
defined(ONIG_DEBUG_STATISTICS)
|
||||
#ifndef ONIG_DEBUG
|
||||
#define ONIG_DEBUG
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(__i386) || defined(__i386__) || defined(_M_IX86) || \
|
||||
(defined(__ppc__) && defined(__APPLE__)) || \
|
||||
defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD86) || \
|
||||
defined(__mc68020__)
|
||||
#define PLATFORM_UNALIGNED_WORD_ACCESS
|
||||
#endif
|
||||
|
||||
/* config */
|
||||
/* spec. config */
|
||||
#define USE_NAMED_GROUP
|
||||
#define USE_SUBEXP_CALL
|
||||
#define USE_BACKREF_WITH_LEVEL /* \k<name+n>, \k<name-n> */
|
||||
#define USE_MONOMANIAC_CHECK_CAPTURES_IN_ENDLESS_REPEAT /* /(?:()|())*\2/ */
|
||||
#define USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE /* /\n$/ =~ "\n" */
|
||||
#define USE_WARNING_REDUNDANT_NESTED_REPEAT_OPERATOR
|
||||
/* #define USE_RECOMPILE_API */
|
||||
/* !!! moved to regenc.h. */ /* #define USE_CRNL_AS_LINE_TERMINATOR */
|
||||
|
||||
/* internal config */
|
||||
#define USE_PARSE_TREE_NODE_RECYCLE
|
||||
#define USE_OP_PUSH_OR_JUMP_EXACT
|
||||
#define USE_QTFR_PEEK_NEXT
|
||||
#define USE_ST_LIBRARY
|
||||
#define USE_SHARED_CCLASS_TABLE
|
||||
|
||||
#define INIT_MATCH_STACK_SIZE 160
|
||||
#define DEFAULT_MATCH_STACK_LIMIT_SIZE 0 /* unlimited */
|
||||
|
||||
#if defined(__GNUC__)
|
||||
# define ARG_UNUSED __attribute__ ((unused))
|
||||
#else
|
||||
# define ARG_UNUSED
|
||||
#endif
|
||||
|
||||
/* */
|
||||
/* escape other system UChar definition */
|
||||
#ifndef RUBY_DEFINES_H
|
||||
#include "mruby.h"
|
||||
#endif
|
||||
#ifdef ONIG_ESCAPE_UCHAR_COLLISION
|
||||
#undef ONIG_ESCAPE_UCHAR_COLLISION
|
||||
#endif
|
||||
#undef USE_MATCH_RANGE_IS_COMPLETE_RANGE
|
||||
#undef USE_CAPTURE_HISTORY
|
||||
#define USE_VARIABLE_META_CHARS
|
||||
#define USE_WORD_BEGIN_END /* "\<": word-begin, "\>": word-end */
|
||||
#define USE_POSIX_REGION_OPTION /* needed for POSIX API support */
|
||||
#define USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE
|
||||
/* #define USE_COMBINATION_EXPLOSION_CHECK */ /* (X*)* */
|
||||
/* #define USE_MULTI_THREAD_SYSTEM */
|
||||
#define THREAD_SYSTEM_INIT /* depend on thread system */
|
||||
#define THREAD_SYSTEM_END /* depend on thread system */
|
||||
#define THREAD_ATOMIC_START /* depend on thread system */
|
||||
#define THREAD_ATOMIC_END /* depend on thread system */
|
||||
#define THREAD_PASS /* depend on thread system */
|
||||
|
||||
#ifdef RUBY
|
||||
|
||||
//#define CHECK_INTERRUPT_IN_MATCH_AT mrb_thread_check_ints()
|
||||
#define CHECK_INTERRUPT_IN_MATCH_AT
|
||||
#define onig_st_init_table st_init_table
|
||||
#define onig_st_init_table_with_size st_init_table_with_size
|
||||
#define onig_st_init_numtable st_init_numtable
|
||||
#define onig_st_init_numtable_with_size st_init_numtable_with_size
|
||||
#define onig_st_init_strtable st_init_strtable
|
||||
#define onig_st_init_strtable_with_size st_init_strtable_with_size
|
||||
#define onig_st_delete st_delete
|
||||
#define onig_st_delete_safe st_delete_safe
|
||||
#define onig_st_insert st_insert
|
||||
#define onig_st_lookup st_lookup
|
||||
#define onig_st_foreach st_foreach
|
||||
#define onig_st_add_direct st_add_direct
|
||||
#define onig_st_free_table st_free_table
|
||||
#define onig_st_cleanup_safe st_cleanup_safe
|
||||
#define onig_st_copy st_copy
|
||||
#define onig_st_nothing_key_clone st_nothing_key_clone
|
||||
#define onig_st_nothing_key_free st_nothing_key_free
|
||||
#define onig_st_is_member st_is_member
|
||||
|
||||
#define USE_UPPER_CASE_TABLE
|
||||
#else
|
||||
|
||||
#define st_init_table onig_st_init_table
|
||||
#define st_init_table_with_size onig_st_init_table_with_size
|
||||
#define st_init_numtable onig_st_init_numtable
|
||||
#define st_init_numtable_with_size onig_st_init_numtable_with_size
|
||||
#define st_init_strtable onig_st_init_strtable
|
||||
#define st_init_strtable_with_size onig_st_init_strtable_with_size
|
||||
#define st_delete onig_st_delete
|
||||
#define st_delete_safe onig_st_delete_safe
|
||||
#define st_insert onig_st_insert
|
||||
#define st_lookup onig_st_lookup
|
||||
#define st_foreach onig_st_foreach
|
||||
#define st_add_direct onig_st_add_direct
|
||||
#define st_free_table onig_st_free_table
|
||||
#define st_cleanup_safe onig_st_cleanup_safe
|
||||
#define st_copy onig_st_copy
|
||||
#define st_nothing_key_clone onig_st_nothing_key_clone
|
||||
#define st_nothing_key_free onig_st_nothing_key_free
|
||||
/* */
|
||||
#define onig_st_is_member st_is_member
|
||||
|
||||
#define CHECK_INTERRUPT_IN_MATCH_AT
|
||||
|
||||
#endif
|
||||
|
||||
#define STATE_CHECK_STRING_THRESHOLD_LEN 7
|
||||
#define STATE_CHECK_BUFF_MAX_SIZE 0x4000
|
||||
|
||||
#define THREAD_PASS_LIMIT_COUNT 8
|
||||
#define xmemset memset
|
||||
#define xmemcpy memcpy
|
||||
#define xmemmove memmove
|
||||
|
||||
#if defined(_WIN32) && !defined(__GNUC__)
|
||||
#define xalloca _alloca
|
||||
#define xvsnprintf _vsnprintf
|
||||
#else
|
||||
#define xalloca malloc
|
||||
#define xvsnprintf vsnprintf
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(USE_RECOMPILE_API) && defined(USE_MULTI_THREAD_SYSTEM)
|
||||
#define ONIG_STATE_INC(reg) (reg)->state++
|
||||
#define ONIG_STATE_DEC(reg) (reg)->state--
|
||||
|
||||
#define ONIG_STATE_INC_THREAD(reg) do {\
|
||||
THREAD_ATOMIC_START;\
|
||||
(reg)->state++;\
|
||||
THREAD_ATOMIC_END;\
|
||||
} while(0)
|
||||
#define ONIG_STATE_DEC_THREAD(reg) do {\
|
||||
THREAD_ATOMIC_START;\
|
||||
(reg)->state--;\
|
||||
THREAD_ATOMIC_END;\
|
||||
} while(0)
|
||||
#else
|
||||
#define ONIG_STATE_INC(reg) /* Nothing */
|
||||
#define ONIG_STATE_DEC(reg) /* Nothing */
|
||||
#define ONIG_STATE_INC_THREAD(reg) /* Nothing */
|
||||
#define ONIG_STATE_DEC_THREAD(reg) /* Nothing */
|
||||
#endif /* USE_RECOMPILE_API && USE_MULTI_THREAD_SYSTEM */
|
||||
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_ALLOCA_H) && (defined(_AIX) || !defined(__GNUC__))
|
||||
#include <alloca.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STRING_H
|
||||
# include <string.h>
|
||||
#else
|
||||
# include <strings.h>
|
||||
#endif
|
||||
|
||||
#include <ctype.h>
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
|
||||
#ifdef ONIG_DEBUG
|
||||
# include <stdio.h>
|
||||
#endif
|
||||
|
||||
#include "regenc.h"
|
||||
|
||||
#define MIN(a,b) (((a)>(b))?(b):(a))
|
||||
#define MAX(a,b) (((a)<(b))?(b):(a))
|
||||
|
||||
#define IS_NULL(p) (((void*)(p)) == (void*)0)
|
||||
#define IS_NOT_NULL(p) (((void*)(p)) != (void*)0)
|
||||
#define CHECK_NULL_RETURN(p) if (IS_NULL(p)) return NULL
|
||||
#define CHECK_NULL_RETURN_MEMERR(p) if (IS_NULL(p)) return ONIGERR_MEMORY
|
||||
#define NULL_UCHARP ((UChar* )0)
|
||||
|
||||
#ifdef PLATFORM_UNALIGNED_WORD_ACCESS
|
||||
|
||||
#define PLATFORM_GET_INC(val,p,type) do{\
|
||||
val = *(type* )p;\
|
||||
(p) += sizeof(type);\
|
||||
} while(0)
|
||||
|
||||
#else
|
||||
|
||||
#define PLATFORM_GET_INC(val,p,type) do{\
|
||||
xmemcpy(&val, (p), sizeof(type));\
|
||||
(p) += sizeof(type);\
|
||||
} while(0)
|
||||
|
||||
/* sizeof(OnigCodePoint) */
|
||||
#define WORD_ALIGNMENT_SIZE SIZEOF_LONG
|
||||
|
||||
#define GET_ALIGNMENT_PAD_SIZE(addr,pad_size) do {\
|
||||
(pad_size) = WORD_ALIGNMENT_SIZE \
|
||||
- ((uintptr_t )(addr) % WORD_ALIGNMENT_SIZE);\
|
||||
if ((pad_size) == WORD_ALIGNMENT_SIZE) (pad_size) = 0;\
|
||||
} while (0)
|
||||
|
||||
#define ALIGNMENT_RIGHT(addr) do {\
|
||||
(addr) += (WORD_ALIGNMENT_SIZE - 1);\
|
||||
(addr) -= ((uintptr_t )(addr) % WORD_ALIGNMENT_SIZE);\
|
||||
} while (0)
|
||||
|
||||
#endif /* PLATFORM_UNALIGNED_WORD_ACCESS */
|
||||
|
||||
/* stack pop level */
|
||||
#define STACK_POP_LEVEL_FREE 0
|
||||
#define STACK_POP_LEVEL_MEM_START 1
|
||||
#define STACK_POP_LEVEL_ALL 2
|
||||
|
||||
/* optimize flags */
|
||||
#define ONIG_OPTIMIZE_NONE 0
|
||||
#define ONIG_OPTIMIZE_EXACT 1 /* Slow Search */
|
||||
#define ONIG_OPTIMIZE_EXACT_BM 2 /* Boyer Moore Search */
|
||||
#define ONIG_OPTIMIZE_EXACT_BM_NOT_REV 3 /* BM (but not simple match) */
|
||||
#define ONIG_OPTIMIZE_EXACT_IC 4 /* Slow Search (ignore case) */
|
||||
#define ONIG_OPTIMIZE_MAP 5 /* char map */
|
||||
|
||||
/* bit status */
|
||||
typedef unsigned int BitStatusType;
|
||||
|
||||
#define BIT_STATUS_BITS_NUM (sizeof(BitStatusType) * 8)
|
||||
#define BIT_STATUS_CLEAR(stats) (stats) = 0
|
||||
#define BIT_STATUS_ON_ALL(stats) (stats) = ~((BitStatusType )0)
|
||||
#define BIT_STATUS_AT(stats,n) \
|
||||
((n) < (int )BIT_STATUS_BITS_NUM ? ((stats) & (1 << n)) : ((stats) & 1))
|
||||
|
||||
#define BIT_STATUS_ON_AT(stats,n) do {\
|
||||
if ((n) < (int )BIT_STATUS_BITS_NUM) \
|
||||
(stats) |= (1 << (n));\
|
||||
else\
|
||||
(stats) |= 1;\
|
||||
} while (0)
|
||||
|
||||
#define BIT_STATUS_ON_AT_SIMPLE(stats,n) do {\
|
||||
if ((n) < (int )BIT_STATUS_BITS_NUM)\
|
||||
(stats) |= (1 << (n));\
|
||||
} while (0)
|
||||
|
||||
|
||||
#define INT_MAX_LIMIT ((1UL << (sizeof(int) * 8 - 1)) - 1)
|
||||
|
||||
#define DIGITVAL(code) ((code) - '0')
|
||||
#define ODIGITVAL(code) DIGITVAL(code)
|
||||
#define XDIGITVAL(enc,code) \
|
||||
(ONIGENC_IS_CODE_DIGIT(enc,code) ? DIGITVAL(code) \
|
||||
: (ONIGENC_IS_CODE_UPPER(enc,code) ? (code) - 'A' + 10 : (code) - 'a' + 10))
|
||||
|
||||
#define IS_SINGLELINE(option) ((option) & ONIG_OPTION_SINGLELINE)
|
||||
#define IS_MULTILINE(option) ((option) & ONIG_OPTION_MULTILINE)
|
||||
#define IS_IGNORECASE(option) ((option) & ONIG_OPTION_IGNORECASE)
|
||||
#define IS_EXTEND(option) ((option) & ONIG_OPTION_EXTEND)
|
||||
#define IS_FIND_LONGEST(option) ((option) & ONIG_OPTION_FIND_LONGEST)
|
||||
#define IS_FIND_NOT_EMPTY(option) ((option) & ONIG_OPTION_FIND_NOT_EMPTY)
|
||||
#define IS_FIND_CONDITION(option) ((option) & \
|
||||
(ONIG_OPTION_FIND_LONGEST | ONIG_OPTION_FIND_NOT_EMPTY))
|
||||
#define IS_NOTBOL(option) ((option) & ONIG_OPTION_NOTBOL)
|
||||
#define IS_NOTEOL(option) ((option) & ONIG_OPTION_NOTEOL)
|
||||
#define IS_POSIX_REGION(option) ((option) & ONIG_OPTION_POSIX_REGION)
|
||||
|
||||
/* OP_SET_OPTION is required for these options.
|
||||
#define IS_DYNAMIC_OPTION(option) \
|
||||
(((option) & (ONIG_OPTION_MULTILINE | ONIG_OPTION_IGNORECASE)) != 0)
|
||||
*/
|
||||
/* ignore-case and multibyte status are included in compiled code. */
|
||||
#define IS_DYNAMIC_OPTION(option) 0
|
||||
|
||||
#define DISABLE_CASE_FOLD_MULTI_CHAR(case_fold_flag) \
|
||||
((case_fold_flag) & ~INTERNAL_ONIGENC_CASE_FOLD_MULTI_CHAR)
|
||||
|
||||
#define REPEAT_INFINITE -1
|
||||
#define IS_REPEAT_INFINITE(n) ((n) == REPEAT_INFINITE)
|
||||
|
||||
/* bitset */
|
||||
#define BITS_PER_BYTE 8
|
||||
#define SINGLE_BYTE_SIZE (1 << BITS_PER_BYTE)
|
||||
#define BITS_IN_ROOM (sizeof(Bits) * BITS_PER_BYTE)
|
||||
#define BITSET_SIZE (SINGLE_BYTE_SIZE / BITS_IN_ROOM)
|
||||
|
||||
#ifdef PLATFORM_UNALIGNED_WORD_ACCESS
|
||||
typedef unsigned int Bits;
|
||||
#else
|
||||
typedef unsigned char Bits;
|
||||
#endif
|
||||
typedef Bits BitSet[BITSET_SIZE];
|
||||
typedef Bits* BitSetRef;
|
||||
|
||||
#define SIZE_BITSET (int)sizeof(BitSet)
|
||||
|
||||
#define BITSET_CLEAR(bs) do {\
|
||||
int i;\
|
||||
for (i = 0; i < (int )BITSET_SIZE; i++) { (bs)[i] = 0; } \
|
||||
} while (0)
|
||||
|
||||
#define BS_ROOM(bs,pos) (bs)[pos / BITS_IN_ROOM]
|
||||
#define BS_BIT(pos) (1 << (pos % BITS_IN_ROOM))
|
||||
|
||||
#define BITSET_AT(bs, pos) (BS_ROOM(bs,pos) & BS_BIT(pos))
|
||||
#define BITSET_SET_BIT(bs, pos) BS_ROOM(bs,pos) |= BS_BIT(pos)
|
||||
#define BITSET_CLEAR_BIT(bs, pos) BS_ROOM(bs,pos) &= ~(BS_BIT(pos))
|
||||
#define BITSET_INVERT_BIT(bs, pos) BS_ROOM(bs,pos) ^= BS_BIT(pos)
|
||||
|
||||
/* bytes buffer */
|
||||
typedef struct _BBuf {
|
||||
UChar* p;
|
||||
unsigned int used;
|
||||
unsigned int alloc;
|
||||
} BBuf;
|
||||
|
||||
#define BBUF_INIT(buf,size) onig_bbuf_init((BBuf* )(buf), (size))
|
||||
|
||||
#define BBUF_SIZE_INC(buf,inc) do{\
|
||||
(buf)->alloc += (inc);\
|
||||
(buf)->p = (UChar* )xrealloc((buf)->p, (buf)->alloc);\
|
||||
if (IS_NULL((buf)->p)) return(ONIGERR_MEMORY);\
|
||||
} while (0)
|
||||
|
||||
#define BBUF_EXPAND(buf,low) do{\
|
||||
do { (buf)->alloc *= 2; } while ((buf)->alloc < (unsigned int )low);\
|
||||
(buf)->p = (UChar* )xrealloc((buf)->p, (buf)->alloc);\
|
||||
if (IS_NULL((buf)->p)) return(ONIGERR_MEMORY);\
|
||||
} while (0)
|
||||
|
||||
#define BBUF_ENSURE_SIZE(buf,size) do{\
|
||||
unsigned int new_alloc = (buf)->alloc;\
|
||||
while (new_alloc < (unsigned int )(size)) { new_alloc *= 2; }\
|
||||
if ((buf)->alloc != new_alloc) {\
|
||||
(buf)->p = (UChar* )xrealloc((buf)->p, new_alloc);\
|
||||
if (IS_NULL((buf)->p)) return(ONIGERR_MEMORY);\
|
||||
(buf)->alloc = new_alloc;\
|
||||
}\
|
||||
} while (0)
|
||||
|
||||
#define BBUF_WRITE(buf,pos,bytes,n) do{\
|
||||
int used = (pos) + (n);\
|
||||
if ((buf)->alloc < (unsigned int )used) BBUF_EXPAND((buf),used);\
|
||||
xmemcpy((buf)->p + (pos), (bytes), (n));\
|
||||
if ((buf)->used < (unsigned int )used) (buf)->used = used;\
|
||||
} while (0)
|
||||
|
||||
#define BBUF_WRITE1(buf,pos,byte) do{\
|
||||
int used = (pos) + 1;\
|
||||
if ((buf)->alloc < (unsigned int )used) BBUF_EXPAND((buf),used);\
|
||||
(buf)->p[(pos)] = (byte);\
|
||||
if ((buf)->used < (unsigned int )used) (buf)->used = used;\
|
||||
} while (0)
|
||||
|
||||
#define BBUF_ADD(buf,bytes,n) BBUF_WRITE((buf),(buf)->used,(bytes),(n))
|
||||
#define BBUF_ADD1(buf,byte) BBUF_WRITE1((buf),(buf)->used,(byte))
|
||||
#define BBUF_GET_ADD_ADDRESS(buf) ((buf)->p + (buf)->used)
|
||||
#define BBUF_GET_OFFSET_POS(buf) ((buf)->used)
|
||||
|
||||
/* from < to */
|
||||
#define BBUF_MOVE_RIGHT(buf,from,to,n) do {\
|
||||
if ((unsigned int )((to)+(n)) > (buf)->alloc) BBUF_EXPAND((buf),(to) + (n));\
|
||||
xmemmove((buf)->p + (to), (buf)->p + (from), (n));\
|
||||
if ((unsigned int )((to)+(n)) > (buf)->used) (buf)->used = (to) + (n);\
|
||||
} while (0)
|
||||
|
||||
/* from > to */
|
||||
#define BBUF_MOVE_LEFT(buf,from,to,n) do {\
|
||||
xmemmove((buf)->p + (to), (buf)->p + (from), (n));\
|
||||
} while (0)
|
||||
|
||||
/* from > to */
|
||||
#define BBUF_MOVE_LEFT_REDUCE(buf,from,to) do {\
|
||||
xmemmove((buf)->p + (to), (buf)->p + (from), (buf)->used - (from));\
|
||||
(buf)->used -= (from - to);\
|
||||
} while (0)
|
||||
|
||||
#define BBUF_INSERT(buf,pos,bytes,n) do {\
|
||||
if (pos >= (buf)->used) {\
|
||||
BBUF_WRITE(buf,pos,bytes,n);\
|
||||
}\
|
||||
else {\
|
||||
BBUF_MOVE_RIGHT((buf),(pos),(pos) + (n),((buf)->used - (pos)));\
|
||||
xmemcpy((buf)->p + (pos), (bytes), (n));\
|
||||
}\
|
||||
} while (0)
|
||||
|
||||
#define BBUF_GET_BYTE(buf, pos) (buf)->p[(pos)]
|
||||
|
||||
|
||||
#define ANCHOR_BEGIN_BUF (1<<0)
|
||||
#define ANCHOR_BEGIN_LINE (1<<1)
|
||||
#define ANCHOR_BEGIN_POSITION (1<<2)
|
||||
#define ANCHOR_END_BUF (1<<3)
|
||||
#define ANCHOR_SEMI_END_BUF (1<<4)
|
||||
#define ANCHOR_END_LINE (1<<5)
|
||||
|
||||
#define ANCHOR_WORD_BOUND (1<<6)
|
||||
#define ANCHOR_NOT_WORD_BOUND (1<<7)
|
||||
#define ANCHOR_WORD_BEGIN (1<<8)
|
||||
#define ANCHOR_WORD_END (1<<9)
|
||||
#define ANCHOR_PREC_READ (1<<10)
|
||||
#define ANCHOR_PREC_READ_NOT (1<<11)
|
||||
#define ANCHOR_LOOK_BEHIND (1<<12)
|
||||
#define ANCHOR_LOOK_BEHIND_NOT (1<<13)
|
||||
|
||||
#define ANCHOR_ANYCHAR_STAR (1<<14) /* ".*" optimize info */
|
||||
#define ANCHOR_ANYCHAR_STAR_ML (1<<15) /* ".*" optimize info (multi-line) */
|
||||
|
||||
/* operation code */
|
||||
enum OpCode {
|
||||
OP_FINISH = 0, /* matching process terminator (no more alternative) */
|
||||
OP_END = 1, /* pattern code terminator (success end) */
|
||||
|
||||
OP_EXACT1 = 2, /* single byte, N = 1 */
|
||||
OP_EXACT2, /* single byte, N = 2 */
|
||||
OP_EXACT3, /* single byte, N = 3 */
|
||||
OP_EXACT4, /* single byte, N = 4 */
|
||||
OP_EXACT5, /* single byte, N = 5 */
|
||||
OP_EXACTN, /* single byte */
|
||||
OP_EXACTMB2N1, /* mb-length = 2 N = 1 */
|
||||
OP_EXACTMB2N2, /* mb-length = 2 N = 2 */
|
||||
OP_EXACTMB2N3, /* mb-length = 2 N = 3 */
|
||||
OP_EXACTMB2N, /* mb-length = 2 */
|
||||
OP_EXACTMB3N, /* mb-length = 3 */
|
||||
OP_EXACTMBN, /* other length */
|
||||
|
||||
OP_EXACT1_IC, /* single byte, N = 1, ignore case */
|
||||
OP_EXACTN_IC, /* single byte, ignore case */
|
||||
|
||||
OP_CCLASS,
|
||||
OP_CCLASS_MB,
|
||||
OP_CCLASS_MIX,
|
||||
OP_CCLASS_NOT,
|
||||
OP_CCLASS_MB_NOT,
|
||||
OP_CCLASS_MIX_NOT,
|
||||
OP_CCLASS_NODE, /* pointer to CClassNode node */
|
||||
|
||||
OP_ANYCHAR, /* "." */
|
||||
OP_ANYCHAR_ML, /* "." multi-line */
|
||||
OP_ANYCHAR_STAR, /* ".*" */
|
||||
OP_ANYCHAR_ML_STAR, /* ".*" multi-line */
|
||||
OP_ANYCHAR_STAR_PEEK_NEXT,
|
||||
OP_ANYCHAR_ML_STAR_PEEK_NEXT,
|
||||
|
||||
OP_WORD,
|
||||
OP_NOT_WORD,
|
||||
OP_WORD_BOUND,
|
||||
OP_NOT_WORD_BOUND,
|
||||
OP_WORD_BEGIN,
|
||||
OP_WORD_END,
|
||||
|
||||
OP_BEGIN_BUF,
|
||||
OP_END_BUF,
|
||||
OP_BEGIN_LINE,
|
||||
OP_END_LINE,
|
||||
OP_SEMI_END_BUF,
|
||||
OP_BEGIN_POSITION,
|
||||
|
||||
OP_BACKREF1,
|
||||
OP_BACKREF2,
|
||||
OP_BACKREFN,
|
||||
OP_BACKREFN_IC,
|
||||
OP_BACKREF_MULTI,
|
||||
OP_BACKREF_MULTI_IC,
|
||||
OP_BACKREF_WITH_LEVEL, /* \k<xxx+n>, \k<xxx-n> */
|
||||
|
||||
OP_MEMORY_START,
|
||||
OP_MEMORY_START_PUSH, /* push back-tracker to stack */
|
||||
OP_MEMORY_END_PUSH, /* push back-tracker to stack */
|
||||
OP_MEMORY_END_PUSH_REC, /* push back-tracker to stack */
|
||||
OP_MEMORY_END,
|
||||
OP_MEMORY_END_REC, /* push marker to stack */
|
||||
|
||||
OP_FAIL, /* pop stack and move */
|
||||
OP_JUMP,
|
||||
OP_PUSH,
|
||||
OP_POP,
|
||||
OP_PUSH_OR_JUMP_EXACT1, /* if match exact then push, else jump. */
|
||||
OP_PUSH_IF_PEEK_NEXT, /* if match exact then push, else none. */
|
||||
OP_REPEAT, /* {n,m} */
|
||||
OP_REPEAT_NG, /* {n,m}? (non greedy) */
|
||||
OP_REPEAT_INC,
|
||||
OP_REPEAT_INC_NG, /* non greedy */
|
||||
OP_REPEAT_INC_SG, /* search and get in stack */
|
||||
OP_REPEAT_INC_NG_SG, /* search and get in stack (non greedy) */
|
||||
OP_NULL_CHECK_START, /* null loop checker start */
|
||||
OP_NULL_CHECK_END, /* null loop checker end */
|
||||
OP_NULL_CHECK_END_MEMST, /* null loop checker end (with capture status) */
|
||||
OP_NULL_CHECK_END_MEMST_PUSH, /* with capture status and push check-end */
|
||||
|
||||
OP_PUSH_POS, /* (?=...) start */
|
||||
OP_POP_POS, /* (?=...) end */
|
||||
OP_PUSH_POS_NOT, /* (?!...) start */
|
||||
OP_FAIL_POS, /* (?!...) end */
|
||||
OP_PUSH_STOP_BT, /* (?>...) start */
|
||||
OP_POP_STOP_BT, /* (?>...) end */
|
||||
OP_LOOK_BEHIND, /* (?<=...) start (no needs end opcode) */
|
||||
OP_PUSH_LOOK_BEHIND_NOT, /* (?<!...) start */
|
||||
OP_FAIL_LOOK_BEHIND_NOT, /* (?<!...) end */
|
||||
|
||||
OP_CALL, /* \g<name> */
|
||||
OP_RETURN,
|
||||
|
||||
OP_STATE_CHECK_PUSH, /* combination explosion check and push */
|
||||
OP_STATE_CHECK_PUSH_OR_JUMP, /* check ok -> push, else jump */
|
||||
OP_STATE_CHECK, /* check only */
|
||||
OP_STATE_CHECK_ANYCHAR_STAR,
|
||||
OP_STATE_CHECK_ANYCHAR_ML_STAR,
|
||||
|
||||
/* no need: IS_DYNAMIC_OPTION() == 0 */
|
||||
OP_SET_OPTION_PUSH, /* set option and push recover option */
|
||||
OP_SET_OPTION /* set option */
|
||||
};
|
||||
|
||||
typedef int RelAddrType;
|
||||
typedef int AbsAddrType;
|
||||
typedef int LengthType;
|
||||
typedef int RepeatNumType;
|
||||
typedef short int MemNumType;
|
||||
typedef short int StateCheckNumType;
|
||||
typedef void* PointerType;
|
||||
|
||||
#define SIZE_OPCODE 1
|
||||
#define SIZE_RELADDR (int)sizeof(RelAddrType)
|
||||
#define SIZE_ABSADDR (int)sizeof(AbsAddrType)
|
||||
#define SIZE_LENGTH (int)sizeof(LengthType)
|
||||
#define SIZE_MEMNUM (int)sizeof(MemNumType)
|
||||
#define SIZE_STATE_CHECK_NUM (int)sizeof(StateCheckNumType)
|
||||
#define SIZE_REPEATNUM (int)sizeof(RepeatNumType)
|
||||
#define SIZE_OPTION (int)sizeof(OnigOptionType)
|
||||
#define SIZE_CODE_POINT (int)sizeof(OnigCodePoint)
|
||||
#define SIZE_POINTER (int)sizeof(PointerType)
|
||||
|
||||
|
||||
#define GET_RELADDR_INC(addr,p) PLATFORM_GET_INC(addr, p, RelAddrType)
|
||||
#define GET_ABSADDR_INC(addr,p) PLATFORM_GET_INC(addr, p, AbsAddrType)
|
||||
#define GET_LENGTH_INC(len,p) PLATFORM_GET_INC(len, p, LengthType)
|
||||
#define GET_MEMNUM_INC(num,p) PLATFORM_GET_INC(num, p, MemNumType)
|
||||
#define GET_REPEATNUM_INC(num,p) PLATFORM_GET_INC(num, p, RepeatNumType)
|
||||
#define GET_OPTION_INC(option,p) PLATFORM_GET_INC(option, p, OnigOptionType)
|
||||
#define GET_POINTER_INC(ptr,p) PLATFORM_GET_INC(ptr, p, PointerType)
|
||||
#define GET_STATE_CHECK_NUM_INC(num,p) PLATFORM_GET_INC(num, p, StateCheckNumType)
|
||||
|
||||
/* code point's address must be aligned address. */
|
||||
#define GET_CODE_POINT(code,p) code = *((OnigCodePoint* )(p))
|
||||
#define GET_BYTE_INC(byte,p) do{\
|
||||
byte = *(p);\
|
||||
(p)++;\
|
||||
} while(0)
|
||||
|
||||
|
||||
/* op-code + arg size */
|
||||
#define SIZE_OP_ANYCHAR_STAR SIZE_OPCODE
|
||||
#define SIZE_OP_ANYCHAR_STAR_PEEK_NEXT (SIZE_OPCODE + 1)
|
||||
#define SIZE_OP_JUMP (SIZE_OPCODE + SIZE_RELADDR)
|
||||
#define SIZE_OP_PUSH (SIZE_OPCODE + SIZE_RELADDR)
|
||||
#define SIZE_OP_POP SIZE_OPCODE
|
||||
#define SIZE_OP_PUSH_OR_JUMP_EXACT1 (SIZE_OPCODE + SIZE_RELADDR + 1)
|
||||
#define SIZE_OP_PUSH_IF_PEEK_NEXT (SIZE_OPCODE + SIZE_RELADDR + 1)
|
||||
#define SIZE_OP_REPEAT_INC (SIZE_OPCODE + SIZE_MEMNUM)
|
||||
#define SIZE_OP_REPEAT_INC_NG (SIZE_OPCODE + SIZE_MEMNUM)
|
||||
#define SIZE_OP_PUSH_POS SIZE_OPCODE
|
||||
#define SIZE_OP_PUSH_POS_NOT (SIZE_OPCODE + SIZE_RELADDR)
|
||||
#define SIZE_OP_POP_POS SIZE_OPCODE
|
||||
#define SIZE_OP_FAIL_POS SIZE_OPCODE
|
||||
#define SIZE_OP_SET_OPTION (SIZE_OPCODE + SIZE_OPTION)
|
||||
#define SIZE_OP_SET_OPTION_PUSH (SIZE_OPCODE + SIZE_OPTION)
|
||||
#define SIZE_OP_FAIL SIZE_OPCODE
|
||||
#define SIZE_OP_MEMORY_START (SIZE_OPCODE + SIZE_MEMNUM)
|
||||
#define SIZE_OP_MEMORY_START_PUSH (SIZE_OPCODE + SIZE_MEMNUM)
|
||||
#define SIZE_OP_MEMORY_END_PUSH (SIZE_OPCODE + SIZE_MEMNUM)
|
||||
#define SIZE_OP_MEMORY_END_PUSH_REC (SIZE_OPCODE + SIZE_MEMNUM)
|
||||
#define SIZE_OP_MEMORY_END (SIZE_OPCODE + SIZE_MEMNUM)
|
||||
#define SIZE_OP_MEMORY_END_REC (SIZE_OPCODE + SIZE_MEMNUM)
|
||||
#define SIZE_OP_PUSH_STOP_BT SIZE_OPCODE
|
||||
#define SIZE_OP_POP_STOP_BT SIZE_OPCODE
|
||||
#define SIZE_OP_NULL_CHECK_START (SIZE_OPCODE + SIZE_MEMNUM)
|
||||
#define SIZE_OP_NULL_CHECK_END (SIZE_OPCODE + SIZE_MEMNUM)
|
||||
#define SIZE_OP_LOOK_BEHIND (SIZE_OPCODE + SIZE_LENGTH)
|
||||
#define SIZE_OP_PUSH_LOOK_BEHIND_NOT (SIZE_OPCODE + SIZE_RELADDR + SIZE_LENGTH)
|
||||
#define SIZE_OP_FAIL_LOOK_BEHIND_NOT SIZE_OPCODE
|
||||
#define SIZE_OP_CALL (SIZE_OPCODE + SIZE_ABSADDR)
|
||||
#define SIZE_OP_RETURN SIZE_OPCODE
|
||||
|
||||
#ifdef USE_COMBINATION_EXPLOSION_CHECK
|
||||
#define SIZE_OP_STATE_CHECK (SIZE_OPCODE + SIZE_STATE_CHECK_NUM)
|
||||
#define SIZE_OP_STATE_CHECK_PUSH (SIZE_OPCODE + SIZE_STATE_CHECK_NUM + SIZE_RELADDR)
|
||||
#define SIZE_OP_STATE_CHECK_PUSH_OR_JUMP (SIZE_OPCODE + SIZE_STATE_CHECK_NUM + SIZE_RELADDR)
|
||||
#define SIZE_OP_STATE_CHECK_ANYCHAR_STAR (SIZE_OPCODE + SIZE_STATE_CHECK_NUM)
|
||||
#endif
|
||||
|
||||
#define MC_ESC(syn) (syn)->meta_char_table.esc
|
||||
#define MC_ANYCHAR(syn) (syn)->meta_char_table.anychar
|
||||
#define MC_ANYTIME(syn) (syn)->meta_char_table.anytime
|
||||
#define MC_ZERO_OR_ONE_TIME(syn) (syn)->meta_char_table.zero_or_one_time
|
||||
#define MC_ONE_OR_MORE_TIME(syn) (syn)->meta_char_table.one_or_more_time
|
||||
#define MC_ANYCHAR_ANYTIME(syn) (syn)->meta_char_table.anychar_anytime
|
||||
|
||||
#define IS_MC_ESC_CODE(code, syn) \
|
||||
((code) == MC_ESC(syn) && \
|
||||
!IS_SYNTAX_OP2((syn), ONIG_SYN_OP2_INEFFECTIVE_ESCAPE))
|
||||
|
||||
|
||||
#define SYN_POSIX_COMMON_OP \
|
||||
( ONIG_SYN_OP_DOT_ANYCHAR | ONIG_SYN_OP_POSIX_BRACKET | \
|
||||
ONIG_SYN_OP_DECIMAL_BACKREF | \
|
||||
ONIG_SYN_OP_BRACKET_CC | ONIG_SYN_OP_ASTERISK_ZERO_INF | \
|
||||
ONIG_SYN_OP_LINE_ANCHOR | \
|
||||
ONIG_SYN_OP_ESC_CONTROL_CHARS )
|
||||
|
||||
#define SYN_GNU_REGEX_OP \
|
||||
( ONIG_SYN_OP_DOT_ANYCHAR | ONIG_SYN_OP_BRACKET_CC | \
|
||||
ONIG_SYN_OP_POSIX_BRACKET | ONIG_SYN_OP_DECIMAL_BACKREF | \
|
||||
ONIG_SYN_OP_BRACE_INTERVAL | ONIG_SYN_OP_LPAREN_SUBEXP | \
|
||||
ONIG_SYN_OP_VBAR_ALT | \
|
||||
ONIG_SYN_OP_ASTERISK_ZERO_INF | ONIG_SYN_OP_PLUS_ONE_INF | \
|
||||
ONIG_SYN_OP_QMARK_ZERO_ONE | \
|
||||
ONIG_SYN_OP_ESC_AZ_BUF_ANCHOR | ONIG_SYN_OP_ESC_CAPITAL_G_BEGIN_ANCHOR | \
|
||||
ONIG_SYN_OP_ESC_W_WORD | \
|
||||
ONIG_SYN_OP_ESC_B_WORD_BOUND | ONIG_SYN_OP_ESC_LTGT_WORD_BEGIN_END | \
|
||||
ONIG_SYN_OP_ESC_S_WHITE_SPACE | ONIG_SYN_OP_ESC_D_DIGIT | \
|
||||
ONIG_SYN_OP_LINE_ANCHOR )
|
||||
|
||||
#define SYN_GNU_REGEX_BV \
|
||||
( ONIG_SYN_CONTEXT_INDEP_ANCHORS | ONIG_SYN_CONTEXT_INDEP_REPEAT_OPS | \
|
||||
ONIG_SYN_CONTEXT_INVALID_REPEAT_OPS | ONIG_SYN_ALLOW_INVALID_INTERVAL | \
|
||||
ONIG_SYN_BACKSLASH_ESCAPE_IN_CC | ONIG_SYN_ALLOW_DOUBLE_RANGE_OP_IN_CC )
|
||||
|
||||
|
||||
#define NCCLASS_FLAGS(cc) ((cc)->flags)
|
||||
#define NCCLASS_FLAG_SET(cc,flag) (NCCLASS_FLAGS(cc) |= (flag))
|
||||
#define NCCLASS_FLAG_CLEAR(cc,flag) (NCCLASS_FLAGS(cc) &= ~(flag))
|
||||
#define IS_NCCLASS_FLAG_ON(cc,flag) ((NCCLASS_FLAGS(cc) & (flag)) != 0)
|
||||
|
||||
/* cclass node */
|
||||
#define FLAG_NCCLASS_NOT (1<<0)
|
||||
#define FLAG_NCCLASS_SHARE (1<<1)
|
||||
|
||||
#define NCCLASS_SET_NOT(nd) NCCLASS_FLAG_SET(nd, FLAG_NCCLASS_NOT)
|
||||
#define NCCLASS_SET_SHARE(nd) NCCLASS_FLAG_SET(nd, FLAG_NCCLASS_SHARE)
|
||||
#define NCCLASS_CLEAR_NOT(nd) NCCLASS_FLAG_CLEAR(nd, FLAG_NCCLASS_NOT)
|
||||
#define IS_NCCLASS_NOT(nd) IS_NCCLASS_FLAG_ON(nd, FLAG_NCCLASS_NOT)
|
||||
#define IS_NCCLASS_SHARE(nd) IS_NCCLASS_FLAG_ON(nd, FLAG_NCCLASS_SHARE)
|
||||
|
||||
typedef struct {
|
||||
int type;
|
||||
/* struct _Node* next; */
|
||||
/* unsigned int flags; */
|
||||
} NodeBase;
|
||||
|
||||
typedef struct {
|
||||
NodeBase base;
|
||||
unsigned int flags;
|
||||
BitSet bs;
|
||||
BBuf* mbuf; /* multi-byte info or NULL */
|
||||
} CClassNode;
|
||||
|
||||
typedef intptr_t OnigStackIndex;
|
||||
|
||||
typedef struct _OnigStackType {
|
||||
unsigned int type;
|
||||
union {
|
||||
struct {
|
||||
UChar *pcode; /* byte code position */
|
||||
UChar *pstr; /* string position */
|
||||
UChar *pstr_prev; /* previous char position of pstr */
|
||||
#ifdef USE_COMBINATION_EXPLOSION_CHECK
|
||||
unsigned int state_check;
|
||||
#endif
|
||||
} state;
|
||||
struct {
|
||||
int count; /* for OP_REPEAT_INC, OP_REPEAT_INC_NG */
|
||||
UChar *pcode; /* byte code position (head of repeated target) */
|
||||
int num; /* repeat id */
|
||||
} repeat;
|
||||
struct {
|
||||
OnigStackIndex si; /* index of stack */
|
||||
} repeat_inc;
|
||||
struct {
|
||||
int num; /* memory num */
|
||||
UChar *pstr; /* start/end position */
|
||||
/* Following information is setted, if this stack type is MEM-START */
|
||||
OnigStackIndex start; /* prev. info (for backtrack "(...)*" ) */
|
||||
OnigStackIndex end; /* prev. info (for backtrack "(...)*" ) */
|
||||
} mem;
|
||||
struct {
|
||||
int num; /* null check id */
|
||||
UChar *pstr; /* start position */
|
||||
} null_check;
|
||||
#ifdef USE_SUBEXP_CALL
|
||||
struct {
|
||||
UChar *ret_addr; /* byte code position */
|
||||
int num; /* null check id */
|
||||
UChar *pstr; /* string position */
|
||||
} call_frame;
|
||||
#endif
|
||||
} u;
|
||||
} OnigStackType;
|
||||
|
||||
typedef struct {
|
||||
void* stack_p;
|
||||
size_t stack_n;
|
||||
OnigOptionType options;
|
||||
OnigRegion* region;
|
||||
const UChar* start; /* search start position (for \G: BEGIN_POSITION) */
|
||||
#ifdef USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE
|
||||
int best_len; /* for ONIG_OPTION_FIND_LONGEST */
|
||||
UChar* best_s;
|
||||
#endif
|
||||
#ifdef USE_COMBINATION_EXPLOSION_CHECK
|
||||
void* state_check_buff;
|
||||
int state_check_buff_size;
|
||||
#endif
|
||||
} OnigMatchArg;
|
||||
|
||||
|
||||
#define IS_CODE_SB_WORD(enc,code) \
|
||||
(ONIGENC_IS_CODE_ASCII(code) && ONIGENC_IS_CODE_WORD(enc,code))
|
||||
|
||||
#ifdef ONIG_DEBUG
|
||||
|
||||
typedef struct {
|
||||
short int opcode;
|
||||
char* name;
|
||||
short int arg_type;
|
||||
} OnigOpInfoType;
|
||||
|
||||
extern OnigOpInfoType OnigOpInfo[];
|
||||
|
||||
/* extern void onig_print_compiled_byte_code(FILE* f, UChar* bp, UChar* bpend, UChar** nextp, OnigEncoding enc); */
|
||||
|
||||
#ifdef ONIG_DEBUG_STATISTICS
|
||||
extern void onig_statistics_init(void);
|
||||
extern void onig_print_statistics(FILE* f);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
extern UChar* onig_error_code_to_format(int code);
|
||||
extern void onig_snprintf_with_pattern(UChar buf[], int bufsize, OnigEncoding enc, UChar* pat, UChar* pat_end, const UChar *fmt, ...);
|
||||
extern int onig_bbuf_init(BBuf* buf, int size);
|
||||
extern int onig_compile(regex_t* reg, const UChar* pattern, const UChar* pattern_end, OnigErrorInfo* einfo, const char *sourcefile, int sourceline);
|
||||
extern void onig_chain_reduce(regex_t* reg);
|
||||
extern void onig_chain_link_add(regex_t* to, regex_t* add);
|
||||
extern void onig_transfer(regex_t* to, regex_t* from);
|
||||
extern int onig_is_code_in_cc(OnigEncoding enc, OnigCodePoint code, CClassNode* cc);
|
||||
extern int onig_is_code_in_cc_len(int enclen, OnigCodePoint code, CClassNode* cc);
|
||||
|
||||
/* strend hash */
|
||||
typedef void hash_table_type;
|
||||
#ifdef RUBY
|
||||
#include "st.h"
|
||||
|
||||
typedef st_data_t hash_data_type;
|
||||
#else
|
||||
typedef unsigned long hash_data_type;
|
||||
#endif
|
||||
|
||||
extern hash_table_type* onig_st_init_strend_table_with_size(st_index_t size);
|
||||
extern int onig_st_lookup_strend(hash_table_type* table, const UChar* str_key, const UChar* end_key, hash_data_type *value);
|
||||
extern int onig_st_insert_strend(hash_table_type* table, const UChar* str_key, const UChar* end_key, hash_data_type value);
|
||||
|
||||
/* encoding property management */
|
||||
#define PROPERTY_LIST_ADD_PROP(Name, CR) \
|
||||
r = onigenc_property_list_add_property((UChar* )Name, CR,\
|
||||
&PropertyNameTable, &PropertyList, &PropertyListNum,\
|
||||
&PropertyListSize);\
|
||||
if (r != 0) goto end
|
||||
|
||||
#define PROPERTY_LIST_INIT_CHECK \
|
||||
if (PropertyInited == 0) {\
|
||||
int r = onigenc_property_list_init(init_property_list);\
|
||||
if (r != 0) return r;\
|
||||
}
|
||||
|
||||
extern int onigenc_property_list_add_property(UChar* name, const OnigCodePoint* prop, hash_table_type **table, const OnigCodePoint*** plist, int *pnum, int *psize);
|
||||
|
||||
typedef int (*ONIGENC_INIT_PROPERTY_LIST_FUNC_TYPE)(void);
|
||||
|
||||
extern int onigenc_property_list_init(ONIGENC_INIT_PROPERTY_LIST_FUNC_TYPE);
|
||||
|
||||
#endif /* ONIGURUMA_REGINT_H */
|
||||
+5600
File diff suppressed because it is too large
Load Diff
+354
@@ -0,0 +1,354 @@
|
||||
#ifndef ONIGURUMA_REGPARSE_H
|
||||
#define ONIGURUMA_REGPARSE_H
|
||||
/**********************************************************************
|
||||
regparse.h - Oniguruma (regular expression library)
|
||||
**********************************************************************/
|
||||
/*-
|
||||
* Copyright (c) 2002-2007 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "regint.h"
|
||||
|
||||
/* node type */
|
||||
#define NT_STR 0
|
||||
#define NT_CCLASS 1
|
||||
#define NT_CTYPE 2
|
||||
#define NT_CANY 3
|
||||
#define NT_BREF 4
|
||||
#define NT_QTFR 5
|
||||
#define NT_ENCLOSE 6
|
||||
#define NT_ANCHOR 7
|
||||
#define NT_LIST 8
|
||||
#define NT_ALT 9
|
||||
#define NT_CALL 10
|
||||
|
||||
/* node type bit */
|
||||
#define NTYPE2BIT(type) (1<<(type))
|
||||
|
||||
#define BIT_NT_STR NTYPE2BIT(NT_STR)
|
||||
#define BIT_NT_CCLASS NTYPE2BIT(NT_CCLASS)
|
||||
#define BIT_NT_CTYPE NTYPE2BIT(NT_CTYPE)
|
||||
#define BIT_NT_CANY NTYPE2BIT(NT_CANY)
|
||||
#define BIT_NT_BREF NTYPE2BIT(NT_BREF)
|
||||
#define BIT_NT_QTFR NTYPE2BIT(NT_QTFR)
|
||||
#define BIT_NT_ENCLOSE NTYPE2BIT(NT_ENCLOSE)
|
||||
#define BIT_NT_ANCHOR NTYPE2BIT(NT_ANCHOR)
|
||||
#define BIT_NT_LIST NTYPE2BIT(NT_LIST)
|
||||
#define BIT_NT_ALT NTYPE2BIT(NT_ALT)
|
||||
#define BIT_NT_CALL NTYPE2BIT(NT_CALL)
|
||||
|
||||
#define IS_NODE_TYPE_SIMPLE(type) \
|
||||
((NTYPE2BIT(type) & (BIT_NT_STR | BIT_NT_CCLASS | BIT_NT_CTYPE |\
|
||||
BIT_NT_CANY | BIT_NT_BREF)) != 0)
|
||||
|
||||
#define NTYPE(node) ((node)->u.base.type)
|
||||
#define SET_NTYPE(node, ntype) (node)->u.base.type = (ntype)
|
||||
|
||||
#define NSTR(node) (&((node)->u.str))
|
||||
#define NCCLASS(node) (&((node)->u.cclass))
|
||||
#define NCTYPE(node) (&((node)->u.ctype))
|
||||
#define NBREF(node) (&((node)->u.bref))
|
||||
#define NQTFR(node) (&((node)->u.qtfr))
|
||||
#define NENCLOSE(node) (&((node)->u.enclose))
|
||||
#define NANCHOR(node) (&((node)->u.anchor))
|
||||
#define NCONS(node) (&((node)->u.cons))
|
||||
#define NCALL(node) (&((node)->u.call))
|
||||
|
||||
#define NCAR(node) (NCONS(node)->car)
|
||||
#define NCDR(node) (NCONS(node)->cdr)
|
||||
|
||||
|
||||
|
||||
#define ANCHOR_ANYCHAR_STAR_MASK (ANCHOR_ANYCHAR_STAR | ANCHOR_ANYCHAR_STAR_ML)
|
||||
#define ANCHOR_END_BUF_MASK (ANCHOR_END_BUF | ANCHOR_SEMI_END_BUF)
|
||||
|
||||
#define ENCLOSE_MEMORY (1<<0)
|
||||
#define ENCLOSE_OPTION (1<<1)
|
||||
#define ENCLOSE_STOP_BACKTRACK (1<<2)
|
||||
|
||||
#define NODE_STR_MARGIN 16
|
||||
#define NODE_STR_BUF_SIZE 24 /* sizeof(CClassNode) - sizeof(int)*4 */
|
||||
#define NODE_BACKREFS_SIZE 6
|
||||
|
||||
#define NSTR_RAW (1<<0) /* by backslashed number */
|
||||
#define NSTR_AMBIG (1<<1)
|
||||
#define NSTR_DONT_GET_OPT_INFO (1<<2)
|
||||
|
||||
#define NSTRING_LEN(node) ((node)->u.str.end - (node)->u.str.s)
|
||||
#define NSTRING_SET_RAW(node) (node)->u.str.flag |= NSTR_RAW
|
||||
#define NSTRING_CLEAR_RAW(node) (node)->u.str.flag &= ~NSTR_RAW
|
||||
#define NSTRING_SET_AMBIG(node) (node)->u.str.flag |= NSTR_AMBIG
|
||||
#define NSTRING_SET_DONT_GET_OPT_INFO(node) \
|
||||
(node)->u.str.flag |= NSTR_DONT_GET_OPT_INFO
|
||||
#define NSTRING_IS_RAW(node) (((node)->u.str.flag & NSTR_RAW) != 0)
|
||||
#define NSTRING_IS_AMBIG(node) (((node)->u.str.flag & NSTR_AMBIG) != 0)
|
||||
#define NSTRING_IS_DONT_GET_OPT_INFO(node) \
|
||||
(((node)->u.str.flag & NSTR_DONT_GET_OPT_INFO) != 0)
|
||||
|
||||
#define BACKREFS_P(br) \
|
||||
(IS_NOT_NULL((br)->back_dynamic) ? (br)->back_dynamic : (br)->back_static);
|
||||
|
||||
#define NQ_TARGET_ISNOT_EMPTY 0
|
||||
#define NQ_TARGET_IS_EMPTY 1
|
||||
#define NQ_TARGET_IS_EMPTY_MEM 2
|
||||
#define NQ_TARGET_IS_EMPTY_REC 3
|
||||
|
||||
/* status bits */
|
||||
#define NST_MIN_FIXED (1<<0)
|
||||
#define NST_MAX_FIXED (1<<1)
|
||||
#define NST_CLEN_FIXED (1<<2)
|
||||
#define NST_MARK1 (1<<3)
|
||||
#define NST_MARK2 (1<<4)
|
||||
#define NST_MEM_BACKREFED (1<<5)
|
||||
#define NST_STOP_BT_SIMPLE_REPEAT (1<<6)
|
||||
#define NST_RECURSION (1<<7)
|
||||
#define NST_CALLED (1<<8)
|
||||
#define NST_ADDR_FIXED (1<<9)
|
||||
#define NST_NAMED_GROUP (1<<10)
|
||||
#define NST_NAME_REF (1<<11)
|
||||
#define NST_IN_REPEAT (1<<12) /* STK_REPEAT is nested in stack. */
|
||||
#define NST_NEST_LEVEL (1<<13)
|
||||
#define NST_BY_NUMBER (1<<14) /* {n,m} */
|
||||
|
||||
#define SET_ENCLOSE_STATUS(node,f) (node)->u.enclose.state |= (f)
|
||||
#define CLEAR_ENCLOSE_STATUS(node,f) (node)->u.enclose.state &= ~(f)
|
||||
|
||||
#define IS_ENCLOSE_CALLED(en) (((en)->state & NST_CALLED) != 0)
|
||||
#define IS_ENCLOSE_ADDR_FIXED(en) (((en)->state & NST_ADDR_FIXED) != 0)
|
||||
#define IS_ENCLOSE_RECURSION(en) (((en)->state & NST_RECURSION) != 0)
|
||||
#define IS_ENCLOSE_MARK1(en) (((en)->state & NST_MARK1) != 0)
|
||||
#define IS_ENCLOSE_MARK2(en) (((en)->state & NST_MARK2) != 0)
|
||||
#define IS_ENCLOSE_MIN_FIXED(en) (((en)->state & NST_MIN_FIXED) != 0)
|
||||
#define IS_ENCLOSE_MAX_FIXED(en) (((en)->state & NST_MAX_FIXED) != 0)
|
||||
#define IS_ENCLOSE_CLEN_FIXED(en) (((en)->state & NST_CLEN_FIXED) != 0)
|
||||
#define IS_ENCLOSE_STOP_BT_SIMPLE_REPEAT(en) \
|
||||
(((en)->state & NST_STOP_BT_SIMPLE_REPEAT) != 0)
|
||||
#define IS_ENCLOSE_NAMED_GROUP(en) (((en)->state & NST_NAMED_GROUP) != 0)
|
||||
|
||||
#define SET_CALL_RECURSION(node) (node)->u.call.state |= NST_RECURSION
|
||||
#define IS_CALL_RECURSION(cn) (((cn)->state & NST_RECURSION) != 0)
|
||||
#define IS_CALL_NAME_REF(cn) (((cn)->state & NST_NAME_REF) != 0)
|
||||
#define IS_BACKREF_NAME_REF(bn) (((bn)->state & NST_NAME_REF) != 0)
|
||||
#define IS_BACKREF_NEST_LEVEL(bn) (((bn)->state & NST_NEST_LEVEL) != 0)
|
||||
#define IS_QUANTIFIER_IN_REPEAT(qn) (((qn)->state & NST_IN_REPEAT) != 0)
|
||||
#define IS_QUANTIFIER_BY_NUMBER(qn) (((qn)->state & NST_BY_NUMBER) != 0)
|
||||
|
||||
#define CALLNODE_REFNUM_UNDEF -1
|
||||
|
||||
typedef struct {
|
||||
NodeBase base;
|
||||
UChar* s;
|
||||
UChar* end;
|
||||
unsigned int flag;
|
||||
int capa; /* (allocated size - 1) or 0: use buf[] */
|
||||
UChar buf[NODE_STR_BUF_SIZE];
|
||||
} StrNode;
|
||||
|
||||
typedef struct {
|
||||
NodeBase base;
|
||||
int state;
|
||||
struct _Node* target;
|
||||
int lower;
|
||||
int upper;
|
||||
int greedy;
|
||||
int target_empty_info;
|
||||
struct _Node* head_exact;
|
||||
struct _Node* next_head_exact;
|
||||
int is_refered; /* include called node. don't eliminate even if {0} */
|
||||
#ifdef USE_COMBINATION_EXPLOSION_CHECK
|
||||
int comb_exp_check_num; /* 1,2,3...: check, 0: no check */
|
||||
#endif
|
||||
} QtfrNode;
|
||||
|
||||
typedef struct {
|
||||
NodeBase base;
|
||||
int state;
|
||||
int type;
|
||||
int regnum;
|
||||
OnigOptionType option;
|
||||
struct _Node* target;
|
||||
AbsAddrType call_addr;
|
||||
/* for multiple call reference */
|
||||
OnigDistance min_len; /* min length (byte) */
|
||||
OnigDistance max_len; /* max length (byte) */
|
||||
int char_len; /* character length */
|
||||
int opt_count; /* referenced count in optimize_node_left() */
|
||||
} EncloseNode;
|
||||
|
||||
#ifdef USE_SUBEXP_CALL
|
||||
|
||||
typedef struct {
|
||||
int offset;
|
||||
struct _Node* target;
|
||||
} UnsetAddr;
|
||||
|
||||
typedef struct {
|
||||
int num;
|
||||
int alloc;
|
||||
UnsetAddr* us;
|
||||
} UnsetAddrList;
|
||||
|
||||
typedef struct {
|
||||
NodeBase base;
|
||||
int state;
|
||||
int group_num;
|
||||
UChar* name;
|
||||
UChar* name_end;
|
||||
struct _Node* target; /* EncloseNode : ENCLOSE_MEMORY */
|
||||
UnsetAddrList* unset_addr_list;
|
||||
} CallNode;
|
||||
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
NodeBase base;
|
||||
int state;
|
||||
int back_num;
|
||||
int back_static[NODE_BACKREFS_SIZE];
|
||||
int* back_dynamic;
|
||||
int nest_level;
|
||||
} BRefNode;
|
||||
|
||||
typedef struct {
|
||||
NodeBase base;
|
||||
int type;
|
||||
struct _Node* target;
|
||||
int char_len;
|
||||
} AnchorNode;
|
||||
|
||||
typedef struct {
|
||||
NodeBase base;
|
||||
struct _Node* car;
|
||||
struct _Node* cdr;
|
||||
} ConsAltNode;
|
||||
|
||||
typedef struct {
|
||||
NodeBase base;
|
||||
int ctype;
|
||||
int not;
|
||||
} CtypeNode;
|
||||
|
||||
typedef struct _Node {
|
||||
union {
|
||||
NodeBase base;
|
||||
StrNode str;
|
||||
CClassNode cclass;
|
||||
QtfrNode qtfr;
|
||||
EncloseNode enclose;
|
||||
BRefNode bref;
|
||||
AnchorNode anchor;
|
||||
ConsAltNode cons;
|
||||
CtypeNode ctype;
|
||||
#ifdef USE_SUBEXP_CALL
|
||||
CallNode call;
|
||||
#endif
|
||||
} u;
|
||||
} Node;
|
||||
|
||||
|
||||
#define NULL_NODE ((Node* )0)
|
||||
|
||||
#define SCANENV_MEMNODES_SIZE 8
|
||||
#define SCANENV_MEM_NODES(senv) \
|
||||
(IS_NOT_NULL((senv)->mem_nodes_dynamic) ? \
|
||||
(senv)->mem_nodes_dynamic : (senv)->mem_nodes_static)
|
||||
|
||||
typedef struct {
|
||||
OnigOptionType option;
|
||||
OnigCaseFoldType case_fold_flag;
|
||||
OnigEncoding enc;
|
||||
const OnigSyntaxType* syntax;
|
||||
BitStatusType capture_history;
|
||||
BitStatusType bt_mem_start;
|
||||
BitStatusType bt_mem_end;
|
||||
BitStatusType backrefed_mem;
|
||||
UChar* pattern;
|
||||
UChar* pattern_end;
|
||||
UChar* error;
|
||||
UChar* error_end;
|
||||
regex_t* reg; /* for reg->names only */
|
||||
int num_call;
|
||||
#ifdef USE_SUBEXP_CALL
|
||||
UnsetAddrList* unset_addr_list;
|
||||
#endif
|
||||
int num_mem;
|
||||
#ifdef USE_NAMED_GROUP
|
||||
int num_named;
|
||||
#endif
|
||||
int mem_alloc;
|
||||
Node* mem_nodes_static[SCANENV_MEMNODES_SIZE];
|
||||
Node** mem_nodes_dynamic;
|
||||
#ifdef USE_COMBINATION_EXPLOSION_CHECK
|
||||
int num_comb_exp_check;
|
||||
int comb_exp_max_regnum;
|
||||
int curr_max_regnum;
|
||||
int has_recursion;
|
||||
#endif
|
||||
int warnings_flag;
|
||||
const char* sourcefile;
|
||||
int sourceline;
|
||||
} ScanEnv;
|
||||
|
||||
|
||||
#define IS_SYNTAX_OP(syn, opm) (((syn)->op & (opm)) != 0)
|
||||
#define IS_SYNTAX_OP2(syn, opm) (((syn)->op2 & (opm)) != 0)
|
||||
#define IS_SYNTAX_BV(syn, bvm) (((syn)->behavior & (bvm)) != 0)
|
||||
|
||||
#ifdef USE_NAMED_GROUP
|
||||
typedef struct {
|
||||
int new_val;
|
||||
} GroupNumRemap;
|
||||
|
||||
extern int onig_renumber_name_table(regex_t* reg, GroupNumRemap* map);
|
||||
#endif
|
||||
|
||||
extern int onig_strncmp(const UChar* s1, const UChar* s2, int n);
|
||||
extern void onig_strcpy(UChar* dest, const UChar* src, const UChar* end);
|
||||
extern void onig_scan_env_set_error_string(ScanEnv* env, int ecode, UChar* arg, UChar* arg_end);
|
||||
extern int onig_scan_unsigned_number(UChar** src, const UChar* end, OnigEncoding enc);
|
||||
extern void onig_reduce_nested_quantifier(Node* pnode, Node* cnode);
|
||||
extern void onig_node_conv_to_str_node(Node* node, int raw);
|
||||
extern int onig_node_str_cat(Node* node, const UChar* s, const UChar* end);
|
||||
extern int onig_node_str_set(Node* node, const UChar* s, const UChar* end);
|
||||
extern void onig_node_free(Node* node);
|
||||
extern Node* onig_node_new_enclose(int type);
|
||||
extern Node* onig_node_new_anchor(int type);
|
||||
extern Node* onig_node_new_str(const UChar* s, const UChar* end);
|
||||
extern Node* onig_node_new_list(Node* left, Node* right);
|
||||
extern Node* onig_node_list_add(Node* list, Node* x);
|
||||
extern Node* onig_node_new_alt(Node* left, Node* right);
|
||||
extern void onig_node_str_clear(Node* node);
|
||||
extern int onig_free_node_list(void);
|
||||
extern int onig_names_free(regex_t* reg);
|
||||
extern int onig_parse_make_tree(Node** root, const UChar* pattern, const UChar* end, regex_t* reg, ScanEnv* env);
|
||||
extern int onig_free_shared_cclass_table(void);
|
||||
|
||||
#ifdef ONIG_DEBUG
|
||||
#ifdef USE_NAMED_GROUP
|
||||
extern int onig_print_names(FILE*, regex_t*);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif /* ONIGURUMA_REGPARSE_H */
|
||||
+203
@@ -0,0 +1,203 @@
|
||||
/*
|
||||
* Rite Hash
|
||||
*
|
||||
*
|
||||
*/
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
typedef uint32_t khint_t;
|
||||
typedef khint_t khiter_t;
|
||||
|
||||
#define INITIAL_HASH_SIZE 32
|
||||
#define UPPER_BOUND(x) ((x)>>2|(x>>1))
|
||||
|
||||
//extern uint8_t __m[];
|
||||
|
||||
/* mask for flags */
|
||||
static uint8_t __m[8] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
|
||||
|
||||
|
||||
#define __ac_isempty(e_flag, d_flag, i) (e_flag[(i)/8]&__m[(i)%8])
|
||||
#define __ac_isdel(e_flag, d_flag, i) (d_flag[(i)/8]&__m[(i)%8])
|
||||
#define __ac_iseither(e_flag, d_flag, i) (__ac_isempty(e_flag,d_flag,i)||__ac_isdel(e_flag,d_flag,i))
|
||||
|
||||
|
||||
/* struct kh_xxx
|
||||
|
||||
name: ash name
|
||||
khkey_t: key data type
|
||||
khval_t: value data type
|
||||
kh_is_map: (not implemented / not used in RiteVM )
|
||||
__hash_func: hash function
|
||||
__hash_equal: hash comparation function
|
||||
*/
|
||||
#define KHASH_INIT(name, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) \
|
||||
typedef struct kh_##name { \
|
||||
khint_t n_buckets; \
|
||||
khint_t size; \
|
||||
khint_t n_occupied; \
|
||||
khint_t upper_bound; \
|
||||
uint8_t *e_flags; \
|
||||
uint8_t *d_flags; \
|
||||
khkey_t *keys; \
|
||||
khval_t *vals; \
|
||||
khint_t mask; \
|
||||
khint_t inc; \
|
||||
mrb_state *mrb; \
|
||||
} kh_##name##_t; \
|
||||
static void kh_alloc_##name(kh_##name##_t *h) \
|
||||
{ \
|
||||
khint_t sz = h->n_buckets; \
|
||||
h->size = h->n_occupied = 0; \
|
||||
h->upper_bound = UPPER_BOUND(sz); \
|
||||
h->e_flags = (uint8_t *)mrb_malloc(h->mrb, sizeof(uint8_t)*sz/4); \
|
||||
h->d_flags = h->e_flags + sz/8; \
|
||||
memset(h->e_flags, 0xff, sz/8*sizeof(uint8_t)); \
|
||||
memset(h->d_flags, 0x00, sz/8*sizeof(uint8_t)); \
|
||||
h->keys = (khkey_t *)mrb_malloc(h->mrb, sizeof(khkey_t)*sz); \
|
||||
h->vals = (khval_t *)mrb_malloc(h->mrb, sizeof(khval_t)*sz); \
|
||||
h->mask = sz-1; \
|
||||
h->inc = sz/2-1; \
|
||||
} \
|
||||
static inline kh_##name##_t *kh_init_##name(mrb_state *mrb){ \
|
||||
kh_##name##_t *h = (kh_##name##_t*)mrb_calloc(mrb, 1, sizeof(kh_##name##_t)); \
|
||||
h->n_buckets = INITIAL_HASH_SIZE; \
|
||||
h->mrb = mrb; \
|
||||
kh_alloc_##name(h); \
|
||||
return h; \
|
||||
} \
|
||||
static inline void kh_destroy_##name(kh_##name##_t *h) \
|
||||
{ \
|
||||
if( h ){ \
|
||||
mrb_free(h->mrb, h->keys); \
|
||||
mrb_free(h->mrb, h->vals); \
|
||||
mrb_free(h->mrb, h->e_flags); \
|
||||
mrb_free(h->mrb, h); \
|
||||
} \
|
||||
} \
|
||||
static inline void kh_clear_##name(kh_##name##_t *h) \
|
||||
{ \
|
||||
if( h && h->e_flags ){ \
|
||||
memset(h->e_flags, 0xff, h->n_buckets/8*sizeof(uint8_t)); \
|
||||
memset(h->d_flags, 0x00, h->n_buckets/8*sizeof(uint8_t)); \
|
||||
h->size = h->n_occupied = 0; \
|
||||
} \
|
||||
} \
|
||||
static inline khint_t kh_get_##name(kh_##name##_t *h, khkey_t key) \
|
||||
{ \
|
||||
khint_t k = __hash_func(h->mrb,key) & (h->mask); \
|
||||
while( !__ac_isempty(h->e_flags, h->d_flags, k) ){ \
|
||||
if( !__ac_isdel(h->e_flags, h->d_flags, k) ){ \
|
||||
if( __hash_equal(h->mrb,h->keys[k], key) ) return k; \
|
||||
} \
|
||||
k = (k+h->inc) & (h->mask); \
|
||||
} \
|
||||
return h->n_buckets; \
|
||||
} \
|
||||
static inline khint_t kh_put_##name(kh_##name##_t *h, khkey_t key); \
|
||||
static void kh_resize_##name(kh_##name##_t *h, khint_t new_n_buckets) \
|
||||
{ \
|
||||
if( new_n_buckets<INITIAL_HASH_SIZE ){ \
|
||||
new_n_buckets = INITIAL_HASH_SIZE; \
|
||||
} else { \
|
||||
khint_t limit = new_n_buckets; \
|
||||
new_n_buckets = INITIAL_HASH_SIZE; \
|
||||
while( new_n_buckets < limit ) new_n_buckets *= 2; \
|
||||
} \
|
||||
uint8_t *old_e_flags = h->e_flags; \
|
||||
uint8_t *old_d_flags = h->d_flags; \
|
||||
khkey_t *old_keys = h->keys; \
|
||||
khval_t *old_vals = h->vals; \
|
||||
khint_t old_n_buckets = h->n_buckets; \
|
||||
h->n_buckets = new_n_buckets; \
|
||||
kh_alloc_##name(h); \
|
||||
/* relocate */ \
|
||||
khint_t i; \
|
||||
for( i=0 ; i<old_n_buckets ; i++ ){ \
|
||||
if( !__ac_isempty(old_e_flags, old_d_flags, i) ){ \
|
||||
khint_t k = kh_put_##name(h, old_keys[i]); \
|
||||
kh_value(h,k) = old_vals[i]; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
static inline khint_t kh_put_##name(kh_##name##_t *h, khkey_t key) \
|
||||
{ \
|
||||
khint_t k; \
|
||||
if( h->n_occupied >= h->upper_bound ){ \
|
||||
kh_resize_##name(h, h->n_buckets*2); \
|
||||
} \
|
||||
k = __hash_func(h->mrb,key) & (h->mask); \
|
||||
while( !__ac_iseither(h->e_flags, h->d_flags, k) ){ \
|
||||
if( __hash_equal(h->mrb,h->keys[k], key) ) break; \
|
||||
k = (k+h->inc) & (h->mask); \
|
||||
} \
|
||||
if( __ac_isempty(h->e_flags, h->d_flags, k) ) { \
|
||||
/* put at empty */ \
|
||||
h->keys[k] = key; \
|
||||
h->e_flags[k/8] &= ~__m[k%8]; \
|
||||
h->size++; \
|
||||
h->n_occupied++; \
|
||||
} else if( __ac_isdel(h->e_flags, h->d_flags, k) ) { \
|
||||
/* put at del */ \
|
||||
h->keys[k] = key; \
|
||||
h->d_flags[k/8] &= ~__m[k%8]; \
|
||||
h->size++; \
|
||||
} \
|
||||
return k; \
|
||||
} \
|
||||
static inline void kh_del_##name(kh_##name##_t *h, khint_t x) \
|
||||
{ \
|
||||
h->d_flags[x/8] |= __m[x%8]; \
|
||||
h->size--; \
|
||||
} \
|
||||
static inline void kh_debug_##name(kh_##name##_t *h) \
|
||||
{ \
|
||||
khint_t i; \
|
||||
printf("idx:e_flag:d_flag\n"); \
|
||||
for( i=0 ; i<h->n_buckets/8 ; i++ ){ \
|
||||
printf("%4d:%02X:%02X\n", i, h->e_flags[i], h->d_flags[i]); \
|
||||
} \
|
||||
} \
|
||||
|
||||
#define khash_t(name) kh_##name##_t
|
||||
|
||||
#define kh_init(name,mrb) kh_init_##name(mrb)
|
||||
#define kh_destroy(name, h) kh_destroy_##name(h)
|
||||
#define kh_clear(name, h) kh_clear_##name(h)
|
||||
#define kh_resize(name, h, s) kh_resize_##name(h, s)
|
||||
#define kh_put(name, h, k, r) kh_put_##name(h, k)
|
||||
#define kh_get(name, h, k) kh_get_##name(h, k)
|
||||
#define kh_del(name, h, k) kh_del_##name(h, k)
|
||||
#define kh_debug(name, h) kh_debug_##name(h)
|
||||
|
||||
#define kh_exist(h, x) (!__ac_iseither((h)->e_flags, (h)->d_flags, (x)))
|
||||
#define kh_key(h, x) ((h)->keys[x])
|
||||
#define kh_val(h, x) ((h)->vals[x])
|
||||
#define kh_value(h, x) ((h)->vals[x])
|
||||
#define kh_begin(h) (khint_t)(0)
|
||||
#define kh_end(h) ((h)->n_buckets)
|
||||
#define kh_size(h) ((h)->size)
|
||||
#define kh_n_buckets(h) ((h)->n_buckets)
|
||||
|
||||
//#define kh_int_hash_func(mrb,key) (uint32_t)(key)
|
||||
#define kh_int_hash_func(mrb,key) (uint32_t)((key)^((key)<<2)^((key)>>2))
|
||||
#define kh_int_hash_equal(mrb,a, b) (a == b)
|
||||
#define kh_int64_hash_func(mrb,key) (uint32_t)((key)>>33^(key)^(key)<<11)
|
||||
#define kh_int64_hash_equal(mrb,a, b) (a == b)
|
||||
static inline khint_t __ac_X31_hash_string(const char *s)
|
||||
{
|
||||
khint_t h = *s;
|
||||
if (h) for (++s ; *s; ++s) h = (h << 5) - h + *s;
|
||||
return h;
|
||||
}
|
||||
#define kh_str_hash_func(mrb,key) __ac_X31_hash_string(key)
|
||||
#define kh_str_hash_equal(mrb,a, b) (strcmp(a, b) == 0)
|
||||
|
||||
#define KHASH_MAP_INIT_INT(name, khval_t) \
|
||||
KHASH_INIT(name, uint32_t, khval_t, 1, kh_int_hash_func, kh_int_hash_equal)
|
||||
typedef const char *kh_cstr_t;
|
||||
#define KHASH_MAP_INIT_STR(name, khval_t) \
|
||||
KHASH_INIT(name, kh_cstr_t, khval_t, 1, kh_str_hash_func, kh_str_hash_equal)
|
||||
|
||||
+1112
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,139 @@
|
||||
/* This is a public domain general purpose hash table package written by Peter Moore @ UCB. */
|
||||
|
||||
/* @(#) st.h 5.1 89/12/14 */
|
||||
|
||||
#ifndef RUBY_ST_H
|
||||
#define RUBY_ST_H 1
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef RUBY_LIB_PREFIX
|
||||
|
||||
#ifdef RUBY_EXTCONF_H
|
||||
#include RUBY_EXTCONF_H
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined STDC_HEADERS
|
||||
#include <stddef.h>
|
||||
#elif defined HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STDINT_H
|
||||
# include <stdint.h>
|
||||
#endif
|
||||
#include <inttypes.h>
|
||||
|
||||
#ifndef CHAR_BIT
|
||||
# ifdef HAVE_LIMITS_H
|
||||
# include <limits.h>
|
||||
# else
|
||||
# define CHAR_BIT 8
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef _
|
||||
# define _(args) args
|
||||
#endif
|
||||
|
||||
#ifndef ANYARGS
|
||||
# ifdef __cplusplus
|
||||
# define ANYARGS ...
|
||||
# else
|
||||
# define ANYARGS
|
||||
# endif
|
||||
#endif
|
||||
|
||||
typedef uintptr_t st_data_t;
|
||||
typedef struct st_table st_table;
|
||||
|
||||
typedef st_data_t st_index_t;
|
||||
typedef int st_compare_func(st_data_t, st_data_t);
|
||||
typedef st_index_t st_hash_func(st_data_t);
|
||||
|
||||
typedef struct st_table_entry st_table_entry;
|
||||
|
||||
struct st_table_entry {
|
||||
st_index_t hash;
|
||||
st_data_t key;
|
||||
st_data_t record;
|
||||
st_table_entry *next;
|
||||
st_table_entry *fore, *back;
|
||||
};
|
||||
|
||||
#ifndef SIZEOF_VOIDP
|
||||
#define SIZEOF_VOIDP 4
|
||||
#endif
|
||||
|
||||
#define SIZEOF_ST_INDEX_T SIZEOF_VOIDP
|
||||
|
||||
struct st_hash_type {
|
||||
int (*compare)(ANYARGS /*st_data_t, st_data_t*/); /* st_compare_func* */
|
||||
st_index_t (*hash)(ANYARGS /*st_data_t*/); /* st_hash_func* */
|
||||
};
|
||||
|
||||
#define ST_INDEX_BITS (sizeof(st_index_t) * CHAR_BIT)
|
||||
|
||||
struct st_table {
|
||||
const struct st_hash_type *type;
|
||||
st_index_t num_bins;
|
||||
unsigned int entries_packed : 1;
|
||||
#ifdef __GNUC__
|
||||
__extension__
|
||||
#endif
|
||||
st_index_t num_entries : ST_INDEX_BITS - 1;
|
||||
struct st_table_entry **bins;
|
||||
struct st_table_entry *head, *tail;
|
||||
};
|
||||
|
||||
#define st_is_member(table,key) st_lookup(table,key,(st_data_t *)0)
|
||||
|
||||
enum st_retval {ST_CONTINUE, ST_STOP, ST_DELETE, ST_CHECK};
|
||||
|
||||
st_table *st_init_table(const struct st_hash_type *);
|
||||
st_table *st_init_table_with_size(const struct st_hash_type *, st_index_t);
|
||||
st_table *st_init_numtable(void);
|
||||
st_table *st_init_numtable_with_size(st_index_t);
|
||||
st_table *st_init_strtable(void);
|
||||
st_table *st_init_strtable_with_size(st_index_t);
|
||||
st_table *st_init_strcasetable(void);
|
||||
st_table *st_init_strcasetable_with_size(st_index_t);
|
||||
int st_delete(st_table *, st_data_t *, st_data_t *); /* returns 0:notfound 1:deleted */
|
||||
int st_delete_safe(st_table *, st_data_t *, st_data_t *, st_data_t);
|
||||
int st_insert(st_table *, st_data_t, st_data_t);
|
||||
int st_insert2(st_table *, st_data_t, st_data_t, st_data_t (*)(st_data_t));
|
||||
int st_lookup(st_table *, st_data_t, st_data_t *);
|
||||
int st_get_key(st_table *, st_data_t, st_data_t *);
|
||||
int st_foreach(st_table *, int (*)(ANYARGS), st_data_t);
|
||||
int st_foreachNew(mrb_state *mrb, st_table *, int (*)(ANYARGS), void*);
|
||||
int st_reverse_foreach(st_table *, int (*)(ANYARGS), st_data_t);
|
||||
void st_add_direct(st_table *, st_data_t, st_data_t);
|
||||
void st_free_table(st_table *);
|
||||
void st_cleanup_safe(st_table *, st_data_t);
|
||||
void st_clear(st_table *);
|
||||
st_table *st_copy(st_table *);
|
||||
int st_numcmp(st_data_t, st_data_t);
|
||||
st_index_t st_numhash(st_data_t);
|
||||
int st_strcasecmp(const char *s1, const char *s2);
|
||||
int st_strncasecmp(const char *s1, const char *s2, size_t n);
|
||||
size_t st_memsize(const st_table *);
|
||||
st_index_t st_hash(const void *ptr, size_t len, st_index_t h);
|
||||
st_index_t st_hash_uint32(st_index_t h, uint32_t i);
|
||||
st_index_t st_hash_uint(st_index_t h, st_index_t i);
|
||||
st_index_t st_hash_end(st_index_t h);
|
||||
st_index_t st_hash_start(st_index_t h);
|
||||
#define st_hash_start(h) ((st_index_t)(h))
|
||||
|
||||
int st_strcasecmp(const char *s1, const char *s2);
|
||||
int st_strncasecmp(const char *s1, const char *s2, size_t n);
|
||||
#define STRCASECMP(s1, s2) (st_strcasecmp(s1, s2))
|
||||
#define STRNCASECMP(s1, s2, n) (st_strncasecmp(s1, s2, n))
|
||||
|
||||
#if defined(__cplusplus)
|
||||
} /* extern "C" { */
|
||||
#endif
|
||||
|
||||
#endif /* RUBY_ST_H */
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
#include "mruby.h"
|
||||
#include "irep.h"
|
||||
#include <string.h>
|
||||
|
||||
void mrb_init_heap(mrb_state*);
|
||||
void mrb_init_core(mrb_state*);
|
||||
void mrb_init_ext(mrb_state*);
|
||||
|
||||
mrb_state*
|
||||
mrb_open_allocf(mrb_allocf f)
|
||||
{
|
||||
mrb_state *mrb = (f)(NULL, NULL, sizeof(mrb_state));
|
||||
|
||||
memset(mrb, 0, sizeof(mrb_state));
|
||||
mrb->allocf = f;
|
||||
mrb->current_white_part = MRB_GC_WHITE_A;
|
||||
|
||||
mrb_init_heap(mrb);
|
||||
mrb_init_core(mrb);
|
||||
mrb_init_ext(mrb);
|
||||
return mrb;
|
||||
}
|
||||
|
||||
static void*
|
||||
allocf(mrb_state *mrb, void *p, size_t size)
|
||||
{
|
||||
if (size == 0) {
|
||||
free(p);
|
||||
return NULL;
|
||||
}
|
||||
else {
|
||||
return realloc(p, size);
|
||||
}
|
||||
}
|
||||
|
||||
mrb_state*
|
||||
mrb_open()
|
||||
{
|
||||
mrb_state *mrb = mrb_open_allocf(allocf);
|
||||
|
||||
return mrb;
|
||||
}
|
||||
|
||||
void
|
||||
mrb_close(mrb_state *mrb)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* free */
|
||||
mrb_free(mrb, mrb->stbase);
|
||||
mrb_free(mrb, mrb->cibase);
|
||||
for (i=0; i<mrb->irep_len; i++) {
|
||||
if (mrb->irep[i]->flags & MRB_IREP_NOFREE) continue;
|
||||
if ((mrb->irep[i]->flags & MRB_ISEQ_NOFREE) == 0) {
|
||||
mrb_free(mrb, mrb->irep[i]->iseq);
|
||||
}
|
||||
mrb_free(mrb, mrb->irep[i]->pool);
|
||||
mrb_free(mrb, mrb->irep[i]->syms);
|
||||
mrb_free(mrb, mrb->irep[i]);
|
||||
}
|
||||
mrb_free(mrb, mrb->irep);
|
||||
mrb_free(mrb, mrb);
|
||||
}
|
||||
|
||||
void
|
||||
mrb_add_irep(mrb_state *mrb, int idx)
|
||||
{
|
||||
if (!mrb->irep) {
|
||||
int max = 256;
|
||||
|
||||
if (idx > max) max = idx+1;
|
||||
mrb->irep = mrb_malloc(mrb, sizeof(mrb_irep*)*max);
|
||||
mrb->irep_capa = max;
|
||||
}
|
||||
else if (mrb->irep_capa < idx) {
|
||||
while (mrb->irep_capa < idx) {
|
||||
mrb->irep_capa *= 2;
|
||||
}
|
||||
mrb->irep = mrb_realloc(mrb, mrb->irep, sizeof(mrb_irep)*mrb->irep_capa);
|
||||
}
|
||||
}
|
||||
|
||||
mrb_value
|
||||
mrb_top_self(mrb_state *mrb)
|
||||
{
|
||||
// for now
|
||||
return mrb_nil_value();
|
||||
}
|
||||
+5234
File diff suppressed because it is too large
Load Diff
+824
@@ -0,0 +1,824 @@
|
||||
/**********************************************************************
|
||||
|
||||
struct.c -
|
||||
|
||||
$Author: marcandre $
|
||||
created at: Tue Mar 22 18:44:30 JST 1995
|
||||
|
||||
Copyright (C) 1993-2007 Yukihiro Matsumoto
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
#include "mruby.h"
|
||||
#include <string.h>
|
||||
#include "error.h"
|
||||
#include "mruby/struct.h"
|
||||
#include "mruby/array.h"
|
||||
#include <stdarg.h>
|
||||
//#include "defines.h"
|
||||
|
||||
#ifdef INCLUDE_REGEXP
|
||||
#include "encoding.h"
|
||||
#endif
|
||||
mrb_sym rb_frame_this_func(mrb_state *mrb);
|
||||
mrb_sym mrb_frame_callee(mrb_state *mrb);
|
||||
mrb_value mrb_exec_recursive_paired(mrb_state *mrb, mrb_value (*func) (mrb_state *, mrb_value, mrb_value, int),
|
||||
mrb_value obj, mrb_value paired_obj, void* arg);
|
||||
|
||||
#include "mruby/numeric.h"
|
||||
#include "mruby/hash.h"
|
||||
#include "mruby/string.h"
|
||||
#include "mruby/class.h"
|
||||
#include "variable.h"
|
||||
#include "mruby/range.h"
|
||||
#include "error.h"
|
||||
//#include "defines.h"
|
||||
#define mrb_long2int(n) ((int)(n))
|
||||
|
||||
|
||||
static mrb_value struct_alloc(mrb_state *mrb, mrb_value);
|
||||
|
||||
static struct RClass *
|
||||
struct_class(mrb_state *mrb)
|
||||
{
|
||||
return mrb_class_get(mrb, "Struct");
|
||||
}
|
||||
|
||||
static inline mrb_value
|
||||
struct_ivar_get(mrb_state *mrb, mrb_value c, mrb_sym id)
|
||||
{
|
||||
struct RClass* kclass;
|
||||
struct RClass* sclass = struct_class(mrb);
|
||||
|
||||
mrb_value ans;
|
||||
for (;;) {
|
||||
//if (mrb_ivar_defined(c, id))
|
||||
// return mrb_iv_get(mrb, c, id);
|
||||
ans = mrb_iv_get(mrb, c, id);
|
||||
if (!mrb_nil_p(ans)) return ans;
|
||||
kclass = RCLASS_SUPER(c);
|
||||
if (kclass == 0 || kclass == sclass)
|
||||
return mrb_nil_value();
|
||||
c = mrb_obj_value(kclass);
|
||||
}
|
||||
}
|
||||
|
||||
mrb_value
|
||||
mrb_struct_iv_get(mrb_state *mrb, mrb_value c, const char *name)
|
||||
{
|
||||
return struct_ivar_get(mrb, c, mrb_intern(mrb, name));
|
||||
}
|
||||
|
||||
mrb_value
|
||||
mrb_struct_s_members(mrb_state *mrb, mrb_value klass)
|
||||
{
|
||||
mrb_value members = struct_ivar_get(mrb, klass, mrb_intern(mrb, "__members__"));
|
||||
|
||||
if (mrb_nil_p(members)) {
|
||||
mrb_raise(mrb, E_TYPE_ERROR, "uninitialized struct");
|
||||
}
|
||||
if (mrb_type(members) != MRB_TT_ARRAY) {
|
||||
mrb_raise(mrb, E_TYPE_ERROR, "corrupted struct");
|
||||
}
|
||||
return members;
|
||||
}
|
||||
|
||||
mrb_value
|
||||
mrb_struct_members(mrb_state *mrb, mrb_value s)
|
||||
{
|
||||
mrb_value members = mrb_struct_s_members(mrb, mrb_obj_value(mrb_obj_class(mrb, s)));
|
||||
if (mrb_type(s) == MRB_TT_STRUCT) {
|
||||
if (RSTRUCT_LEN(s) != RARRAY_LEN(members)) {
|
||||
mrb_raise(mrb, E_TYPE_ERROR, "struct size differs (%ld required %ld given)",
|
||||
RARRAY_LEN(members), RSTRUCT_LEN(s));
|
||||
}
|
||||
}
|
||||
return members;
|
||||
}
|
||||
|
||||
static mrb_value
|
||||
mrb_struct_s_members_m(mrb_state *mrb, mrb_value klass)
|
||||
{
|
||||
mrb_value members, ary;
|
||||
mrb_value *p, *pend;
|
||||
|
||||
members = mrb_struct_s_members(mrb, klass);
|
||||
ary = mrb_ary_new_capa(mrb, RARRAY_LEN(members));//mrb_ary_new2(RARRAY_LEN(members));
|
||||
p = RARRAY_PTR(members); pend = p + RARRAY_LEN(members);
|
||||
while (p < pend) {
|
||||
mrb_ary_push(mrb, ary, *p);
|
||||
p++;
|
||||
}
|
||||
|
||||
return ary;
|
||||
}
|
||||
|
||||
/* 15.2.18.4.6 */
|
||||
/*
|
||||
* call-seq:
|
||||
* struct.members -> array
|
||||
*
|
||||
* Returns an array of strings representing the names of the instance
|
||||
* variables.
|
||||
*
|
||||
* Customer = Struct.new(:name, :address, :zip)
|
||||
* joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
|
||||
* joe.members #=> [:name, :address, :zip]
|
||||
*/
|
||||
|
||||
static mrb_value
|
||||
mrb_struct_members_m(mrb_state *mrb, mrb_value obj)
|
||||
{
|
||||
return mrb_struct_s_members_m(mrb, mrb_obj_value(mrb_obj_class(mrb, obj)));
|
||||
}
|
||||
|
||||
mrb_value
|
||||
mrb_struct_getmember(mrb_state *mrb, mrb_value obj, mrb_sym id)
|
||||
{
|
||||
mrb_value members, slot, *ptr, *ptr_members;
|
||||
long i, len;
|
||||
|
||||
ptr = RSTRUCT_PTR(obj);
|
||||
members = mrb_struct_members(mrb, obj);
|
||||
ptr_members = RARRAY_PTR(members);
|
||||
slot = mrb_str_new_cstr(mrb, mrb_sym2name(mrb, id));
|
||||
len = RARRAY_LEN(members);
|
||||
for (i=0; i<len; i++) {
|
||||
if (mrb_obj_equal(mrb, ptr_members[i], slot)) {
|
||||
return ptr[i];
|
||||
}
|
||||
}
|
||||
mrb_name_error(mrb, id, "%s is not struct member", mrb_sym2name(mrb, id));
|
||||
return mrb_nil_value(); /* not reached */
|
||||
}
|
||||
|
||||
static mrb_value
|
||||
mrb_struct_ref(mrb_state *mrb, mrb_value obj)
|
||||
{
|
||||
//return mrb_struct_getmember(mrb, obj, rb_frame_this_func(mrb));
|
||||
return mrb_nil_value();
|
||||
}
|
||||
|
||||
static mrb_value mrb_struct_ref0(mrb_state* mrb, mrb_value obj) {return RSTRUCT_PTR(obj)[0];}
|
||||
static mrb_value mrb_struct_ref1(mrb_state* mrb, mrb_value obj) {return RSTRUCT_PTR(obj)[1];}
|
||||
static mrb_value mrb_struct_ref2(mrb_state* mrb, mrb_value obj) {return RSTRUCT_PTR(obj)[2];}
|
||||
static mrb_value mrb_struct_ref3(mrb_state* mrb, mrb_value obj) {return RSTRUCT_PTR(obj)[3];}
|
||||
static mrb_value mrb_struct_ref4(mrb_state* mrb, mrb_value obj) {return RSTRUCT_PTR(obj)[4];}
|
||||
static mrb_value mrb_struct_ref5(mrb_state* mrb, mrb_value obj) {return RSTRUCT_PTR(obj)[5];}
|
||||
static mrb_value mrb_struct_ref6(mrb_state* mrb, mrb_value obj) {return RSTRUCT_PTR(obj)[6];}
|
||||
static mrb_value mrb_struct_ref7(mrb_state* mrb, mrb_value obj) {return RSTRUCT_PTR(obj)[7];}
|
||||
static mrb_value mrb_struct_ref8(mrb_state* mrb, mrb_value obj) {return RSTRUCT_PTR(obj)[8];}
|
||||
static mrb_value mrb_struct_ref9(mrb_state* mrb, mrb_value obj) {return RSTRUCT_PTR(obj)[9];}
|
||||
|
||||
#define numberof(array) (int)(sizeof(array) / sizeof((array)[0]))
|
||||
#define N_REF_FUNC numberof(ref_func)
|
||||
|
||||
static mrb_value (*const ref_func[])(mrb_state*, mrb_value) = {
|
||||
mrb_struct_ref0,
|
||||
mrb_struct_ref1,
|
||||
mrb_struct_ref2,
|
||||
mrb_struct_ref3,
|
||||
mrb_struct_ref4,
|
||||
mrb_struct_ref5,
|
||||
mrb_struct_ref6,
|
||||
mrb_struct_ref7,
|
||||
mrb_struct_ref8,
|
||||
mrb_struct_ref9,
|
||||
};
|
||||
|
||||
static void
|
||||
mrb_struct_modify(mrb_value s)
|
||||
{
|
||||
//if (OBJ_FROZEN(s)) mrb_error_frozen("Struct");
|
||||
}
|
||||
|
||||
mrb_sym
|
||||
mrb_id_attrset(mrb_sym id)
|
||||
{
|
||||
//id &= ~ID_SCOPE_MASK;
|
||||
//id |= ID_ATTRSET;
|
||||
return id;
|
||||
}
|
||||
|
||||
static mrb_value
|
||||
mrb_struct_set(mrb_state *mrb, mrb_value obj, mrb_value val)
|
||||
{
|
||||
mrb_value members, slot, *ptr, *ptr_members;
|
||||
long i, len;
|
||||
|
||||
members = mrb_struct_members(mrb, obj);
|
||||
ptr_members = RARRAY_PTR(members);
|
||||
len = RARRAY_LEN(members);
|
||||
mrb_struct_modify(obj);
|
||||
ptr = RSTRUCT_PTR(obj);
|
||||
for (i=0; i<len; i++) {
|
||||
slot = ptr_members[i];
|
||||
if (mrb_id_attrset(SYM2ID(slot)) == 0/*rb_frame_this_func(mrb)*/) {
|
||||
return ptr[i] = val;
|
||||
}
|
||||
}
|
||||
mrb_name_error(mrb, 0/*rb_frame_this_func(mrb)*/, "`%s' is not a struct member",
|
||||
mrb_sym2name(mrb, 0/*rb_frame_this_func(mrb)*/));
|
||||
return mrb_nil_value(); /* not reached */
|
||||
}
|
||||
|
||||
#define is_notop_id(id) (id)//((id)>tLAST_TOKEN)
|
||||
#define is_local_id(id) (is_notop_id(id))//&&((id)&ID_SCOPE_MASK)==ID_LOCAL)
|
||||
int
|
||||
mrb_is_local_id(mrb_sym id)
|
||||
{
|
||||
return is_local_id(id);
|
||||
}
|
||||
|
||||
#define is_const_id(id) (is_notop_id(id))//&&((id)&ID_SCOPE_MASK)==ID_CONST)
|
||||
int
|
||||
mrb_is_const_id(mrb_sym id)
|
||||
{
|
||||
return is_const_id(id);
|
||||
}
|
||||
|
||||
static mrb_value
|
||||
make_struct(mrb_state *mrb, mrb_value name, mrb_value members, struct RClass * klass)
|
||||
{
|
||||
mrb_value nstr, *ptr_members;
|
||||
mrb_sym id;
|
||||
long i, len;
|
||||
struct RClass *c;
|
||||
|
||||
//OBJ_FREEZE(members);
|
||||
if (mrb_nil_p(name)) {
|
||||
c = mrb_class_new(mrb, klass);
|
||||
//mrb_make_metaclass(nstr, RBASIC(klass)->c);
|
||||
//mrb_class_inherited(klass, nstr);
|
||||
}
|
||||
else {
|
||||
/* old style: should we warn? */
|
||||
name = mrb_str_to_str(mrb, name);
|
||||
id = mrb_to_id(mrb, name);
|
||||
if (!mrb_is_const_id(id)) {
|
||||
//mrb_name_error(id, "identifier %s needs to be constant", StringValuePtr(name));
|
||||
mrb_name_error(mrb, id, "identifier %s needs to be constant", mrb_string_value_ptr(mrb, name));
|
||||
}
|
||||
if (mrb_const_defined_at(mrb, klass, id)) {
|
||||
//mrb_warn("redefining constant Struct::%s", StringValuePtr(name));
|
||||
mrb_warn("redefining constant Struct::%s", mrb_string_value_ptr(mrb, name));
|
||||
//?rb_mod_remove_const(klass, mrb_sym2name(mrb, id));
|
||||
}
|
||||
c = mrb_define_class_under(mrb, klass, RSTRING_PTR(name), klass);
|
||||
}
|
||||
MRB_SET_INSTANCE_TT(c, MRB_TT_STRUCT);
|
||||
nstr = mrb_obj_value(c);
|
||||
mrb_iv_set(mrb, nstr, mrb_intern(mrb, "__members__"), members);
|
||||
|
||||
mrb_define_class_method(mrb, c, "new", mrb_class_new_instance_m, ARGS_ANY());
|
||||
mrb_define_class_method(mrb, c, "[]", mrb_class_new_instance_m, ARGS_ANY());
|
||||
mrb_define_class_method(mrb, c, "members", mrb_struct_s_members_m, ARGS_NONE());
|
||||
//RSTRUCT(nstr)->basic.c->super = c->c;
|
||||
ptr_members = RARRAY_PTR(members);
|
||||
len = RARRAY_LEN(members);
|
||||
for (i=0; i< len; i++) {
|
||||
mrb_sym id = SYM2ID(ptr_members[i]);
|
||||
if (mrb_is_local_id(id) || mrb_is_const_id(id)) {
|
||||
if (i < N_REF_FUNC) {
|
||||
mrb_define_method_id(mrb, c, id, (mrb_func_t)ref_func[i], 0);
|
||||
}
|
||||
else {
|
||||
mrb_define_method_id(mrb, c, id, mrb_struct_ref, 0);
|
||||
}
|
||||
mrb_define_method_id(mrb, c, mrb_id_attrset(id), (mrb_func_t)mrb_struct_set, 1);
|
||||
}
|
||||
}
|
||||
|
||||
return nstr;
|
||||
}
|
||||
|
||||
mrb_value
|
||||
mrb_struct_define(mrb_state *mrb, const char *name, ...)
|
||||
{
|
||||
va_list ar;
|
||||
mrb_value nm, ary;
|
||||
char *mem;
|
||||
|
||||
if (!name) nm = mrb_nil_value();
|
||||
else nm = mrb_str_new2(mrb, name);
|
||||
ary = mrb_ary_new(mrb);
|
||||
|
||||
va_start(ar, name);
|
||||
while ((mem = va_arg(ar, char*)) != 0) {
|
||||
mrb_sym slot = mrb_intern(mrb, mem);
|
||||
mrb_ary_push(mrb, ary, mrb_str_new_cstr(mrb, mrb_sym2name(mrb, slot)));
|
||||
}
|
||||
va_end(ar);
|
||||
|
||||
return make_struct(mrb, nm, ary, struct_class(mrb));
|
||||
}
|
||||
|
||||
/* 15.2.18.3.1 */
|
||||
/*
|
||||
* call-seq:
|
||||
* Struct.new( [aString] [, aSym]+> ) -> StructClass
|
||||
* StructClass.new(arg, ...) -> obj
|
||||
* StructClass[arg, ...] -> obj
|
||||
*
|
||||
* Creates a new class, named by <i>aString</i>, containing accessor
|
||||
* methods for the given symbols. If the name <i>aString</i> is
|
||||
* omitted, an anonymous structure class will be created. Otherwise,
|
||||
* the name of this struct will appear as a constant in class
|
||||
* <code>Struct</code>, so it must be unique for all
|
||||
* <code>Struct</code>s in the system and should start with a capital
|
||||
* letter. Assigning a structure class to a constant effectively gives
|
||||
* the class the name of the constant.
|
||||
*
|
||||
* <code>Struct::new</code> returns a new <code>Class</code> object,
|
||||
* which can then be used to create specific instances of the new
|
||||
* structure. The number of actual parameters must be
|
||||
* less than or equal to the number of attributes defined for this
|
||||
* class; unset parameters default to <code>nil</code>. Passing too many
|
||||
* parameters will raise an <code>ArgumentError</code>.
|
||||
*
|
||||
* The remaining methods listed in this section (class and instance)
|
||||
* are defined for this generated class.
|
||||
*
|
||||
* # Create a structure with a name in Struct
|
||||
* Struct.new("Customer", :name, :address) #=> Struct::Customer
|
||||
* Struct::Customer.new("Dave", "123 Main") #=> #<struct Struct::Customer name="Dave", address="123 Main">
|
||||
*
|
||||
* # Create a structure named by its constant
|
||||
* Customer = Struct.new(:name, :address) #=> Customer
|
||||
* Customer.new("Dave", "123 Main") #=> #<struct Customer name="Dave", address="123 Main">
|
||||
*/
|
||||
static mrb_value
|
||||
mrb_struct_s_def(mrb_state *mrb, mrb_value klass)
|
||||
{
|
||||
mrb_value name, rest;
|
||||
mrb_value *pargv;
|
||||
int argcnt;
|
||||
long i;
|
||||
mrb_value b, st;
|
||||
mrb_sym id;
|
||||
mrb_value *argv;
|
||||
int argc;
|
||||
|
||||
name = mrb_nil_value();
|
||||
rest = mrb_nil_value();
|
||||
mrb_get_args(mrb, "&*", &b, &argv, &argc);
|
||||
if (argc > 0) name = argv[0];
|
||||
if (argc > 1) rest = argv[1];
|
||||
//mrb_scan_args(argc, argv, "1*", &name, &rest);
|
||||
if (mrb_type(rest) == MRB_TT_ARRAY) {
|
||||
if (!mrb_nil_p(name) && SYMBOL_P(name)) {
|
||||
/* 1stArgument:symbol -> name=nil rest=argv[0]-[n] */
|
||||
mrb_ary_unshift(mrb, rest, name);
|
||||
name = mrb_nil_value();
|
||||
}
|
||||
for (i=0; i<RARRAY_LEN(rest); i++) {
|
||||
id = mrb_to_id(mrb, RARRAY_PTR(rest)[i]);
|
||||
RARRAY_PTR(rest)[i] = mrb_str_new_cstr(mrb, mrb_sym2name(mrb, id));
|
||||
}
|
||||
}
|
||||
else {
|
||||
pargv = &argv[1];
|
||||
argcnt = argc-1;
|
||||
if (!mrb_nil_p(name) && SYMBOL_P(name)) {
|
||||
/* 1stArgument:symbol -> name=nil rest=argv[0]-[n] */
|
||||
//mrb_ary_unshift(mrb, rest, name);
|
||||
name = mrb_nil_value();
|
||||
pargv = &argv[0];
|
||||
argcnt++;
|
||||
}
|
||||
rest = mrb_ary_new_from_values(mrb, pargv, argcnt);
|
||||
}
|
||||
st = make_struct(mrb, name, rest, struct_class(mrb));
|
||||
if (!mrb_nil_p(b)) {
|
||||
mrb_funcall(mrb, b, "call", 1, &st);
|
||||
}
|
||||
|
||||
return st;
|
||||
}
|
||||
|
||||
static long
|
||||
num_members(mrb_state *mrb, struct RClass *klass)
|
||||
{
|
||||
mrb_value members;
|
||||
members = struct_ivar_get(mrb, mrb_obj_value(klass), mrb_intern(mrb, "__members__"));
|
||||
if (mrb_type(members) != MRB_TT_ARRAY) {
|
||||
mrb_raise(mrb, E_TYPE_ERROR, "broken members");
|
||||
}
|
||||
return RARRAY_LEN(members);
|
||||
}
|
||||
|
||||
/* 15.2.18.4.8 */
|
||||
/*
|
||||
*/
|
||||
static mrb_value
|
||||
mrb_struct_initialize_withArg(mrb_state *mrb, int argc, mrb_value *argv, mrb_value self)
|
||||
{
|
||||
struct RClass *klass = mrb_obj_class(mrb, self);
|
||||
long n;
|
||||
struct RStruct *st;
|
||||
|
||||
mrb_struct_modify(self);
|
||||
n = num_members(mrb, klass);
|
||||
if (n < argc) {
|
||||
mrb_raise(mrb, E_ARGUMENT_ERROR, "struct size differs");
|
||||
}
|
||||
st = RSTRUCT(self);
|
||||
st->ptr = malloc(sizeof(mrb_value)*argc);
|
||||
st->len = n;
|
||||
memcpy(st->ptr, argv, sizeof(mrb_value)*argc);
|
||||
//if (n > argc) {
|
||||
// mrb_mem_clear(RSTRUCT_PTR(self)+argc, n-argc);
|
||||
//}
|
||||
return self;
|
||||
}
|
||||
|
||||
static mrb_value
|
||||
mrb_struct_initialize_m(mrb_state *mrb, /*int argc, mrb_value *argv,*/ mrb_value self)
|
||||
{
|
||||
mrb_value *argv;
|
||||
int argc;
|
||||
|
||||
mrb_get_args(mrb, "*", &argv, &argc);
|
||||
return mrb_struct_initialize_withArg(mrb, argc, argv, self);
|
||||
}
|
||||
|
||||
mrb_value
|
||||
mrb_struct_initialize(mrb_state *mrb, mrb_value self, mrb_value values)
|
||||
{
|
||||
return mrb_struct_initialize_withArg(mrb, RARRAY_LEN/*INT*/(values), RARRAY_PTR(values), self);
|
||||
}
|
||||
|
||||
mrb_value
|
||||
mrb_struct_alloc(mrb_state *mrb, mrb_value klass, mrb_value values)
|
||||
{
|
||||
return mrb_class_new_instance(mrb, RARRAY_LEN(values), RARRAY_PTR(values), mrb_class(mrb, klass));
|
||||
}
|
||||
|
||||
mrb_value
|
||||
mrb_struct_new(mrb_state *mrb, struct RClass *klass, ...)
|
||||
{
|
||||
mrb_value tmpargs[N_REF_FUNC], *mem = tmpargs;
|
||||
int size, i;
|
||||
va_list args;
|
||||
|
||||
size = mrb_long2int(num_members(mrb, klass));
|
||||
if (size > numberof(tmpargs)) {
|
||||
tmpargs[0] = mrb_ary_tmp_new(mrb, size);
|
||||
mem = RARRAY_PTR(tmpargs[0]);
|
||||
}
|
||||
va_start(args, klass);
|
||||
for (i=0; i<size; i++) {
|
||||
mem[i] = va_arg(args, mrb_value);
|
||||
}
|
||||
va_end(args);
|
||||
|
||||
return mrb_class_new_instance(mrb, size, mem, klass);
|
||||
}
|
||||
|
||||
static mrb_value
|
||||
inspect_struct(mrb_state *mrb, mrb_value s, mrb_value dummy, int recur)
|
||||
{
|
||||
const char *cn = mrb_class_name(mrb, mrb_obj_class(mrb, s));
|
||||
mrb_value members, str = mrb_str_new2(mrb, "#<struct ");
|
||||
mrb_value *ptr, *ptr_members;
|
||||
long i, len;
|
||||
|
||||
if (cn) {
|
||||
mrb_str_append(mrb, str, mrb_str_new_cstr(mrb, cn));
|
||||
}
|
||||
if (recur) {
|
||||
return mrb_str_cat2(mrb, str, ":...>");
|
||||
}
|
||||
|
||||
members = mrb_struct_members(mrb, s);
|
||||
ptr_members = RARRAY_PTR(members);
|
||||
ptr = RSTRUCT_PTR(s);
|
||||
len = RSTRUCT_LEN(s);
|
||||
for (i=0; i<len; i++) {
|
||||
mrb_value slot;
|
||||
mrb_sym id;
|
||||
|
||||
if (i > 0) {
|
||||
mrb_str_cat2(mrb, str, ", ");
|
||||
}
|
||||
else if (cn) {
|
||||
mrb_str_cat2(mrb, str, " ");
|
||||
}
|
||||
slot = ptr_members[i];
|
||||
id = SYM2ID(slot);
|
||||
if (mrb_is_local_id(id) || mrb_is_const_id(id)) {
|
||||
//mrb_str_append(str, mrb_id2str(id));
|
||||
mrb_str_append(mrb, str, mrb_str_new_cstr(mrb, mrb_sym2name(mrb, id)));
|
||||
}
|
||||
else {
|
||||
mrb_str_append(mrb, str, mrb_inspect(mrb, slot));
|
||||
}
|
||||
mrb_str_cat2(mrb, str, "=");
|
||||
mrb_str_append(mrb, str, mrb_inspect(mrb, ptr[i]));
|
||||
}
|
||||
mrb_str_cat2(mrb, str, ">");
|
||||
//OBJ_INFECT(str, s);
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* struct.to_s -> string
|
||||
* struct.inspect -> string
|
||||
*
|
||||
* Describe the contents of this struct in a string.
|
||||
*/
|
||||
static mrb_value
|
||||
mrb_struct_inspect(mrb_state *mrb, mrb_value s)
|
||||
{
|
||||
return inspect_struct(mrb, s, s, 0);
|
||||
}
|
||||
|
||||
/* 15.2.18.4.9 */
|
||||
/* :nodoc: */
|
||||
mrb_value
|
||||
mrb_struct_init_copy(mrb_state *mrb, mrb_value copy)
|
||||
{
|
||||
mrb_value s;
|
||||
mrb_get_args(mrb, "o", &s);
|
||||
|
||||
if (mrb_obj_equal(mrb, copy, s)) return copy;
|
||||
//mrb_check_frozen(copy);
|
||||
if (!mrb_obj_is_instance_of(mrb, s, mrb_obj_class(mrb, copy))) {
|
||||
mrb_raise(mrb, E_TYPE_ERROR, "wrong argument class");
|
||||
}
|
||||
if (RSTRUCT_LEN(copy) != RSTRUCT_LEN(s)) {
|
||||
mrb_raise(mrb, E_TYPE_ERROR, "struct size mismatch");
|
||||
}
|
||||
memcpy(RSTRUCT_PTR(copy), RSTRUCT_PTR(s), sizeof(mrb_value)*RSTRUCT_LEN(copy));
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
static mrb_value
|
||||
mrb_struct_aref_id(mrb_state *mrb, mrb_value s, mrb_sym id)
|
||||
{
|
||||
mrb_value *ptr, members, *ptr_members;
|
||||
long i, len;
|
||||
|
||||
ptr = RSTRUCT_PTR(s);
|
||||
members = mrb_struct_members(mrb, s);
|
||||
ptr_members = RARRAY_PTR(members);
|
||||
len = RARRAY_LEN(members);
|
||||
for (i=0; i<len; i++) {
|
||||
if (SYM2ID(ptr_members[i]) == id) {
|
||||
return ptr[i];
|
||||
}
|
||||
}
|
||||
mrb_name_error(mrb, id, "no member '%s' in struct", mrb_sym2name(mrb, id));
|
||||
return mrb_nil_value(); /* not reached */
|
||||
}
|
||||
|
||||
/* 15.2.18.4.2 */
|
||||
/*
|
||||
* call-seq:
|
||||
* struct[symbol] -> anObject
|
||||
* struct[fixnum] -> anObject
|
||||
*
|
||||
* Attribute Reference---Returns the value of the instance variable
|
||||
* named by <i>symbol</i>, or indexed (0..length-1) by
|
||||
* <i>fixnum</i>. Will raise <code>NameError</code> if the named
|
||||
* variable does not exist, or <code>IndexError</code> if the index is
|
||||
* out of range.
|
||||
*
|
||||
* Customer = Struct.new(:name, :address, :zip)
|
||||
* joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
|
||||
*
|
||||
* joe["name"] #=> "Joe Smith"
|
||||
* joe[:name] #=> "Joe Smith"
|
||||
* joe[0] #=> "Joe Smith"
|
||||
*/
|
||||
mrb_value
|
||||
mrb_struct_aref_n(mrb_state *mrb, mrb_value s, mrb_value idx)
|
||||
{
|
||||
long i;
|
||||
|
||||
if (mrb_type(idx) == MRB_TT_STRING || mrb_type(idx) == MRB_TT_SYMBOL) {
|
||||
return mrb_struct_aref_id(mrb, s, mrb_to_id(mrb, idx));
|
||||
}
|
||||
|
||||
i = mrb_fixnum(idx);
|
||||
if (i < 0) i = RSTRUCT_LEN(s) + i;
|
||||
if (i < 0)
|
||||
mrb_raise(mrb, E_INDEX_ERROR, "offset %ld too small for struct(size:%ld)",
|
||||
i, RSTRUCT_LEN(s));
|
||||
if (RSTRUCT_LEN(s) <= i)
|
||||
mrb_raise(mrb, E_INDEX_ERROR, "offset %ld too large for struct(size:%ld)",
|
||||
i, RSTRUCT_LEN(s));
|
||||
return RSTRUCT_PTR(s)[i];
|
||||
}
|
||||
|
||||
mrb_value
|
||||
mrb_struct_aref(mrb_state *mrb, mrb_value s)
|
||||
{
|
||||
mrb_value idx;
|
||||
|
||||
mrb_get_args(mrb, "o", &idx);
|
||||
return mrb_struct_aref_n(mrb, s, idx);
|
||||
}
|
||||
|
||||
static mrb_value
|
||||
mrb_struct_aset_id(mrb_state *mrb, mrb_value s, mrb_sym id, mrb_value val)
|
||||
{
|
||||
mrb_value members, *ptr, *ptr_members;
|
||||
long i, len;
|
||||
|
||||
members = mrb_struct_members(mrb, s);
|
||||
len = RARRAY_LEN(members);
|
||||
mrb_struct_modify(s);
|
||||
if (RSTRUCT_LEN(s) != len) {
|
||||
mrb_raise(mrb, E_TYPE_ERROR, "struct size differs (%ld required %ld given)",
|
||||
len, RSTRUCT_LEN(s));
|
||||
}
|
||||
ptr = RSTRUCT_PTR(s);
|
||||
ptr_members = RARRAY_PTR(members);
|
||||
for (i=0; i<len; i++) {
|
||||
if (SYM2ID(ptr_members[i]) == id) {
|
||||
ptr[i] = val;
|
||||
return val;
|
||||
}
|
||||
}
|
||||
mrb_name_error(mrb, id, "no member '%s' in struct", mrb_sym2name(mrb, id));
|
||||
return val; /* not reach */
|
||||
}
|
||||
|
||||
/* 15.2.18.4.3 */
|
||||
/*
|
||||
* call-seq:
|
||||
* struct[symbol] = obj -> obj
|
||||
* struct[fixnum] = obj -> obj
|
||||
*
|
||||
* Attribute Assignment---Assigns to the instance variable named by
|
||||
* <i>symbol</i> or <i>fixnum</i> the value <i>obj</i> and
|
||||
* returns it. Will raise a <code>NameError</code> if the named
|
||||
* variable does not exist, or an <code>IndexError</code> if the index
|
||||
* is out of range.
|
||||
*
|
||||
* Customer = Struct.new(:name, :address, :zip)
|
||||
* joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
|
||||
*
|
||||
* joe["name"] = "Luke"
|
||||
* joe[:zip] = "90210"
|
||||
*
|
||||
* joe.name #=> "Luke"
|
||||
* joe.zip #=> "90210"
|
||||
*/
|
||||
|
||||
mrb_value
|
||||
mrb_struct_aset(mrb_state *mrb, mrb_value s)
|
||||
{
|
||||
long i;
|
||||
mrb_value idx;
|
||||
mrb_value val;
|
||||
mrb_get_args(mrb, "oo", &idx, &val);
|
||||
|
||||
if (mrb_type(idx) == MRB_TT_STRING || mrb_type(idx) == MRB_TT_SYMBOL) {
|
||||
return mrb_struct_aset_id(mrb, s, mrb_to_id(mrb, idx), val);
|
||||
}
|
||||
|
||||
i = mrb_fixnum(idx);
|
||||
if (i < 0) i = RSTRUCT_LEN(s) + i;
|
||||
if (i < 0) {
|
||||
mrb_raise(mrb, E_INDEX_ERROR, "offset %ld too small for struct(size:%ld)",
|
||||
i, RSTRUCT_LEN(s));
|
||||
}
|
||||
if (RSTRUCT_LEN(s) <= i) {
|
||||
mrb_raise(mrb, E_INDEX_ERROR, "offset %ld too large for struct(size:%ld)",
|
||||
i, RSTRUCT_LEN(s));
|
||||
}
|
||||
mrb_struct_modify(s);
|
||||
return RSTRUCT_PTR(s)[i] = val;
|
||||
}
|
||||
|
||||
static mrb_value
|
||||
recursive_equal(mrb_state *mrb, mrb_value s, mrb_value s2, int recur)
|
||||
{
|
||||
mrb_value *ptr, *ptr2;
|
||||
long i, len;
|
||||
|
||||
if (recur) return mrb_true_value(); /* Subtle! */
|
||||
ptr = RSTRUCT_PTR(s);
|
||||
ptr2 = RSTRUCT_PTR(s2);
|
||||
len = RSTRUCT_LEN(s);
|
||||
for (i=0; i<len; i++) {
|
||||
if (!mrb_equal(mrb, ptr[i], ptr2[i])) return mrb_false_value();
|
||||
}
|
||||
return mrb_true_value();
|
||||
}
|
||||
|
||||
/* 15.2.18.4.1 */
|
||||
/*
|
||||
* call-seq:
|
||||
* struct == other_struct -> true or false
|
||||
*
|
||||
* Equality---Returns <code>true</code> if <i>other_struct</i> is
|
||||
* equal to this one: they must be of the same class as generated by
|
||||
* <code>Struct::new</code>, and the values of all instance variables
|
||||
* must be equal (according to <code>Object#==</code>).
|
||||
*
|
||||
* Customer = Struct.new(:name, :address, :zip)
|
||||
* joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
|
||||
* joejr = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
|
||||
* jane = Customer.new("Jane Doe", "456 Elm, Anytown NC", 12345)
|
||||
* joe == joejr #=> true
|
||||
* joe == jane #=> false
|
||||
*/
|
||||
|
||||
static mrb_value
|
||||
mrb_struct_equal(mrb_state *mrb, mrb_value s)
|
||||
{
|
||||
mrb_value s2;
|
||||
|
||||
mrb_get_args(mrb, "o", &s2);
|
||||
if (mrb_obj_equal(mrb, s, s2)) return mrb_true_value();
|
||||
if (mrb_type(s2) != MRB_TT_STRUCT) return mrb_false_value();
|
||||
if (mrb_obj_class(mrb, s) != mrb_obj_class(mrb, s2)) return mrb_false_value();
|
||||
if (RSTRUCT_LEN(s) != RSTRUCT_LEN(s2)) {
|
||||
mrb_bug("inconsistent struct"); /* should never happen */
|
||||
}
|
||||
|
||||
return mrb_exec_recursive_paired(mrb, recursive_equal, s, s2, (void*)0);
|
||||
}
|
||||
|
||||
static mrb_value
|
||||
recursive_eql(mrb_state *mrb, mrb_value s, mrb_value s2, int recur)
|
||||
{
|
||||
mrb_value *ptr, *ptr2;
|
||||
long i, len;
|
||||
|
||||
if (recur) return mrb_true_value(); /* Subtle! */
|
||||
ptr = RSTRUCT_PTR(s);
|
||||
ptr2 = RSTRUCT_PTR(s2);
|
||||
len = RSTRUCT_LEN(s);
|
||||
for (i=0; i<len; i++) {
|
||||
if (!mrb_eql(mrb, ptr[i], ptr2[i])) return mrb_false_value();
|
||||
}
|
||||
return mrb_true_value();
|
||||
}
|
||||
|
||||
/* 15.2.18.4.12(x) */
|
||||
/*
|
||||
* code-seq:
|
||||
* struct.eql?(other) -> true or false
|
||||
*
|
||||
* Two structures are equal if they are the same object, or if all their
|
||||
* fields are equal (using <code>eql?</code>).
|
||||
*/
|
||||
static mrb_value
|
||||
mrb_struct_eql(mrb_state *mrb, mrb_value s)
|
||||
{
|
||||
mrb_value s2;
|
||||
|
||||
mrb_get_args(mrb, "o", &s2);
|
||||
if (mrb_obj_equal(mrb, s, s2)) return mrb_true_value();
|
||||
if (mrb_type(s2) != MRB_TT_STRUCT) return mrb_false_value();
|
||||
if (mrb_obj_class(mrb, s) != mrb_obj_class(mrb, s2)) return mrb_false_value();
|
||||
if (RSTRUCT_LEN(s) != RSTRUCT_LEN(s2)) {
|
||||
mrb_bug("inconsistent struct"); /* should never happen */
|
||||
}
|
||||
|
||||
return mrb_exec_recursive_paired(mrb, recursive_eql, s, s2, (void*)0);
|
||||
}
|
||||
|
||||
/*
|
||||
* A <code>Struct</code> is a convenient way to bundle a number of
|
||||
* attributes together, using accessor methods, without having to write
|
||||
* an explicit class.
|
||||
*
|
||||
* The <code>Struct</code> class is a generator of specific classes,
|
||||
* each one of which is defined to hold a set of variables and their
|
||||
* accessors. In these examples, we'll call the generated class
|
||||
* ``<i>Customer</i>Class,'' and we'll show an example instance of that
|
||||
* class as ``<i>Customer</i>Inst.''
|
||||
*
|
||||
* In the descriptions that follow, the parameter <i>symbol</i> refers
|
||||
* to a symbol, which is either a quoted string or a
|
||||
* <code>Symbol</code> (such as <code>:name</code>).
|
||||
*/
|
||||
void
|
||||
mrb_init_struct(mrb_state *mrb)
|
||||
{
|
||||
struct RClass *st;
|
||||
st = mrb_define_class(mrb, "Struct", mrb->object_class);
|
||||
//mrb_include_module(mrb_cStruct, rb_mEnumerable);
|
||||
|
||||
//mrb_undef_alloc_func(mrb_cStruct);
|
||||
mrb_define_class_method(mrb, st, "new", mrb_struct_s_def, ARGS_ANY()); /* 15.2.18.3.1 */
|
||||
|
||||
mrb_define_method(mrb, st, "==", mrb_struct_equal, ARGS_REQ(1)); /* 15.2.18.4.1 */
|
||||
mrb_define_method(mrb, st, "[]", mrb_struct_aref, ARGS_REQ(1)); /* 15.2.18.4.2 */
|
||||
mrb_define_method(mrb, st, "[]=", mrb_struct_aset, ARGS_REQ(2)); /* 15.2.18.4.3 */
|
||||
mrb_define_method(mrb, st, "members", mrb_struct_members_m, ARGS_NONE()); /* 15.2.18.4.6 */
|
||||
mrb_define_method(mrb, st, "initialize", mrb_struct_initialize_m,ARGS_ANY()); /* 15.2.18.4.8 */
|
||||
mrb_define_method(mrb, st, "initialize_copy", mrb_struct_init_copy, ARGS_REQ(1)); /* 15.2.18.4.9 */
|
||||
mrb_define_method(mrb, st, "inspect", mrb_struct_inspect, ARGS_NONE()); /* 15.2.18.4.10(x) */
|
||||
mrb_define_alias(mrb, st, "to_s", "inspect"); /* 15.2.18.4.11(x) */
|
||||
mrb_define_method(mrb, st, "eql?", mrb_struct_eql, ARGS_REQ(1)); /* 15.2.18.4.12(x) */
|
||||
|
||||
}
|
||||
+255
@@ -0,0 +1,255 @@
|
||||
#include "mruby.h"
|
||||
#include "ritehash.h"
|
||||
#include <string.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include "mruby/string.h"
|
||||
#include <ctype.h>
|
||||
#include "mruby/class.h"
|
||||
#include "variable.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef INCLUDE_REGEXP
|
||||
#include "re.h"
|
||||
#include "regex.h"
|
||||
#include "st.h"
|
||||
#endif
|
||||
|
||||
/* ------------------------------------------------------ */
|
||||
KHASH_MAP_INIT_INT(s2n, const char*);
|
||||
KHASH_MAP_INIT_STR(n2s, mrb_sym);
|
||||
/* ------------------------------------------------------ */
|
||||
mrb_sym
|
||||
mrb_intern(mrb_state *mrb, const char *name)
|
||||
{
|
||||
khash_t(n2s) *h = mrb->name2sym;
|
||||
khash_t(s2n) *rh = mrb->sym2name;
|
||||
khiter_t k;
|
||||
int r;
|
||||
size_t len;
|
||||
char *p;
|
||||
mrb_sym sym;
|
||||
|
||||
k = kh_get(n2s, h, name);
|
||||
if (k != kh_end(h))
|
||||
return kh_value(h, k);
|
||||
|
||||
sym = ++mrb->symidx;
|
||||
len = strlen(name);
|
||||
p = mrb_malloc(mrb, len+1);
|
||||
memcpy(p, name, len);
|
||||
p[len] = 0;
|
||||
k = kh_put(n2s, h, p, &r);
|
||||
kh_value(h, k) = sym;
|
||||
|
||||
k = kh_put(s2n, rh, sym, &r);
|
||||
kh_value(rh, k) = p;
|
||||
|
||||
return sym;
|
||||
}
|
||||
|
||||
const char*
|
||||
mrb_sym2name(mrb_state *mrb, mrb_sym sym)
|
||||
{
|
||||
khash_t(s2n) *h = mrb->sym2name;
|
||||
khiter_t k;
|
||||
|
||||
k = kh_get(s2n, h, sym);
|
||||
if (k == kh_end(h)) {
|
||||
return NULL; /* missing */
|
||||
}
|
||||
return kh_value(h, k);
|
||||
}
|
||||
|
||||
void
|
||||
mrb_free_symtbls(mrb_state *mrb)
|
||||
{
|
||||
khash_t(s2n) *h = mrb->sym2name;
|
||||
khiter_t k;
|
||||
|
||||
for (k = kh_begin(h); k != kh_end(h); ++k)
|
||||
if (kh_exist(h, k)) mrb_free(mrb, (char*)kh_value(h, k));
|
||||
kh_destroy(s2n,mrb->sym2name);
|
||||
kh_destroy(n2s,mrb->name2sym);
|
||||
}
|
||||
|
||||
void
|
||||
mrb_init_symtbl(mrb_state *mrb)
|
||||
{
|
||||
mrb->name2sym = kh_init(n2s, mrb);
|
||||
mrb->sym2name = kh_init(s2n, mrb);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* Document-class: Symbol
|
||||
*
|
||||
* <code>Symbol</code> objects represent names and some strings
|
||||
* inside the Ruby
|
||||
* interpreter. They are generated using the <code>:name</code> and
|
||||
* <code>:"string"</code> literals
|
||||
* syntax, and by the various <code>to_sym</code> methods. The same
|
||||
* <code>Symbol</code> object will be created for a given name or string
|
||||
* for the duration of a program's execution, regardless of the context
|
||||
* or meaning of that name. Thus if <code>Fred</code> is a constant in
|
||||
* one context, a method in another, and a class in a third, the
|
||||
* <code>Symbol</code> <code>:Fred</code> will be the same object in
|
||||
* all three contexts.
|
||||
*
|
||||
* module One
|
||||
* class Fred
|
||||
* end
|
||||
* $f1 = :Fred
|
||||
* end
|
||||
* module Two
|
||||
* Fred = 1
|
||||
* $f2 = :Fred
|
||||
* end
|
||||
* def Fred()
|
||||
* end
|
||||
* $f3 = :Fred
|
||||
* $f1.object_id #=> 2514190
|
||||
* $f2.object_id #=> 2514190
|
||||
* $f3.object_id #=> 2514190
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/* 15.2.11.3.1 */
|
||||
/*
|
||||
* call-seq:
|
||||
* sym == obj -> true or false
|
||||
*
|
||||
* Equality---If <i>sym</i> and <i>obj</i> are exactly the same
|
||||
* symbol, returns <code>true</code>.
|
||||
*/
|
||||
|
||||
static mrb_value
|
||||
sym_equal(mrb_state *mrb, mrb_value sym1)
|
||||
{
|
||||
mrb_value sym2;
|
||||
|
||||
mrb_get_args(mrb, "o", &sym2);
|
||||
if (mrb_obj_equal(mrb, sym1, sym2)) return mrb_true_value();
|
||||
return mrb_false_value();
|
||||
}
|
||||
|
||||
/* 15.2.11.3.2 */
|
||||
/* 15.2.11.3.3 */
|
||||
/*
|
||||
* call-seq:
|
||||
* sym.id2name -> string
|
||||
* sym.to_s -> string
|
||||
*
|
||||
* Returns the name or string corresponding to <i>sym</i>.
|
||||
*
|
||||
* :fred.id2name #=> "fred"
|
||||
*/
|
||||
mrb_value
|
||||
mrb_sym_to_s(mrb_state *mrb, mrb_value sym)
|
||||
{
|
||||
mrb_sym id = SYM2ID(sym);
|
||||
|
||||
#ifdef INCLUDE_REGEXP
|
||||
//return str_new3(mrb_cString, mrb_id2str(id));
|
||||
return str_new3(mrb, mrb_obj_class(mrb, sym), mrb_str_new_cstr(mrb, mrb_sym2name(mrb, id)));
|
||||
#else
|
||||
return mrb_str_new_cstr(mrb, mrb_sym2name(mrb, id)); //mrb_str_new2(mrb_id2name(SYM2ID(sym)));
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
/* 15.2.11.3.4 */
|
||||
/*
|
||||
* call-seq:
|
||||
* sym.to_sym -> sym
|
||||
* sym.intern -> sym
|
||||
*
|
||||
* In general, <code>to_sym</code> returns the <code>Symbol</code> corresponding
|
||||
* to an object. As <i>sym</i> is already a symbol, <code>self</code> is returned
|
||||
* in this case.
|
||||
*/
|
||||
|
||||
static mrb_value
|
||||
sym_to_sym(mrb_state *mrb, mrb_value sym)
|
||||
{
|
||||
return sym;
|
||||
}
|
||||
|
||||
/* 15.2.11.3.5(x) */
|
||||
/*
|
||||
* call-seq:
|
||||
* sym.inspect -> string
|
||||
*
|
||||
* Returns the representation of <i>sym</i> as a symbol literal.
|
||||
*
|
||||
* :fred.inspect #=> ":fred"
|
||||
*/
|
||||
|
||||
static mrb_value
|
||||
sym_inspect(mrb_state *mrb, mrb_value sym)
|
||||
{
|
||||
#ifdef INCLUDE_ENCODING
|
||||
#define STR_ENC_GET(mrb, str) mrb_enc_from_index(mrb, ENCODING_GET(mrb, str))
|
||||
mrb_value str;
|
||||
mrb_sym id = SYM2ID(sym);
|
||||
mrb_encoding *enc;
|
||||
const char *ptr;
|
||||
long len;
|
||||
char *dest;
|
||||
mrb_encoding *resenc = mrb_default_internal_encoding(mrb);
|
||||
|
||||
if (resenc == NULL) resenc = mrb_default_external_encoding(mrb);
|
||||
sym = mrb_str_new_cstr(mrb, mrb_sym2name(mrb, id));//mrb_id2str(id);
|
||||
enc = STR_ENC_GET(mrb, sym);
|
||||
ptr = RSTRING_PTR(sym);
|
||||
len = RSTRING_LEN(sym);
|
||||
if ((resenc != enc && !mrb_str_is_ascii_only_p(mrb, sym)) || len != (long)strlen(ptr) ||
|
||||
!mrb_enc_symname_p(ptr, enc) || !sym_printable(mrb, ptr, ptr + len, enc)) {
|
||||
str = mrb_str_inspect(mrb, sym);
|
||||
len = RSTRING_LEN(str);
|
||||
mrb_str_resize(mrb, str, len + 1);
|
||||
dest = RSTRING_PTR(str);
|
||||
memmove(dest + 1, dest, len);
|
||||
dest[0] = ':';
|
||||
}
|
||||
else {
|
||||
char *dest;
|
||||
str = mrb_enc_str_new(mrb, 0, len + 1, enc);
|
||||
dest = RSTRING_PTR(str);
|
||||
dest[0] = ':';
|
||||
memcpy(dest + 1, ptr, len);
|
||||
}
|
||||
return str;
|
||||
#else
|
||||
mrb_value str;
|
||||
const char *name;
|
||||
mrb_sym id = SYM2ID(sym);
|
||||
|
||||
name = mrb_sym2name(mrb, id); //mrb_id2name(id);
|
||||
str = mrb_str_new(mrb, 0, strlen(name)+1);
|
||||
RSTRING(str)->buf[0] = ':';
|
||||
strcpy(RSTRING(str)->buf+1, name);
|
||||
if (!mrb_symname_p(name)) {
|
||||
str = mrb_str_dump(mrb, str);
|
||||
strncpy(RSTRING(str)->buf, ":\"", 2);
|
||||
}
|
||||
return str;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
mrb_init_symbols(mrb_state *mrb)
|
||||
{
|
||||
struct RClass *sym;
|
||||
|
||||
sym = mrb->symbol_class = mrb_define_class(mrb, "Symbol", mrb->object_class);
|
||||
|
||||
mrb_define_method(mrb, sym, "===", sym_equal, ARGS_REQ(1)); /* 15.2.11.3.1 */
|
||||
mrb_define_method(mrb, sym, "id2name", mrb_sym_to_s, ARGS_NONE()); /* 15.2.11.3.2 */
|
||||
mrb_define_method(mrb, sym, "to_s", mrb_sym_to_s, ARGS_NONE()); /* 15.2.11.3.3 */
|
||||
mrb_define_method(mrb, sym, "to_sym", sym_to_sym, ARGS_NONE()); /* 15.2.11.3.4 */
|
||||
|
||||
mrb_define_method(mrb, sym, "inspect", sym_inspect, ARGS_NONE()); /* 15.2.11.3.5(x) */
|
||||
}
|
||||
+4366
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,109 @@
|
||||
/**********************************************************************
|
||||
|
||||
transcode_data.h -
|
||||
|
||||
$Author: duerst $
|
||||
created at: Mon 10 Dec 2007 14:01:47 JST 2007
|
||||
|
||||
Copyright (C) 2007 Martin Duerst
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
//#include "ruby/ruby.h"
|
||||
|
||||
#ifndef RUBY_TRANSCODE_DATA_H
|
||||
#define RUBY_TRANSCODE_DATA_H 1
|
||||
|
||||
#define WORDINDEX_SHIFT_BITS 2
|
||||
#define WORDINDEX2INFO(widx) ((widx) << WORDINDEX_SHIFT_BITS)
|
||||
#define INFO2WORDINDEX(info) ((info) >> WORDINDEX_SHIFT_BITS)
|
||||
#define BYTE_LOOKUP_BASE(bl) ((bl)[0])
|
||||
#define BYTE_LOOKUP_INFO(bl) ((bl)[1])
|
||||
|
||||
#define PType (unsigned int)
|
||||
|
||||
#define NOMAP (PType 0x01) /* direct map */
|
||||
#define ONEbt (0x02) /* one byte payload */
|
||||
#define TWObt (0x03) /* two bytes payload */
|
||||
#define THREEbt (0x05) /* three bytes payload */
|
||||
#define FOURbt (0x06) /* four bytes payload, UTF-8 only, macros start at getBT0 */
|
||||
#define INVALID (PType 0x07) /* invalid byte sequence */
|
||||
#define UNDEF (PType 0x09) /* legal but undefined */
|
||||
#define ZERObt (PType 0x0A) /* zero bytes of payload, i.e. remove */
|
||||
#define FUNii (PType 0x0B) /* function from info to info */
|
||||
#define FUNsi (PType 0x0D) /* function from start to info */
|
||||
#define FUNio (PType 0x0E) /* function from info to output */
|
||||
#define FUNso (PType 0x0F) /* function from start to output */
|
||||
#define STR1 (PType 0x11) /* string 4 <= len <= 259 bytes: 1byte length + content */
|
||||
#define GB4bt (PType 0x12) /* GB18030 four bytes payload */
|
||||
#define FUNsio (PType 0x13) /* function from start and info to output */
|
||||
|
||||
#define STR1_LENGTH(byte_addr) (unsigned int)(*(byte_addr) + 4)
|
||||
#define STR1_BYTEINDEX(w) ((w) >> 6)
|
||||
#define makeSTR1(bi) (((bi) << 6) | STR1)
|
||||
#define makeSTR1LEN(len) ((len)-4)
|
||||
|
||||
#define o1(b1) (PType((((unsigned char)(b1))<<8)|ONEbt))
|
||||
#define o2(b1,b2) (PType((((unsigned char)(b1))<<8)|(((unsigned char)(b2))<<16)|TWObt))
|
||||
#define o3(b1,b2,b3) (PType(((((unsigned char)(b1))<<8)|(((unsigned char)(b2))<<16)|(((unsigned int)(unsigned char)(b3))<<24)|THREEbt)&0xffffffffU))
|
||||
#define o4(b0,b1,b2,b3) (PType(((((unsigned char)(b1))<<8)|(((unsigned char)(b2))<<16)|(((unsigned char)(b3))<<24)|((((unsigned char)(b0))&0x07)<<5)|FOURbt)&0xffffffffU))
|
||||
#define g4(b0,b1,b2,b3) (PType(((((unsigned char)(b0))<<8)|(((unsigned char)(b2))<<16)|((((unsigned char)(b1))&0x0f)<<24)|((((unsigned int)(unsigned char)(b3))&0x0f)<<28)|GB4bt)&0xffffffffU))
|
||||
#define funsio(diff) (PType((((unsigned int)(diff))<<8)|FUNsio))
|
||||
|
||||
#define getBT1(a) ((unsigned char)((a)>> 8))
|
||||
#define getBT2(a) ((unsigned char)((a)>>16))
|
||||
#define getBT3(a) ((unsigned char)((a)>>24))
|
||||
#define getBT0(a) (((unsigned char)((a)>> 5)&0x07)|0xF0) /* for UTF-8 only!!! */
|
||||
|
||||
#define getGB4bt0(a) ((unsigned char)((a)>> 8))
|
||||
#define getGB4bt1(a) ((((unsigned char)((a)>>24))&0x0F)|0x30)
|
||||
#define getGB4bt2(a) ((unsigned char)((a)>>16))
|
||||
#define getGB4bt3(a) ((((unsigned char)((a)>>28))&0x0F)|0x30)
|
||||
|
||||
#define o2FUNii(b1,b2) (PType((((unsigned char)(b1))<<8)|(((unsigned char)(b2))<<16)|FUNii))
|
||||
|
||||
/* do we need these??? maybe not, can be done with simple tables */
|
||||
#define ONETRAIL /* legal but undefined if one more trailing UTF-8 */
|
||||
#define TWOTRAIL /* legal but undefined if two more trailing UTF-8 */
|
||||
#define THREETRAIL /* legal but undefined if three more trailing UTF-8 */
|
||||
|
||||
typedef enum {
|
||||
asciicompat_converter, /* ASCII-compatible -> ASCII-compatible */
|
||||
asciicompat_decoder, /* ASCII-incompatible -> ASCII-compatible */
|
||||
asciicompat_encoder /* ASCII-compatible -> ASCII-incompatible */
|
||||
/* ASCII-incompatible -> ASCII-incompatible is intentionally omitted. */
|
||||
} mrb_transcoder_asciicompat_type_t;
|
||||
|
||||
typedef struct mrb_transcoder mrb_transcoder;
|
||||
|
||||
/* static structure, one per supported encoding pair */
|
||||
struct mrb_transcoder {
|
||||
const char *src_encoding;
|
||||
const char *dst_encoding;
|
||||
unsigned int conv_tree_start;
|
||||
const unsigned char *byte_array;
|
||||
unsigned int byte_array_length;
|
||||
const unsigned int *word_array;
|
||||
unsigned int word_array_length;
|
||||
int word_size;
|
||||
int input_unit_length;
|
||||
int max_input;
|
||||
int max_output;
|
||||
mrb_transcoder_asciicompat_type_t asciicompat_type;
|
||||
size_t state_size;
|
||||
int (*state_init_func)(void*); /* ret==0:success ret!=0:failure(errno) */
|
||||
int (*state_fini_func)(void*); /* ret==0:success ret!=0:failure(errno) */
|
||||
mrb_value (*func_ii)(void*, mrb_value); /* info -> info */
|
||||
mrb_value (*func_si)(void*, const unsigned char*, size_t); /* start -> info */
|
||||
ssize_t (*func_io)(void*, mrb_value, const unsigned char*, size_t); /* info -> output */
|
||||
ssize_t (*func_so)(void*, const unsigned char*, size_t, unsigned char*, size_t); /* start -> output */
|
||||
ssize_t (*finish_func)(void*, unsigned char*, size_t); /* -> output */
|
||||
ssize_t (*resetsize_func)(void*); /* -> len */
|
||||
ssize_t (*resetstate_func)(void*, unsigned char*, size_t); /* -> output */
|
||||
ssize_t (*func_sio)(void*, const unsigned char*, size_t, mrb_value, unsigned char*, size_t); /* start -> output */
|
||||
};
|
||||
|
||||
void mrb_declare_transcoder(mrb_state *mrb, const char *enc1, const char *enc2, const char *lib);
|
||||
void mrb_register_transcoder(mrb_state *mrb, const mrb_transcoder *);
|
||||
|
||||
#endif /* RUBY_TRANSCODE_DATA_H */
|
||||
+2607
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,34 @@
|
||||
#include "mruby.h"
|
||||
#ifdef INCLUDE_ENCODING
|
||||
#include "regenc.h"
|
||||
|
||||
static int
|
||||
us_ascii_mbc_enc_len(const UChar* p, const UChar* e, OnigEncoding enc)
|
||||
{
|
||||
if (*p & 0x80)
|
||||
return ONIGENC_CONSTRUCT_MBCLEN_INVALID();
|
||||
return ONIGENC_CONSTRUCT_MBCLEN_CHARFOUND(1);
|
||||
}
|
||||
|
||||
OnigEncodingDefine(us_ascii, US_ASCII) = {
|
||||
us_ascii_mbc_enc_len,
|
||||
"US-ASCII",/* name */
|
||||
1, /* max byte length */
|
||||
1, /* min byte length */
|
||||
onigenc_is_mbc_newline_0x0a,
|
||||
onigenc_single_byte_mbc_to_code,
|
||||
onigenc_single_byte_code_to_mbclen,
|
||||
onigenc_single_byte_code_to_mbc,
|
||||
onigenc_ascii_mbc_case_fold,
|
||||
onigenc_ascii_apply_all_case_fold,
|
||||
onigenc_ascii_get_case_fold_codes_by_str,
|
||||
onigenc_minimum_property_name_to_ctype,
|
||||
onigenc_ascii_is_code_ctype,
|
||||
onigenc_not_support_get_ctype_code_range,
|
||||
onigenc_single_byte_left_adjust_char_head,
|
||||
onigenc_always_true_is_allowed_reverse_match
|
||||
};
|
||||
ENC_ALIAS("ASCII", "US-ASCII")
|
||||
ENC_ALIAS("ANSI_X3.4-1968", "US-ASCII")
|
||||
ENC_ALIAS("646", "US-ASCII")
|
||||
#endif //INCLUDE_ENCODING
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user