static void str_format (void) { int32 arg = 1; const char *strfrmt = luaL_check_string(arg); struct Capture cap; cap.src_end = strfrmt+strlen(strfrmt)+1; luaL_resetbuffer(); while (*strfrmt) { if (*strfrmt != '%') luaL_addchar(*strfrmt++); else if (*++strfrmt == '%') luaL_addchar(*strfrmt++); /* %% */ else { /* format item */ char form[MAX_FORMAT]; /* store the format ('%...') */ char *buff; const char *initf = strfrmt; form[0] = '%'; cap.level = 0; if (isdigit((byte)initf[0]) && initf[1] == '$') { arg = initf[0] - '0'; initf += 2; /* skip the 'n$' */ } arg++; strfrmt = match(initf, "[-+ #0]*(%d*)%.?(%d*)", &cap); if (cap.capture[0].len > 2 || cap.capture[1].len > 2) /* < 100? */ lua_error("invalid format (width or precision too long)"); strncpy(form+1, initf, strfrmt-initf+1); /* +1 to include conversion */ form[strfrmt-initf+2] = 0; buff = luaL_openspace(1000); /* to store the formatted value */ switch (*strfrmt++) { case 'q': luaI_addquoted(luaL_check_string(arg)); continue; case 's': { const char *s = luaL_check_string(arg); buff = luaL_openspace(strlen(s)); sprintf(buff, form, s); break; } case 'c': case 'd': case 'i': sprintf(buff, form, (int)luaL_check_number(arg)); break; case 'o': case 'u': case 'x': case 'X': sprintf(buff, form, (unsigned int)luaL_check_number(arg)); break; case 'e': case 'E': case 'f': case 'g': case 'G': sprintf(buff, form, luaL_check_number(arg)); break; default: /* also treat cases 'pnLlh' */ lua_error("invalid option in `format'"); } luaL_addsize(strlen(buff)); } } closeandpush(); /* push the result */ }
static TaggedString *strconc(char *l, char *r) { size_t nl = strlen(l); char *buffer = luaL_openspace(nl + strlen(r) + 1); strcpy(buffer, l); strcpy(buffer + nl, r); return luaS_new(buffer); }
static TaggedString *strconc (TaggedString *l, TaggedString *r) { size_t nl = l->u.s.len; size_t nr = r->u.s.len; char *buffer = luaL_openspace(nl+nr+1); memcpy(buffer, l->str, nl); memcpy(buffer+nl, r->str, nr); return luaS_newlstr(buffer, nl+nr); }
static const char *to_string(lua_Object obj) { char *buff = luaL_openspace(30); TObject *o = luaA_Address(obj); switch (ttype(o)) { case LUA_T_NUMBER: case LUA_T_STRING: return lua_getstring(obj); case LUA_T_ARRAY: { sprintf(buff, "table: %p", (void *)o->value.a); return buff; } case LUA_T_CLOSURE: { sprintf(buff, "function: %p", (void *)o->value.cl); return buff; } case LUA_T_PROTO: { sprintf(buff, "function: %p", (void *)o->value.tf); return buff; } case LUA_T_CPROTO: { // WORKAROUND: C++ forbids casting from a pointer-to-function to a // pointer-to-object. We use a union to work around that. union { void *objPtr; lua_CFunction funcPtr; } ptrUnion; ptrUnion.funcPtr = o->value.f; sprintf(buff, "function: %p", ptrUnion.objPtr); return buff; } case LUA_T_USERDATA: { sprintf(buff, "userdata: %d", o->value.ud.id); return buff; } case LUA_T_TASK: { sprintf(buff, "task: %d", (int)o->value.n); return buff; } case LUA_T_NIL: return "nil"; default: #ifdef LUA_DEBUG LUA_INTERNALERROR("internal error"); #endif return NULL; } }
static void to_string (void) { lua_Object obj = lua_getparam(1); char *buff = luaL_openspace(30); TObject *o = luaA_Address(obj); switch (ttype(o)) { case LUA_T_NUMBER: lua_pushstring(lua_getstring(obj)); return; case LUA_T_STRING: lua_pushobject(obj); return; case LUA_T_ARRAY: { sprintf(buff, "table: %p", (void *)o->value.a); break; } case LUA_T_CLOSURE: { sprintf(buff, "function: %p", (void *)o->value.cl); break; } case LUA_T_PROTO: { sprintf(buff, "function: %p", (void *)o->value.tf); break; } case LUA_T_CPROTO: { sprintf(buff, "function: %p", (void *)o->value.f); break; } case LUA_T_USERDATA: { sprintf(buff, "userdata: %p", o->value.ts->u.d.v); break; } case LUA_T_TASK: { sprintf(buff, "task: %d", (int)o->value.n); break; } case LUA_T_NIL: lua_pushstring("nil"); return; default: LUA_INTERNALERROR("invalid type"); } lua_pushstring(buff); }
static void addnchar (const char *s, int32 n) { char *b = luaL_openspace(n); memcpy(b, s, n); luaL_addsize(n); }