static int lessequal (lua_State *L, const TValue *l, const TValue *r) { int res; if (ttype(l) != ttype(r)) return luaG_ordererror(L, l, r); else if (ttisnumber(l)) return luai_numle(nvalue(l), nvalue(r)); else if (ttisstring(l)) return l_strcmp(rawtsvalue(l), rawtsvalue(r)) <= 0; else if ((res = call_orderTM(L, l, r, TM_LE)) != -1) /* first try `le' */ return res; else if ((res = call_orderTM(L, r, l, TM_LT)) != -1) /* else try `lt' */ return !res; return luaG_ordererror(L, l, r); }
static void PrintConstant(const Proto* f, int i) { const TValue* o=&f->k[i]; switch (ttype(o)) { case LUA_TNIL: printf("nil"); break; case LUA_TBOOLEAN: printf(bvalue(o) ? "true" : "false"); break; case LUA_TINT: printf(LUA_INTEGER_FMT,ivalue(o)); break; case LUA_TNUMBER: #ifdef LNUM_COMPLEX // TBD: Do we get complex values here? { lua_Number b= nvalue_img_fast(o); printf( LUA_NUMBER_FMT "%s" LUA_NUMBER_FMT "i", nvalue_fast(o), b>=0 ? "+":"", b ); } #endif printf(LUA_NUMBER_FMT,nvalue_fast(o)); break; case LUA_TSTRING: PrintString(rawtsvalue(o)); break; default: /* cannot happen */ printf("? type=%d",ttype(o)); break; } }
int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) { int res; if (ttype(l) != ttype(r)) return luaG_ordererror(L, l, r); else if (ttisnumber(l)) return luai_numlt(nvalue(l), nvalue(r)); else if (ttisstring(l)) return l_strcmp(rawtsvalue(l), rawtsvalue(r)) < 0; #if LUA_WIDESTRING else if (ttiswstring(l)) return l_wstrcmp(rawtwsvalue(l), rawtwsvalue(r)) < 0; #endif /* LUA_WIDESTRING */ else if ((res = call_orderTM(L, l, r, TM_LT)) != -1) return res; return luaG_ordererror(L, l, r); }
static void DumpConstants(const Proto* f, DumpState* D) { int i,n=f->sizek; DumpInt(n,D); for (i=0; i<n; i++) { const TValue* o=&f->k[i]; DumpChar(ttype(o),D); switch (ttype(o)) { case LUA_TNIL: break; case LUA_TBOOLEAN: DumpChar(bvalue(o),D); break; case LUA_TNUMBER: DumpNumber(nvalue(o),D); break; case LUA_TSTRING: DumpString(rawtsvalue(o),D); break; default: lua_assert(0); /* cannot happen */ break; } } n=f->sizep; DumpInt(n,D); for (i=0; i<n; i++) DumpFunction(f->p[i],f->source,D); }
static void DumpConstants(const ktap_proto *f, DumpState *D) { int i, n = f->sizek; DumpInt(n, D); for (i = 0; i < n; i++) { const ktap_value* o=&f->k[i]; DumpChar(ttypenv(o), D); switch (ttypenv(o)) { case KTAP_TNIL: break; case KTAP_TBOOLEAN: DumpChar(bvalue(o), D); break; case KTAP_TNUMBER: DumpNumber(nvalue(o), D); break; case KTAP_TSTRING: DumpString(rawtsvalue(o), D); break; default: printf("ktap: DumpConstants with unknown vaule type %d\n", ttypenv(o)); ktap_assert(0); } } n = f->sizep; DumpInt(n, D); for (i = 0; i < n; i++) DumpFunction(f->p[i], D); }
/* * main search function */ const Tvalue *kp_table_get(Table *t, const Tvalue *key) { switch (ttype(key)) { case KTAP_TNIL: return ktap_nilobject; case KTAP_TSHRSTR: return kp_table_getstr(t, rawtsvalue(key)); case KTAP_TNUMBER: { ktap_Number n = nvalue(key); int k = (int)n; if ((ktap_Number)k == nvalue(key)) /* index is int? */ return kp_table_getint(t, k); /* use specialized version */ /* else go through */ } default: { Node *n = mainposition(t, key); do { /* check whether `key' is somewhere in the chain */ if (rawequalobj(gkey(n), key)) return gval(n); /* that's it */ else n = gnext(n); } while (n); return ktap_nilobject; } } }
/* ** returns the `main' position of an element in a table (that is, the index ** of its hash value) ** ** Floating point numbers with integer value give the hash position of the ** integer (so they use the same table position). */ static Node *mainposition (const Table *t, const TValue *key) { switch (ttype(key)) { #ifdef LUA_TINT case LUA_TINT: return hashint(t,ivalue(key)); #endif case LUA_TNUMBER: { #ifdef LUA_TINT lua_Integer i; if (tt_integer_valued(key,&i)) return hashint(t, i); # ifdef LNUM_COMPLEX /* Complex numbers are hashed by their scalar part. Pure imaginary values * with scalar 0 or -0 should give same hash. */ if (nvalue_img_fast(key)!=0 && luai_numeq(nvalue_fast(key),0)) return gnode(t, 0); /* 0 and -0 to give same hash */ # endif #else if (luai_numeq(nvalue(key),0)) return gnode(t, 0); /* 0 and -0 to give same hash */ #endif return hashnum(t,nvalue_fast(key)); } case LUA_TSTRING: return hashstr(t, rawtsvalue(key)); case LUA_TBOOLEAN: return hashboolean(t, bvalue(key)); case LUA_TLIGHTUSERDATA: return hashpointer(t, pvalue(key)); default: return hashpointer(t, gcvalue(key)); } }
int debug_getsize(lua_State* L) { TValue* o = L->base; switch (o->tt) { /* Container types */ case LUA_TTABLE: { Table *h = hvalue(o); lua_pushinteger(L, sizeof(Table) + sizeof(TValue) * h->sizearray + sizeof(Node) * sizenode(h)); break; } case LUA_TFUNCTION: { Closure *cl = clvalue(o); lua_pushinteger(L, (cl->c.isC) ? sizeCclosure(cl->c.nupvalues) : sizeLclosure(cl->l.nupvalues)); break; } case LUA_TTHREAD: { lua_State *th = thvalue(o); lua_pushinteger(L, sizeof(lua_State) + sizeof(TValue) * th->stacksize + sizeof(CallInfo) * th->size_ci); break; } case LUA_TPROTO: { Proto *p = pvalue(o); lua_pushinteger(L, sizeof(Proto) + sizeof(Instruction) * p->sizecode + sizeof(Proto *) * p->sizep + sizeof(TValue) * p->sizek + sizeof(int) * p->sizelineinfo + sizeof(LocVar) * p->sizelocvars + sizeof(TString *) * p->sizeupvalues); break; } /* Non-containers */ case LUA_TUSERDATA: { lua_pushnumber(L, uvalue(o)->len); break; } case LUA_TLIGHTUSERDATA: { lua_pushnumber(L, sizeof(void*)); break; } case LUA_TSTRING: { TString *s = rawtsvalue(o); lua_pushinteger(L, sizeof(TString) + s->tsv.len + 1); break; } case LUA_TNUMBER: { lua_pushinteger(L, sizeof(lua_Number)); break; } case LUA_TBOOLEAN: { lua_pushinteger(L, sizeof(int)); break; } default: return 0; } return 1; }
/* ** tells whether a key or value can be cleared from a weak ** table. Non-collectable objects are never removed from weak ** tables. Strings behave as `values', so are never removed too. for ** other objects: if really collected, cannot keep them; for objects ** being finalized, keep them in keys, but not in values */ static int iscleared (const TValue *o) { if (!iscollectable(o)) return 0; else if (ttisstring(o)) { stringmark(rawtsvalue(o)); /* strings are `values', so are never weak */ return 0; } else return iswhite(gcvalue(o)); }
/* ** tells whether a key or value can be cleared from a weak ** table. Non-collectable objects are never removed from weak ** tables. Strings behave as `values', so are never removed too. for ** other objects: if really collected, cannot keep them; for objects ** being finalized, keep them in keys, but not in values */ static int iscleared (global_State *g, const TValue *o) { if (!iscollectable(o)) return 0; else if (ttisstring(o)) { markobject(g, rawtsvalue(o)); /* strings are `values', so are never weak */ return 0; } else return iswhite(gcvalue(o)); }
int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) { int res; int tl= ttype(l); if (tl == ttype(r)) { switch(tl) { #ifdef LUA_TINT case LUA_TINT: return ivalue(l) < ivalue(r); #endif case LUA_TNUMBER: #ifdef LNUM_COMPLEX if ( (nvalue_img_fast(l)!=0) || (nvalue_img_fast(r)!=0) ) error_complex( L, l, r ); #endif return luai_numlt(nvalue_fast(l), nvalue_fast(r)); case LUA_TSTRING: return l_strcmp(rawtsvalue(l), rawtsvalue(r)) < 0; } if ((res = call_orderTM(L, l, r, TM_LT)) != -1) return res; /* fall through to 'luaG_ordererror()' */ } #ifdef LUA_TINT else if (ttype_ext(l) == ttype_ext(r)) { lua_Integer tmp; /* Avoid accuracy losing casts: if 'r' is integer by value, do comparisons * in integer realm. Only otherwise cast 'l' to FP (which might change its * value). */ # ifdef LNUM_COMPLEX if ( (nvalue_img(l)!=0) || (nvalue_img(r)!=0) ) error_complex( L, l, r ); # endif if (tl==LUA_TINT) { /* l:int, r:num */ return tt_integer_valued(r,&tmp) ? (ivalue(l) < tmp) : luai_numlt( cast_num(ivalue(l)), nvalue_fast(r) ); } else { /* l:num, r:int */ return tt_integer_valued(l,&tmp) ? (tmp < ivalue(r)) : luai_numlt( nvalue_fast(l), cast_num(ivalue(r)) ); } } #endif return luaG_ordererror(L, l, r); }
TString *createString(lua_State *luaState, const char *str, size_t len) { TString *res; lua_pushlstring(luaState, str, len); res = rawtsvalue(luaState->top - 1); lua_pop(luaState, 1); return res; }
/* ** The next function tells whether a key or value can be cleared from ** a weak table. Non-collectable objects are never removed from weak ** tables. Strings behave as `values', so are never removed too. for ** other objects: if really collected, cannot keep them; for userdata ** being finalized, keep them in keys, but not in values */ static int iscleared (const TValue *o, int iskey) { if (!iscollectable(o)) return 0; if (ttisstring(o)) { stringmark(rawtsvalue(o)); /* strings are `values', so are never weak */ return 0; } return iswhite(gcvalue(o)) || (ttisuserdata(o) && (!iskey && isfinalized(uvalue(o)))); }
static int lessequal (lua_State *L, const TValue *l, const TValue *r) { int res; int tl= ttype(l); if (tl == ttype(r)) { switch(tl) { #ifdef LUA_TINT case LUA_TINT: return ivalue(l) <= ivalue(r); #endif case LUA_TNUMBER: #ifdef LNUM_COMPLEX if ( (nvalue_img_fast(l)!=0) || (nvalue_img_fast(r)!=0) ) error_complex( L, l, r ); #endif return luai_numle(nvalue_fast(l), nvalue_fast(r)); case LUA_TSTRING: return l_strcmp(rawtsvalue(l), rawtsvalue(r)) <= 0; } if ((res = call_orderTM(L, l, r, TM_LE)) != -1) /* first try `le' */ return res; else if ((res = call_orderTM(L, r, l, TM_LT)) != -1) /* else try `lt' */ return !res; /* fall through to 'luaG_ordererror()' */ } #ifdef LUA_TINT else if (ttype_ext(l) == ttype_ext(r)) { lua_Integer tmp; # ifdef LNUM_COMPLEX if ( (nvalue_img(l)!=0) || (nvalue_img(r)!=0) ) error_complex( L, l, r ); # endif if (tl==LUA_TINT) { /* l:int, r:num */ return tt_integer_valued(r,&tmp) ? (ivalue(l) <= tmp) : luai_numle( cast_num(ivalue(l)), nvalue_fast(r) ); } else { /* l:num, r:int */ return tt_integer_valued(l,&tmp) ? (tmp <= ivalue(r)) : luai_numle( nvalue_fast(l), cast_num(ivalue(r)) ); } } #endif return luaG_ordererror(L, l, r); }
const ktap_val_t *kp_tab_getstr(ktap_tab_t *t, const ktap_str_t *ts) { int i; for (i = 0; i <= t->hmask; i++) { ktap_val_t *v = gkey(gnode(t, i)); if (is_string(v) && (ts == rawtsvalue(v))) return gval(gnode(t, i)); } return niltv; }
/* * ktap will not use lua's length operator for table, * also # is not for length operator any more in ktap. */ int kp_obj_len(ktap_state_t *ks, const ktap_val_t *v) { switch(itype(v)) { case KTAP_TTAB: return kp_tab_len(ks, hvalue(v)); case KTAP_TSTR: return rawtsvalue(v)->len; default: kp_printf(ks, "cannot get length of type %d\n", v->type); return -1; } return 0; }
int kp_obj_equal(const ktap_val_t *t1, const ktap_val_t *t2) { switch (itype(t1)) { case KTAP_TNIL: return 1; case KTAP_TNUM: return nvalue(t1) == nvalue(t2); case KTAP_TTRUE: case KTAP_TFALSE: return itype(t1) == itype(t2); case KTAP_TLIGHTUD: return pvalue(t1) == pvalue(t2); case KTAP_TFUNC: return fvalue(t1) == fvalue(t2); case KTAP_TSTR: return rawtsvalue(t1) == rawtsvalue(t2); default: return gcvalue(t1) == gcvalue(t2); } return 0; }
/* * search function for short strings */ const Tvalue *kp_table_getstr(Table *t, Tstring *key) { Node *n = hashstr(t, key); do { /* check whether `key' is somewhere in the chain */ if (ttisshrstring(gkey(n)) && eqshrstr(rawtsvalue(gkey(n)), key)) return gval(n); /* that's it */ else n = gnext(n); } while (n); return ktap_nilobject; }
/* * ktap will not use lua's length operator on table meaning, * also # is not for length operator any more in ktap. */ int kp_obj_len(ktap_state *ks, const ktap_value *v) { switch(v->type) { case KTAP_TYPE_TABLE: return kp_tab_length(ks, hvalue(v)); case KTAP_TYPE_STRING: return rawtsvalue(v)->tsv.len; default: kp_printf(ks, "cannot get length of type %d\n", v->type); return -1; } return 0; }
/* ** returns the `main' position of an element in a table (that is, the index ** of its hash value) */ static Node *mainposition (const Table *t, const TValue *key) { switch (ttype(key)) { case LV_TNUMBER: return hashnum(t, nvalue(key)); case LV_TSTRING: return hashstr(t, rawtsvalue(key)); case LV_TBOOLEAN: return hashboolean(t, bvalue(key)); case LV_TLIGHTUSERDATA: return hashpointer(t, pvalue(key)); default: return hashpointer(t, gcvalue(key)); } }
static void ktap_concat(ktap_state *ks, int start, int end) { int i, len = 0; StkId top = ks->ci->u.l.base; ktap_string *ts; char *ptr, *buffer; for (i = start; i <= end; i++) { if (!ttisstring(top + i)) { kp_error(ks, "cannot concat non-string\n"); setnilvalue(top + start); return; } len += rawtsvalue(top + i)->tsv.len; } if (len >= KTAP_PERCPU_BUFFER_SIZE) { kp_error(ks, "Error: too long string concatenation\n"); return; } preempt_disable_notrace(); buffer = kp_percpu_data(KTAP_PERCPU_DATA_BUFFER); ptr = buffer; for (i = start; i <= end; i++) { int len = rawtsvalue(top + i)->tsv.len; strncpy(ptr, svalue(top + i), len); ptr += len; } ts = kp_tstring_newlstr(ks, buffer, len); setsvalue(top + start, ts); preempt_enable_notrace(); }
/* * equality of ktap values. ks == NULL means raw equality */ int kp_equalobjv(ktap_state *ks, const ktap_value *t1, const ktap_value *t2) { switch (ttype(t1)) { case KTAP_TNIL: return 1; case KTAP_TNUMBER: return nvalue(t1) == nvalue(t2); case KTAP_TBOOLEAN: return bvalue(t1) == bvalue(t2); /* true must be 1 !! */ case KTAP_TLIGHTUSERDATA: return pvalue(t1) == pvalue(t2); case KTAP_TLCF: return fvalue(t1) == fvalue(t2); case KTAP_TSHRSTR: return eqshrstr(rawtsvalue(t1), rawtsvalue(t2)); case KTAP_TLNGSTR: return kp_tstring_eqlngstr(rawtsvalue(t1), rawtsvalue(t2)); case KTAP_TUSERDATA: if (uvalue(t1) == uvalue(t2)) return 1; else if (ks == NULL) return 0; case KTAP_TTABLE: if (hvalue(t1) == hvalue(t2)) return 1; else if (ks == NULL) return 0; #ifdef __KERNEL__ case KTAP_TBTRACE: return kp_btrace_equal(btvalue(t1), btvalue(t2)); #endif default: return gcvalue(t1) == gcvalue(t2); } return 0; }
static void PrintConstant(const Proto *f, int i) { const TValue *o = &f->k[i]; switch (ttype(o)) { case LUA_TNIL: printf("nil"); break; case LUA_TBOOLEAN: printf(bvalue(o) ? "true" : "false"); break; case LUA_TNUMBER: printf(LUA_NUMBER_FMT, nvalue(o)); break; case LUA_TSTRING: PrintString(rawtsvalue(o)); break; default: /* cannot happen */ printf("? type=%d", ttype(o)); break; } }
void luaV_concat (lua_State *L, int total) { lua_assert(total >= 2); do { StkId top = L->top; int n = 2; /* number of elements handled in this pass (at least 2) */ if (!(ttisstring(top-2) || ttisnumber(top-2)) || !tostring(L, top-1)) { if (!call_binTM(L, top-2, top-1, top-2, TM_CONCAT)) luaG_concaterror(L, top-2, top-1); } else if (tsvalue(top-1)->len == 0) /* second operand is empty? */ (void)tostring(L, top - 2); /* result is first operand */ else if (ttisstring(top-2) && tsvalue(top-2)->len == 0) { setsvalue2s(L, top-2, rawtsvalue(top-1)); /* result is second op. */ } else { /* at least two non-empty string values; get as many as possible */ size_t tl = tsvalue(top-1)->len; char *buffer; int i; /* collect total length */ for (i = 1; i < total && tostring(L, top-i-1); i++) { size_t l = tsvalue(top-i-1)->len; if (l >= (MAX_SIZET/sizeof(char)) - tl) luaG_runerror(L, "string length overflow"); tl += l; } buffer = luaZ_openspace(L, &G(L)->buff, tl); tl = 0; n = i; do { /* concat all strings */ size_t l = tsvalue(top-i)->len; memcpy(buffer+tl, svalue(top-i), l * sizeof(char)); tl += l; } while (--i > 0); setsvalue2s(L, top-n, luaS_newlstr(L, buffer, tl)); } total -= n-1; /* got 'n' strings to create 1 new */ L->top -= n-1; /* popped 'n' strings and pushed one */ } while (total > 1); /* repeat until only 1 result left */ }
/* next (used for iteration) */ void luaR_next(lua_State *L, void *data, TValue *key, TValue *val) { const luaR_entry* pentries = (const luaR_entry*)data; char strkey[LUA_MAX_ROTABLE_NAME + 1], *pstrkey = NULL; luaR_numkey numkey = 0; unsigned keypos; /* Special case: if key is nil, return the first element of the rotable */ if (ttisnil(key)) luaR_next_helper(L, pentries, 0, key, val); else if (ttisstring(key) || ttisnumber(key)) { /* Find the previoud key again */ if (ttisstring(key)) { luaR_getcstr(strkey, rawtsvalue(key), LUA_MAX_ROTABLE_NAME); pstrkey = strkey; } else numkey = (luaR_numkey)nvalue(key); luaR_findentry(data, pstrkey, numkey, &keypos); /* Advance to next key */ keypos ++; luaR_next_helper(L, pentries, keypos, key, val); } }
void kp_showobj(ktap_State *ks, const Tvalue *v) { switch (ttype(v)) { case KTAP_TNIL: kp_printf(ks, "nil"); break; case KTAP_TNUMBER: kp_printf(ks, "%d", nvalue(v)); break; case KTAP_TBOOLEAN: kp_printf(ks, "%s", (bvalue(v) == 1) ? "true" : "false"); break; case KTAP_TLIGHTUSERDATA: kp_printf(ks, "%d", pvalue(v)); break; case KTAP_TLCF: kp_printf(ks, "0x%x", fvalue(v)); break; case KTAP_TSHRSTR: case KTAP_TLNGSTR: kp_printf(ks, "\"%s\"", getstr(rawtsvalue(v))); break; case KTAP_TUSERDATA: kp_printf(ks, "%d", uvalue(v)); break; case KTAP_TTABLE: kp_table_dump(ks, hvalue(v)); break; #ifdef __KERNEL__ case KTAP_TEVENT: kp_show_event(ks); break; #endif default: kp_printf(ks, "[unknown value type: %d]", ttype(v)); break; } }
//----------------------------------------------------------------// static void _dumpType ( lua_State* L, int idx, const char *name, bool verbose, TableSet& foundTables ) { MOAILuaState state ( L ); const char *format = DUMP_FORMAT; idx = state.AbsIndex( idx ); StkId tvalue = state->base + idx - 1; switch ( lua_type ( state, idx )) { case LUA_TBOOLEAN: ZLLog::Print ( format, tvalue, "bool", name ); ZLLog::Print ( " = %s", lua_toboolean ( state, idx ) ? "true" : "false" ); break; case LUA_TFUNCTION: { const char *funcType = iscfunction ( tvalue ) ? "C function" : "Lua function"; ZLLog::Print ( format, clvalue ( tvalue ), funcType, name ); break; } case LUA_TLIGHTUSERDATA: ZLLog::Print ( format, pvalue ( tvalue ), "pointer", name ); break; case LUA_TNIL: ZLLog::Print ( format, tvalue, "nil", name ); break; case LUA_TNONE: // Intentionally do nothing--not even the line break. return; case LUA_TNUMBER: ZLLog::Print ( format, tvalue, "number", name ); ZLLog::Print ( " = %f", lua_tonumber ( state, idx )); break; case LUA_TSTRING: ZLLog::Print ( format, rawtsvalue( tvalue ), "string", name ); ZLLog::Print ( " = \"%s\"", lua_tostring ( state, idx )); break; case LUA_TTABLE: { struct Table* htable = hvalue( tvalue ); if ( foundTables.contains ( htable )) { ZLLog::Print ( DUMP_FORMAT " (see above)", htable, "table", name ); break; } else { foundTables.insert ( htable ); ZLLog::Print ( format, htable, "table", name ); if ( verbose ) { ZLLog::Print ( "\n" ); lua_pushnil ( state ); while ( lua_next ( state, idx ) ) { STLString elementName( name ); elementName.append ( "." ); elementName.append ( lua_tostring ( state, -2 )); _dumpType ( state, -1, elementName.c_str (), verbose, foundTables ); lua_pop ( state, 1 ); } } } } return; // suppress newline case LUA_TTHREAD: ZLLog::Print ( format, thvalue( tvalue ), "thread", name ); break; case LUA_TUSERDATA: if ( lua_islightuserdata ( state, idx ) ) { ZLLog::Print ( format, lua_topointer ( state, idx ) , "light userdata", name ); } else { ZLLog::Print ( format, lua_topointer( state, idx ), "userdata", name ); if ( verbose ) { lua_getglobal ( state, "tostring" ); lua_pushvalue ( state, idx ); lua_pcall ( state, 1, 1, 0 ); ZLLog::Print ( "\n\t%s", lua_tostring ( state, -1 )); state.Pop ( 1 ); } } break; default: ZLLog::Print ( "*** Unexpected type: %d ***", lua_type ( state, idx )); } ZLLog::Print ( "\n" ); }
int kp_strfmt(ktap_state *ks, struct trace_seq *seq) { int arg = 1; size_t sfl; ktap_value *arg_fmt = kp_arg(ks, 1); int argnum = kp_arg_nr(ks); const char *strfrmt, *strfrmt_end; strfrmt = svalue(arg_fmt); sfl = rawtsvalue(arg_fmt)->tsv.len; strfrmt_end = strfrmt + sfl; while (strfrmt < strfrmt_end) { if (*strfrmt != L_ESC) trace_seq_putc(seq, *strfrmt++); else if (*++strfrmt == L_ESC) trace_seq_putc(seq, *strfrmt++); else { /* format item */ char form[MAX_FORMAT]; if (++arg > argnum) { ktap_argerror(ks, arg, "no value"); return -1; } strfrmt = scanformat(ks, strfrmt, form); switch (*strfrmt++) { case 'c': trace_seq_printf(seq, form, nvalue(kp_arg(ks, arg))); break; case 'd': case 'i': { ktap_number n = nvalue(kp_arg(ks, arg)); INTFRM_T ni = (INTFRM_T)n; addlenmod(form, INTFRMLEN); trace_seq_printf(seq, form, ni); break; } case 'p': { char str[KSYM_SYMBOL_LEN]; SPRINT_SYMBOL(str, nvalue(kp_arg(ks, arg))); trace_seq_puts(seq, str); break; } case 'o': case 'u': case 'x': case 'X': { ktap_number n = nvalue(kp_arg(ks, arg)); unsigned INTFRM_T ni = (unsigned INTFRM_T)n; addlenmod(form, INTFRMLEN); trace_seq_printf(seq, form, ni); break; } case 's': { ktap_value *v = kp_arg(ks, arg); const char *s; size_t l; if (isnil(v)) { trace_seq_puts(seq, "nil"); return 0; } if (ttisevent(v)) { kp_event_tostring(ks, seq); return 0; } s = svalue(v); l = rawtsvalue(v)->tsv.len; if (!strchr(form, '.') && l >= 100) { /* * no precision and string is too long * to be formatted; * keep original string */ trace_seq_puts(seq, s); break; } else { trace_seq_printf(seq, form, s); break; } } default: /* also treat cases `pnLlh' */ kp_error(ks, "invalid option " KTAP_QL("%%%c") " to " KTAP_QL("format"), *(strfrmt - 1)); } } } return 0; }