void test_kString(KonohaContext *kctx) { intptr_t i; kString *s; for (i = 0; i < 100; ++i) { s = KLIB new_kString(kctx, GcUnsafe, "abcd", 4, 0); assert(strcmp(S_text(s), "abcd") == 0); assert(S_size(s) == 4); assert(kString_is(ASCII, s) == 1); } for (i = 0; i < 100; ++i) { s = KLIB new_kString(kctx, GcUnsafe, "abcd", 4, 0); assert(strcmp(S_text(s), "abcd") == 0); assert(S_size(s) == 4); assert(S_text(s) == (char*)s->inline_text); } for (i = 0; i < 100; ++i) { static const char *text = "12345678901234567890"; s = KLIB new_kString(kctx, GcUnsafe, text, 20, StringPolicy_TEXT | StringPolicy_UTF8); assert(strcmp(S_text(s), text) == 0); assert(S_size(s) == 20); assert(S_text(s) == text); assert(kString_is(ASCII, s) == 0); } }
// boolean NameSpace.import(String pkgname, String symbol); static KMETHOD NameSpace_ImportPackageSymbol(KonohaContext *kctx, KonohaStack *sfp) { kString *key = sfp[2].asString; ksymbol_t keyword = ksymbolA(S_text(key), S_size(key), _NEWID); KMakeTrace(trace, sfp); kNameSpace_ImportPackageSymbol(kctx, sfp[0].asNameSpace, S_text(sfp[1].asString), keyword, trace); }
static kBlock* kStmt_ParseClassBlockNULL(KonohaContext *kctx, kStmt *stmt, kToken *tokenClassName) { kBlock *bk = NULL; kToken *blockToken = (kToken *)kStmt_GetObject(kctx, stmt, KW_BlockPattern, NULL); if(blockToken != NULL && blockToken->resolvedSyntaxInfo->keyword == KW_BlockPattern) { const char *cname = S_text(tokenClassName->text); TokenSeq range = {Stmt_ns(stmt), GetSugarContext(kctx)->preparedTokenList}; TokenSeq_Push(kctx, range); SUGAR TokenSeq_Tokenize(kctx, &range, S_text(blockToken->text), blockToken->uline); { TokenSeq sourceRange = {range.ns, range.tokenList, range.endIdx}; kToken *prevToken = blockToken; int i; for(i = range.beginIdx; i < range.endIdx; i++) { kToken *tk = range.tokenList->TokenItems[i]; if(tk->hintChar == '(' && prevToken->unresolvedTokenType == TokenType_SYMBOL && strcmp(cname, S_text(prevToken->text)) == 0) { kTokenVar *newToken = new_(TokenVar, TokenType_SYMBOL, sourceRange.tokenList); KFieldSet(newToken, newToken->text, SYM_s(MN_new)); } KLIB kArray_Add(kctx, sourceRange.tokenList, tk); prevToken = tk; } TokenSeq_end(kctx, (&sourceRange)); bk = SUGAR new_kBlock(kctx, stmt/*parent*/, NULL, &sourceRange); KLIB kObject_setObject(kctx, stmt, KW_BlockPattern, TY_Block, bk); } TokenSeq_Pop(kctx, range); } return bk; }
static SugarSyntaxVar *kNameSpace_guessSyntaxFromTokenList(KonohaContext *kctx, kNameSpace *ns, kArray *tokenList) { int beginIdx = 0, endIdx = kArray_size(tokenList); if(beginIdx < endIdx) { ksymbol_t keyword = tokenList->TokenItems[beginIdx]->resolvedSyntaxInfo->keyword; if(keyword == KW_TextPattern) { ksymbol_t kw; if(isSubKeyword(kctx, tokenList, beginIdx, endIdx)) { char buf[256]; PLATAPI snprintf_i(buf, sizeof(buf), "%s_%s", S_text(tokenList->TokenItems[beginIdx]->text), S_text(tokenList->TokenItems[beginIdx+1]->text)); kw = ksymbolA((const char *)buf, strlen(buf), SYM_NEWID); } else { kw = ksymbolA(S_text(tokenList->TokenItems[beginIdx]->text), S_size(tokenList->TokenItems[beginIdx]->text), SYM_NEWID); } return (SugarSyntaxVar *)NEWSYN_(ns, kw); } else if(keyword == KW_DOLLAR) { // $TokenPattern char buf[256]; PLATAPI snprintf_i(buf, sizeof(buf), "$%s", S_text(tokenList->TokenItems[beginIdx+1]->text)); ksymbol_t kw = ksymbolA((const char *)buf, strlen(buf), SYM_NEWID); return (SugarSyntaxVar *)NEWSYN_(ns, kw); } } return NULL; }
// ## void AprTable.set(String key, String val) static KMETHOD AprTable_set(KonohaContext *kctx, KonohaStack *sfp) { kAprTable *self = (kAprTable *) sfp[0].asObject; const char *key = S_text(sfp[1].asString); const char *val = S_text(sfp[2].asString); apr_table_set(self->tbl, key, val); KReturnVoid(); }
//## boolean chdir(String path) static KMETHOD System_chdir(KonohaContext *kctx, KonohaStack *sfp) { KMakeTrace(trace, sfp); char buffer[K_PATHMAX]; kString *path = sfp[1].asString; const char *systemPath = PLATAPI formatSystemPath(kctx, buffer, sizeof(buffer), S_text(path), S_size(path), trace); int ret = chdir(systemPath); if(ret == -1) { KTraceErrorPoint(trace, SystemFault, "chdir", LogFileName(S_text(path)), LogErrno); } KReturnUnboxValue(ret != -1); }
//## Stat System.lstat(String path) static KMETHOD System_lstat(KonohaContext *kctx, KonohaStack *sfp) { KMakeTrace(trace, sfp); char buffer[K_PATHMAX]; kString *path = sfp[1].asString; const char *systemPath = PLATAPI formatSystemPath(kctx, buffer, sizeof(buffer), S_text(path), S_size(path), trace); struct stat buf = {}; /* zero */ int ret = lstat(systemPath, &buf); if(ret == -1) { int fault = KLIB DiagnosisFaultType(kctx, kString_guessUserFault(path)|SystemError, trace); KTraceErrorPoint(trace, fault, "lstat", LogText("path", S_text(path)), LogErrno); } KReturn(KLIB new_kObject(kctx, OnStack, KGetReturnType(sfp), (uintptr_t)&buf)); }
static KMETHOD System_lchown(KonohaContext *kctx, KonohaStack *sfp) { KMakeTrace(trace, sfp); char buffer[K_PATHMAX]; kString *path = sfp[1].asString; const char *systemPath = PLATAPI formatSystemPath(kctx, buffer, sizeof(buffer), S_text(path), S_size(path), trace); uid_t owner = (uid_t)sfp[2].intValue; gid_t group = (gid_t)sfp[3].intValue; int ret = lchown(systemPath, owner, group); if(ret == -1) { KTraceErrorPoint(trace, SystemFault, "lchown", LogFileName(S_text(path)), LogOwner(owner), LogGroup(group), LogErrno); } KReturnUnboxValue(ret != -1); }
static void RegExp_set(KonohaContext *kctx, kRegExp *re, kString *ptns, kString *opts) { const char *ptn = S_text(ptns); const char *opt = S_text(opts); kRegExp_setOptions(re, opt); KFieldSet(re, re->pattern, ptns); re->reg = pcre_regmalloc(kctx, ptns); int cflags = pcre_ParseComplflags(kctx, opt); if(!kString_is(ASCII, ptns)) { /* Add 'u' option when the pattern is multibyte string. */ cflags |= PCRE_UTF8; } pcre_regcomp(kctx, re->reg, ptn, cflags); re->eflags = pcre_ParseExecflags(kctx, opt); }
//## PyObject PyObject.(PyObject o); static KMETHOD PyObject_(KonohaContext *kctx, KonohaStack *sfp) { // consider about module function and class method. // Now, PyObject_() support only module function. // [TODO] Support class method. // int argc = kctx->esp - sfp - 2; // believe me kPyObject *pmod = (kPyObject*)sfp[0].asObject; PyObject *pFunc = PyObject_GetAttrString(pmod->self, S_text(kctx->esp[-1].s)); PyObject *pArgs = NULL, *pValue = NULL; if(pFunc != NULL) { if(PyCallable_Check(pFunc)) { int i; pArgs = PyTuple_New(argc); for (i = 0; i < argc; ++i) { pValue = ((kPyObject*)sfp[i+1].o)->self; Py_INCREF(pValue); PyTuple_SetItem(pArgs, i, pValue); } pValue = PyObject_CallObject(pFunc, pArgs); } } Py_XDECREF(pFunc); Py_XDECREF(pArgs); RETURN_PyObject(pValue); }
//## String JSON.getInt(String key); static KMETHOD kJSON_getInt(KonohaContext *kctx, KonohaStack *sfp) { JSON obj = ((kJSON *)sfp[0].asObject)->json; const char *key = S_text(sfp[1].asString); int32_t json = JSON_getInt(obj, key); KReturnUnboxValue(json); }
// class methodList start ============================================================================================== // ## void Request.puts(String s) static KMETHOD Request_puts(KonohaContext *kctx, KonohaStack *sfp) { kRequest *self = (kRequest *) sfp[0].asObject; kString *data = sfp[1].asString; ap_rputs(S_text(data), self->r); KReturnVoid(); }
// ##void Request.setContentEncoding(String enc); static KMETHOD Request_setContentEncoding(KonohaContext *kctx, KonohaStack *sfp) { kRequest *self = (kRequest *) sfp[0].asObject; kString *enc = sfp[1].asString; self->r->content_encoding = apr_pstrdup(self->r->pool, S_text(enc)); KReturnVoid(); }
//## String System.realpath(String path) static KMETHOD System_realpath(KonohaContext *kctx, KonohaStack *sfp) { KMakeTrace(trace, sfp); char buffer[K_PATHMAX], filepath[K_PATHMAX] = {0}; kString *path = sfp[1].asString; const char *systemPath = PLATAPI formatSystemPath(kctx, buffer, sizeof(buffer), S_text(path), S_size(path), trace); char *cwd = realpath(systemPath, filepath); if(cwd != NULL) { const char *konohaPath = PLATAPI formatKonohaPath(kctx, buffer, sizeof(buffer), cwd, strlen(cwd), trace); KReturn(KLIB new_kString(kctx, OnStack, konohaPath, strlen(konohaPath), 0)); } else { KTraceErrorPoint(trace, SystemFault, "realpath", LogFileName(S_text(path)), LogErrno); KReturn(KNULL(String)); } }
//## String DIR.readPath() static KMETHOD DIR_readPath(KonohaContext *kctx, KonohaStack *sfp) { kDir *dir = (kDir *)sfp[0].asObject; if(dir->dirp != NULL) { KMakeTrace(trace, sfp); struct dirent entry, *result; int ret = readdir_r(dir->dirp, &entry, &result); if(result != NULL) { char *d_name = result->d_name, delim[2] = {'/', 0}; KGrowingBuffer wb; KLIB Kwb_Init(&(kctx->stack->cwb), &wb); KLIB Kwb_Write(kctx, &wb, S_text(dir->PathInfoNULL), S_size(dir->PathInfoNULL)); KLIB Kwb_Write(kctx, &wb, delim, 1); if(dir->readerIconv != ICONV_NULL) { KLIB Kwb_Write(kctx, &wb, d_name, strlen(d_name)); } else { KLIB Kwb_iconv(kctx, &wb, dir->readerIconv, d_name, strlen(d_name), trace); } KReturnWith( KLIB new_kString(kctx, OnStack, KLIB Kwb_top(kctx, &wb, 0), Kwb_bytesize(&wb), StringPolicy_SystemInfo), KLIB Kwb_Free(&wb) ); } if(ret == -1) { KTraceErrorPoint(trace, SystemFault, "readdir", LogErrno); } kDir_close(kctx, dir); } KReturn(KNULL(String)); }
//## boolean System.rmdir(String path) static KMETHOD System_rmdir(KonohaContext *kctx, KonohaStack *sfp) { KMakeTrace(trace, sfp); char buffer[K_PATHMAX]; kString *path = sfp[1].asString; const char *systemPath = PLATAPI formatSystemPath(kctx, buffer, sizeof(buffer), S_text(path), S_size(path), trace); int ret = rmdir(systemPath); if(ret == -1) { int fault = KLIB DiagnosisFaultType(kctx, kString_guessUserFault(path)|SystemError, trace); KTraceErrorPoint(trace, fault, "rmdir", LogFileName(S_text(path)), LogErrno); } else { KTraceChangeSystemPoint(trace, "rmdir", LogFileName(S_text(path))); } KReturnUnboxValue(ret != -1); }
//## boolean System.mkdir(String path, int mode) static KMETHOD System_mkdir(KonohaContext *kctx, KonohaStack *sfp) { KMakeTrace(trace, sfp); char buffer[K_PATHMAX]; kString *path = sfp[1].asString; const char *systemPath = PLATAPI formatSystemPath(kctx, buffer, sizeof(buffer), S_text(path), S_size(path), trace); mode_t mode = (mode_t)sfp[2].intValue; int ret = mkdir(systemPath, mode); if(ret == -1) { KTraceErrorPoint(trace, SystemFault, "mkdir", LogFileName(S_text(path)), LogMode(mode), LogErrno); } else { KTraceChangeSystemPoint(trace, "mkdir", LogFileName(S_text(path)), LogMode(mode)); } KReturnUnboxValue(ret != -1); }
static KMETHOD TypeCheck_Float(KonohaContext *kctx, KonohaStack *sfp) { VAR_TypeCheck(stmt, expr, gma, reqty); kToken *tk = expr->termToken; sfp[4].floatValue = strtod(S_text(tk->text), NULL); // just using tramsformation float KReturn(SUGAR kExpr_SetUnboxConstValue(kctx, expr, TY_float, sfp[4].unboxValue)); }
// ## void Request.setContentType(String type); static KMETHOD Request_setContentType(KonohaContext *kctx, KonohaStack *sfp) { kRequest *self = (kRequest *) sfp[0].asObject; kString *type = sfp[1].asString; self->r->content_type = apr_pstrdup(self->r->pool, S_text(type)); KReturnVoid(); }
//## JSON JSON.get(String key); static KMETHOD kJSON_get(KonohaContext *kctx, KonohaStack *sfp) { JSON obj = ((kJSON *)sfp[0].asObject)->json; const char *key = S_text(sfp[1].asString); JSON json = JSON_get(obj, key); KReturn(NewJsonObject(kctx, sfp, json)); }
static void kArray_executeRegExp(KonohaContext *kctx, kArray *resultArray, kRegExp *regex, kString *s0) { int stringPolicy = kString_is(ASCII, s0) ? StringPolicy_ASCII : 0; if(IS_NOTNULL(regex) && S_size(regex->pattern) > 0) { const char *s = S_text(s0); // necessary const char *base = s; const char *eos = base + S_size(s0); size_t i, nmatch = pcre_nmatchsize(kctx, regex->reg); kregmatch_t *p, pmatch[nmatch+1]; int isGlobalOption = RegExp_isGlobal(regex); do { int res = pcre_regexec(kctx, regex->reg, s, nmatch, pmatch, regex->eflags); if(res != 0) { // FIXME //LOG_regex(kctx, sfp, res, regex, s); break; } for(p = pmatch, i = 0; i < nmatch; p++, i++) { if(p->rm_so == -1) break; KLIB new_kString(kctx, resultArray, s + (p->rm_so), ((p->rm_eo) - (p->rm_so)), stringPolicy); } if(isGlobalOption) { size_t eo = pmatch[0].rm_eo; // shift matched pattern s += (eo > 0) ? eo : 1; if(!(s < eos)) isGlobalOption = 0; // stop iteration } } while(isGlobalOption); } }
// String Tagger.parse(String input) static KMETHOD Tagger_Parse(KonohaContext *kctx, KonohaStack *sfp) { mecab_t * mecab = ((struct _kTagger *)(sfp[0].asObject))->mecab; const char *input = S_text(sfp[1].asString); const char* result = mecab_sparse_tostr(mecab, input); KReturn(KLIB new_kString(kctx, GcUnsafe, result, strlen(result), 0)); }
//## Expr Stmt.printError(String msg); static KMETHOD Stmt_Message2rintError(KonohaContext *kctx, KonohaStack *sfp) { kStmt *stmt = sfp[0].asStmt; kString *msg = sfp[1].asString; SUGAR kStmt_Message2(kctx, stmt, NULL, ErrTag, "%s", S_text(msg)); KReturn(K_NULLEXPR); }
//## Expr Stmt.message(int error, Expr expr, String msg); static KMETHOD StmtExpr_Message(KonohaContext *kctx, KonohaStack *sfp) { kStmt *stmt = sfp[0].asStmt; kinfotag_t level = (kinfotag_t)sfp[1].intValue; kString *msg = sfp[3].asString; KReturn(SUGAR kStmt_Message2(kctx, stmt, sfp[2].asToken, level, "%s", S_text(msg))); }
//## JSONFloat JSON.getFloat(String key); static KMETHOD kJSON_getFloat(KonohaContext *kctx, KonohaStack *sfp) { JSON obj = ((kJSON *)sfp[0].asObject)->json; const char *key = S_text(sfp[1].asString); double json = JSON_getDouble(obj, key); KReturnFloatValue(json); }
// boolean NameSpace.hate(String symbol); static KMETHOD NameSpace_hate(KonohaContext *kctx, KonohaStack *sfp) { kString *key = sfp[2].asString; ksymbol_t keyword = ksymbolA(S_text(key), S_size(key), _NEWID); KMakeTrace(trace, sfp); kNameSpace_RemoveSyntax(kctx, sfp[0].asNameSpace, keyword, trace); }
//## int Token.error(String s, String s, int begin, int end); static KMETHOD Token_error(KonohaContext *kctx, KonohaStack *sfp) { kTokenVar *tk = (kTokenVar *) sfp[0].asToken; if(IS_NOTNULL(tk)) { SUGAR kToken_ToError(kctx, tk, ErrTag, "%s", S_text(sfp[1].asString)); } KReturnUnboxValue(sfp[4].intValue); }
// String Tagger.NBestParse(int n, String input) static KMETHOD Tagger_NBestParse(KonohaContext *kctx, KonohaStack *sfp) { struct _kTagger *mecab = (struct _kTagger *)sfp[0].asObject; kint_t ival = sfp[1].intValue; const char *input = S_text(sfp[2].asString); const char* result = mecab_nbest_sparse_tostr(mecab->mecab, ival, input); KReturn(KLIB new_kString(kctx, GcUnsafe, result, strlen(result), 0)); }
//## LogPool LogPool.new(String host, int port) static KMETHOD LogPool_new(KonohaContext *kctx, KonohaStack *sfp) { kRawPtr *ret = (kRawPtr *) sfp[0].asObject; char *host = (char *) S_text(sfp[1].asString); int port = sfp[2].intValue; RawPtr_init(kctx, sfp[0].asObject, logpool_open_client(NULL, host, port)); RETURN_(ret); }
static void RegExp_p(KonohaContext *kctx, KonohaValue *v, int pos, KGrowingBuffer *wb) { kRegExp *re = v[pos].asRegExp; KLIB Kwb_printf(kctx, wb, "/%s/%s%s%s", S_text(re->pattern), RegExp_isGlobal(re) ? "g" : "", RegExp_isIgnoreCase(re) ? "i" : "", RegExp_isMultiline(re) ? "m" : ""); }