コード例 #1
0
ファイル: lbzip2.c プロジェクト: rzel/lua-larc
static int compress_to_buffer(lua_State *L, bz_userdata *ud)
{
	luaL_Buffer B;
	luaL_buffinit(L, &B);
	do
	{
		ud->z.next_out = luaL_prepbuffer(&B);
		ud->z.avail_out = LUAL_BUFFERSIZE;
		if ((ud->status = BZ2_bzCompress(&ud->z, ud->flush)) < BZ_OK)
			break;
		luaL_addsize(&B, LUAL_BUFFERSIZE - ud->z.avail_out);
	}
	while (ud->z.avail_out == 0);
	switch (ud->status)
	{
		case BZ_RUN_OK: case BZ_FLUSH_OK: case BZ_FINISH_OK:
			ud->status = BZ_OK;
		case BZ_OK: case BZ_STREAM_END:
			if (ud->z.avail_in != 0)
				return luaL_error(L, "unknown failure in bzCompress");
	}
	luaL_pushresult(&B);
	return 1;
}
コード例 #2
0
ファイル: lpcap.c プロジェクト: c0i/Dorothy
/*
** Push all values of the current capture into the stack; returns
** number of values pushed
*/
static int pushcapture (CapState *cs) {
  lua_State *L = cs->L;
  luaL_checkstack(L, 4, "too many captures");
  switch (captype(cs->cap)) {
    case Cposition: {
      lua_pushinteger(L, cs->cap->s - cs->s + 1);
      cs->cap++;
      return 1;
    }
    case Cconst: {
      pushluaval(cs);
      cs->cap++;
      return 1;
    }
    case Carg: {
      int arg = (cs->cap++)->idx;
      if (arg + FIXEDARGS > cs->ptop)
        return luaL_error(L, "reference to absent extra argument #%d", arg);
      lua_pushvalue(L, arg + FIXEDARGS);
      return 1;
    }
    case Csimple: {
      int k = pushnestedvalues(cs, 1);
      lua_insert(L, -k);  /* make whole match be first result */
      return k;
    }
    case Cruntime: {
      lua_pushvalue(L, (cs->cap++)->idx);  /* value is in the stack */
      return 1;
    }
    case Cstring: {
      luaL_Buffer b;
      luaL_buffinit(L, &b);
      stringcap(&b, cs);
      luaL_pushresult(&b);
      return 1;
    }
    case Csubst: {
      luaL_Buffer b;
      luaL_buffinit(L, &b);
      substcap(&b, cs);
      luaL_pushresult(&b);
      return 1;
    }
    case Cgroup: {
      if (cs->cap->idx == 0)  /* anonymous group? */
        return pushnestedvalues(cs, 0);  /* add all nested values */
      else {  /* named group: add no values */
        nextcap(cs);  /* skip capture */
        return 0;
      }
    }
    case Cbackref: return backrefcap(cs);
    case Ctable: return tablecap(cs);
    case Cfunction: return functioncap(cs);
    case Cnum: return numcap(cs);
    case Cquery: return querycap(cs);
    case Cfold: return foldcap(cs);
    default: assert(0); return 0;
  }
}
コード例 #3
0
ファイル: lua_zlib.c プロジェクト: LuaDist/lua-zlib
/**
 * @upvalue z_stream - Memory for the z_stream.
 * @upvalue remainder - Any remainder from the last deflate call.
 *
 * @param string - "print" to deflate stream.
 * @param int - flush output buffer? Z_SYNC_FLUSH, Z_FULL_FLUSH, or Z_FINISH.
 *
 * if no params, terminates the stream (as if we got empty string and Z_FINISH).
 */
static int lz_filter_impl(lua_State *L, int (*filter)(z_streamp, int), int (*end)(z_streamp), char* name) {
    int flush = Z_NO_FLUSH, result;
    z_stream* stream;
    luaL_Buffer buff;
    size_t avail_in;

    if ( filter == deflate ) {
        const char *const opts[] = { "none", "sync", "full", "finish", NULL };
        flush = luaL_checkoption(L, 2, opts[0], opts);
        if ( flush ) flush++; 
        /* Z_NO_FLUSH(0) Z_SYNC_FLUSH(2), Z_FULL_FLUSH(3), Z_FINISH (4) */

        /* No arguments or nil, we are terminating the stream: */
        if ( lua_gettop(L) == 0 || lua_isnil(L, 1) ) {
            flush = Z_FINISH;
        }
    }

    stream = (z_stream*)lua_touserdata(L, lua_upvalueindex(1));
    if ( stream == NULL ) {
        if ( lua_gettop(L) >= 1 && lua_isstring(L, 1) ) {
            lua_pushfstring(L, "IllegalState: calling %s function when stream was previously closed", name);
            lua_error(L);
        }
        lua_pushstring(L, "");
        lua_pushboolean(L, 1);
        return 2; /* Ignore duplicate calls to "close". */
    }

    luaL_buffinit(L, &buff);

    if ( lua_gettop(L) > 1 ) lua_pushvalue(L, 1);

    if ( lua_isstring(L, lua_upvalueindex(2)) ) {
        lua_pushvalue(L, lua_upvalueindex(2));
        if ( lua_gettop(L) > 1 && lua_isstring(L, -2) ) {
            lua_concat(L, 2);
        }
    }

    /*  Do the actual deflate'ing: */
    stream->next_in = lua_gettop(L) > 0 ?
        (unsigned char*)lua_tolstring(L, -1, &avail_in) :
        NULL;
    stream->avail_in = avail_in;

    if ( ! stream->avail_in && ! flush ) {
        /*  Passed empty string, make it a noop instead of erroring out. */
        lua_pushstring(L, "");
        lua_pushboolean(L, 0);
        lua_pushinteger(L, stream->total_in);
        lua_pushinteger(L, stream->total_out);
        return 4;
    }

    do {
        stream->next_out  = (unsigned char*)luaL_prepbuffer(&buff);
        stream->avail_out = LUAL_BUFFERSIZE;
        result = filter(stream, flush);
        if ( Z_BUF_ERROR != result ) {
            /* Ignore Z_BUF_ERROR since that just indicates that we
             * need a larger buffer in order to proceed.  Thanks to
             * Tobias Markmann for finding this bug!
             */
            lz_assert(L, result, stream, __FILE__, __LINE__);
        }
        luaL_addsize(&buff, LUAL_BUFFERSIZE - stream->avail_out);
    } while ( stream->avail_out == 0 );

    /*  Need to do this before we alter the stack: */
    luaL_pushresult(&buff);

    /*  Save remainder in lua_upvalueindex(2): */
    if ( NULL != stream->next_in ) {
        lua_pushlstring(L, (char*)stream->next_in, stream->avail_in);
        lua_replace(L, lua_upvalueindex(2));
    }

    /*  "close" the stream/remove finalizer: */
    if ( result == Z_STREAM_END ) {
        /*  Clear-out the metatable so end is not called twice: */
        lua_pushnil(L);
        lua_setmetatable(L, lua_upvalueindex(1));

        /*  nil the upvalue: */
        lua_pushnil(L);
        lua_replace(L, lua_upvalueindex(1));

        /*  Close the stream: */
        lz_assert(L, end(stream), stream, __FILE__, __LINE__);

        lua_pushboolean(L, 1);
    } else {
        lua_pushboolean(L, 0);
    }
    lua_pushinteger(L, stream->total_in);
    lua_pushinteger(L, stream->total_out);
    return 4;
}
コード例 #4
0
ファイル: lauxlib.c プロジェクト: dhrebeniuk/linosity
LUALIB_API void luaL_pushresultsize (luaL_Buffer *B, size_t sz) {
  luaL_addsize(B, sz);
  luaL_pushresult(B);
}
コード例 #5
0
ファイル: uart.c プロジェクト: AlbertFERNANDES/elua
// Lua: uart.read( id, format, [timeout], [timer_id] )
static int uart_read( lua_State* L )
{
  int id, res, mode, issign;
  unsigned timer_id = PLATFORM_TIMER_SYS_ID;
  s32 maxsize = 0, count = 0;
  const char *fmt;
  luaL_Buffer b;
  char cres;
  timer_data_type timeout = PLATFORM_TIMER_INF_TIMEOUT;
  
  id = luaL_checkinteger( L, 1 );
  MOD_CHECK_ID( uart, id );

  // Check format
  if( lua_isnumber( L, 2 ) )
  {
    if( ( maxsize = ( s32 )lua_tointeger( L, 2 ) ) < 0 )
      return luaL_error( L, "invalid max size" );
    mode = UART_READ_MODE_MAXSIZE;
  }
  else
  {
    fmt = luaL_checkstring( L, 2 );
    if( !strcmp( fmt, "*l" ) )
      mode = UART_READ_MODE_LINE;
    else if( !strcmp( fmt, "*n" ) )
      mode = UART_READ_MODE_NUMBER;
    else if( !strcmp( fmt, "*s" ) )
      mode = UART_READ_MODE_SPACE;
    else
      return luaL_error( L, "invalid format" );
  }

  // Check timeout and timer id
  uart_get_timeout_data( L, 3, &timeout, &timer_id );

  // Read data
  luaL_buffinit( L, &b );
  while( 1 )
  {
    if( ( res = platform_uart_recv( id, timer_id, timeout ) ) == -1 )
      break; 
    cres = ( char )res;
    count ++;
    issign = ( count == 1 ) && ( ( res == '-' ) || ( res == '+' ) );
    // [TODO] this only works for lines that actually end with '\n', other line endings
    // are not supported.
    if( ( cres == '\n' ) && ( mode == UART_READ_MODE_LINE ) )
      break;
    if( !isdigit( (unsigned char) cres ) && !issign && ( mode == UART_READ_MODE_NUMBER ) )
      break;
    if( isspace( (unsigned char) cres ) && ( mode == UART_READ_MODE_SPACE ) )
      break;
    luaL_putchar( &b, cres );
    if( ( count == maxsize ) && ( mode == UART_READ_MODE_MAXSIZE ) )
      break;
  }
  luaL_pushresult( &b );

  // Return an integer if needed
  if( mode == UART_READ_MODE_NUMBER )
  {
    res = lua_tointeger( L, -1 );
    lua_pop( L, 1 );
    lua_pushinteger( L, res );
  }
  return 1;  
}
コード例 #6
0
/* TODO: Only reads up to LUAL_BUFFERSIZE bytes of input. */
extern int shellprompt_os_get_output(lua_State *L)
{
    luaL_Buffer ans;
    char *buf;
    pid_t child;
    size_t nremain, nfill;
    ssize_t nread;
    int fds[2] = {-1, -1};
    int status;
    int argc, i;
    const char **argv;

    luaL_buffinit(L, &ans);
    argv = 0;
    argc = lua_gettop(L);
    if (argc < 1) {
        goto cleanup;
    }
    if (!(argv = calloc(argc+1, sizeof(*argv)))) {
        goto cleanup;
    }
    for (i = 0; i < argc; i++) {
        if (!(argv[i] = luaL_checkstring(L, i+1))) {
            goto cleanup;
        }
    }
    if (pipe(fds) == -1) {
        goto cleanup;
    }
    if ((child = fork()) == (pid_t)-1) {
        goto cleanup;
    }
    if (!child) {
        int devnull;

        close(fds[0]);
        devnull = open("/dev/null", O_RDWR);
        dup2(devnull, 0);  /* stdin */
        dup2(fds[1],  1);  /* stdout */
        dup2(devnull, 2);  /* stderr */
        execvp(argv[0], (char **)argv);
        _exit(127);
    }
    close(fds[1]);
    buf = luaL_prepbuffer(&ans);
    nremain = LUAL_BUFFERSIZE;
    nfill = 0;
    while (nremain > 0) {
        nread = read(fds[0], buf+nfill, nremain);
        if ((nread == (ssize_t)-1) && (errno == EINTR)) {
            continue;
        }
        if (nread <= 0) {
            break;
        }
        nfill += nread;
        nremain -= nread;
    }
    luaL_addsize(&ans, (size_t)nfill);
    waitpid(child, &status, 0);
cleanup:
    close(fds[0]);
    close(fds[1]);
    free(argv);
    luaL_pushresult(&ans);
    return 1;
}
コード例 #7
0
ファイル: main.cpp プロジェクト: srdgame/luasp
int lsp::read_request_data(lua_State *L)
{
	FCGX_Request* r = (FCGX_Request*)luaL_lsp_get_io_ctx(L);

	const char* p=FCGX_GetParam("CONTENT_LENGTH", r->envp);
	int content_length = p? atoi(p) : -1;

	if(content_length < 0)
		return 411;//HTTP_LENGTH_REQUIRED;

	// TODO: for max post?
	if(content_length > 4096)
		return 400;//HTTP_BAD_REQUEST;

	int retval = 0;

	luaL_Buffer buf;
	luaL_buffinit(L,&buf);

	//if(ap_should_client_block(apr))
	{
		char *tmp = new char[1024];
		int len = 0;

		while(len<content_length)
		{
			int n = content_length - len;

			//n = ap_get_client_block(apr,tmp,n>sizeof(tmp)?sizeof(tmp):n);
			n = FCGX_GetStr(tmp, n > 1024 ? 1024 : n, r->in);

			if(n <= 0)
				break;

			len += n;
			luaL_addlstring(&buf,tmp,n);
		}

		if(len!=content_length)
			retval = -1;//HTTP_REQUEST_TIME_OUT;

		delete[] tmp;
	}

	const char* content_type = FCGX_GetParam("CONTENT_TYPE", r->envp);

	int n = lua_gettop(L);

	if(content_type && !strcmp(content_type,"application/x-www-form-urlencoded"))
	{
		lua_getglobal(L,"args_decode");
		luaL_pushresult(&buf);

		if(lua_isfunction(L,-2) && !lua_pcall(L,1,1,0))
			lua_setglobal(L,"args_post");
	}
	else
	{
		lua_getfield(L,LUA_GLOBALSINDEX,"env");
		luaL_pushresult(&buf);

		if(lua_istable(L,-2))
			lua_setfield(L,-2,"content");
	}

	lua_pop(L,lua_gettop(L)-n);

	return retval;
}
コード例 #8
0
static int str_format (lua_State *L) {
  int top = lua_gettop(L);
  int arg = 1;
  size_t sfl;
  const char *strfrmt = luaL_checklstring(L, arg, &sfl);
  const char *strfrmt_end = strfrmt+sfl;
  luaL_Buffer b;
  luaL_buffinit(L, &b);
  while (strfrmt < strfrmt_end) {
    if (*strfrmt != L_ESC)
      luaL_addchar(&b, *strfrmt++);
    else if (*++strfrmt == L_ESC)
      luaL_addchar(&b, *strfrmt++);  /* %% */
    else { /* format item */
      char form[MAX_FORMAT];  /* to store the format (`%...') */
      char *buff = luaL_prepbuffsize(&b, MAX_ITEM);  /* to put formatted item */
      int nb = 0;  /* number of bytes in added item */
      if (++arg > top)
        luaL_argerror(L, arg, "no value");
      strfrmt = scanformat(L, strfrmt, form);
      switch (*strfrmt++) {
        case 'c': {
          nb = sprintf(buff, form, luaL_checkint(L, arg));
          break;
        }
        case 'd': case 'i': {
          lua_Number n = luaL_checknumber(L, arg);
          LUA_INTFRM_T ni = (LUA_INTFRM_T)n;
          lua_Number diff = n - (lua_Number)ni;
          luaL_argcheck(L, -1 < diff && diff < 1, arg,
                        "not a number in proper range");
          addlenmod(form, LUA_INTFRMLEN);
          nb = sprintf(buff, form, ni);
          break;
        }
        case 'o': case 'u': case 'x': case 'X': {
          lua_Number n = luaL_checknumber(L, arg);
          unsigned LUA_INTFRM_T ni = (unsigned LUA_INTFRM_T)n;
          lua_Number diff = n - (lua_Number)ni;
          luaL_argcheck(L, -1 < diff && diff < 1, arg,
                        "not a non-negative number in proper range");
          addlenmod(form, LUA_INTFRMLEN);
          nb = sprintf(buff, form, ni);
          break;
        }
        case 'e': case 'E': case 'f':
#if defined(LUA_USE_AFORMAT)
        case 'a': case 'A':
#endif
        case 'g': case 'G': {
          addlenmod(form, LUA_FLTFRMLEN);
          nb = sprintf(buff, form, (LUA_FLTFRM_T)luaL_checknumber(L, arg));
          break;
        }
        case 'q': {
          addquoted(L, &b, arg);
          break;
        }
        case 's': {
          size_t l;
          const char *s = luaL_tolstring(L, arg, &l);
          if (!strchr(form, '.') && l >= 100) {
            /* no precision and string is too long to be formatted;
               keep original string */
            luaL_addvalue(&b);
            break;
          }
          else {
            nb = sprintf(buff, form, s);
            lua_pop(L, 1);  /* remove result from 'luaL_tolstring' */
            break;
          }
        }
        default: {  /* also treat cases `pnLlh' */
          return luaL_error(L, "invalid option " LUA_QL("%%%c") " to "
                               LUA_QL("format"), *(strfrmt - 1));
        }
      }
      luaL_addsize(&b, nb);
    }
  }
  luaL_pushresult(&b);
  return 1;
}
コード例 #9
0
ファイル: lregex.c プロジェクト: gvsurenderreddy/LuaFAR
int rx_gsub (lua_State *L, int is_function, int is_wide)
{
  size_t len, flen;
  TFarRegex* fr;
  FARAPIREGEXPCONTROL RegExpControl = GetRegExpControl(L);
  const wchar_t *s, *f;
  int max_rep_capture, ftype, n, matches, reps;
  luaL_Buffer out;
  struct RegExpSearch data;
  memset(&data, 0, sizeof(data));

  if (is_function) {
    if (is_wide)
      data.Text = check_utf16_string(L, 1, &len);
    else
      data.Text = check_utf8_string(L, 1, &len);
    fr = push_far_regex(L, RegExpControl, check_regex_pattern(L, 2, 5));
    lua_replace(L, 2);
  }
  else {
    fr = CheckFarRegex(L, 1);
    if (is_wide)
      data.Text = check_utf16_string(L, 2, &len);
    else
      data.Text = check_utf8_string(L, 2, &len);
  }

  data.Length = len;
  s = data.Text;
  f = NULL;
  flen = 0;
  max_rep_capture = 0;
  ftype = lua_type(L, 3);
  if (ftype == LUA_TSTRING) {
    const wchar_t* p;
    f = check_utf8_string(L, 3, &flen);
    for (p=f; *p; p++) {
      if (*p == L'%') {
        int n, ch;
        if ((ch = *++p) == 0) break;
        n = (ch >= L'0' && ch <= L'9') ? ch - L'0' :
            (ch >= L'A' && ch <= L'Z') ? ch - L'A' + 10 :
            (ch >= L'a' && ch <= L'z') ? ch - L'a' + 10 : -1;
        if (max_rep_capture < n) max_rep_capture = n;
      }
    }
  }
  else if (ftype != LUA_TTABLE && ftype != LUA_TFUNCTION)
    luaL_argerror(L, 3, "string or table or function");

  if (lua_isnoneornil(L, 4)) n = -1;
  else {
    n = (int)luaL_checkinteger(L, 4);
    if (n < 0) n = 0;
  }
  lua_settop(L, 3);

  data.Count = RegExpControl(fr->hnd, RECTL_BRACKETSCOUNT, 0, 0);
  if ( (ftype == LUA_TSTRING) &&
       !(max_rep_capture == 1 && data.Count == 1) &&
       (data.Count <= max_rep_capture))
    luaL_error(L, "replace string: invalid capture index");
  data.Match = (struct RegExpMatch*)lua_newuserdata(L, data.Count*sizeof(struct RegExpMatch));
  data.Match[0].end = -1;

  matches = reps = 0;
  luaL_buffinit(L, &out);

  while (n < 0 || reps < n) {
    int rep;
    intptr_t from, to;
    intptr_t prev_end = data.Match[0].end;
    if (!RegExpControl(fr->hnd, RECTL_SEARCHEX, 0, &data))
      break;
    if (data.Match[0].end == prev_end) {
      if (data.Position < data.Length) {
        luaL_addlstring(&out, (const char*)(s+data.Position), sizeof(wchar_t));
        data.Position++;
        continue;
      }
      break;
    }
    matches++;
    rep = 0;
    from = data.Match[0].start;
    to = data.Match[0].end;
    luaL_addlstring(&out, (const char*)(s + data.Position),
      (from - data.Position) * sizeof(wchar_t));
    if (ftype == LUA_TSTRING) {
      size_t i, start = 0;
      for (i=0; i<flen; i++) {
        if (f[i] == L'%') {
          if (++i < flen) {
            int ch = f[i];
            int n = (ch >= L'0' && ch <= L'9') ? ch - L'0' :
                    (ch >= L'A' && ch <= L'Z') ? ch - L'A' + 10 :
                    (ch >= L'a' && ch <= L'z') ? ch - L'a' + 10 : -1;
            if (n >= 0) {
              if (n==1 && data.Count==1) n = 0;
              luaL_addlstring(&out, (const char*)(f+start), (i-1-start)*sizeof(wchar_t));
              if (data.Match[n].start >= 0) {
                luaL_addlstring(&out, (const char*)(s + data.Match[n].start),
                    (data.Match[n].end - data.Match[n].start) * sizeof(wchar_t));
              }
            }
            else { // delete the percent sign
              luaL_addlstring(&out, (const char*)(f+start), (i-1-start)*sizeof(wchar_t));
              luaL_addlstring(&out, (const char*)(f+i), sizeof(wchar_t));
            }
            start = i+1;
          }
          else {
            luaL_addlstring(&out, (const char*)(f+start), (i-1-start)*sizeof(wchar_t));
            start = flen;
            break;
          }
        }
      }
      rep++;
      luaL_addlstring(&out, (const char*)(f+start), (flen-start)*sizeof(wchar_t));
    }
    else if (ftype == LUA_TTABLE) {
      int n = data.Count==1 ? 0:1;
      if (data.Match[n].start >= 0) {
        if (is_wide)
          push_utf16_string(L, s + data.Match[n].start, (data.Match[n].end - data.Match[n].start));
        else
          push_utf8_string(L, s + data.Match[n].start, (data.Match[n].end - data.Match[n].start));
        lua_gettable(L, 3);
        if (lua_isstring(L, -1)) {
          if (!is_wide) {
            size_t len;
            const wchar_t* ws = check_utf8_string(L, -1, &len);
            lua_pushlstring(L, (const char*)ws, len*sizeof(wchar_t));
            lua_remove(L, -2);
          }
          luaL_addvalue(&out);
          rep++;
        }
        else if (lua_toboolean(L,-1))
          luaL_error(L, "invalid replacement type");
        else
          lua_pop(L, 1);
      }
    }
    else { // if (ftype == LUA_TFUNCTION)
      intptr_t i, skip = data.Count==1 ? 0:1;
      lua_checkstack(L, (int)(data.Count+1-skip));
      lua_pushvalue(L, 3);
      for (i=skip; i<data.Count; i++) {
        if (data.Match[i].start >= 0) {
          if (is_wide)
            push_utf16_string(L, s + data.Match[i].start, (data.Match[i].end - data.Match[i].start));
          else
            push_utf8_string(L, s + data.Match[i].start, (data.Match[i].end - data.Match[i].start));
        }
        else
          lua_pushboolean(L, 0);
      }
      if (lua_pcall(L, (int)(data.Count-skip), 1, 0) == 0) {
        if (lua_isstring(L, -1)) {
          if (!is_wide) {
            size_t len;
            const wchar_t* ws = check_utf8_string(L, -1, &len);
            lua_pushlstring(L, (const char*)ws, len*sizeof(wchar_t));
            lua_remove(L, -2);
          }
          luaL_addvalue(&out);
          rep++;
        }
        else if (lua_toboolean(L,-1))
          luaL_error(L, "invalid return type");
        else
          lua_pop(L, 1);
      }
      else
        luaL_error(L, lua_tostring(L, -1));
    }
    if (rep)
      reps++;
    else
      luaL_addlstring(&out, (const char*)(s+from), (to-from)*sizeof(wchar_t));
    if (data.Position < to)
      data.Position = to;
    else if (data.Position < data.Length) {
      luaL_addlstring(&out, (const char*)(s + data.Position), sizeof(wchar_t));
      data.Position++;
    }
    else
      break;
  }
  luaL_addlstring(&out, (const char*)(s + data.Position),
    (data.Length - data.Position) * sizeof(wchar_t));
  luaL_pushresult(&out);
  if (!is_wide) {
    push_utf8_string(L, (const wchar_t*)lua_tostring(L, -1), lua_objlen(L, -1) / sizeof(wchar_t));
  }
  lua_pushinteger(L, matches);
  lua_pushinteger(L, reps);
  return 3;
}
コード例 #10
0
ファイル: ls_odbc.c プロジェクト: LuaDist2/luasql-oci8
/*
** Retrieves data from the i_th column in the current row
** Input
**   types: index in stack of column types table
**   hstmt: statement handle
**   i: column number
** Returns:
**   0 if successfull, non-zero otherwise;
*/
static int push_column(lua_State *L, int coltypes, const SQLHSTMT hstmt, 
        SQLUSMALLINT i) {
    const char *tname;
    char type;
    /* get column type from types table */
	lua_rawgeti (L, LUA_REGISTRYINDEX, coltypes);
	lua_rawgeti (L, -1, i);	/* typename of the column */
    tname = lua_tostring(L, -1);
    if (!tname)
		return luasql_faildirect(L, "invalid type in table.");
    type = tname[1];
    lua_pop(L, 2);	/* pops type name and coltypes table */

    /* deal with data according to type */
    switch (type) {
        /* nUmber */
        case 'u': { 
			double num;
			SQLINTEGER got;
			SQLRETURN rc = SQLGetData(hstmt, i, SQL_C_DOUBLE, &num, 0, &got);
			if (error(rc))
				return fail(L, hSTMT, hstmt);
			if (got == SQL_NULL_DATA)
				lua_pushnil(L);
			else
				lua_pushnumber(L, num);
			return 0;
		}
                  /* bOol */
        case 'o': { 
			char b;
			SQLINTEGER got;
			SQLRETURN rc = SQLGetData(hstmt, i, SQL_C_BIT, &b, 0, &got);
			if (error(rc))
				return fail(L, hSTMT, hstmt);
			if (got == SQL_NULL_DATA)
				lua_pushnil(L);
			else
				lua_pushboolean(L, b);
			return 0;
		}
        /* sTring */
        case 't': 
        /* bInary */
        case 'i': { 
			SQLSMALLINT stype = (type == 't') ? SQL_C_CHAR : SQL_C_BINARY;
			SQLINTEGER got;
			char *buffer;
			luaL_Buffer b;
			SQLRETURN rc;
			luaL_buffinit(L, &b);
			buffer = luaL_prepbuffer(&b);
			rc = SQLGetData(hstmt, i, stype, buffer, LUAL_BUFFERSIZE, &got);
			if (got == SQL_NULL_DATA) {
				lua_pushnil(L);
				return 0;
			}
			/* concat intermediary chunks */
			while (rc == SQL_SUCCESS_WITH_INFO) {
				if (got >= LUAL_BUFFERSIZE || got == SQL_NO_TOTAL) {
					got = LUAL_BUFFERSIZE;
					/* get rid of null termination in string block */
					if (stype == SQL_C_CHAR) got--;
				}
				luaL_addsize(&b, got);
				buffer = luaL_prepbuffer(&b);
				rc = SQLGetData(hstmt, i, stype, buffer, 
					LUAL_BUFFERSIZE, &got);
			}
			/* concat last chunk */
			if (rc == SQL_SUCCESS) {
				if (got >= LUAL_BUFFERSIZE || got == SQL_NO_TOTAL) {
					got = LUAL_BUFFERSIZE;
					/* get rid of null termination in string block */
					if (stype == SQL_C_CHAR) got--;
				}
				luaL_addsize(&b, got);
			}
			if (rc == SQL_ERROR) return fail(L, hSTMT, hstmt);
			/* return everything we got */
			luaL_pushresult(&b);
			return 0;
		}
    }
    return 0;
}
コード例 #11
0
//--------------------------------------------------------------------
static void https_send_read_request_rsp_cb(VMUINT16 request_id,
                                           VMUINT8 result,
                                           VMUINT16 status,
                                           VMINT32 cause,
                                           VMUINT8 protocol,
                                           VMUINT32 content_length,
                                           VMBOOL more,
                                           VMUINT8* content_type,
                                           VMUINT8 content_type_len,
                                           VMUINT8* new_url,
                                           VMUINT32 new_url_len,
                                           VMUINT8* reply_header,
                                           VMUINT32 reply_header_len,
                                           VMUINT8* reply_segment,
                                           VMUINT32 reply_segment_len)
{
    int ret = -1;

    if(result != 0) {
        vm_https_cancel(request_id);
        vm_https_unset_channel(g_channel_id);
    } else {
        g_request_id = request_id;
    	if (g_https_header_cb_ref != LUA_NOREF) {
			int i;
			luaL_Buffer b;

			lua_rawgeti(L, LUA_REGISTRYINDEX, g_https_header_cb_ref);
			if ((lua_type(L, -1) != LUA_TFUNCTION) && (lua_type(L, -1) != LUA_TLIGHTFUNCTION)) {
			  // * BAD CB function reference
			  lua_remove(L, -1);
			}
			else {
				luaL_buffinit(L, &b);
				for(i = 0; i < reply_header_len; i++) {
					luaL_addchar(&b, reply_header[i]);
				}
				luaL_pushresult(&b);
				lua_call(L, 1, 0);
			}
    	}
    	else {
    		fputs("\n--- Header: ---\n", stdout);
			for(int i = 0; i < reply_header_len; i++) {
				fputc(reply_header[i], stdout);
			}
    		fputs("\n---------------\n", stdout);
			fflush(stdout);
    	}

    	if (g_https_response_cb_ref != LUA_NOREF) {
			int i;
			luaL_Buffer b;

			lua_rawgeti(L, LUA_REGISTRYINDEX, g_https_response_cb_ref);
			if ((lua_type(L, -1) != LUA_TFUNCTION) && (lua_type(L, -1) != LUA_TLIGHTFUNCTION)) {
			  // * BAD CB function reference
			  lua_remove(L, -1);
			}
			else {
				luaL_buffinit(L, &b);
				for(i = 0; i < reply_segment_len; i++) {
					luaL_addchar(&b, reply_segment[i]);
				}
				luaL_pushresult(&b);
				lua_pushinteger(L, more);
				lua_call(L, 2, 0);
			}
    	}
    	else {
			for(int i = 0; i < reply_segment_len; i++) {
				fputc(reply_segment[i], stdout);
			}
			fflush(stdout);
    	}

        if(more) {
            ret = vm_https_read_content(request_id, ++g_read_seg_num, 128);
            if(ret != 0) {
                vm_https_cancel(request_id);
                vm_https_unset_channel(g_channel_id);
            }
        }
    }
}
コード例 #12
0
ファイル: lstrlib.c プロジェクト: BackupTheBerlios/gltron-svn
static int str_format (lua_State *L) {
    int arg = 1;
    const char *strfrmt = luaL_check_string(L, arg);
    luaL_Buffer b;
    luaL_buffinit(L, &b);
    while (*strfrmt) {
        if (*strfrmt != '%')
            luaL_putchar(&b, *strfrmt++);
        else if (*++strfrmt == '%')
            luaL_putchar(&b, *strfrmt++);  /* %% */
        else { /* format item */
            struct Capture cap;
            char form[MAX_FORMAT];  /* to store the format ('%...') */
            char buff[MAX_ITEM];  /* to store the formatted item */
            const char *initf = strfrmt;
            form[0] = '%';
            if (isdigit((unsigned char)*initf) && *(initf+1) == '$') {
                arg = *initf - '0';
                initf += 2;  /* skip the 'n$' */
            }
            arg++;
            cap.src_end = strfrmt+strlen(strfrmt)+1;
            cap.level = 0;
            strfrmt = match(L, initf, "[-+ #0]*(%d*)%.?(%d*)", &cap);
            if (cap.capture[0].len > 2 || cap.capture[1].len > 2 ||  /* < 100? */
                    strfrmt-initf > MAX_FORMAT-2)
                lua_error(L, "invalid format (width or precision too long)");
            strncpy(form+1, initf, strfrmt-initf+1); /* +1 to include conversion */
            form[strfrmt-initf+2] = 0;
            switch (*strfrmt++) {
            case 'c':
            case 'd':
            case 'i':
                sprintf(buff, form, luaL_check_int(L, arg));
                break;
            case 'o':
            case 'u':
            case 'x':
            case 'X':
                sprintf(buff, form, (unsigned int)luaL_check_number(L, arg));
                break;
            case 'e':
            case 'E':
            case 'f':
            case 'g':
            case 'G':
                sprintf(buff, form, luaL_check_number(L, arg));
                break;
            case 'q':
                luaI_addquoted(L, &b, arg);
                continue;  /* skip the "addsize" at the end */
            case 's': {
                size_t l;
                const char *s = luaL_check_lstr(L, arg, &l);
                if (cap.capture[1].len == 0 && l >= 100) {
                    /* no precision and string is too long to be formatted;
                       keep original string */
                    lua_pushvalue(L, arg);
                    luaL_addvalue(&b);
                    continue;  /* skip the "addsize" at the end */
                }
                else {
                    sprintf(buff, form, s);
                    break;
                }
            }
            default:  /* also treat cases 'pnLlh' */
                lua_error(L, "invalid option in `format'");
            }
            luaL_addlstring(&b, buff, strlen(buff));
        }
    }
    luaL_pushresult(&b);
    return 1;
}
コード例 #13
0
ファイル: log.c プロジェクト: alcoheca/jivelite
static int do_log(lua_State *L, enum log_priority priority, bool_t stacktrace) {
	LOG_CATEGORY *category;
	luaL_Buffer buf;
	lua_Debug ar;
	char *src;
	int i, argc;

	/* stack is:
	 * 1: log category
	 * 2: message...
	 */

	category = lua_touserdata(L, 1);
	if (!category) {
		return 0;
	};

	if (log_category_get_priority(category) < priority) {
		return 0;
	}

	argc = lua_gettop(L);

	/* calling function */
	lua_getstack(L, 1, &ar);
	lua_getinfo(L, "Sl", &ar);

	src = ar.short_src + strlen(ar.short_src);
	while (src-- > ar.short_src) {
		if (*src == '/') {
			src++;
			break;
		}
	}

	luaL_buffinit(L, &buf);

	/* log arguments */
	for (i=2; i<=argc; i++) {
		lua_getglobal(L, "tostring");
		lua_pushvalue(L, i);
		lua_call(L, 1, 1);

		luaL_addvalue(&buf);
	}

	luaL_pushresult(&buf);

	/* optional stack trace */
	if (stacktrace) {
		lua_getglobal(L, "debug");
		lua_getfield(L, -1, "traceback");
		lua_pushvalue(L, -3);
		lua_pushinteger(L, 2);
		lua_call(L, 2, 1);
	}

	log_category_log(category, priority, "%s:%d %s", src, ar.currentline, lua_tostring(L, -1));

	return 0;
}
コード例 #14
0
ファイル: error.c プロジェクト: anhk/lua-xmlreader
/* Mostly ripped from code in parser.c and error.c in libxml. Not ideal, but 
 * it seems impossible to hook into libxml's error string generation */
int xml_push_error(lua_State *L, xmlErrorPtr err) {
  if (err==NULL)
    luaL_error(L, "a NULL error was raised. Should not happen");

  char *file = err->file;
  int line = err->line;
/*  int code = err->code; */
  int domain = err->domain;
  xmlErrorLevel level = err->level;
  const xmlChar *name = NULL;
  xmlNodePtr node = err->node;

  luaL_Buffer buf;
  luaL_buffinit(L, &buf);
  luaL_Buffer *B = &buf;

  if ((node != NULL) && (node->type == XML_ELEMENT_NODE))
    name = node->name;

  if (file != NULL) {
    lua_pushfstring(L, "%s:%d: ", file, line);
    luaL_addvalue(B);
  } else if ((line != 0) && (domain == XML_FROM_PARSER)) {
    lua_pushfstring(L, "Entity: line %d: ", line);
    luaL_addvalue(B);
  }

  if (name != NULL) {
    lua_pushfstring(L, "element %s: ", name);
    luaL_addvalue(B);
  }

  switch (domain) {
    case XML_FROM_PARSER:
      luaL_addstring(B, "parser ");
      break;
    case XML_FROM_NAMESPACE:
      luaL_addstring(B, "namespace ");
      break;
    case XML_FROM_DTD:
    case XML_FROM_VALID:
      luaL_addstring(B, "validity ");
      break;
    case XML_FROM_HTML:
      luaL_addstring(B, "HTML parser ");
      break;
    case XML_FROM_MEMORY:
      luaL_addstring(B, "memory ");
      break;
    case XML_FROM_OUTPUT:
      luaL_addstring(B, "output ");
      break;
    case XML_FROM_IO:
      luaL_addstring(B, "I/O ");
      break;
    case XML_FROM_XINCLUDE:
      luaL_addstring(B, "XInclude ");
      break;
    case XML_FROM_XPATH:
      luaL_addstring(B, "XPath ");
      break;
    case XML_FROM_XPOINTER:
      luaL_addstring(B, "parser ");
      break;
    case XML_FROM_REGEXP:
      luaL_addstring(B, "regexp ");
      break;
    case XML_FROM_MODULE:
      luaL_addstring(B, "module ");
      break;
    case XML_FROM_SCHEMASV:
      luaL_addstring(B, "Schemas validity ");
      break;
    case XML_FROM_SCHEMASP:
      luaL_addstring(B, "Schemas parser ");
      break;
    case XML_FROM_RELAXNGP:
      luaL_addstring(B, "Relax-NG parser ");
      break;
    case XML_FROM_RELAXNGV:
      luaL_addstring(B, "Relax-NG validity ");
      break;
    case XML_FROM_CATALOG:
      luaL_addstring(B, "Catalog ");
      break;
    case XML_FROM_C14N:
      luaL_addstring(B, "C14N ");
      break;
    case XML_FROM_XSLT:
      luaL_addstring(B, "XSLT ");
      break;
    case XML_FROM_I18N:
      luaL_addstring(B, "encoding ");
      break;
    default:
      break;
  }
  switch (level) {
    case XML_ERR_NONE:
      luaL_addstring(B, ": ");
      break;
    case XML_ERR_WARNING:
      luaL_addstring(B, "warning : ");
      break;
    case XML_ERR_ERROR:
      luaL_addstring(B, "error : ");
      break;
    case XML_ERR_FATAL:
      luaL_addstring(B, "error : ");
      break;
  }

  if (err->message)
    luaL_addstring(B, err->message);

  luaL_pushresult(B);
  return 1;
}
コード例 #15
0
ファイル: tools.c プロジェクト: Rocket-Buddha/GameCode4
static void inter_copy_func( lua_State *L2, uint_t L2_cache_i, lua_State *L, uint_t i ) {

    lua_CFunction cfunc= lua_tocfunction( L,i );
    unsigned n;

    ASSERT_L( L2_cache_i != 0 );

  STACK_GROW(L,2);

  STACK_CHECK(L)
    if (!cfunc) {   // Lua function
        luaL_Buffer b;
        const char *s;
        size_t sz;
        int tmp;
        const char *name= NULL;

#if 0
        // "To get information about a function you push it onto the 
        // stack and start the what string with the character '>'."
        //
        { lua_Debug ar;
        lua_pushvalue( L, i );
        lua_getinfo(L, ">n", &ar);      // fills 'name' and 'namewhat', pops function
        name= ar.namewhat;
        
        fprintf( stderr, "NAME: %s\n", name );  // just gives NULL
        }
#endif 
        // 'lua_dump()' needs the function at top of stack
        //
        if (i!=-1) lua_pushvalue( L, i );

        luaL_buffinit(L,&b);
        tmp= lua_dump(L, buf_writer, &b);
        ASSERT_L(tmp==0);
            //
            // "value returned is the error code returned by the last call 
            // to the writer" (and we only return 0)

        luaL_pushresult(&b);    // pushes dumped string on 'L'
        s= lua_tolstring(L,-1,&sz);
        ASSERT_L( s && sz );

        if (i!=-1) lua_remove( L, -2 );

        // Note: Line numbers seem to be taken precisely from the 
        //       original function. 'name' is not used since the chunk
        //       is precompiled (it seems...). 
        //
        // TBD: Can we get the function's original name through, as well?
        //
        if (luaL_loadbuffer(L2, s, sz, name) != 0) {
            // chunk is precompiled so only LUA_ERRMEM can happen
            // "Otherwise, it pushes an error message"
            //
            STACK_GROW( L,1 );
            luaL_error( L, "%s", lua_tostring(L2,-1) );
        }
        lua_pop(L,1);   // remove the dumped string
  STACK_MID(L,0)
    }
コード例 #16
0
ファイル: lstrlib.c プロジェクト: guodawei/lua
static int str_pack (lua_State *L) {
  luaL_Buffer b;
  Header h;
  const char *fmt = luaL_checkstring(L, 1);  /* format string */
  int arg = 1;  /* current argument to pack */
  size_t totalsize = 0;  /* accumulate total size of result */
  initheader(L, &h);
  lua_pushnil(L);  /* mark to separate arguments from string buffer */
  luaL_buffinit(L, &b);
  while (*fmt != '\0') {
    int size, ntoalign;
    KOption opt = getdetails(&h, totalsize, &fmt, &size, &ntoalign);
    totalsize += ntoalign + size;
    while (ntoalign-- > 0)
     luaL_addchar(&b, LUAL_PACKPADBYTE);  /* fill alignment */
    arg++;
    switch (opt) {
      case Kint: {  /* signed integers */
        lua_Integer n = luaL_checkinteger(L, arg);
        if (size < SZINT) {  /* need overflow check? */
          lua_Integer lim = (lua_Integer)1 << ((size * NB) - 1);
          luaL_argcheck(L, -lim <= n && n < lim, arg, "integer overflow");
        }
        packint(&b, (lua_Unsigned)n, h.islittle, size, (n < 0));
        break;
      }
      case Kuint: {  /* unsigned integers */
        lua_Integer n = luaL_checkinteger(L, arg);
        if (size < SZINT)  /* need overflow check? */
          luaL_argcheck(L, (lua_Unsigned)n < ((lua_Unsigned)1 << (size * NB)),
                           arg, "unsigned overflow");
        packint(&b, (lua_Unsigned)n, h.islittle, size, 0);
        break;
      }
      case Kfloat: {  /* floating-point options */
        volatile Ftypes u;
        char *buff = luaL_prepbuffsize(&b, size);
        lua_Number n = luaL_checknumber(L, arg);  /* get argument */
        if (size == sizeof(u.f)) u.f = (float)n;  /* copy it into 'u' */
        else if (size == sizeof(u.d)) u.d = (double)n;
        else u.n = n;
        /* move 'u' to final result, correcting endianness if needed */
        copywithendian(buff, u.buff, size, h.islittle);
        luaL_addsize(&b, size);
        break;
      }
      case Kchar: {  /* fixed-size string */
        size_t len;
        const char *s = luaL_checklstring(L, arg, &len);
        luaL_argcheck(L, len <= (size_t)size, arg,
                         "string longer than given size");
        luaL_addlstring(&b, s, len);  /* add string */
        while (len++ < (size_t)size)  /* pad extra space */
          luaL_addchar(&b, LUAL_PACKPADBYTE);
        break;
      }
      case Kstring: {  /* strings with length count */
        size_t len;
        const char *s = luaL_checklstring(L, arg, &len);
        luaL_argcheck(L, size >= (int)sizeof(size_t) ||
                         len < ((size_t)1 << (size * NB)),
                         arg, "string length does not fit in given size");
        packint(&b, (lua_Unsigned)len, h.islittle, size, 0);  /* pack length */
        luaL_addlstring(&b, s, len);
        totalsize += len;
        break;
      }
      case Kzstr: {  /* zero-terminated string */
        size_t len;
        const char *s = luaL_checklstring(L, arg, &len);
        luaL_argcheck(L, strlen(s) == len, arg, "string contains zeros");
        luaL_addlstring(&b, s, len);
        luaL_addchar(&b, '\0');  /* add zero at the end */
        totalsize += len + 1;
        break;
      }
      case Kpadding: luaL_addchar(&b, LUAL_PACKPADBYTE);  /* FALLTHROUGH */
      case Kpaddalign: case Knop:
        arg--;  /* undo increment */
        break;
    }
  }
  luaL_pushresult(&b);
  return 1;
}
コード例 #17
0
ファイル: jive.c プロジェクト: gnalbandian/squeezeplay
/* paths_setup
** Modify the lua path and cpath, prepending standard directories
** relative to this executable.
*/
static void paths_setup(lua_State *L, char *app) {
	char *temp, *binpath, *path;
	
	temp = malloc(PATH_MAX+1);
	if (!temp) {
		l_message("Error", "malloc failure for temp");
		exit(-1);
	}
	binpath = malloc(PATH_MAX+1);
	if (!binpath) {
		l_message("Error", "malloc failure for binpath");
		exit(-1);
	}
	path = malloc(PATH_MAX+1);
	if (!path) {
		l_message("Error", "malloc failure for path");
		exit(-1);
	}

	// full path to jive binary
	if (app[0] == '/') {
		// we were called with a full path
		strcpy(path, app);
	}
	else {
		// add working dir + app and resolve
		getcwd(temp, PATH_MAX+1);
		strcat(temp, "/");       
		strcat(temp, app);
		realpath(temp, path);
	}

	// directory containing jive
	strcpy(binpath, dirname(path));

	// set paths in lua (package.path & package cpath)
	lua_getglobal(L, "package");
	if (lua_istable(L, -1)) {
		luaL_Buffer b;
		luaL_buffinit(L, &b);

		// default lua path
		lua_getfield(L, -1, "path");
		luaL_addvalue(&b);
		luaL_addstring(&b, ";");

		// lua path relative to executable
#if !defined(WIN32)
		strcpy(temp, binpath);
		strcat(temp, "/../share/lua/5.1");
		realpath(temp, path);
#endif

		luaL_addstring(&b, path);
		luaL_addstring(&b, DIR_SEPARATOR_STR "?.lua;");
		luaL_addstring(&b, path);
		luaL_addstring(&b, DIR_SEPARATOR_STR "?" DIR_SEPARATOR_STR "?.lua;");

		// script path relative to executale
		strcpy(temp, binpath);
		strcat(temp, "/" LUA_DEFAULT_PATH);
		realpath(temp, path);

		luaL_addstring(&b, path);
		luaL_addstring(&b, DIR_SEPARATOR_STR "?.lua;");

		// script path relative to CWD
		getcwd(temp, PATH_MAX+1);
		strcat(temp, "/" LUA_DEFAULT_PATH );
		realpath(temp, path);

		luaL_addstring(&b, path);
		luaL_addstring(&b, DIR_SEPARATOR_STR "?.lua;");

		// lua path relative to CWD
		getcwd(temp, PATH_MAX+1);
		strcat(temp, "/../share/lua/5.1");
		realpath(temp, path);

		luaL_addstring(&b, path);
		luaL_addstring(&b, DIR_SEPARATOR_STR "?.lua;");
		luaL_addstring(&b, path);
		luaL_addstring(&b, DIR_SEPARATOR_STR "?" DIR_SEPARATOR_STR "?.lua;");

		// set lua path
		luaL_pushresult(&b);
		lua_setfield(L, -2, "path");

		luaL_buffinit(L, &b);

		// default lua cpath
		lua_getfield(L, -1, "cpath");
		luaL_addvalue(&b);
		luaL_addstring(&b, ";");

		// lua cpath
#if !defined(WIN32)
		strcpy(temp, binpath);
		strcat(temp, "/../lib/lua/5.1");
		realpath(temp, path);
#endif

		luaL_addstring(&b, path);
		luaL_addstring(&b, DIR_SEPARATOR_STR "?." LIBRARY_EXT ";");
		luaL_addstring(&b, path);
		luaL_addstring(&b, DIR_SEPARATOR_STR "?" DIR_SEPARATOR_STR "core." LIBRARY_EXT ";");

		// cpath relative to executable
		strcpy(temp, binpath);
		strcat(temp, "/" LUA_DEFAULT_PATH);
		realpath(temp, path);

		luaL_addstring(&b, path);
		luaL_addstring(&b, DIR_SEPARATOR_STR "?." LIBRARY_EXT ";");

		// cpath relative to CWD
		getcwd(temp, PATH_MAX+1);
		strcat(temp, "/../lib/lua/5.1");
		realpath(temp, path);

		luaL_addstring(&b, path);
		luaL_addstring(&b, DIR_SEPARATOR_STR "?." LIBRARY_EXT ";");

		// set lua cpath
		luaL_pushresult(&b);

		lua_setfield(L, -2, "cpath");
	}
	else {
		l_message("Error", "'package' is not a table");
	}

	// pop package table off the stack
	lua_pop(L, 1); 

	free(temp);
	free(binpath);
	free(path);
}
コード例 #18
0
static int str_format (lua_State *L) {
  int arg = 1;
  size_t sfl;
  const char *strfrmt = luaL_checklstring(L, arg, &sfl);
  const char *strfrmt_end = strfrmt+sfl;
  luaL_Buffer b;
  luaL_buffinit(L, &b);
  while (strfrmt < strfrmt_end) {
    if (*strfrmt != '%')
      luaL_putchar(&b, *strfrmt++);
    else if (*++strfrmt == '%')
      luaL_putchar(&b, *strfrmt++);  /* %% */
    else { /* format item */
      char form[MAX_FORMAT];  /* to store the format (`%...') */
      char buff[MAX_ITEM];  /* to store the formatted item */
      int hasprecision = 0;
      if (isdigit(uchar(*strfrmt)) && *(strfrmt+1) == '$')
        return luaL_error(L, "obsolete option (d$) to `format'");
      arg++;
      strfrmt = scanformat(L, strfrmt, form, &hasprecision);
      switch (*strfrmt++) {
        case 'c':  case 'd':  case 'i': {
          sprintf(buff, form, luaL_checkint(L, arg));
          break;
        }
        case 'o':  case 'u':  case 'x':  case 'X': {
          sprintf(buff, form, (unsigned int)(luaL_checknumber(L, arg)));
          break;
        }
        case 'e':  case 'E': case 'f':
        case 'g': case 'G': {
          sprintf(buff, form, luaL_checknumber(L, arg));
          break;
        }
        case 'q': {
          luaI_addquoted(L, &b, arg);
          continue;  /* skip the `addsize' at the end */
        }
        case 's': {
          size_t l;
          const char *s = luaL_checklstring(L, arg, &l);
          if (!hasprecision && l >= 100) {
            /* no precision and string is too long to be formatted;
               keep original string */
            lua_pushvalue(L, arg);
            luaL_addvalue(&b);
            continue;  /* skip the `addsize' at the end */
          }
          else {
            sprintf(buff, form, s);
            break;
          }
        }
        default: {  /* also treat cases `pnLlh' */
          return luaL_error(L, "invalid option to `format'");
        }
      }
      luaL_addlstring(&b, buff, strlen(buff));
    }
  }
  luaL_pushresult(&b);
  return 1;
}
コード例 #19
0
ファイル: headerinfo.c プロジェクト: benpop/lua-headerinfo
static int headerinfo (lua_State *L) {
  const char *dump;
  lua_settop(L, 1);
  if (lua_isnil(L, 1)) {
    if (luaL_loadstring(L, "return function () end") != LUA_OK)
      return Error(L, "unable to load dummy function");
    lua_replace(L, 1);
  }
  switch (lua_type(L, 1)) {
    case LUA_TSTRING: {
      size_t l;
      dump = lua_tolstring(L, 1, &l);
      if (l < HEADERSIZE || strncmp(LUA_SIGNATURE, dump, SIGSIZE) != 0)
        return Error(L, "not a valid Lua function dump");
      break;
    }
    case LUA_TFUNCTION: {
      luaL_Buffer b;
      luaL_buffinit(L, &b);
      if (lua_dump(L, Writer, &b) != LUA_OK)
        return Error(L, "unable to dump given function");
      luaL_pushresult(&b);
      lua_replace(L, 1);
      dump = lua_tostring(L, 1);
      break;
    }
    default: {
      return Error(L, "not a function or function dump");
    }
  }

  lua_createtable(L, 0, INFOSIZE);

  {
    int major = (GetInfo(dump, 0) >> 4);
    int minor = (GetInfo(dump, 0) & 0xf);
    lua_pushfstring(L, "%d.%d", major, minor);
    lua_setfield(L, 2, "version");
  }

  lua_pushinteger(L, GetInfo(dump, 1));
  lua_setfield(L, 2, "format");

  lua_pushstring(L, (GetInfo(dump, 2) ? "little-endian" : "big-endian"));
  lua_setfield(L, 2, "endianness");

  lua_pushinteger(L, GetInfo(dump, 3));
  lua_setfield(L, 2, "int_size");

  lua_pushinteger(L, GetInfo(dump, 4));
  lua_setfield(L, 2, "size_size");

  lua_pushinteger(L, GetInfo(dump, 5));
  lua_setfield(L, 2, "instruction_size");

  lua_pushinteger(L, GetInfo(dump, 6));
  lua_setfield(L, 2, "number_size");

  lua_pushboolean(L, GetInfo(dump, 7));
  lua_setfield(L, 2, "number_is_int");

  return 1;
}
コード例 #20
0
ファイル: lbaselib.c プロジェクト: ueverything/mmo-resourse
static int luaB_towstring (lua_State *L) {
  char buff[64];
  switch (lua_type(L, 1)) {
    case LUA_TNUMBER:
      lua_pushwstring(L, lua_towstring(L, 1));
      return 1;
    case LUA_TSTRING: {
	 luaL_Buffer b;
	 size_t l;
	 size_t i;
	 const char *s = lua_tostring(L, 1);
	 l = lua_strlen(L, 1);
	 if (l == 0)
	 {
	     lua_pushwstring(L, L"");
	 }
	 else
	 {
		 luaL_wbuffinit(L, &b);
		 for (i=0; i<l; i++)
			luaL_putwchar(&b, (lua_WChar)s[i]);
		 luaL_pushresult(&b);
	 }
      return 1;
    }
    case LUA_TWSTRING:
      lua_pushvalue(L, 1);
      return 1;
    case LUA_TTABLE:
      sprintf(buff, "%.40s: %p", lua_type(L, 1), lua_topointer(L, 1));
      break;
    case LUA_TFUNCTION:
      sprintf(buff, "function: %p", lua_topointer(L, 1));
      break;
    case LUA_TUSERDATA: {
      const char *t = lua_typename(L, lua_type(L, 1));
      if (strcmp(t, "userdata") == 0)
        sprintf(buff, "userdata: %p", lua_touserdata(L, 1));
      else
        sprintf(buff, "%.40s: %p", t, lua_touserdata(L, 1));
      break;
    }
    case LUA_TNIL:
      lua_pushliteral(L, "nil");
      return 1;
    case LUA_TTHREAD:
      sprintf(buff, "thread: %p", (void *)lua_tothread(L, 1));
      break;
    default:
      luaL_argerror(L, 1, "value expected");
  }

  {
	 luaL_Buffer b;
	 size_t l;
	 size_t i;
	 const lua_WChar *s = lua_towstring(L, 1);
	 l = lua_strlen(L, 1);
	 luaL_wbuffinit(L, &b);
	 for (i=0; i<l; i++)
		luaL_putwchar(&b, (lua_WChar)(s[i]));
	 luaL_pushresult(&b);
  }

/*  lua_pushstring(L, buff);*/
  return 1;
}
コード例 #21
0
ファイル: lwstrlib.c プロジェクト: anissen/WikiAdventure
static int str_lualex(lua_State *L) {
  size_t l = 0;
  const lua_WChar *str = luaL_checklwstring(L, 1, &l);
  int isWide = luaL_checkint(L, 2) != 0;
  size_t i;
  luaL_Buffer b;
  luaL_wbuffinit(L, &b);

  for (i = 0; i < l; ++i)
  {
//	int needUnicodeZero = 1;

    switch (str[i])
	{
      case '\\':
		++i;
        switch (str[i]) {
          case 'a': luaL_putwchar(&b, '\a'); break;
          case 'b': luaL_putwchar(&b, '\b'); break;
          case 'f': luaL_putwchar(&b, '\f'); break;
          case 'n': luaL_putwchar(&b, '\n'); break;
          case 'r': luaL_putwchar(&b, '\r'); break;
          case 't': luaL_putwchar(&b, '\t'); break;
          case 'v': luaL_putwchar(&b, '\v'); break;
          case 'x': {
			  int ch;
			  ++i;
			  ch = tolower(str[i]);
              if (!isdigit(ch) && !(ch >= 'a' && ch <= 'f') )
			  {
				  --i;
				  luaL_putwchar(&b, 'x');
			  }
			  else {  /* \xxx */
				  int c = 0;
				  int i = 0;
				  int numDigits = isWide ? 4 : 2;
				  do {
					  ch = towlower(str[i]);
					  if (iswdigit((wint_t)ch))
					    c = 16*c + (ch-'0');
					  else if (ch >= 'a' && ch <= 'f')
						c = 16*c + (ch-'a') + 10;
					  ++i;
					  ch = towlower(str[i]);
				  } while (++i<numDigits && iswdigit((wint_t)ch) || (ch >= 'a' && ch <= 'f'));
				  luaL_putwchar(&b, c);
//				  needUnicodeZero = 0;
			  }
			  break;
          }
          default: {
            if (!iswdigit(str[i]))
				luaL_putwchar(&b, str[i]);
            else {  /* \xxx */
              int c = 0;
              int count = 0;
              do {
                c = 10*c + (str[i]-'0');
				++i;
              } while (++count<3 && iswdigit(str[i]));
              luaL_putwchar(&b, c);
            }
          }
        }
        break;
      default:
		  luaL_putwchar(&b, str[i]);
    }
	if (isWide) //  &&  needUnicodeZero)
	  luaL_putwchar(&b, str[i]);
  }

  luaL_pushresult(&b);
  return 1;
}
コード例 #22
0
ファイル: ls_firebird.c プロジェクト: hugohuang1111/moai-dev
/*
** Pushes the indexed value onto the lua stack
*/
static void push_column(lua_State *L, int i, cur_data *cur) {
    int varcharlen;
    struct tm timevar;
    char timestr[256];
    ISC_STATUS blob_stat;
    isc_blob_handle blob_handle = NULL;
    ISC_QUAD blob_id;
    luaL_Buffer b;
    char *buffer;
    unsigned short actual_seg_len;

    if( (cur->out_sqlda->sqlvar[i].sqlind != NULL) &&
            (*(cur->out_sqlda->sqlvar[i].sqlind) != 0) ) {
        /* a null field? */
        lua_pushnil(L);
    } else {
        switch(cur->out_sqlda->sqlvar[i].sqltype & ~1) {
        case SQL_VARYING:
            varcharlen = (int)isc_vax_integer(cur->out_sqlda->sqlvar[i].sqldata, 2);
            lua_pushlstring(L, cur->out_sqlda->sqlvar[i].sqldata+2, varcharlen);
            break;
        case SQL_TEXT:
            lua_pushlstring(L, cur->out_sqlda->sqlvar[i].sqldata, cur->out_sqlda->sqlvar[i].sqllen);
            break;
        case SQL_SHORT:
            lua_pushnumber(L, *(short*)(cur->out_sqlda->sqlvar[i].sqldata));
            break;
        case SQL_LONG:
            lua_pushnumber(L, *(long*)(cur->out_sqlda->sqlvar[i].sqldata));
            break;
        case SQL_INT64:
            lua_pushnumber(L, (lua_Number)*(ISC_INT64*)(cur->out_sqlda->sqlvar[i].sqldata));
            break;
        case SQL_FLOAT:
            lua_pushnumber(L, *(float*)(cur->out_sqlda->sqlvar[i].sqldata));
            break;
        case SQL_DOUBLE:
            lua_pushnumber(L, *(double*)(cur->out_sqlda->sqlvar[i].sqldata));
            break;
        case SQL_TYPE_TIME:
            isc_decode_sql_time((ISC_TIME*)(cur->out_sqlda->sqlvar[i].sqldata), &timevar);
            strftime(timestr, 255, "%X", &timevar);
            lua_pushstring(L, timestr);
            break;
        case SQL_TYPE_DATE:
            isc_decode_sql_date((ISC_DATE*)(cur->out_sqlda->sqlvar[i].sqldata), &timevar);
            strftime(timestr, 255, "%x", &timevar);
            lua_pushstring(L, timestr);
            break;
        case SQL_TIMESTAMP:
            isc_decode_timestamp((ISC_TIMESTAMP*)(cur->out_sqlda->sqlvar[i].sqldata), &timevar);
            strftime(timestr, 255, "%x %X", &timevar);
            lua_pushstring(L, timestr);
            break;
        case SQL_BLOB:
            /* get the BLOB ID and open it */
            memcpy(&blob_id, cur->out_sqlda->sqlvar[i].sqldata, sizeof(ISC_QUAD));
            isc_open_blob2(	cur->env->status_vector,
                            &cur->conn->db, &cur->conn->transaction,
                            &blob_handle, &blob_id, 0, NULL );
            /* fetch the blob data */
            luaL_buffinit(L, &b);
            buffer = luaL_prepbuffer(&b);

            blob_stat = isc_get_segment(	cur->env->status_vector,
                                            &blob_handle, &actual_seg_len,
                                            LUAL_BUFFERSIZE, buffer );
            while(blob_stat == 0 || cur->env->status_vector[1] == isc_segment) {
                luaL_addsize(&b, actual_seg_len);
                buffer = luaL_prepbuffer(&b);
                blob_stat = isc_get_segment(	cur->env->status_vector,
                                                &blob_handle, &actual_seg_len,
                                                LUAL_BUFFERSIZE, buffer );
            }

            /* finnished, close the BLOB */
            isc_close_blob(cur->env->status_vector, &blob_handle);
            blob_handle = NULL;

            luaL_pushresult(&b);
            break;
        default:
            lua_pushstring(L, "<unsupported data type>");
            break;
        }
    }
}
コード例 #23
0
ファイル: liolib.cpp プロジェクト: philm001/Omni-FEM
static int errorfb (lua_State *L) {
  int level = 1;  /* skip level 0 (it's this function) */
  int firstpart = 1;  /* still before eventual `...' */
  lua_Debug ar;
  luaL_Buffer b;
  luaL_buffinit(L, &b);
  luaL_addstring(&b, "error: ");
  luaL_addstring(&b, luaL_check_string(L, 1));
  luaL_addstring(&b, "\n");
  while (lua_getstack(L, level++, &ar)) {
    char buff[120];  /* enough to fit following `sprintf's */
    if (level == 2)
      luaL_addstring(&b, "stack traceback:\n");
    else if (level > LEVELS1 && firstpart) {
      /* no more than `LEVELS2' more levels? */
      if (!lua_getstack(L, level+LEVELS2, &ar))
        level--;  /* keep going */
      else {
        luaL_addstring(&b, "       ...\n");  /* too many levels */
        while (lua_getstack(L, level+LEVELS2, &ar))  /* find last levels */
          level++;
      }
      firstpart = 0;
      continue;
    }
    sprintf(buff, "%4d:  ", level-1);
    luaL_addstring(&b, buff);
    lua_getinfo(L, "Snl", &ar);
    switch (*ar.namewhat) {
      case 'g':  case 'l':  /* global, local */
        sprintf(buff, "function `%.50s'", ar.name);
        break;
      case 'f':  /* field */
        sprintf(buff, "method `%.50s'", ar.name);
        break;
      case 't':  /* tag method */
        sprintf(buff, "`%.50s' tag method", ar.name);
        break;
      default: {
        if (*ar.what == 'm')  /* main? */
          sprintf(buff, "main of %.70s", ar.short_src);
        else if (*ar.what == 'C')  /* C function? */
          sprintf(buff, "%.70s", ar.short_src);
        else
          sprintf(buff, "function <%d:%.70s>", ar.linedefined, ar.short_src);
        ar.source = NULL;  /* do not print source again */
      }
    }
    luaL_addstring(&b, buff);
    if (ar.currentline > 0) {
      sprintf(buff, " at line %d", ar.currentline);
      luaL_addstring(&b, buff);
    }
    if (ar.source) {
      sprintf(buff, " [%.70s]", ar.short_src);
      luaL_addstring(&b, buff);
    }
    luaL_addstring(&b, "\n");
  }
  luaL_pushresult(&b);
  lua_getglobal(L, LUA_ALERT);
  if (lua_isfunction(L, -1)) {  /* avoid loop if _ALERT is not defined */
    lua_pushvalue(L, -2);  /* error message */
    lua_rawcall(L, 1, 0);
  }
  return 0;
}
コード例 #24
0
ファイル: lzlib.c プロジェクト: live-clones/luatex
static int lzlib_compress(lua_State *L)
{
    const char *next_in = luaL_checkstring(L, 1);
    int avail_in = lua_rawlen(L, 1);
    int level = luaL_optint(L, 2, Z_DEFAULT_COMPRESSION);
    int method = luaL_optint(L, 3, Z_DEFLATED);
    int windowBits = luaL_optint(L, 4, 15);
    int memLevel = luaL_optint(L, 5, 8);
    int strategy = luaL_optint(L, 6, Z_DEFAULT_STRATEGY);

    int ret;
    z_stream zs;
    luaL_Buffer b;
    luaL_buffinit(L, &b);

    zs.zalloc = Z_NULL;
    zs.zfree = Z_NULL;

    zs.next_out = Z_NULL;
    zs.avail_out = 0;
    zs.next_in = Z_NULL;
    zs.avail_in = 0;

    ret = deflateInit2(&zs, level, method, windowBits, memLevel, strategy);

    if (ret != Z_OK)
    {
        lua_pushnil(L);
        lua_pushnumber(L, ret);
        return 2;
    }

    zs.next_in = (Bytef*)next_in;
    zs.avail_in = avail_in;

    for(;;)
    {
        zs.next_out = (Bytef*)luaL_prepbuffer(&b);
        zs.avail_out = LUAL_BUFFERSIZE;

        /* munch some more */
        ret = deflate(&zs, Z_FINISH);

        /* push gathered data */
        luaL_addsize(&b, LUAL_BUFFERSIZE - zs.avail_out);

        /* done processing? */
        if (ret == Z_STREAM_END)
            break;

        /* error condition? */
        if (ret != Z_OK)
            break;
    }

    /* cleanup */
    deflateEnd(&zs);

    luaL_pushresult(&b);
    lua_pushnumber(L, ret);
    return 2;
}
コード例 #25
0
ファイル: pbc-lua53.c プロジェクト: doublefox1981/pbc
/*
	lightuserdata pattern
	string format "ixrsmbp"
	integer size
 */
static int
_pattern_pack(lua_State *L) {
	struct pbc_pattern * pat = (struct pbc_pattern *)checkuserdata(L,1);
	if (pat == NULL) {
		return luaL_error(L, "pack pattern is NULL");
	}
	size_t format_sz = 0;
	const char * format = lua_tolstring(L,2,&format_sz);
	int size = lua_tointeger(L,3);

	char * data = (char *)alloca(size);
//	A trick , we don't need default value. zero buffer for array and message field.
//	pbc_pattern_set_default(pat, data);
	memset(data, 0 , size);

	char * ptr = data;

	int i;

	for (i=0;i<format_sz;i++) {
		if (format[i] >= 'a' && format[i] <='z') {
			ptr = _get_value(L, 4+i, ptr, format[i]);
		} else {
			if (!lua_istable(L,4+i)) {
				luaL_error(L,"need table for array type");
			}
			int j;
			int n = lua_rawlen(L,4+i);
			for (j=0;j<n;j++) {
				lua_rawgeti(L,4+i,j+1);
				_get_array_value(L,(struct _pbc_array *)ptr,format[i]);
				lua_pop(L,1);
			}
			ptr += sizeof(pbc_array);
		}
	}

	luaL_Buffer b;
	luaL_buffinit(L, &b);

	int cap = 128;
	for (;;) {
		char * temp = (char *)luaL_prepbuffsize(&b , cap);

		struct pbc_slice slice;
		slice.buffer = temp;
		slice.len = cap;

		int ret = pbc_pattern_pack(pat, data, &slice);

		if (ret < 0) {
			cap = cap * 2;
			continue;
		}

		luaL_addsize(&b , slice.len);
		break;
	}
	luaL_pushresult(&b);

	pbc_pattern_close_arrays(pat, data);
	return 1;
}
コード例 #26
0
ファイル: script.c プロジェクト: khwangster/wrk2
void script_header_done(lua_State *L, luaL_Buffer *buffer) {
    luaL_pushresult(buffer);
}
コード例 #27
0
ファイル: lstrlib.c プロジェクト: aronarts/FireNET
static int str_format (lua_State *L) {
  int arg = 1;
  size_t sfl;
  const char *strfrmt = luaL_checklstring(L, arg, &sfl);
  const char *strfrmt_end = strfrmt+sfl;
  luaL_Buffer b;
  luaL_buffinit(L, &b);
  while (strfrmt < strfrmt_end) {
    if (*strfrmt != L_ESC)
      luaL_addchar(&b, *strfrmt++);
    else if (*++strfrmt == L_ESC)
      luaL_addchar(&b, *strfrmt++);  /* %% */
    else { /* format item */
      char form[MAX_FORMAT];  /* to store the format (`%...') */
      char buff[MAX_ITEM];  /* to store the formatted item */
      arg++;
      strfrmt = scanformat(L, strfrmt, form);
      switch (*strfrmt++) {
        case 'c': {
          sprintf(buff, form, (int)luaL_checknumber(L, arg));
          break;
        }
        case 'd':  case 'i': {
          addintlen(form);
          sprintf(buff, form, (LUA_INTFRM_T)luaL_checknumber(L, arg));
          break;
        }
        case 'o':  case 'u':  case 'x':  case 'X': {
          addintlen(form);
          sprintf(buff, form, (unsigned LUA_INTFRM_T)luaL_checknumber(L, arg));
          break;
        }
        case 'e':  case 'E': case 'f':
        case 'g': case 'G': {
          sprintf(buff, form, (double)luaL_checknumber(L, arg));
          break;
        }
        case 'q': {
          addquoted(L, &b, arg);
          continue;  /* skip the 'addsize' at the end */
        }
        case 's': {
          size_t l;
          const char *s = luaL_checklstring(L, arg, &l);
          if (!strchr(form, '.') && l >= 100) {
            /* no precision and string is too long to be formatted;
               keep original string */
            lua_pushvalue(L, arg);
            luaL_addvalue(&b);
            continue;  /* skip the `addsize' at the end */
          }
          else {
            sprintf(buff, form, s);
            break;
          }
        }
        default: {  /* also treat cases `pnLlh' */
          return luaL_error(L, "invalid option " LUA_QL("%%%c") " to "
                               LUA_QL("format"), *(strfrmt - 1));
        }
      }
      luaL_addlstring(&b, buff, strlen(buff));
    }
  }
  luaL_pushresult(&b);
  return 1;
}
コード例 #28
0
ファイル: luaproc.c プロジェクト: tcoram/luaproc
/* create and schedule a new lua process */
static int luaproc_create_newproc( lua_State *L ) {

  size_t len;
  luaproc *lp;
  luaL_Buffer buff;
  const char *code;
  int d;
  int lt = lua_type( L, 1 );

  /* check function argument type - must be function or string; in case it is
     a function, dump it into a binary string */
  if ( lt == LUA_TFUNCTION ) {
    lua_settop( L, 1 );
    luaL_buffinit( L, &buff );
    d = dump( L, luaproc_buff_writer, &buff, FALSE );
    if ( d != 0 ) {
      lua_pushnil( L );
      lua_pushfstring( L, "error %d dumping function to binary string", d );
      return 2;
    }
    luaL_pushresult( &buff );
    lua_insert( L, 1 );
  } else if ( lt != LUA_TSTRING ) {
    lua_pushnil( L );
    lua_pushfstring( L, "cannot use '%s' to create a new process",
                     luaL_typename( L, 1 ));
    return 2;
  }

  /* get pointer to code string */
  code = lua_tolstring( L, 1, &len );

  /* get exclusive access to recycled lua processes list */
  pthread_mutex_lock( &mutex_recycle_list );

  /* check if a lua process can be recycled */
  if ( recyclemax > 0 ) {
    lp = list_remove( &recycle_list );
    /* otherwise create a new lua process */
    if ( lp == NULL ) {
      lp = luaproc_new( L );
    }
  } else {
    lp = luaproc_new( L );
  }

  /* release exclusive access to recycled lua processes list */
  pthread_mutex_unlock( &mutex_recycle_list );

  /* init lua process */
  lp->status = LUAPROC_STATUS_IDLE;
  lp->args   = 0;
  lp->chan   = NULL;

  /* load code in lua process */
  luaproc_loadbuffer( L, lp, code, len );

  /* if lua process is being created from a function, copy its upvalues and
     remove dumped binary string from stack */
  if ( lt == LUA_TFUNCTION ) {
    if ( luaproc_copyupvalues( L, lp->lstate, 2 ) == FALSE ) {
      luaproc_recycle_insert( lp ); 
      return 2;
    }
    lua_pop( L, 1 );
  }

  sched_inc_lpcount();   /* increase active lua process count */
  sched_queue_proc( lp );  /* schedule lua process for execution */
  lua_pushboolean( L, TRUE );

  return 1;
}
コード例 #29
0
ファイル: lxplib.c プロジェクト: WeyrSDev/gamecode3
/*
** Check whether there is pending Cdata, and call its handle if necessary
*/
static void dischargestring (lxp_userdata *xpu) {
  assert(xpu->state == XPSstring);
  xpu->state = XPSok;
  luaL_pushresult(xpu->b);
  docall(xpu, 1, 0);
}
コード例 #30
0
ファイル: lstrlib.c プロジェクト: guodawei/lua
static int str_format (lua_State *L) {
  int top = lua_gettop(L);
  int arg = 1;
  size_t sfl;
  const char *strfrmt = luaL_checklstring(L, arg, &sfl);
  const char *strfrmt_end = strfrmt+sfl;
  luaL_Buffer b;
  luaL_buffinit(L, &b);
  while (strfrmt < strfrmt_end) {
    if (*strfrmt != L_ESC)
      luaL_addchar(&b, *strfrmt++);
    else if (*++strfrmt == L_ESC)
      luaL_addchar(&b, *strfrmt++);  /* %% */
    else { /* format item */
      char form[MAX_FORMAT];  /* to store the format ('%...') */
      char *buff = luaL_prepbuffsize(&b, MAX_ITEM);  /* to put formatted item */
      int nb = 0;  /* number of bytes in added item */
      if (++arg > top)
        luaL_argerror(L, arg, "no value");
      strfrmt = scanformat(L, strfrmt, form);
      switch (*strfrmt++) {
        case 'c': {
          nb = l_sprintf(buff, MAX_ITEM, form, (int)luaL_checkinteger(L, arg));
          break;
        }
        case 'd': case 'i':
        case 'o': case 'u': case 'x': case 'X': {
          lua_Integer n = luaL_checkinteger(L, arg);
          addlenmod(form, LUA_INTEGER_FRMLEN);
          nb = l_sprintf(buff, MAX_ITEM, form, (LUAI_UACINT)n);
          break;
        }
        case 'a': case 'A':
          addlenmod(form, LUA_NUMBER_FRMLEN);
          nb = lua_number2strx(L, buff, MAX_ITEM, form,
                                  luaL_checknumber(L, arg));
          break;
        case 'e': case 'E': case 'f':
        case 'g': case 'G': {
          lua_Number n = luaL_checknumber(L, arg);
          addlenmod(form, LUA_NUMBER_FRMLEN);
          nb = l_sprintf(buff, MAX_ITEM, form, (LUAI_UACNUMBER)n);
          break;
        }
        case 'q': {
          addliteral(L, &b, arg);
          break;
        }
        case 's': {
          size_t l;
          const char *s = luaL_tolstring(L, arg, &l);
          if (form[2] == '\0')  /* no modifiers? */
            luaL_addvalue(&b);  /* keep entire string */
          else {
            luaL_argcheck(L, l == strlen(s), arg, "string contains zeros");
            if (!strchr(form, '.') && l >= 100) {
              /* no precision and string is too long to be formatted */
              luaL_addvalue(&b);  /* keep entire string */
            }
            else {  /* format the string into 'buff' */
              nb = l_sprintf(buff, MAX_ITEM, form, s);
              lua_pop(L, 1);  /* remove result from 'luaL_tolstring' */
            }
          }
          break;
        }
        default: {  /* also treat cases 'pnLlh' */
          return luaL_error(L, "invalid option '%%%c' to 'format'",
                               *(strfrmt - 1));
        }
      }
      lua_assert(nb < MAX_ITEM);
      luaL_addsize(&b, nb);
    }
  }
  luaL_pushresult(&b);
  return 1;
}