| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728 |
- #if defined(SQ_USE_TRE) || defined(SQ_USE_TRE_STATIC)
- #include <ctype.h>
- #include <string.h>
- #include <stdio.h>
- #include "squirrel.h"
- #include "sqstdblobimpl.h"
- #include "tre/tre.h"
- ////////
- #include "dynamic_library.h"
- /*SquiLu
- local library_functions = [
- ["int", "tre_regncomp", "regex_t *preg, const char *regex, size_t len, int cflags"],
- //["int", "tre_regwncomp", "regex_t *preg, const wchar_t *regex, size_t len, int cflags"],
- ["int", "tre_regnexec", "const regex_t *preg, const char *string, size_t len, size_t nmatch, regmatch_t pmatch[], int eflags"],
- ["int", "tre_reganexec", "const regex_t *preg, const char *string, size_t len, regamatch_t *match, regaparams_t params, int eflags"],
- //["int", "tre_regwnexec", "const regex_t *preg, const wchar_t *string, size_t len, size_t nmatch, regmatch_t pmatch[], int eflags"],
- //["int", "tre_regawnexec", "const regex_t *preg, const wchar_t *string, size_t len, regamatch_t *match, regaparams_t params, int eflags"],
- ["void", "tre_regaparams_default", "regaparams_t *params"],
- ["int", "tre_config", "int query, void *result"],
- ["int", "tre_have_backrefs", "const regex_t *preg"],
- ["int", "tre_have_approx", "const regex_t *preg"],
- //["int", "tre_reguexec", "const regex_t *preg, const tre_str_source *string, size_t nmatch, regmatch_t pmatch[], int eflags"],
- ["size_t", "tre_regerror", "int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size"],
- ["void", "tre_regfree", "regex_t *preg"],
- //next entry should be the last one
- //to make valid the test made on load_library function
- ["char *", "tre_version", "void"],
- ];
- function write_library_functions_declaration(){
- foreach(k,v in library_functions) {
- putsnl("typedef " + v[0] + " (*" + v[1] + "_t)(" + v[2] + ");");
- putsnl("static " + v[1] + "_t dl" + v[1] + " = 0;");
- }
- }
- function write_library_functions_load(){
- foreach(k,v in library_functions){
- putsnl("dl" + v[1] + " = (" + v[1] + "_t) libdyn.dlsym(\"" + v[1] + "\");");
- putsnl("if(!dl" + v[1] + ") return false;");
- }
- }
- function write_library_functions_static_defines(){
- foreach(k,v in library_functions){
- putsnl("#define dl" + v[1] + " " + v[1]);
- }
- }
- SquiLu*/
- #ifdef SQ_USE_TRE_STATIC
- #define load_library(x) true
- //@write_library_functions_static_defines()
- // generated-code:begin
- #define dltre_regncomp tre_regncomp
- #define dltre_regnexec tre_regnexec
- #define dltre_reganexec tre_reganexec
- #define dltre_regaparams_default tre_regaparams_default
- #define dltre_config tre_config
- #define dltre_have_backrefs tre_have_backrefs
- #define dltre_have_approx tre_have_approx
- #define dltre_regerror tre_regerror
- #define dltre_regfree tre_regfree
- #define dltre_version tre_version
- // generated-code:end
- #else
- static DynamicLibrary libdyn;
- //@write_library_functions_declaration();
- // generated-code:begin
- typedef int (*tre_regncomp_t)(regex_t *preg, const char *regex, size_t len, int cflags);
- static tre_regncomp_t dltre_regncomp = 0;
- typedef int (*tre_regnexec_t)(const regex_t *preg, const char *string, size_t len, size_t nmatch, regmatch_t pmatch[], int eflags);
- static tre_regnexec_t dltre_regnexec = 0;
- typedef int (*tre_reganexec_t)(const regex_t *preg, const char *string, size_t len, regamatch_t *match, regaparams_t params, int eflags);
- static tre_reganexec_t dltre_reganexec = 0;
- typedef void (*tre_regaparams_default_t)(regaparams_t *params);
- static tre_regaparams_default_t dltre_regaparams_default = 0;
- typedef int (*tre_config_t)(int query, void *result);
- static tre_config_t dltre_config = 0;
- typedef int (*tre_have_backrefs_t)(const regex_t *preg);
- static tre_have_backrefs_t dltre_have_backrefs = 0;
- typedef int (*tre_have_approx_t)(const regex_t *preg);
- static tre_have_approx_t dltre_have_approx = 0;
- typedef size_t (*tre_regerror_t)(int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size);
- static tre_regerror_t dltre_regerror = 0;
- typedef void (*tre_regfree_t)(regex_t *preg);
- static tre_regfree_t dltre_regfree = 0;
- typedef char * (*tre_version_t)(void);
- static tre_version_t dltre_version = 0;
- // generated-code:end
- static const char *dynamicLibName = DYNLIB_FOR_OS(libtre);
- static bool load_library(const char *libname)
- {
- if(dltre_version) return true;
- if(libdyn.open(libname))
- {
- //@write_library_functions_load();
- // generated-code:begin
- dltre_regncomp = (tre_regncomp_t) libdyn.dlsym("tre_regncomp");
- if(!dltre_regncomp) return false;
- dltre_regnexec = (tre_regnexec_t) libdyn.dlsym("tre_regnexec");
- if(!dltre_regnexec) return false;
- dltre_reganexec = (tre_reganexec_t) libdyn.dlsym("tre_reganexec");
- if(!dltre_reganexec) return false;
- dltre_regaparams_default = (tre_regaparams_default_t) libdyn.dlsym("tre_regaparams_default");
- if(!dltre_regaparams_default) return false;
- dltre_config = (tre_config_t) libdyn.dlsym("tre_config");
- if(!dltre_config) return false;
- dltre_have_backrefs = (tre_have_backrefs_t) libdyn.dlsym("tre_have_backrefs");
- if(!dltre_have_backrefs) return false;
- dltre_have_approx = (tre_have_approx_t) libdyn.dlsym("tre_have_approx");
- if(!dltre_have_approx) return false;
- dltre_regerror = (tre_regerror_t) libdyn.dlsym("tre_regerror");
- if(!dltre_regerror) return false;
- dltre_regfree = (tre_regfree_t) libdyn.dlsym("tre_regfree");
- if(!dltre_regfree) return false;
- dltre_version = (tre_version_t) libdyn.dlsym("tre_version");
- if(!dltre_version) return false;
- // generated-code:end
- return true;
- }
- return false;
- }
- #endif // SQ_USE_TRE_STATIC
- struct sqtre_st {
- regex_t re;
- regamatch_t amatch;
- regaparams_t aparams;
- /* associated squirrel vm */
- //HSQUIRRELVM v;
- };
- static const SQChar TRE_Tag[] = _SC("sqtre");
- #define GET_tre_INSTANCE() SQ_GET_INSTANCE(v, 1, sqtre_st, TRE_Tag) \
- if(self == NULL) return sq_throwerror(v, _SC("sqtre object already closed"));
- static SQRESULT generate_error (HSQUIRRELVM v, const sqtre_st *sqtre, int errcode) {
- char errbuf[80];
- tre_regerror (errcode, &sqtre->re, errbuf, sizeof (errbuf));
- return sq_throwerror(v, _SC("%s"), errbuf);
- }
- static SQRESULT sq_tre_releasehook(SQUserPointer p, SQInteger /*size*/, void */*ep*/)
- {
- sqtre_st *self = ((sqtre_st *)p);
- if(self)
- {
- if(self->amatch.pmatch)
- {
- sq_free(self->amatch.pmatch, self->amatch.nmatch * sizeof(*self->amatch.pmatch));
- }
- dltre_regfree(&self->re);
- sq_free(self, sizeof(*self));
- }
- return 1;
- }
- static SQRESULT sq_tre_constructor(HSQUIRRELVM v)
- {
- if(!load_library(dynamicLibName)) return sq_throwerror(v, _SC("Failed to load libtre !"));
- SQ_FUNC_VARS(v);
- SQ_GET_STRING(v, 2, pattern);
- SQ_OPT_INTEGER(v, 3, eflags, REG_EXTENDED);
- sqtre_st *sqtre = (sqtre_st *)sq_malloc(sizeof(*sqtre));
- memset(sqtre, 0, sizeof(sqtre_st));
- //sqtre->v = v;
- int rc = dltre_regncomp(
- &sqtre->re,
- pattern, /* the pattern */
- pattern_size,
- eflags); /* 0 = default eflags */
- if(rc)
- {
- SQRESULT res = generate_error(v, sqtre, rc);
- sq_free(sqtre, sizeof(sqtre_st));
- return res;
- }
- if (eflags & REG_NOSUB) sqtre->re.re_nsub = 0;
- else
- {
- sqtre->amatch.nmatch = sqtre->re.re_nsub+1; //+1 fror the whole match at 0
- sqtre->amatch.pmatch = (regmatch_t *) sq_malloc(sqtre->amatch.nmatch * sizeof (regmatch_t));
- }
- /*
- sq_resetobject(&sqtre->callout_cb);
- sq_resetobject(&sqtre->callout_cb_udata);
- */
- sq_setinstanceup(v,1,sqtre);
- sq_setreleasehook(v,1,sq_tre_releasehook);
- return 0;
- }
- #define GET_EXTRA_MATCH_PARAMS(stack_pos) \
- SQ_OPT_INTEGER(v, stack_pos, start_offset, 0); \
- SQ_OPT_INTEGER(v, stack_pos+1, eflags, 0); \
- SQ_OPT_INTEGER(v, stack_pos+2, max_len, 0); \
- \
- if(start_offset < 0) return sq_throwerror(v, _SC("start_offset can't be negative")); \
- SQInteger subject_str_size = subject_size - start_offset; \
- if(subject_str_size < 0) return sq_throwerror(v, _SC("str size - start_offset can't be negative")); \
- const SQChar *subject_str = subject + start_offset; \
- if(max_len && (max_len < subject_str_size)) subject_str_size = max_len;
- static SQRESULT sq_tre_exec(HSQUIRRELVM v)
- {
- SQ_FUNC_VARS(v);
- GET_tre_INSTANCE();
- SQ_GET_STRING(v, 2, subject);
- GET_EXTRA_MATCH_PARAMS(4);
- int rc = dltre_reganexec(
- &self->re, /* the compiled pattern */
- subject_str, /* the subject string */
- subject_str_size, /* the length of the subject */
- &self->amatch,
- self->aparams,
- eflags); /* 0 = default eflags */
- const int array_pos = 3;
- SQInteger rtype = sq_gettype(v, array_pos);
- if (rc == 0)
- {
- if(rtype == OT_ARRAY)
- {
- int nelms = self->amatch.nmatch;
- regmatch_t *pmatch = self->amatch.pmatch;
- sq_clear(v, array_pos);
- for (int i = 0; i < nelms; i++)
- {
- SQInteger pos = pmatch[i].rm_so + start_offset;
- sq_pushinteger(v, pos);
- sq_arrayappend(v, array_pos);
- pos = pmatch[i].rm_eo + start_offset;
- sq_pushinteger(v, pos);
- sq_arrayappend(v, array_pos);
- }
- }
- }
- sq_pushinteger(v, rc);
- return 1;
- }
- static SQRESULT sq_tre_match(HSQUIRRELVM v)
- {
- SQ_FUNC_VARS(v);
- GET_tre_INSTANCE();
- SQ_GET_STRING(v, 2, subject);
- GET_EXTRA_MATCH_PARAMS(3);
- int rc = dltre_reganexec(
- &self->re, /* the compiled pattern */
- subject_str, /* the subject string */
- subject_str_size, /* the length of the subject */
- &self->amatch,
- self->aparams,
- eflags); /* 0 = default eflags */
- if(rc == 0)
- {
- regmatch_t *pmatch = self->amatch.pmatch;
- SQInteger start_pos = pmatch[0].rm_so, end_pos = pmatch[0].rm_eo;
- if(start_pos == end_pos) sq_pushinteger(v, start_pos + start_offset); //empty match return it's position
- else sq_pushstring(v, subject_str + start_pos, end_pos - start_pos);
- return 1;
- }
- if(rc == REG_ESPACE) //only no matching errore
- {
- return sq_throwerror(v, _SC("tre_match error %d"), (int)rc);
- }
- return 0;
- }
- static SQRESULT sq_tre_gmatch(HSQUIRRELVM v)
- {
- SQ_FUNC_VARS(v);
- GET_tre_INSTANCE();
- SQ_GET_STRING(v, 2, subject);
- GET_EXTRA_MATCH_PARAMS(4);
- SQInteger rc;
- bool isFirst = true;
- regmatch_t *pmatch = self->amatch.pmatch;
- SQInteger nmatch = self->amatch.nmatch;
- while( (rc = dltre_reganexec(
- &self->re, /* the compiled pattern */
- subject_str, /* the subject string */
- subject_str_size, /* the length of the subject */
- &self->amatch,
- self->aparams,
- eflags)) == 0) /* use default match context */
- {
- if(isFirst)
- {
- sq_push(v, 3); //push the function
- isFirst = false;
- }
- sq_pushroottable(v); //this
- SQInteger start_pos, end_pos = 0, i = 0,
- param_count = 1; //root table already on the stack
- for(;i < nmatch; i++) {
- start_pos = pmatch[i].rm_so;
- end_pos = pmatch[i].rm_eo;
- if(start_pos == end_pos) sq_pushinteger(v, start_pos + start_offset); //empty match return it's position
- else sq_pushstring(v, subject_str + start_pos, end_pos - start_pos);
- ++param_count;
- }
- i = sq_call(v, param_count, SQTrue, SQTrue);
- if(i < 0) return i;
- SQObjectType rtype = sq_gettype(v, -1);
- SQBool keep_matching = SQFalse;
- if(rtype == OT_BOOL) {
- sq_getbool(v, -1, &keep_matching);
- }
- sq_poptop(v); //remove return parameter
- if(!keep_matching) break;
- end_pos = pmatch[0].rm_eo;
- subject_str_size -= end_pos;
- if(subject_str_size <= 0) break;
- start_offset += end_pos;
- subject_str += end_pos; //the last match + 1
- }
- if(rc == REG_ESPACE) //only no matching errore
- {
- return sq_throwerror(v, _SC("tre_match error %d"), (int)rc);
- }
- return 0;
- }
- #include "sqstdblobimpl.h"
- static SQRESULT sq_tre_gsub(HSQUIRRELVM v)
- {
- SQ_FUNC_VARS(v);
- GET_tre_INSTANCE();
- SQ_GET_STRING(v, 2, subject);
- SQ_OPT_INTEGER(v, 4, eflags, 0);
- SQ_OPT_INTEGER(v, 5, max_sub, 0);
- if(max_sub < 0) return sq_throwerror(v, _SC("max substitutions can't be less than zero"));
- SQBlob blob(0,8192);
- const int replacement_idx = 3;
- SQObjectType ptype = sq_gettype(v, replacement_idx);
- const SQChar *replacement;
- SQInteger replacement_size, start_offset=0;
- SQInteger rc;
- bool isFirst = true;
- regmatch_t *pmatch = self->amatch.pmatch;
- SQInteger nmatch = self->amatch.nmatch;
- if(ptype == OT_STRING)
- {
- sq_getstr_and_size(v, replacement_idx, &replacement, &replacement_size);
- }
- while( (rc = dltre_reganexec(
- &self->re, /* the compiled pattern */
- subject, /* the subject string */
- subject_size, /* the length of the subject */
- &self->amatch,
- self->aparams,
- eflags)) == 0) /* use default match context */
- {
- SQInteger i, start_pos, end_pos;
- blob.Write(subject, pmatch[0].rm_so);
- switch(ptype){
- case OT_CLOSURE:{
- if(isFirst)
- {
- sq_push(v, replacement_idx); //push the function
- isFirst = false;
- }
- sq_pushroottable(v); //this
- SQInteger param_count = 1; //root table
- for(i=0; i < nmatch; i++) {
- start_pos = pmatch[i].rm_so;
- end_pos = pmatch[i].rm_eo;
- if(start_pos == end_pos) sq_pushinteger(v, start_pos + start_offset);
- else sq_pushstring(v, subject + start_pos, end_pos - start_pos);
- ++param_count;
- }
- i = sq_call(v, param_count, SQTrue, SQTrue);
- if(i < 0) return i;
- if(sq_gettype(v, -1) == OT_STRING){
- const SQChar *svalue;
- sq_getstring(v, -1, &svalue);
- blob.Write(svalue, sq_getsize(v, -1));
- }
- sq_poptop(v);
- }
- break;
- case OT_ARRAY:{
- SQInteger array_idx = 0;
- for(i=0; i < nmatch; i++) {
- sq_pushinteger(v, array_idx++);
- if(SQ_SUCCEEDED(sq_get(v, replacement_idx)) &&
- SQ_SUCCEEDED(sq_getstr_and_size(v, -1, &replacement, &replacement_size))){
- blob.Write(replacement, replacement_size);
- sq_pop(v, 1); //remove value
- }
- }
- }
- break;
- case OT_TABLE:{
- for(i=0; i < nmatch; i++) {
- start_pos = pmatch[i].rm_so;
- end_pos = pmatch[i].rm_eo;
- sq_pushstring(v, subject + start_pos, end_pos - start_pos);
- if(SQ_SUCCEEDED(sq_get(v, replacement_idx)) &&
- SQ_SUCCEEDED(sq_getstr_and_size(v, -1, &replacement, &replacement_size))){
- blob.Write(replacement, replacement_size);
- sq_pop(v, 1); //remove value
- }
- }
- }
- break;
- case OT_STRING:{
- for(i=0; i < replacement_size; i++) {
- SQInteger c = replacement[i];
- switch(c)
- {
- case '$':
- ++i;
- if(i < replacement_size)
- {
- SQInteger idx = replacement[i] - '0', match_idx = 0;
- for(int j=0; j < nmatch; j++) {
- if(match_idx == idx)
- {
- start_pos = pmatch[j].rm_so;
- end_pos = pmatch[j].rm_eo;
- blob.Write(subject + start_pos, end_pos-start_pos);
- break;
- }
- ++match_idx;
- }
- if(idx != match_idx)
- {
- return sq_throwerror(v, _SC("there is no match for replacement $%d"), idx);
- }
- continue;
- }
- else
- {
- return sq_throwerror(v, _SC("unexpected end of replacement string"));
- }
- break;
- case '\\':
- ++i;
- if(i < replacement_size)
- {
- blob.WriteChar(replacement[i]);
- continue;
- }
- //falthrough last character on replacement string
- default:
- blob.WriteChar(c);
- }
- }
- }
- break;
- default:
- return sq_throwerror(v, _SC("gsub only works with closure, array, table for replacement"));
- }
- end_pos = pmatch[0].rm_eo;
- subject_size -= end_pos;
- if(subject_size <= 0) break;
- subject += end_pos; //the last match + 1
- if(max_sub)
- {
- if(--max_sub == 0) break;
- }
- }
- if(rc == REG_ESPACE) //only no matching errore
- {
- return sq_throwerror(v, _SC("tre_match error %d"), (int)rc);
- }
- if(subject_size > 0) blob.Write(subject+start_offset, subject_size-start_offset);
- sq_pushstring(v, (const SQChar *)blob.GetBuf(), blob.Len());
- return 1;
- }
- static SQRESULT sq_tre_have_backrefs(HSQUIRRELVM v)
- {
- SQ_FUNC_VARS_NO_TOP(v);
- GET_tre_INSTANCE();
- sq_pushinteger(v, dltre_have_backrefs(&self->re));
- return 1;
- }
- static SQRESULT sq_tre_have_approx(HSQUIRRELVM v)
- {
- SQ_FUNC_VARS_NO_TOP(v);
- GET_tre_INSTANCE();
- sq_pushinteger(v, dltre_have_approx(&self->re));
- return 1;
- }
- static SQRESULT sq_tre__typeof(HSQUIRRELVM v)
- {
- sq_pushstring(v,_SC(TRE_Tag),-1);
- return 1;
- }
- static SQRESULT sq_tre_version(HSQUIRRELVM v)
- {
- const char *buf = dltre_version();
- sq_pushstring(v, (const SQChar*)buf, -1);
- return 1;
- }
- static SQRESULT sq_tre_loadlib(HSQUIRRELVM v)
- {
- SQ_FUNC_VARS_NO_TOP(v);
- SQ_GET_STRING(v, 2, libname);
- sq_pushbool(v, load_library(libname));
- return 1;
- }
- static SQRESULT sq_tre_regaparams_default(HSQUIRRELVM v)
- {
- SQ_FUNC_VARS_NO_TOP(v);
- GET_tre_INSTANCE();
- dltre_regaparams_default(&self->aparams);
- return 0;
- }
- static SQRESULT sq_tre_regamatch(HSQUIRRELVM v)
- {
- SQ_FUNC_VARS_NO_TOP(v);
- GET_tre_INSTANCE();
- SQ_GET_STRING(v, 2, pkey);
- #define GET_PKEY(skey) \
- else if(strcmp(pkey, #skey) == 0) \
- { \
- sq_pushinteger(v, self->amatch.skey); \
- }
- if(0){}
- GET_PKEY(cost)
- GET_PKEY(num_ins)
- GET_PKEY(num_del)
- GET_PKEY(num_subst)
- GET_PKEY(nmatch)
- else return sq_throwerror(v, _SC("unknown parameter '%s'"), pkey);
- return 1;
- }
- static SQRESULT sq_tre_regaparams(HSQUIRRELVM v)
- {
- SQ_FUNC_VARS(v);
- GET_tre_INSTANCE();
- SQ_GET_STRING(v, 2, pkey);
- SQ_OPT_INTEGER(v, 3, pvalue, 0);
- SQBool doSet = (_top_ == 3);
- #define GET_SET_PKEY(skey) \
- else if(strcmp(pkey, #skey) == 0) \
- { \
- sq_pushinteger(v, self->aparams.skey); \
- if(doSet) self->aparams.skey = pvalue; \
- }
- if(0){}
- GET_SET_PKEY(max_cost)
- GET_SET_PKEY(cost_ins)
- GET_SET_PKEY(cost_del)
- GET_SET_PKEY(cost_subst)
- GET_SET_PKEY(max_ins)
- GET_SET_PKEY(max_del)
- GET_SET_PKEY(max_subst)
- GET_SET_PKEY(max_err)
- else return sq_throwerror(v, _SC("unknown parameter '%s'"), pkey);
- return 1;
- }
- static SQRESULT sq_tre_config(HSQUIRRELVM v)
- {
- SQ_FUNC_VARS_NO_TOP(v);
- SQ_GET_INTEGER(v, 2, option);
- void *config_result;
- switch(option)
- {
- case TRE_CONFIG_APPROX:
- case TRE_CONFIG_WCHAR:
- case TRE_CONFIG_MULTIBYTE:
- case TRE_CONFIG_SYSTEM_ABI:
- tre_config(option, &config_result);
- sq_pushinteger(v, (SQInteger)config_result);
- break;
- case TRE_CONFIG_VERSION:
- tre_config(option, &config_result);
- sq_pushstring(v, (const SQChar*)config_result, -1);
- break;
- default:
- return sq_throwerror(v, _SC("unknown config option '%d'"), option);
- }
- return 1;
- }
- #define _DECL_FUNC(name,nparams,tycheck) {_SC(#name),sq_tre_##name,nparams,tycheck}
- static SQRegFunction sq_tre_methods[] =
- {
- _DECL_FUNC(constructor,-2,_SC(".sn")),
- _DECL_FUNC(config,2,_SC("xi")),
- _DECL_FUNC(regaparams_default,1,_SC("x")),
- _DECL_FUNC(regaparams,-2,_SC("xsi")),
- _DECL_FUNC(regamatch,2,_SC("xs")),
- _DECL_FUNC(exec,-3,_SC("xsannn")),
- _DECL_FUNC(match,-2,_SC("xsnnn")),
- _DECL_FUNC(gmatch,-3,_SC("xscnnn")),
- _DECL_FUNC(gsub,-3,_SC("xs s|c|a|t nn")),
- _DECL_FUNC(_typeof,1,_SC("x")),
- _DECL_FUNC(version,1,_SC(".")),
- _DECL_FUNC(have_approx,1,_SC("x")),
- _DECL_FUNC(have_backrefs,1,_SC("x")),
- _DECL_FUNC(loadlib,2,_SC(".s")),
- {0,0}
- };
- #undef _DECL_FUNC
- typedef struct {
- const SQChar *Str;
- SQInteger Val;
- } KeyIntType, * KeyIntPtrType;
- static KeyIntType sqtre_constants[] = {
- #define MK_CONST(c) {_SC(#c), TRE_##c}
- #define MK_CONST2(c) {_SC(#c), (SQInteger)TRE_##c}
- #define MK_CONST_REG(c) {_SC(#c), (SQInteger)REG_##c}
- //MK_CONST(SSL_SESSION_ID_SIZE),
- MK_CONST2(CONFIG_VERSION),
- MK_CONST2(CONFIG_APPROX),
- MK_CONST2(CONFIG_WCHAR),
- MK_CONST2(CONFIG_MULTIBYTE),
- MK_CONST2(CONFIG_SYSTEM_ABI),
- MK_CONST_REG(OK),
- MK_CONST_REG(NOMATCH),
- MK_CONST_REG(BADPAT),
- MK_CONST_REG(ECOLLATE),
- MK_CONST_REG(ECTYPE),
- MK_CONST_REG(EESCAPE),
- MK_CONST_REG(ESUBREG),
- MK_CONST_REG(EBRACK),
- MK_CONST_REG(EPAREN),
- MK_CONST_REG(EBRACE),
- MK_CONST_REG(BADBR),
- MK_CONST_REG(ERANGE),
- MK_CONST_REG(ESPACE),
- MK_CONST_REG(BADRPT),
- MK_CONST_REG(EXTENDED),
- MK_CONST_REG(ICASE),
- MK_CONST_REG(NEWLINE),
- MK_CONST_REG(NOSUB),
- MK_CONST_REG(BASIC),
- MK_CONST_REG(LITERAL),
- MK_CONST_REG(RIGHT_ASSOC),
- MK_CONST_REG(UNGREEDY),
- MK_CONST_REG(NOTBOL),
- MK_CONST_REG(NOTEOL),
- MK_CONST_REG(APPROX_MATCHER),
- MK_CONST_REG(BACKTRACKING_MATCHER),
- {0,0}
- };
- #ifdef __cplusplus
- extern "C" {
- #endif
- SQRESULT sqext_register_tre(HSQUIRRELVM v)
- {
- sq_pushstring(v,TRE_Tag,-1);
- sq_newclass(v,SQFalse);
- sq_settypetag(v,-1,(void*)TRE_Tag);
- sq_insert_reg_funcs(v, sq_tre_methods);
- //add constants
- KeyIntPtrType KeyIntPtr;
- for (KeyIntPtr = sqtre_constants; KeyIntPtr->Str; KeyIntPtr++) {
- sq_pushstring(v, KeyIntPtr->Str, -1); //first the key
- sq_pushinteger(v, KeyIntPtr->Val); //then the value
- sq_newslot(v, -3, SQFalse); //store then
- }
- sq_newslot(v,-3,SQTrue);
- return 0;
- }
- #ifdef __cplusplus
- }
- #endif
- #endif //SQ_USE_TRE
|