static void Kwb_writeRegexFormat(KonohaContext *kctx, KGrowingBuffer *wb, const char *fmttext, size_t fmtlen, const char *base, kregmatch_t *r, size_t matched) { const char *ch = fmttext; const char *eof = ch + fmtlen; // end of fmt char buf[1]; for (; ch < eof; ch++) { if(*ch == '\\') { buf[0] = *ch; KLIB Kwb_write(kctx, wb, buf, 1); ch++; } else if(*ch == '$' && isdigit(ch[1])) { size_t grpidx = (size_t)ch[1] - '0'; // get head of grourp_index if(grpidx < matched) { ch++; while(isdigit(ch[1])) { size_t nidx = grpidx * 10 + (ch[1] - '0'); if(nidx < matched) { grpidx = nidx; ch++; if(ch < eof) { continue; } } } kregmatch_t *rp = &r[grpidx]; KLIB Kwb_write(kctx, wb, base + rp->rm_so, rp->rm_eo - rp->rm_so); continue; // skip putc } } buf[0] = *ch; KLIB Kwb_write(kctx, wb, buf, 1); } }
//## @Const method String String.replace(RegExp searchvalue, String newvalue); static KMETHOD String_replace(KonohaContext *kctx, KonohaStack *sfp) { kString *s0 = sfp[0].asString; kRegExp *re = sfp[1].asRegExp; const char* fmttext = S_text(sfp[2].asString); size_t fmtlen = S_size(sfp[2].asString); kString *s = s0; if(IS_NOTNULL(re) && S_size(re->pattern) > 0) { KGrowingBuffer wb; KLIB Kwb_Init(&(kctx->stack->cwb), &wb); const char *str = S_text(s0); // necessary const char *base = str; const char *eos = str + S_size(s0); // end of str kregmatch_t pmatch[KREGEXP_MATCHSIZE+1]; int isGlobalOption = RegExp_isGlobal(re); do { if(str >= eos) break; int res = pcre_regexec(kctx, re->reg, str, KREGEXP_MATCHSIZE, pmatch, re->eflags); if(res != 0) { // TODO //LOG_regex(kctx, sfp, res, re, str); break; } size_t len = pmatch[0].rm_eo; if(pmatch[0].rm_so > 0) { KLIB Kwb_write(kctx, &wb, str, pmatch[0].rm_so); } size_t matched = knh_regexp_Matched(pmatch, KREGEXP_MATCHSIZE); if(len > 0) { Kwb_writeRegexFormat(kctx, &wb, fmttext, fmtlen, base, pmatch, matched); str += len; } else { if(str == base) { // 0-length match at head of string Kwb_writeRegexFormat(kctx, &wb, fmttext, fmtlen, base, pmatch, matched); } break; } } while(isGlobalOption); KLIB Kwb_write(kctx, &wb, str, strlen(str)); // write out remaining string s = Kwb_newString(kctx, OnStack, &wb); // close cwb KLIB Kwb_Free(&wb); } KReturn(s); }
static void kMethod_writeToBuffer(KonohaContext *kctx, kMethod *mtd, KGrowingBuffer *wb) { kParam *pa = Method_param(mtd); Method_writeAttributeToBuffer(kctx, mtd, wb); KLIB Kwb_printf(kctx, wb, "%s %s.%s%s", TY_t(pa->rtype), TY_t(mtd->typeId), MethodName_t(mtd->mn)); { size_t i; KLIB Kwb_write(kctx, wb, "(", 1); for(i = 0; i < pa->psize; i++) { if(i > 0) { KLIB Kwb_write(kctx, wb, ", ", 2); } if(FN_isCOERCION(pa->paramtypeItems[i].fn)) { KLIB Kwb_printf(kctx, wb, "@Coercion "); } KLIB Kwb_printf(kctx, wb, "%s %s", TY_t(pa->paramtypeItems[i].ty), SYM_t(pa->paramtypeItems[i].fn)); } KLIB Kwb_write(kctx, wb, ")", 1); } }
static void DumpVisitor_init(KonohaContext *kctx, struct IRBuilder *builder, kMethod *mtd) { unsigned i; KGrowingBuffer wb; KLIB Kwb_init(&(kctx->stack->cwb), &wb); kParam *pa = Method_param(mtd); KLIB Kwb_printf(kctx, &wb, "METHOD %s%s(", T_mn(mtd->mn)); for (i = 0; i < pa->psize; i++) { if(i != 0) { KLIB Kwb_write(kctx, &wb, ", ", 2); } KLIB Kwb_printf(kctx, &wb, "%s %s", TY_t(pa->paramtypeItems[i].ty), SYM_t(pa->paramtypeItems[i].fn)); } emit_string(KLIB Kwb_top(kctx, &wb, 1), "", ") {", 0); builder->local_fields = (void *) KMalloc_UNTRACE(sizeof(int)); DUMPER(builder)->indent = 0; }