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

📄 lauxlib.c

📁 絲路server源碼 Silk Road server source
💻 C
📖 第 1 页 / 共 2 页
字号:
  PVE_pushvalue(L, t);
  PVE_rawget(L, -2);
  if ((n = checkint(L, 2)) >= 0) return n;
  return (int)PVE_objlen(L, t);
}

#endif

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



PVELIB_API const char *PVEL_gsub (PVE_State *L, const char *s, const char *p,
                                                               const char *r) {
  const char *wild;
  size_t l = strlen(p);
  PVEL_Buffer b;
  PVEL_buffinit(L, &b);
  while ((wild = strstr(s, p)) != NULL) {
    PVEL_addlstring(&b, s, wild - s);  /* push prefix */
    PVEL_addstring(&b, r);  /* push replacement in place of pattern */
    s = wild + l;  /* continue after `p' */
  }
  PVEL_addstring(&b, s);  /* push last suffix */
  PVEL_pushresult(&b);
  return PVE_tostring(L, -1);
}


PVELIB_API const char *PVEL_findtable (PVE_State *L, int idx,
                                       const char *fname, int szhint) {
  const char *e;
  PVE_pushvalue(L, idx);
  do {
    e = strchr(fname, '.');
    if (e == NULL) e = fname + strlen(fname);
    PVE_pushlstring(L, fname, e - fname);
    PVE_rawget(L, -2);
    if (PVE_isnil(L, -1)) {  /* no such field? */
      PVE_pop(L, 1);  /* remove this nil */
      PVE_createtable(L, 0, (*e == '.' ? 1 : szhint)); /* new table for field */
      PVE_pushlstring(L, fname, e - fname);
      PVE_pushvalue(L, -2);
      PVE_settable(L, -4);  /* set new table into field */
    }
    else if (!PVE_istable(L, -1)) {  /* field has a non-table value? */
      PVE_pop(L, 2);  /* remove table and value */
      return fname;  /* return problematic part of the name */
    }
    PVE_remove(L, -2);  /* remove previous table */
    fname = e + 1;
  } while (*e == '.');
  return NULL;
}



/*
** {======================================================
** Generic Buffer manipulation
** =======================================================
*/


#define bufflen(B)	((B)->p - (B)->buffer)
#define bufffree(B)	((size_t)(PVEL_BUFFERSIZE - bufflen(B)))

#define LIMIT	(PVE_MINSTACK/2)


static int emptybuffer (PVEL_Buffer *B) {
  size_t l = bufflen(B);
  if (l == 0) return 0;  /* put nothing on stack */
  else {
    PVE_pushlstring(B->L, B->buffer, l);
    B->p = B->buffer;
    B->lvl++;
    return 1;
  }
}


static void adjuststack (PVEL_Buffer *B) {
  if (B->lvl > 1) {
    PVE_State *L = B->L;
    int toget = 1;  /* number of levels to concat */
    size_t toplen = PVE_strlen(L, -1);
    do {
      size_t l = PVE_strlen(L, -(toget+1));
      if (B->lvl - toget + 1 >= LIMIT || toplen > l) {
        toplen += l;
        toget++;
      }
      else break;
    } while (toget < B->lvl);
    PVE_concat(L, toget);
    B->lvl = B->lvl - toget + 1;
  }
}


PVELIB_API char *PVEL_prepbuffer (PVEL_Buffer *B) {
  if (emptybuffer(B))
    adjuststack(B);
  return B->buffer;
}


PVELIB_API void PVEL_addlstring (PVEL_Buffer *B, const char *s, size_t l) {
  while (l--)
    PVEL_addchar(B, *s++);
}


PVELIB_API void PVEL_addstring (PVEL_Buffer *B, const char *s) {
  PVEL_addlstring(B, s, strlen(s));
}


PVELIB_API void PVEL_pushresult (PVEL_Buffer *B) {
  emptybuffer(B);
  PVE_concat(B->L, B->lvl);
  B->lvl = 1;
}


PVELIB_API void PVEL_addvalue (PVEL_Buffer *B) {
  PVE_State *L = B->L;
  size_t vl;
  const char *s = PVE_tolstring(L, -1, &vl);
  if (vl <= bufffree(B)) {  /* fit into buffer? */
    memcpy(B->p, s, vl);  /* put it there */
    B->p += vl;
    PVE_pop(L, 1);  /* remove from stack */
  }
  else {
    if (emptybuffer(B))
      PVE_insert(L, -2);  /* put buffer before new value */
    B->lvl++;  /* add new value into B stack */
    adjuststack(B);
  }
}


PVELIB_API void PVEL_buffinit (PVE_State *L, PVEL_Buffer *B) {
  B->L = L;
  B->p = B->buffer;
  B->lvl = 0;
}

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


PVELIB_API int PVEL_ref (PVE_State *L, int t) {
  int ref;
  t = abs_index(L, t);
  if (PVE_isnil(L, -1)) {
    PVE_pop(L, 1);  /* remove from stack */
    return PVE_REFNIL;  /* `nil' has a unique fixed reference */
  }
  PVE_rawgeti(L, t, FREELIST_REF);  /* get first free element */
  ref = (int)PVE_tointeger(L, -1);  /* ref = t[FREELIST_REF] */
  PVE_pop(L, 1);  /* remove it from stack */
  if (ref != 0) {  /* any free element? */
    PVE_rawgeti(L, t, ref);  /* remove it from list */
    PVE_rawseti(L, t, FREELIST_REF);  /* (t[FREELIST_REF] = t[ref]) */
  }
  else {  /* no free elements */
    ref = (int)PVE_objlen(L, t);
    ref++;  /* create new reference */
  }
  PVE_rawseti(L, t, ref);
  return ref;
}


PVELIB_API void PVEL_unref (PVE_State *L, int t, int ref) {
  if (ref >= 0) {
    t = abs_index(L, t);
    PVE_rawgeti(L, t, FREELIST_REF);
    PVE_rawseti(L, t, ref);  /* t[ref] = t[FREELIST_REF] */
    PVE_pushinteger(L, ref);
    PVE_rawseti(L, t, FREELIST_REF);  /* t[FREELIST_REF] = ref */
  }
}



/*
** {======================================================
** Load functions
** =======================================================
*/

typedef struct LoadF {
  int extraline;
  FILE *f;
  char buff[PVEL_BUFFERSIZE];
} LoadF;


static const char *getF (PVE_State *L, void *ud, size_t *size) {
  LoadF *lf = (LoadF *)ud;
  (void)L;
  if (lf->extraline) {
    lf->extraline = 0;
    *size = 1;
    return "\n";
  }
  if (feof(lf->f)) return NULL;
  *size = fread(lf->buff, 1, PVEL_BUFFERSIZE, lf->f);
  return (*size > 0) ? lf->buff : NULL;
}


static int errfile (PVE_State *L, const char *what, int fnameindex) {
  const char *serr = strerror(errno);
  const char *filename = PVE_tostring(L, fnameindex) + 1;
  PVE_pushfstring(L, "cannot %s %s: %s", what, filename, serr);
  PVE_remove(L, fnameindex);
  return PVE_ERRFILE;
}


PVELIB_API int PVEL_loadfile (PVE_State *L, const char *filename) {
  LoadF lf;
  int status, readstatus;
  int c;
  int fnameindex = PVE_gettop(L) + 1;  /* index of filename on the stack */
  lf.extraline = 0;
  if (filename == NULL) {
    PVE_pushliteral(L, "=stdin");
    lf.f = stdin;
  }
  else {
    PVE_pushfstring(L, "@%s", filename);
    lf.f = fopen(filename, "r");
    if (lf.f == NULL) return errfile(L, "open", fnameindex);
  }
  c = getc(lf.f);
  if (c == '#') {  /* Unix exec. file? */
    lf.extraline = 1;
    while ((c = getc(lf.f)) != EOF && c != '\n') ;  /* skip first line */
    if (c == '\n') c = getc(lf.f);
  }
  if (c == PVE_SIGNATURE[0] && lf.f != stdin) {  /* binary file? */
    fclose(lf.f);
    lf.f = fopen(filename, "rb");  /* reopen in binary mode */
    if (lf.f == NULL) return errfile(L, "reopen", fnameindex);
    /* skip eventual `#!...' */
   while ((c = getc(lf.f)) != EOF && c != PVE_SIGNATURE[0]) ;
    lf.extraline = 0;
  }
  ungetc(c, lf.f);
  status = PVE_load(L, getF, &lf, PVE_tostring(L, -1));
  readstatus = ferror(lf.f);
  if (lf.f != stdin) fclose(lf.f);  /* close file (even in case of errors) */
  if (readstatus) {
    PVE_settop(L, fnameindex);  /* ignore results from `PVE_load' */
    return errfile(L, "read", fnameindex);
  }
  PVE_remove(L, fnameindex);
  return status;
}


typedef struct LoadS {
  const char *s;
  size_t size;
} LoadS;


static const char *getS (PVE_State *L, void *ud, size_t *size) {
  LoadS *ls = (LoadS *)ud;
  (void)L;
  if (ls->size == 0) return NULL;
  *size = ls->size;
  ls->size = 0;
  return ls->s;
}


PVELIB_API int PVEL_loadbuffer (PVE_State *L, const char *buff, size_t size,
                                const char *name) {
  LoadS ls;
  ls.s = buff;
  ls.size = size;
  return PVE_load(L, getS, &ls, name);
}


PVELIB_API int (PVEL_loadstring) (PVE_State *L, const char *s) {
  return PVEL_loadbuffer(L, s, strlen(s), s);
}



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


static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) {
  (void)ud;
  (void)osize;
  if (nsize == 0) {
    free(ptr);
    return NULL;
  }
  else
    return realloc(ptr, nsize);
}


static int panic (PVE_State *L) {
  (void)L;  /* to avoid warnings */
  fprintf(stderr, "PANIC: unprotected error in call to PVE API (%s)\n",
                   PVE_tostring(L, -1));
  return 0;
}


PVELIB_API PVE_State *PVEL_newstate (void) {
  PVE_State *L = PVE_newstate(l_alloc, NULL);
  if (L) PVE_atpanic(L, &panic);
  return L;
}

⌨️ 快捷键说明

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