⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lbaselib.c.svn-base

📁 絲路server源碼 Silk Road server source
💻 SVN-BASE
📖 第 1 页 / 共 2 页
字号:
/*
** $Id: lbaselib.c,v 1.191a 2006/06/02 15:34:00 roberto Exp $
** Basic library
** See Copyright Notice in PVE.h
*/



#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define lbaselib_c
#define PVE_LIB

#include "PVE.h"

#include "lauxlib.h"
#include "PVElib.h"




/*
** If your system does not support `stdout', you can just remove this function.
** If you need, you can define your own `print' function, following this
** model but changing `fputs' to put the strings at a proper place
** (a console window or a log file, for instance).
*/
static int PVEB_print (PVE_State *L) {
  int n = PVE_gettop(L);  /* number of arguments */
  int i;
  PVE_getglobal(L, "tostring");
  for (i=1; i<=n; i++) {
    const char *s;
    PVE_pushvalue(L, -1);  /* function to be called */
    PVE_pushvalue(L, i);   /* value to print */
    PVE_call(L, 1, 1);
    s = PVE_tostring(L, -1);  /* get result */
    if (s == NULL)
      return PVEL_error(L, PVE_QL("tostring") " must return a string to "
                           PVE_QL("print"));
    if (i>1) fputs("\t", stdout);
    fputs(s, stdout);
    PVE_pop(L, 1);  /* pop result */
  }
  fputs("\n", stdout);
  return 0;
}


static int PVEB_tonumber (PVE_State *L) {
  int base = PVEL_optint(L, 2, 10);
  if (base == 10) {  /* standard conversion */
    PVEL_checkany(L, 1);
    if (PVE_isnumber(L, 1)) {
      PVE_pushnumber(L, PVE_tonumber(L, 1));
      return 1;
    }
  }
  else {
    const char *s1 = PVEL_checkstring(L, 1);
    char *s2;
    unsigned long n;
    PVEL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range");
    n = strtoul(s1, &s2, base);
    if (s1 != s2) {  /* at least one valid digit? */
      while (isspace((unsigned char)(*s2))) s2++;  /* skip trailing spaces */
      if (*s2 == '\0') {  /* no invalid trailing characters? */
        PVE_pushnumber(L, (PVE_Number)n);
        return 1;
      }
    }
  }
  PVE_pushnil(L);  /* else not a number */
  return 1;
}


static int PVEB_error (PVE_State *L) {
  int level = PVEL_optint(L, 2, 1);
  PVE_settop(L, 1);
  if (PVE_isstring(L, 1) && level > 0) {  /* add extra information? */
    PVEL_where(L, level);
    PVE_pushvalue(L, 1);
    PVE_concat(L, 2);
  }
  return PVE_error(L);
}


static int PVEB_getmetatable (PVE_State *L) {
  PVEL_checkany(L, 1);
  if (!PVE_getmetatable(L, 1)) {
    PVE_pushnil(L);
    return 1;  /* no metatable */
  }
  PVEL_getmetafield(L, 1, "__metatable");
  return 1;  /* returns either __metatable field (if present) or metatable */
}


static int PVEB_setmetatable (PVE_State *L) {
  int t = PVE_type(L, 2);
  PVEL_checktype(L, 1, PVE_TTABLE);
  PVEL_argcheck(L, t == PVE_TNIL || t == PVE_TTABLE, 2,
                    "nil or table expected");
  if (PVEL_getmetafield(L, 1, "__metatable"))
    PVEL_error(L, "cannot change a protected metatable");
  PVE_settop(L, 2);
  PVE_setmetatable(L, 1);
  return 1;
}


static void getfunc (PVE_State *L, int opt) {
  if (PVE_isfunction(L, 1)) PVE_pushvalue(L, 1);
  else {
    PVE_Debug ar;
    int level = opt ? PVEL_optint(L, 1, 1) : PVEL_checkint(L, 1);
    PVEL_argcheck(L, level >= 0, 1, "level must be non-negative");
    if (PVE_getstack(L, level, &ar) == 0)
      PVEL_argerror(L, 1, "invalid level");
    PVE_getinfo(L, "f", &ar);
    if (PVE_isnil(L, -1))
      PVEL_error(L, "no function environment for tail call at level %d",
                    level);
  }
}


static int PVEB_getfenv (PVE_State *L) {
  getfunc(L, 1);
  if (PVE_iscfunction(L, -1))  /* is a C function? */
    PVE_pushvalue(L, PVE_GLOBALSINDEX);  /* return the thread's global env. */
  else
    PVE_getfenv(L, -1);
  return 1;
}


static int PVEB_setfenv (PVE_State *L) {
  PVEL_checktype(L, 2, PVE_TTABLE);
  getfunc(L, 0);
  PVE_pushvalue(L, 2);
  if (PVE_isnumber(L, 1) && PVE_tonumber(L, 1) == 0) {
    /* change environment of current thread */
    PVE_pushthread(L);
    PVE_insert(L, -2);
    PVE_setfenv(L, -2);
    return 0;
  }
  else if (PVE_iscfunction(L, -2) || PVE_setfenv(L, -2) == 0)
    PVEL_error(L,
          PVE_QL("setfenv") " cannot change environment of given object");
  return 1;
}


static int PVEB_rawequal (PVE_State *L) {
  PVEL_checkany(L, 1);
  PVEL_checkany(L, 2);
  PVE_pushboolean(L, PVE_rawequal(L, 1, 2));
  return 1;
}


static int PVEB_rawget (PVE_State *L) {
  PVEL_checktype(L, 1, PVE_TTABLE);
  PVEL_checkany(L, 2);
  PVE_settop(L, 2);
  PVE_rawget(L, 1);
  return 1;
}

static int PVEB_rawset (PVE_State *L) {
  PVEL_checktype(L, 1, PVE_TTABLE);
  PVEL_checkany(L, 2);
  PVEL_checkany(L, 3);
  PVE_settop(L, 3);
  PVE_rawset(L, 1);
  return 1;
}


static int PVEB_gcinfo (PVE_State *L) {
  PVE_pushinteger(L, PVE_getgccount(L));
  return 1;
}


static int PVEB_collectgarbage (PVE_State *L) {
  static const char *const opts[] = {"stop", "restart", "collect",
    "count", "step", "setpause", "setstepmul", NULL};
  static const int optsnum[] = {PVE_GCSTOP, PVE_GCRESTART, PVE_GCCOLLECT,
    PVE_GCCOUNT, PVE_GCSTEP, PVE_GCSETPAUSE, PVE_GCSETSTEPMUL};
  int o = PVEL_checkoption(L, 1, "collect", opts);
  int ex = PVEL_optint(L, 2, 0);
  int res = PVE_gc(L, optsnum[o], ex);
  switch (optsnum[o]) {
    case PVE_GCCOUNT: {
      int b = PVE_gc(L, PVE_GCCOUNTB, 0);
      PVE_pushnumber(L, res + ((PVE_Number)b/1024));
      return 1;
    }
    case PVE_GCSTEP: {
      PVE_pushboolean(L, res);
      return 1;
    }
    default: {
      PVE_pushnumber(L, res);
      return 1;
    }
  }
}


static int PVEB_type (PVE_State *L) {
  PVEL_checkany(L, 1);
  PVE_pushstring(L, PVEL_typename(L, 1));
  return 1;
}


static int PVEB_next (PVE_State *L) {
  PVEL_checktype(L, 1, PVE_TTABLE);
  PVE_settop(L, 2);  /* create a 2nd argument if there isn't one */
  if (PVE_next(L, 1))
    return 2;
  else {
    PVE_pushnil(L);
    return 1;
  }
}


static int PVEB_pairs (PVE_State *L) {
  PVEL_checktype(L, 1, PVE_TTABLE);
  PVE_pushvalue(L, PVE_upvalueindex(1));  /* return generator, */
  PVE_pushvalue(L, 1);  /* state, */
  PVE_pushnil(L);  /* and initial value */
  return 3;
}


static int ipairsaux (PVE_State *L) {
  int i = PVEL_checkint(L, 2);
  PVEL_checktype(L, 1, PVE_TTABLE);
  i++;  /* next value */
  PVE_pushinteger(L, i);
  PVE_rawgeti(L, 1, i);
  return (PVE_isnil(L, -1)) ? 0 : 2;
}


static int PVEB_ipairs (PVE_State *L) {
  PVEL_checktype(L, 1, PVE_TTABLE);
  PVE_pushvalue(L, PVE_upvalueindex(1));  /* return generator, */
  PVE_pushvalue(L, 1);  /* state, */
  PVE_pushinteger(L, 0);  /* and initial value */
  return 3;
}


static int load_aux (PVE_State *L, int status) {
  if (status == 0)  /* OK? */
    return 1;
  else {
    PVE_pushnil(L);
    PVE_insert(L, -2);  /* put before error message */
    return 2;  /* return nil plus error message */
  }
}


static int PVEB_loadstring (PVE_State *L) {
  size_t l;
  const char *s = PVEL_checklstring(L, 1, &l);
  const char *chunkname = PVEL_optstring(L, 2, s);
  return load_aux(L, PVEL_loadbuffer(L, s, l, chunkname));
}


static int PVEB_loadfile (PVE_State *L) {
  const char *fname = PVEL_optstring(L, 1, NULL);
  return load_aux(L, PVEL_loadfile(L, fname));
}


/*
** Reader for generic `load' function: `PVE_load' uses the
** stack for internal stuff, so the reader cannot change the
** stack top. Instead, it keeps its resulting string in a
** reserved slot inside the stack.
*/
static const char *generic_reader (PVE_State *L, void *ud, size_t *size) {
  (void)ud;  /* to avoid warnings */
  PVEL_checkstack(L, 2, "too many nested functions");
  PVE_pushvalue(L, 1);  /* get function */
  PVE_call(L, 0, 1);  /* call it */
  if (PVE_isnil(L, -1)) {
    *size = 0;
    return NULL;
  }
  else if (PVE_isstring(L, -1)) {
    PVE_replace(L, 3);  /* save string in a reserved stack slot */
    return PVE_tolstring(L, 3, size);
  }
  else PVEL_error(L, "reader function must return a string");
  return NULL;  /* to avoid warnings */
}


static int PVEB_load (PVE_State *L) {
  int status;
  const char *cname = PVEL_optstring(L, 2, "=(load)");
  PVEL_checktype(L, 1, PVE_TFUNCTION);
  PVE_settop(L, 3);  /* function, eventual name, plus one reserved slot */
  status = PVE_load(L, generic_reader, NULL, cname);
  return load_aux(L, status);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -