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

📄 lbaselib.c.svn-base

📁 絲路server源碼 Silk Road server source
💻 SVN-BASE
📖 第 1 页 / 共 2 页
字号:


static int PVEB_dofile (PVE_State *L) {
  const char *fname = PVEL_optstring(L, 1, NULL);
  int n = PVE_gettop(L);
  if (PVEL_loadfile(L, fname) != 0) PVE_error(L);
  PVE_call(L, 0, PVE_MULTRET);
  return PVE_gettop(L) - n;
}


static int PVEB_assert (PVE_State *L) {
  PVEL_checkany(L, 1);
  if (!PVE_toboolean(L, 1))
    return PVEL_error(L, "%s", PVEL_optstring(L, 2, "assertion failed!"));
  return PVE_gettop(L);
}


static int PVEB_unpack (PVE_State *L) {
  int i, e, n;
  PVEL_checktype(L, 1, PVE_TTABLE);
  i = PVEL_optint(L, 2, 1);
  e = PVEL_opt(L, PVEL_checkint, 3, PVEL_getn(L, 1));
  n = e - i + 1;  /* number of elements */
  if (n <= 0) return 0;  /* empty range */
  PVEL_checkstack(L, n, "table too big to unpack");
  for (; i<=e; i++)  /* push arg[i...e] */
    PVE_rawgeti(L, 1, i);
  return n;
}


static int PVEB_select (PVE_State *L) {
  int n = PVE_gettop(L);
  if (PVE_type(L, 1) == PVE_TSTRING && *PVE_tostring(L, 1) == '#') {
    PVE_pushinteger(L, n-1);
    return 1;
  }
  else {
    int i = PVEL_checkint(L, 1);
    if (i < 0) i = n + i;
    else if (i > n) i = n;
    PVEL_argcheck(L, 1 <= i, 1, "index out of range");
    return n - i;
  }
}


static int PVEB_pcall (PVE_State *L) {
  int status;
  PVEL_checkany(L, 1);
  status = PVE_pcall(L, PVE_gettop(L) - 1, PVE_MULTRET, 0);
  PVE_pushboolean(L, (status == 0));
  PVE_insert(L, 1);
  return PVE_gettop(L);  /* return status + all results */
}


static int PVEB_xpcall (PVE_State *L) {
  int status;
  PVEL_checkany(L, 2);
  PVE_settop(L, 2);
  PVE_insert(L, 1);  /* put error function under function to be called */
  status = PVE_pcall(L, 0, PVE_MULTRET, 1);
  PVE_pushboolean(L, (status == 0));
  PVE_replace(L, 1);
  return PVE_gettop(L);  /* return status + all results */
}


static int PVEB_tostring (PVE_State *L) {
  PVEL_checkany(L, 1);
  if (PVEL_callmeta(L, 1, "__tostring"))  /* is there a metafield? */
    return 1;  /* use its value */
  switch (PVE_type(L, 1)) {
    case PVE_TNUMBER:
      PVE_pushstring(L, PVE_tostring(L, 1));
      break;
    case PVE_TSTRING:
      PVE_pushvalue(L, 1);
      break;
    case PVE_TBOOLEAN:
      PVE_pushstring(L, (PVE_toboolean(L, 1) ? "true" : "false"));
      break;
    case PVE_TNIL:
      PVE_pushliteral(L, "nil");
      break;
    default:
      PVE_pushfstring(L, "%s: %p", PVEL_typename(L, 1), PVE_topointer(L, 1));
      break;
  }
  return 1;
}


static int PVEB_newproxy (PVE_State *L) {
  PVE_settop(L, 1);
  PVE_newuserdata(L, 0);  /* create proxy */
  if (PVE_toboolean(L, 1) == 0)
    return 1;  /* no metatable */
  else if (PVE_isboolean(L, 1)) {
    PVE_newtable(L);  /* create a new metatable `m' ... */
    PVE_pushvalue(L, -1);  /* ... and mark `m' as a valid metatable */
    PVE_pushboolean(L, 1);
    PVE_rawset(L, PVE_upvalueindex(1));  /* weaktable[m] = true */
  }
  else {
    int validproxy = 0;  /* to check if weaktable[metatable(u)] == true */
    if (PVE_getmetatable(L, 1)) {
      PVE_rawget(L, PVE_upvalueindex(1));
      validproxy = PVE_toboolean(L, -1);
      PVE_pop(L, 1);  /* remove value */
    }
    PVEL_argcheck(L, validproxy, 1, "boolean or proxy expected");
    PVE_getmetatable(L, 1);  /* metatable is valid; get it */
  }
  PVE_setmetatable(L, 2);
  return 1;
}


static const PVEL_Reg base_funcs[] = {
  {"assert", PVEB_assert},
  {"collectgarbage", PVEB_collectgarbage},
  {"dofile", PVEB_dofile},
  {"error", PVEB_error},
  {"gcinfo", PVEB_gcinfo},
  {"getfenv", PVEB_getfenv},
  {"getmetatable", PVEB_getmetatable},
  {"loadfile", PVEB_loadfile},
  {"load", PVEB_load},
  {"loadstring", PVEB_loadstring},
  {"next", PVEB_next},
  {"pcall", PVEB_pcall},
  {"print", PVEB_print},
  {"rawequal", PVEB_rawequal},
  {"rawget", PVEB_rawget},
  {"rawset", PVEB_rawset},
  {"select", PVEB_select},
  {"setfenv", PVEB_setfenv},
  {"setmetatable", PVEB_setmetatable},
  {"tonumber", PVEB_tonumber},
  {"tostring", PVEB_tostring},
  {"type", PVEB_type},
  {"unpack", PVEB_unpack},
  {"xpcall", PVEB_xpcall},
  {NULL, NULL}
};


/*
** {======================================================
** Coroutine library
** =======================================================
*/

static int auxresume (PVE_State *L, PVE_State *co, int narg) {
  int status;
  if (!PVE_checkstack(co, narg))
    PVEL_error(L, "too many arguments to resume");
  if (PVE_status(co) == 0 && PVE_gettop(co) == 0) {
    PVE_pushliteral(L, "cannot resume dead coroutine");
    return -1;  /* error flag */
  }
  PVE_xmove(L, co, narg);
  status = PVE_resume(co, narg);
  if (status == 0 || status == PVE_YIELD) {
    int nres = PVE_gettop(co);
    if (!PVE_checkstack(L, nres))
      PVEL_error(L, "too many results to resume");
    PVE_xmove(co, L, nres);  /* move yielded values */
    return nres;
  }
  else {
    PVE_xmove(co, L, 1);  /* move error message */
    return -1;  /* error flag */
  }
}


static int PVEB_coresume (PVE_State *L) {
  PVE_State *co = PVE_tothread(L, 1);
  int r;
  PVEL_argcheck(L, co, 1, "coroutine expected");
  r = auxresume(L, co, PVE_gettop(L) - 1);
  if (r < 0) {
    PVE_pushboolean(L, 0);
    PVE_insert(L, -2);
    return 2;  /* return false + error message */
  }
  else {
    PVE_pushboolean(L, 1);
    PVE_insert(L, -(r + 1));
    return r + 1;  /* return true + `resume' returns */
  }
}


static int PVEB_auxwrap (PVE_State *L) {
  PVE_State *co = PVE_tothread(L, PVE_upvalueindex(1));
  int r = auxresume(L, co, PVE_gettop(L));
  if (r < 0) {
    if (PVE_isstring(L, -1)) {  /* error object is a string? */
      PVEL_where(L, 1);  /* add extra info */
      PVE_insert(L, -2);
      PVE_concat(L, 2);
    }
    PVE_error(L);  /* propagate error */
  }
  return r;
}


static int PVEB_cocreate (PVE_State *L) {
  PVE_State *NL = PVE_newthread(L);
  PVEL_argcheck(L, PVE_isfunction(L, 1) && !PVE_iscfunction(L, 1), 1,
    "PVE function expected");
  PVE_pushvalue(L, 1);  /* move function to top */
  PVE_xmove(L, NL, 1);  /* move function from L to NL */
  return 1;
}


static int PVEB_cowrap (PVE_State *L) {
  PVEB_cocreate(L);
  PVE_pushcclosure(L, PVEB_auxwrap, 1);
  return 1;
}


static int PVEB_yield (PVE_State *L) {
  return PVE_yield(L, PVE_gettop(L));
}


static int PVEB_costatus (PVE_State *L) {
  PVE_State *co = PVE_tothread(L, 1);
  PVEL_argcheck(L, co, 1, "coroutine expected");
  if (L == co) PVE_pushliteral(L, "running");
  else {
    switch (PVE_status(co)) {
      case PVE_YIELD:
        PVE_pushliteral(L, "suspended");
        break;
      case 0: {
        PVE_Debug ar;
        if (PVE_getstack(co, 0, &ar) > 0)  /* does it have frames? */
          PVE_pushliteral(L, "normal");  /* it is running */
        else if (PVE_gettop(co) == 0)
            PVE_pushliteral(L, "dead");
        else
          PVE_pushliteral(L, "suspended");  /* initial state */
        break;
      }
      default:  /* some error occured */
        PVE_pushliteral(L, "dead");
        break;
    }
  }
  return 1;
}


static int PVEB_corunning (PVE_State *L) {
  if (PVE_pushthread(L))
    return 0;  /* main thread is not a coroutine */
  else
    return 1;
}


static const PVEL_Reg co_funcs[] = {
  {"create", PVEB_cocreate},
  {"resume", PVEB_coresume},
  {"running", PVEB_corunning},
  {"status", PVEB_costatus},
  {"wrap", PVEB_cowrap},
  {"yield", PVEB_yield},
  {NULL, NULL}
};

/* }====================================================== */


static void auxopen (PVE_State *L, const char *name,
                     PVE_CFunction f, PVE_CFunction u) {
  PVE_pushcfunction(L, u);
  PVE_pushcclosure(L, f, 1);
  PVE_setfield(L, -2, name);
}


static void base_open (PVE_State *L) {
  /* set global _G */
  PVE_pushvalue(L, PVE_GLOBALSINDEX);
  PVE_setglobal(L, "_G");
  /* open lib into global table */
  PVEL_register(L, "_G", base_funcs);
  PVE_pushliteral(L, PVE_VERSION);
  PVE_setglobal(L, "_VERSION");  /* set global _VERSION */
  /* `ipairs' and `pairs' need auxliliary functions as upvalues */
  auxopen(L, "ipairs", PVEB_ipairs, ipairsaux);
  auxopen(L, "pairs", PVEB_pairs, PVEB_next);
  /* `newproxy' needs a weaktable as upvalue */
  PVE_createtable(L, 0, 1);  /* new table `w' */
  PVE_pushvalue(L, -1);  /* `w' will be its own metatable */
  PVE_setmetatable(L, -2);
  PVE_pushliteral(L, "kv");
  PVE_setfield(L, -2, "__mode");  /* metatable(w).__mode = "kv" */
  PVE_pushcclosure(L, PVEB_newproxy, 1);
  PVE_setglobal(L, "newproxy");  /* set global `newproxy' */
}


PVELIB_API int PVEopen_base (PVE_State *L) {
  base_open(L);
  PVEL_register(L, PVE_COLIBNAME, co_funcs);
  return 2;
}

⌨️ 快捷键说明

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