static bool String_equal(KonohaContext *kctx, kString *str0, kString *str1) { if(kString_size(str0) == kString_size(str1)) { return strncmp(kString_text(str0), kString_text(str1), kString_size(str0)) == 0; } return false; }
//## boolean NameSpace.DefineMacro(String symbol, int param, String source); static KMETHOD NameSpace_DefineMacro(KonohaContext *kctx, KonohaStack *sfp) { ksymbol_t keyword = KAsciiSymbol(kString_text(sfp[1].asString), kString_size(sfp[1].asString), _NEWID); int paramsize = (int)sfp[2].intValue; kString *source = sfp[3].asString; KReturnUnboxValue(SUGAR SetMacroData(kctx, sfp[0].asNameSpace, keyword, paramsize, kString_text(source), true)); }
/* copied from src/sugar/sugarfunc.h */ static kString *kToken_ResolveEscapeSequence(KonohaContext *kctx, kToken *tk, size_t start) { KBuffer wb; KLIB KBuffer_Init(&(kctx->stack->cwb), &wb); const char *text = kString_text(tk->text) + start; const char *end = kString_text(tk->text) + kString_size(tk->text); KLIB KBuffer_Write(kctx, &wb, kString_text(tk->text), start); while(text < end) { int ch = *text; if(ch == '\\' && *(text+1) != '\0') { switch (*(text+1)) { /* * compatible with ECMA-262 * http://ecma-international.org/ecma-262/5.1/#sec-7.8.4 */ case 'b': ch = '\b'; text++; break; case 't': ch = '\t'; text++; break; case 'n': ch = '\n'; text++; break; case 'v': ch = '\v'; text++; break; case 'f': ch = '\f'; text++; break; case 'r': ch = '\r'; text++; break; case '"': ch = '"'; text++; break; case '\'': ch = '\''; text++; break; case '\\': ch = '\\'; text++; break; default: return NULL; } } { char buf[1] = {ch}; KLIB KBuffer_Write(kctx, &wb, (const char *)buf, 1); } text++; } return KLIB KBuffer_Stringfy(kctx, &wb, OnGcStack, StringPolicy_FreeKBuffer); }
//## FILE FILE.new(String path, String mode); static KMETHOD File_new(KonohaContext *kctx, KonohaStack *sfp) { KMakeTrace(trace, sfp); char buffer[K_PATHMAX]; kString *path = sfp[1].asString; const char *systemPath = I18NAPI formatSystemPath(kctx, buffer, sizeof(buffer), kString_text(path), kString_size(path), trace); const char *mode = kString_text(sfp[2].asString); FILE *fp = fopen(systemPath, mode); kFile *file = (kFile *) sfp[0].asObject; if(fp == NULL) { int fault = KLIB DiagnosisFaultType(kctx, kString_GuessUserFault(path)|SystemError, trace); KTraceErrorPoint(trace, fault, "fopen", LogText("filename", kString_text(path)), LogText("mode", mode), LogErrno); KLIB KRuntime_raise(kctx, KException_("IO"), fault, NULL, sfp); } if(mode[0] == 'w' || mode[0] == 'a' || mode[1] == '+') { KTraceChangeSystemPoint(trace, "fopen", LogFileName(kString_text(path)), LogText("mode", mode)); } file->fp = fp; KFieldInit(file, file->PathInfoNULL, path); if(!I18NAPI isSystemCharsetUTF8(kctx)) { if(mode[0] == 'w' || mode[0] == 'a' || mode[1] == '+') { file->writerIconv = I18NAPI iconvUTF8ToSystemCharset(kctx, trace); } else { file->readerIconv = I18NAPI iconvSystemCharsetToUTF8(kctx, trace); } } KReturn(file); }
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(kString_text(s), "abcd") == 0); assert(kString_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(kString_text(s), "abcd") == 0); assert(kString_size(s) == 4); assert(kString_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(kString_text(s), text) == 0); assert(kString_size(s) == 20); assert(kString_text(s) == text); assert(kString_Is(ASCII, s) == 0); } }
//## @Native String XmlReader.getAttributeNs(String ns, String name); static KMETHOD XmlReader_getAttributeNs(KonohaContext *kctx, KonohaStack *sfp) { xmlTextReaderPtr reader = getRawXmlReader(sfp[0]); xmlChar* ns = (xmlChar *)kString_text(sfp[1].asString); xmlChar* name = (xmlChar *)kString_text(sfp[2].asString); char* ret = (reader != NULL) ? (char *) xmlTextReaderGetAttributeNs(reader,ns,name) : NULL; KReturn(KLIB new_kString(kctx, GcUnsafe, ret, strlen(ret), 0)); }
// ## void AprTable.set(String key, String val) static KMETHOD AprTable_Set(KonohaContext *kctx, KonohaStack *sfp) { kAprTable *self = (kAprTable *) sfp[0].asObject; const char *key = kString_text(sfp[1].asString); const char *val = kString_text(sfp[2].asString); apr_table_set(self->tbl, key, val); KReturnVoid(); }
static kString *remove_escapes(KonohaContext *kctx, kToken *tk) { kString *text = tk->text; if(kToken_Is(RequiredReformat, tk)) { const char *escape = strchr(kString_text(text), '\\'); DBG_ASSERT(escape != NULL); text = kToken_ResolveEscapeSequence(kctx, tk, escape - kString_text(text)); } return text; }
//## 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, kString_text(kctx->esp[-1].asString)); 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].asObject)->self; Py_INCREF(pValue); PyTuple_SetItem(pArgs, i, pValue); } pValue = PyObject_CallObject(pFunc, pArgs); } } Py_XDECREF(pFunc); Py_XDECREF(pArgs); KReturnPyObject(pValue); }
// ##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, kString_text(enc)); KReturnVoid(); }
// ## 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, kString_text(type)); KReturnVoid(); }
//## 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}; KBuffer wb; KLIB KBuffer_Init(&(kctx->stack->cwb), &wb); KLIB KBuffer_Write(kctx, &wb, kString_text(dir->PathInfoNULL), kString_size(dir->PathInfoNULL)); KLIB KBuffer_Write(kctx, &wb, delim, 1); if(dir->readerIconv != ICONV_NULL) { KLIB KBuffer_Write(kctx, &wb, d_name, strlen(d_name)); } else { KLIB KBuffer_iconv(kctx, &wb, dir->readerIconv, d_name, strlen(d_name), trace); } KReturn(KLIB KBuffer_Stringfy(kctx, &wb, OnStack, StringPolicy_FreeKBuffer)); } 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 I18NModule.formatSystemPath(kctx, buffer, sizeof(buffer), kString_text(path), kString_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(kString_text(path)), LogErrno); } else { KTraceChangeSystemPoint(trace, "rmdir", LogFileName(kString_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 I18NModule.formatSystemPath(kctx, buffer, sizeof(buffer), kString_text(path), kString_size(path), trace); mode_t mode = (mode_t)sfp[2].intValue; int ret = mkdir(systemPath, mode); if(ret == -1) { KTraceErrorPoint(trace, SystemFault, "mkdir", LogFileName(kString_text(path)), LogMode(mode), LogErrno); } else { KTraceChangeSystemPoint(trace, "mkdir", LogFileName(kString_text(path)), LogMode(mode)); } KReturnUnboxValue(ret != -1); }
//## @Native String XmlReader.lookupNameSpace(String ns); static KMETHOD XmlReader_lookupNameSpace(KonohaContext *kctx, KonohaStack *sfp) { xmlTextReaderPtr reader = getRawXmlReader(sfp[0]); xmlChar* ns = (xmlChar *)kString_text(sfp[1].asString); char* ret = (reader != NULL) ? (char *) xmlTextReaderLookupNamespace(reader,ns) : NULL; KReturn(KLIB new_kString(kctx, GcUnsafe, ret, strlen(ret), 0)); }
static KMETHOD TypeCheck_ExtendedIntLiteral(KonohaContext *kctx, KonohaStack *sfp) { VAR_TypeCheck(expr, gma, reqty); kToken *tk = expr->TermToken; long long n = kstrtoll(kString_text(tk->text)); KReturn(SUGAR kNode_SetUnboxConst(kctx, expr, KType_Int, (uintptr_t)n)); }
// 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 = kString_text(sfp[1].asString); const char* result = mecab_sparse_tostr(mecab, input); KReturn(KLIB new_kString(kctx, GcUnsafe, result, strlen(result), 0)); }
// ## 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(kString_text(data), self->r); KReturnVoid(); }
//## void File.print(String line); static KMETHOD File_print(KonohaContext *kctx, KonohaStack *sfp) { kFile *file = sfp[0].asFile; kString *line = sfp[1].asString; KMakeTrace(trace, sfp); if(file->writerIconv == ICONV_NULL || kString_Is(ASCII, line)) { TRACE_fwrite(kctx, file, kString_text(line), kString_size(line), trace); } else { KBuffer wb; KLIB KBuffer_Init(&(kctx->stack->cwb), &wb); KLIB KBuffer_iconv(kctx, &wb, file->writerIconv, kString_text(line), kString_size(line), trace); TRACE_fwrite(kctx, file, KLIB KBuffer_text(kctx, &wb, NonZero), KBuffer_bytesize(&wb), trace); KLIB KBuffer_Free(&wb); } }
// boolean NameSpace.hate(String symbol); static KMETHOD NameSpace_hate(KonohaContext *kctx, KonohaStack *sfp) { kString *key = sfp[2].asString; ksymbol_t keyword = KAsciiSymbol(kString_text(key), kString_size(key), _NEWID); KMakeTrace(trace, sfp); kNameSpace_RemoveSyntax(kctx, sfp[0].asNameSpace, keyword, trace); }
static void TEST_reportCaughtException(KonohaContext *kctx, kException *e, struct KonohaValueVar *bottomStack, struct KonohaValueVar *topStack) { int line = (topStack != NULL) ? (kuhalfword_t)topStack[K_RTNIDX].calledFileLine : 0; const char *exceptionName = KSymbol_text(e->symbol); PLATAPI printf_i("LINE%d: %s\n", line, exceptionName); fprintf(stdout, "LINE %d: %s %s\n", line, exceptionName, kString_text(e->Message)); }
static void UI_ReportCaughtException(KonohaContext *kctx, kException *e, KonohaStack *bottomStack, KonohaStack *topStack) { const char *exceptionName; const char *optionalMessage; int fault; KonohaStack *sfp; KBuffer wb; DBG_ASSERT(IS_Exception(e)); exceptionName = KSymbol_text(e->symbol); optionalMessage = kString_text(e->Message); fault = e->fault; PLATAPI printf_i("%s", BeginTag(kctx, ErrTag)); if(optionalMessage != NULL && optionalMessage[0] != 0) { PLATAPI printf_i("%s: SoftwareFault %s", exceptionName, optionalMessage); } else { PLATAPI printf_i("%s:", exceptionName); if(KFlag_Is(int, fault, SoftwareFault)) { PLATAPI printf_i(" SoftwareFault"); } if(KFlag_Is(int, fault, UserFault)) { PLATAPI printf_i(" UserFault"); }
static KMETHOD TypeCheck_Float(KonohaContext *kctx, KonohaStack *sfp) { VAR_TypeCheck2(stmt, expr, ns, reqc); kToken *tk = expr->TermToken; sfp[4].floatValue = strtod(kString_text(tk->text), NULL); // just using tramsformation float KReturn(SUGAR kNode_SetUnboxConst(kctx, expr, KType_float, sfp[4].unboxValue)); }
//## Node Node.message(int error, Token tk, String msg); static KMETHOD NodeToken_Message(KonohaContext *kctx, KonohaStack *sfp) { kNode *stmt = sfp[0].asNode; kinfotag_t level = (kinfotag_t)sfp[1].intValue; kString *msg = sfp[3].asString; KReturn(SUGAR MessageNode(kctx, stmt, sfp[2].asToken, kNode_ns(stmt), level, "%s", kString_text(msg))); }
//## Node Node.message(int error, String msg); static KMETHOD Node_Message(KonohaContext *kctx, KonohaStack *sfp) { kNode *node = sfp[0].asNode; kinfotag_t level = (kinfotag_t)sfp[1].intValue; kString *msg = sfp[2].asString; KReturn(SUGAR MessageNode(kctx, node, NULL, kNode_ns(node), level, "%s", kString_text(msg))); }
static KMETHOD TypeCheck_Getter(KonohaContext *kctx, KonohaStack *sfp) { VAR_TypeCheck2(stmt, expr, ns, reqc); kToken *fieldToken = expr->NodeList->TokenItems[0]; ksymbol_t fn = fieldToken->symbol; kNode *self = KLIB TypeCheckNodeAt(kctx, expr, 1, ns, KClass_INFER, 0); if(self != K_NULLNODE) { kMethod *mtd = KLIB kNameSpace_GetGetterMethodNULL(kctx, ns, KClass_(self->typeAttr), fn); if(mtd != NULL) { KFieldSet(expr->NodeList, expr->NodeList->MethodItems[0], mtd); KReturn(KLIB TypeCheckMethodParam(kctx, mtd, expr, ns, reqc)); } else { // dynamic field o.name => o.get(name) kparamtype_t p[1] = {{KType_Symbol}}; kparamId_t paramdom = KLIB Kparamdom(kctx, 1, p); mtd = KLIB kNameSpace_GetMethodBySignatureNULL(kctx, ns, KClass_(self->typeAttr), KMethodNameAttr_Getter, paramdom, 1, p); if(mtd != NULL) { KFieldSet(expr->NodeList, expr->NodeList->MethodItems[0], mtd); KLIB kArray_Add(kctx, expr->NodeList, new_UnboxConstNode(kctx, ns, KType_Symbol, KSymbol_Unmask(fn))); KReturn(KLIB TypeCheckMethodParam(kctx, mtd, expr, ns, reqc)); } } KLIB MessageNode(kctx, stmt, fieldToken, ns, ErrTag, "undefined field: %s", kString_text(fieldToken->text)); } }
static KMETHOD System_symlink(KonohaContext *kctx, KonohaStack *sfp) { char buffer[K_PATHMAX], buffer2[K_PATHMAX]; kString *path = sfp[1].asString, *path2 = sfp[2].asString; KMakeTrace(trace, sfp); const char *oldpath = PLATAPI I18NModule.formatSystemPath(kctx, buffer, sizeof(buffer), kString_text(path), kString_size(path), trace); const char *newpath = PLATAPI I18NModule.formatSystemPath(kctx, buffer2, sizeof(buffer2), kString_text(path2), kString_size(path2), trace); int ret = symlink(oldpath, newpath); if(ret == -1) { int fault = KLIB DiagnosisFaultType(kctx, kString_GuessUserFault(path)|kString_GuessUserFault(path2)|SystemError, trace); KTraceErrorPoint(trace, fault, "symlink", LogFileName(kString_text(path)), LogFileName2(kString_text(path2)), LogErrno); } else { KTraceChangeSystemPoint(trace, "symlink", LogFileName(kString_text(path)), LogFileName2(kString_text(path2)), LogErrno); } KReturnUnboxValue(ret != -1); }
//## void Curl.appendHeader(String headers); static KMETHOD Curl_appendHeader(KonohaContext *kctx, KonohaStack *sfp) { kCurl* kcurl = (kCurl *)sfp[0].asObject; const char *h = kString_text(sfp[1].asString); kcurl->headers = curl_slist_append(kcurl->headers, h); KReturnVoid(); }
// 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 = kString_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)); }
//## String System.getenv(String name) static KMETHOD System_getenv(KonohaContext *kctx, KonohaStack *sfp) { const char *name = kString_text(sfp[1].asString); char *ret = getenv(name); if(ret == NULL) { KReturn(KNULL(String)); } KReturn(KLIB new_kString(kctx, OnStack, ret, strlen(ret), 0)); }