//## 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)); }
//## String Curl.receiveString(); static KMETHOD Curl_receiveString(KonohaContext *kctx, KonohaStack *sfp) { kCurl* kcurl = (kCurl *)sfp[0].asObject; /* presets */ struct ReceiveBuffer rbuf = {0}; rbuf.kctx = kctx; KLIB KBuffer_Init(&(kctx->stack->cwb), &rbuf.wb); curl_easy_setopt(kcurl->curl, CURLOPT_WRITEFUNCTION, writeToBuffer); curl_easy_setopt(kcurl->curl, CURLOPT_WRITEDATA, &rbuf); /* perform */ KMakeTrace(trace, sfp); CURLcode res; if(kcurl->headers != NULL) { curl_easy_setopt(kcurl->curl, CURLOPT_HTTPHEADER, kcurl->headers); } KTraceResponseCheckPoint(trace, 0, "curl_easy_perform", res = curl_easy_perform(kcurl->curl) ); if(res != CURLE_OK) { int fault = diagnosisCurlFaultType(kctx, res, (kcurl->URLInfoNULL == NULL) ? 0 : kString_GuessUserFault(kcurl->URLInfoNULL)); KTraceErrorPoint(trace, fault, "curl_easy_perform", LogURL(kcurl), LogCurlStrError(res)); } KReturn(KLIB KBuffer_Stringfy(rbuf.kctx, &rbuf.wb, OnStack, StringPolicy_FreeKBuffer)); }
//## String DIR.readFileName() static KMETHOD DIR_readFileName(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; if(dir->readerIconv == ICONV_NULL) { KReturn(KLIB new_kString(kctx, OnStack, d_name, strlen(d_name), StringPolicy_SystemInfo)); } else { KBuffer wb; KLIB KBuffer_Init(&(kctx->stack->cwb), &wb); 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)); }
/* 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); }
//## String String.new(Bytes ba); static KMETHOD String_new_fromBytes_withDefaultDecode(KonohaContext *kctx, KonohaStack *sfp) { kBytes *ba = sfp[1].asBytes; kString *s = TS_EMPTY; if(ba->bytesize != 0) { KMakeTrace(trace, sfp); KBuffer wb; KLIB KBuffer_Init(&(kctx->stack->cwb), &wb); KBuffer_convertCharset(kctx, &wb, "UTF-8", I18NAPI systemCharset, ba->buf, ba->bytesize, trace); KLIB KBuffer_text(kctx, &wb, EnsureZero); /* String must be Null terminated */ s = KLIB KBuffer_Stringfy(kctx, &wb, OnStack, StringPolicy_FreeKBuffer); } KReturn(s); }
//## String File.readLine(); static KMETHOD File_readLine(KonohaContext *kctx, KonohaStack *sfp) { kFile *file = (kFile *)sfp[0].asObject; if(file->fp != NULL) { KBuffer wb; KLIB KBuffer_Init(&(kctx->stack->cwb), &wb); int ch, pos = 0, hasUTF8 = false, bufferCount = 0, policy = StringPolicy_ASCII; char buffer[K_PAGESIZE]; KMakeTrace(trace, sfp); while((ch = TRACE_fgetc(kctx, file, trace)) != EOF) { //DBG_P("ch='%c', pos=%d", ch, pos); if(ch == '\r') continue; if(ch == '\n') { if(bufferCount == 0 && (!hasUTF8 || file->readerIconv == ICONV_NULL)) { KReturn(KLIB new_kString(kctx, OnStack, buffer, pos, policy)); } break; } if(ch > 127) { hasUTF8 = true; policy = StringPolicy_UTF8; } buffer[pos] = ch; pos++; if(!(pos < K_PAGESIZE)) { if(hasUTF8 && file->readerIconv != ICONV_NULL) { KLIB KBuffer_iconv(kctx, &wb, file->readerIconv, buffer, pos, trace); } else { KLIB KBuffer_Write(kctx, &wb, buffer, pos); } bufferCount++; hasUTF8 = false; pos = 0; } } if(pos > 0) { if(hasUTF8 && file->readerIconv != ICONV_NULL) { KLIB KBuffer_iconv(kctx, &wb, file->readerIconv, buffer, pos, trace); } else { KLIB KBuffer_Write(kctx, &wb, buffer, pos); } } kFile_CheckEOF(kctx, file, trace); KReturn(KLIB KBuffer_Stringfy(kctx, &wb, OnStack, policy | StringPolicy_FreeKBuffer)); } else { KReturn(KNULL(String)); } }
//## @Public @Const @Immutable @Coercion String Symbol.toString(); static KMETHOD KSymbol_toString(KonohaContext *kctx, KonohaStack *sfp) { ksymbol_t symbol = (ksymbol_t)sfp[0].intValue; kString *s = KSymbol_GetString(kctx, KSymbol_Unmask(symbol)); if(KSymbol_Attr(symbol) != 0) { KBuffer wb; const char *prefix = KSymbol_prefixText(symbol); KLIB KBuffer_Init(&(kctx->stack->cwb), &wb); KLIB KBuffer_Write(kctx, &wb, prefix, strlen(prefix)); KLIB KBuffer_Write(kctx, &wb, kString_text(s), kString_size(s)); s = KLIB KBuffer_Stringfy(kctx, &wb, OnStack, StringPolicy_FreeKBuffer); } KReturn(s); }
//## String String.new(Bytes ba, String charset); static KMETHOD String_new_fromBytes_withSpecifiedDecode(KonohaContext *kctx, KonohaStack *sfp) { kBytes *ba = sfp[1].asBytes; kString *charset = sfp[2].asString; kString *s = TS_EMPTY; if(ba->bytesize != 0) { // At this point, we assuem 'ba' is null terminated. DBG_ASSERT(ba->buf[ba->bytesize] == '\0'); KMakeTrace(trace, sfp); KBuffer wb; KLIB KBuffer_Init(&(kctx->stack->cwb), &wb); KBuffer_convertCharset(kctx, &wb, kString_text(charset), "UTF-8", ba->buf, ba->bytesize, trace); s = KLIB KBuffer_Stringfy(kctx, &wb, OnStack, StringPolicy_FreeKBuffer); } KReturn(s); }
static KMETHOD Statement_import(KonohaContext *kctx, KonohaStack *sfp) { int ret = false; VAR_Statement(stmt, gma); kTokenArray *tokenList = (kTokenArray *) kStmt_GetObjectNULL(kctx, stmt, KW_TokenPattern); if(tokenList == NULL) { KReturnUnboxValue(false); } kNameSpace *ns = Stmt_ns(stmt); SugarSyntaxVar *syn = (SugarSyntaxVar *) SYN_(ns, KW_ExprMethodCall); kExpr *expr; kTokenVar *tkImport = /*G*/new_(TokenVar, 0, OnGcStack); tkImport->resolvedSymbol = MN_("import"); if(IS_Token(tokenList)) { kTokenArray *list = ((kToken *) tokenList)->subTokenList; if(IS_String(list)) { /* case: import cstyle; */ kString *pkgname = (kString *) list; expr = CreateImportCall(kctx, syn, tkImport, ns, pkgname); } else if(kArray_size(list) == 1) { /* case : import("konoha.import"); */ kExpr *param0 = makeStringConstValue(kctx, list->TokenItems[0]->text); expr = SUGAR new_UntypedCallStyleExpr(kctx, syn, 3, tkImport, new_ConstValueExpr(kctx, O_ct(ns), UPCAST(ns)), param0); } else if(kArray_size(list) == 2) { /* case : import("konoha.import", "import"); */ kExpr *param0 = makeStringConstValue(kctx, list->TokenItems[0]->text); kExpr *param1 = makeStringConstValue(kctx, list->TokenItems[1]->text); expr = SUGAR new_UntypedCallStyleExpr(kctx, syn, 4, tkImport, new_ConstValueExpr(kctx, O_ct(ns), UPCAST(ns)), param0, param1); } else { KReturnUnboxValue(false); } } else { KGrowingBuffer wb; KLIB KBuffer_Init(&(kctx->stack->cwb), &wb); /* case : import konoha.import */ ksymbol_t star = SYM_("*"); size_t i = 0; if(i + 2 < kArray_size(tokenList)) { for (; i < kArray_size(tokenList)-1; i+=2) { /* name . */ kToken *tk = tokenList->TokenItems[i+0]; if(i+2 < kArray_size(tokenList)) { kToken *startTk = tokenList->TokenItems[i+2]; if(startTk->resolvedSyntaxInfo->keyword == star) { break; } } KLIB KBuffer_Write(kctx, &wb, S_text(tk->text), S_size(tk->text)); KLIB KBuffer_Write(kctx, &wb, ".", 1); } } kString *name = tokenList->TokenItems[i]->text; KLIB KBuffer_Write(kctx, &wb, S_text(name), S_size(name)); kString *pkgname = KLIB new_kString(kctx, OnGcStack, KLIB KBuffer_Stringfy(kctx, &wb, 1), KBuffer_bytesize(&wb), 0); expr = CreateImportCall(kctx, syn, tkImport, ns, pkgname); } KLIB kObjectProto_SetObject(kctx, stmt, KW_ExprPattern, TY_Expr, expr); ret = SUGAR kStmt_TypeCheckByName(kctx, stmt, KW_ExprPattern, gma, CT_void, TypeCheckPolicy_ALLOWVOID); if(ret) { kStmt_typed(stmt, EXPR); } KReturnUnboxValue(ret); }