static void knh_write_Method(CTX ctx, knh_OutputStream_t *w, const knh_ClassTBL_t *ct, knh_Method_t *o) { knh_write_TAB(ctx, w); if(Method_isAbstract(o)) { knh_write_ascii(ctx, w, "@Abstract "); } knh_write_type(ctx, w, knh_type_tocid(ctx, knh_ParamArray_rtype(DP(o)->mp), ct->cid)); knh_putc(ctx, w, ' '); if(Method_isStatic(o)) { knh_write_ascii(ctx, w, S_tochar(ct->sname)); knh_putc(ctx, w, '.'); } knh_write_mn(ctx, w, SP(o)->mn); knh_putc(ctx, w, '('); size_t i; for(i = 0; i < knh_Method_psize(o); i++) { knh_param_t *p = knh_ParamArray_get(DP(o)->mp, i); if(i > 0) { knh_write_delim(ctx, w); } knh_write_type(ctx, w, knh_type_tocid(ctx, p->type, ct->cid)); knh_putc(ctx, w, ' '); knh_write_ascii(ctx, w, FN__(p->fn)); } if(ParamArray_isVARGs(DP(o)->mp)) { knh_write_delim(ctx, w); knh_write_dots(ctx, w); } knh_putc(ctx, w, ')'); knh_write_EOL(ctx, w); }
void knh_vprintf(Ctx *ctx, knh_OutputStream_t *w, const char *fmt, va_list ap) { knh_valist_t args[10]; const char *c = fmt; int i, ch, bindex = 0, bindex_max = 10; for(i = 0; i < bindex_max; i++) args[i].atype = 0; while((ch = *c) != '\0') { c++; if(ch == '%') { int index; ch = *c; if(ch == '%') { c++; continue; } index = bindex++; c = knh_vprintf_parseindex(c++, &index); //DBG_P("bindex=%d, index=%d", bindex, index); switch(ch) { case 'd': case 'u': args[index].atype = VA_DIGIT; break; case 'l': case 'i': args[index].atype = VA_LONG; break; case 'f': case 'e': args[index].atype = VA_FLOAT; break; case 's': args[index].atype = VA_CHAR; break; case 'p': args[index].atype = VA_POINTER; break; case 'L': case 'K': case 'k': case 'O': case 'o': args[index].atype = VA_OBJECT; break; case 'N': case 'F': args[index].atype = VA_FIELDN; break; case 'M': args[index].atype = VA_METHODN; break; case 'C': args[index].atype = VA_CLASS; break; case 'T': args[index].atype = VA_TYPE; break; case 'B': args[index].atype = VA_BYTES; break; // TODO // we should care if "fmt" has "%%". // sometimes, next args is NULL. case '%': index--; c++; default: bindex--; } if(bindex == 10) { DBG_ASSERT(bindex < 10); break; } } } for(i = 0; i < 10; i++) { switch(args[i].atype) { case VA_DIGIT: args[i].dvalue = (knh_intptr_t)va_arg(ap, knh_intptr_t); break; case VA_LONG: args[i].ivalue = (knh_int_t)va_arg(ap, knh_int_t); break; case VA_FLOAT: #if defined(K_USING_NOFLOAT) args[i].fvalue = (knh_float_t)va_arg(ap, knh_float_t); #else args[i].fvalue = (knh_float_t)va_arg(ap, double); #endif break; case VA_CHAR: args[i].svalue = (char*)va_arg(ap, char*); break; case VA_POINTER: args[i].pvalue = (void*)va_arg(ap, void*); break; case VA_OBJECT: args[i].ovalue = (Object*)va_arg(ap, Object*); break; case VA_FIELDN: args[i].fn = (knh_fieldn_t)va_arg(ap, int/*knh_fieldn_t*/); break; case VA_METHODN: args[i].mn = (knh_methodn_t)va_arg(ap, int/*knh_methodn_t*/); break; case VA_CLASS: args[i].cid = (knh_class_t)va_arg(ap, int/*knh_class_t*/); break; case VA_TYPE: args[i].type = (knh_type_t)va_arg(ap, int/*knh_type_t*/); break; case VA_BYTES: args[i].bvalue = (knh_bytes_t)va_arg(ap, knh_bytes_t); break; default: bindex_max = i; goto L_FORMAT; } } L_FORMAT: { knh_bytes_t b; knh_Method_t *mtd = NULL; knh_sfp_t *esp = ctx->esp; c = fmt; bindex = 0; b.text = c; b.len = 0; while((ch = *c) != '\0') { c++; if(ch == '\\') { if(b.len > 0) { knh_print(ctx, w, b); } ch = *c; switch(ch) { case '\0' : return ; case 'n': knh_println(ctx, w, STEXT("")); break; case 't': knh_write_TAB(ctx, w); break; default: knh_putc(ctx, w, '\\'); knh_putc(ctx, w, ch); } b.text = c; b.len = 0; } else if(ch == '%') { if(b.len > 0) { knh_print(ctx, w, b); } ch = *c; if(ch == '%') { knh_putc(ctx, w, '%'); c++; b.text = c; b.len = 0; continue; } int index = bindex++; c = knh_vprintf_parseindex(++c, &index); switch(ch) { case '\0' : return ; case 'd': DBG_ASSERT(args[index].atype == VA_DIGIT); knh_write_dfmt(ctx, w, K_INTPTR_FMT, args[index].dvalue); break; case 'u': DBG_ASSERT(args[index].atype == VA_DIGIT); knh_write_dfmt(ctx, w, K_INTPTR_UFMT, args[index].uvalue); break; case 'l': case 'i' : DBG_ASSERT(args[index].atype == VA_LONG); knh_write_ifmt(ctx, w, K_INT_FMT, args[index].ivalue); break; case 'f': DBG_ASSERT(args[index].atype == VA_FLOAT); knh_write_ffmt(ctx, w, K_FLOAT_FMT, args[index].fvalue); break; case 'e': DBG_ASSERT(args[index].atype == VA_FLOAT); knh_write_ffmt(ctx, w, K_FLOAT_FMTE, args[index].fvalue); break; case 's': DBG_ASSERT(args[index].atype == VA_CHAR); knh_write(ctx, w, B(args[index].svalue)); break; case 'p': DBG_ASSERT(args[index].atype == VA_POINTER); knh_write__p(ctx, w, args[index].pvalue); break; case 'L': DBG_ASSERT(args[index].atype == VA_OBJECT); if(IS_Token(args[index].ovalue)) { knh_write_token(ctx, w, (knh_Token_t*)args[index].ovalue); break; } case 'O': case 'o': DBG_ASSERT(args[index].atype == VA_OBJECT); mtd = knh_getSystemFormatter(ctx, knh_Object_cid(args[index].ovalue), MN__s); knh_write_Object(ctx, w, esp, &mtd, args[index].ovalue); break; case 'K': case 'k': DBG_ASSERT(args[index].atype == VA_OBJECT); mtd = knh_getSystemFormatter(ctx, knh_Object_cid(args[index].ovalue), MN__k); knh_write_Object(ctx, w, esp, &mtd, args[index].ovalue); break; case 'N': case 'F': DBG_ASSERT(args[index].atype == VA_FIELDN); knh_write_text(ctx, w, FN__(args[index].fn)); break; case 'M': DBG_ASSERT(args[index].atype == VA_METHODN); knh_write_mn(ctx, w, args[index].mn); break; case 'C': DBG_ASSERT(args[index].atype == VA_CLASS); knh_write_sname(ctx, w, args[index].cid); break; case 'T': DBG_ASSERT(args[index].atype == VA_TYPE); knh_write_type(ctx, w, args[index].type); break; case 'B': DBG_ASSERT(args[index].atype == VA_BYTES); knh_write(ctx,w, args[index].bvalue); break; case '%': index--; bindex--; default: //knh_putc(ctx, w, '%'); knh_putc(ctx, w, ch); } b.text = c; b.len = 0; if(!(bindex <= bindex_max)) { DBG_ASSERT(bindex <= bindex_max); break; } } else { b.len = b.len+1; } } if(b.len > 0) { knh_print(ctx, w, b); } } }