add mruby sources

This commit is contained in:
mimaki
2012-04-20 09:39:03 +09:00
parent 54ad561098
commit e0d6430f63
111 changed files with 87350 additions and 4 deletions
+18
View File
@@ -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
+120
View File
@@ -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`"
-4
View File
@@ -1,4 +0,0 @@
mruby
=====
Lightweight Ruby
+14
View File
@@ -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以外削除)
* 気づいたら書き加える
View File
View File
View File
+42
View File
@@ -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
View File
@@ -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 */
+42
View File
@@ -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 */
+71
View File
@@ -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 */
+59
View File
@@ -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 */
+17
View File
@@ -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 */
+46
View File
@@ -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 */
+44
View File
@@ -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 */
+21
View File
@@ -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 */
+133
View File
@@ -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 */
+16
View File
@@ -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
View File
+62
View File
@@ -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`"
+79
View File
@@ -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
+63
View File
@@ -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
View File
@@ -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
+9
View File
@@ -0,0 +1,9 @@
#
# Exception
#
class Exception
# 15.2.22.4.1
def self.exception(*args, &block)
self.new(*args, &block)
end
end
+58
View File
@@ -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
+17
View File
@@ -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));
}
+45
View File
@@ -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
+42
View File
@@ -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
+20
View File
@@ -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
+30
View File
@@ -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
+93
View File
@@ -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
+30
View File
@@ -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
+89
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
+96
View File
@@ -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
View File
@@ -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;
}
+8
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
+2273
View File
File diff suppressed because it is too large Load Diff
+144
View File
@@ -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 */
}
+73
View File
@@ -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);
+28
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
+360
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
+479
View File
@@ -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
View File
@@ -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 */
+280
View File
@@ -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 */
}
}
+217
View File
@@ -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 */
View File
+1146
View File
File diff suppressed because it is too large Load Diff
+26
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
+105
View File
@@ -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);
}
+10
View File
@@ -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
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
+50
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
+125
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
+632
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
+152
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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) */
}
+3306
View File
File diff suppressed because it is too large Load Diff
+85
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
+909
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
+833
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
+354
View File
@@ -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
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
+1283
View File
File diff suppressed because it is too large Load Diff
+139
View File
@@ -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
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
+824
View File
@@ -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
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
+109
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
+34
View File
@@ -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