📄 lauxlib.c.svn-base
字号:
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 + -