The Battle for Wesnoth  1.13.4+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
lobject.cpp
Go to the documentation of this file.
1 /*
2 ** Some generic functions over Lua objects
3 ** See Copyright Notice in lua.h
4 */
5 
6 #include <stdarg.h>
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10 
11 #define lobject_c
12 #define LUA_CORE
13 
14 #include "lua.h"
15 
16 #include "lctype.h"
17 #include "ldebug.h"
18 #include "ldo.h"
19 #include "lmem.h"
20 #include "lobject.h"
21 #include "lstate.h"
22 #include "lstring.h"
23 #include "lvm.h"
24 
25 
26 
28 
29 
30 /*
31 ** converts an integer to a "floating point byte", represented as
32 ** (eeeeexxx), where the real value is (1xxx) * 2^(eeeee - 1) if
33 ** eeeee != 0 and (xxx) otherwise.
34 */
35 int luaO_int2fb (unsigned int x) {
36  int e = 0; /* exponent */
37  if (x < 8) return x;
38  while (x >= 0x10) {
39  x = (x+1) >> 1;
40  e++;
41  }
42  return ((e+1) << 3) | (cast_int(x) - 8);
43 }
44 
45 
46 /* converts back */
47 int luaO_fb2int (int x) {
48  int e = (x >> 3) & 0x1f;
49  if (e == 0) return x;
50  else return ((x & 7) + 8) << (e - 1);
51 }
52 
53 
54 int luaO_ceillog2 (unsigned int x) {
55  static const lu_byte log_2[256] = {
56  0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
57  6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
58  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
59  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
60  8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
61  8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
62  8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
63  8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8
64  };
65  int l = 0;
66  x--;
67  while (x >= 256) { l += 8; x >>= 8; }
68  return l + log_2[x];
69 }
70 
71 
73  switch (op) {
74  case LUA_OPADD: return luai_numadd(NULL, v1, v2);
75  case LUA_OPSUB: return luai_numsub(NULL, v1, v2);
76  case LUA_OPMUL: return luai_nummul(NULL, v1, v2);
77  case LUA_OPDIV: return luai_numdiv(NULL, v1, v2);
78  case LUA_OPMOD: return luai_nummod(NULL, v1, v2);
79  case LUA_OPPOW: return luai_numpow(NULL, v1, v2);
80  case LUA_OPUNM: return luai_numunm(NULL, v1);
81  default: lua_assert(0); return 0;
82  }
83 }
84 
85 
86 int luaO_hexavalue (int c) {
87  if (lisdigit(c)) return c - '0';
88  else return ltolower(c) - 'a' + 10;
89 }
90 
91 
92 #if !defined(lua_strx2number)
93 
94 #include <math.h>
95 
96 
97 static int isneg (const char **s) {
98  if (**s == '-') { (*s)++; return 1; }
99  else if (**s == '+') (*s)++;
100  return 0;
101 }
102 
103 
104 static lua_Number readhexa (const char **s, lua_Number r, int *count) {
105  for (; lisxdigit(cast_uchar(**s)); (*s)++) { /* read integer part */
106  r = (r * cast_num(16.0)) + cast_num(luaO_hexavalue(cast_uchar(**s)));
107  (*count)++;
108  }
109  return r;
110 }
111 
112 
113 /*
114 ** convert an hexadecimal numeric string to a number, following
115 ** C99 specification for 'strtod'
116 */
117 static lua_Number lua_strx2number (const char *s, char **endptr) {
118  lua_Number r = 0.0;
119  int e = 0, i = 0;
120  int neg = 0; /* 1 if number is negative */
121  *endptr = cast(char *, s); /* nothing is valid yet */
122  while (lisspace(cast_uchar(*s))) s++; /* skip initial spaces */
123  neg = isneg(&s); /* check signal */
124  if (!(*s == '0' && (*(s + 1) == 'x' || *(s + 1) == 'X'))) /* check '0x' */
125  return 0.0; /* invalid format (no '0x') */
126  s += 2; /* skip '0x' */
127  r = readhexa(&s, r, &i); /* read integer part */
128  if (*s == '.') {
129  s++; /* skip dot */
130  r = readhexa(&s, r, &e); /* read fractional part */
131  }
132  if (i == 0 && e == 0)
133  return 0.0; /* invalid format (no digit) */
134  e *= -4; /* each fractional digit divides value by 2^-4 */
135  *endptr = cast(char *, s); /* valid up to here */
136  if (*s == 'p' || *s == 'P') { /* exponent part? */
137  int exp1 = 0;
138  int neg1;
139  s++; /* skip 'p' */
140  neg1 = isneg(&s); /* signal */
141  if (!lisdigit(cast_uchar(*s)))
142  goto ret; /* must have at least one digit */
143  while (lisdigit(cast_uchar(*s))) /* read exponent */
144  exp1 = exp1 * 10 + *(s++) - '0';
145  if (neg1) exp1 = -exp1;
146  e += exp1;
147  }
148  *endptr = cast(char *, s); /* valid up to here */
149  ret:
150  if (neg) r = -r;
151  return l_mathop(ldexp)(r, e);
152 }
153 
154 #endif
155 
156 
157 int luaO_str2d (const char *s, size_t len, lua_Number *result) {
158  char *endptr;
159  if (strpbrk(s, "nN")) /* reject 'inf' and 'nan' */
160  return 0;
161  else if (strpbrk(s, "xX")) /* hexa? */
162  *result = lua_strx2number(s, &endptr);
163  else
164  *result = lua_str2number(s, &endptr);
165  if (endptr == s) return 0; /* nothing recognized */
166  while (lisspace(cast_uchar(*endptr))) endptr++;
167  return (endptr == s + len); /* OK if no trailing characters */
168 }
169 
170 
171 
172 static void pushstr (lua_State *L, const char *str, size_t l) {
173  setsvalue2s(L, L->top++, luaS_newlstr(L, str, l));
174 }
175 
176 
177 /* this function handles only `%d', `%c', %f, %p, and `%s' formats */
178 const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
179  int n = 0;
180  for (;;) {
181  const char *e = strchr(fmt, '%');
182  if (e == NULL) break;
183  luaD_checkstack(L, 2); /* fmt + item */
184  pushstr(L, fmt, e - fmt);
185  switch (*(e+1)) {
186  case 's': {
187  const char *s = va_arg(argp, char *);
188  if (s == NULL) s = "(null)";
189  pushstr(L, s, strlen(s));
190  break;
191  }
192  case 'c': {
193  char buff;
194  buff = cast(char, va_arg(argp, int));
195  pushstr(L, &buff, 1);
196  break;
197  }
198  case 'd': {
199  setnvalue(L->top++, cast_num(va_arg(argp, int)));
200  break;
201  }
202  case 'f': {
203  setnvalue(L->top++, cast_num(va_arg(argp, l_uacNumber)));
204  break;
205  }
206  case 'p': {
207  char buff[4*sizeof(void *) + 8]; /* should be enough space for a `%p' */
208  int l = sprintf(buff, "%p", va_arg(argp, void *));
209  pushstr(L, buff, l);
210  break;
211  }
212  case '%': {
213  pushstr(L, "%", 1);
214  break;
215  }
216  default: {
217  luaG_runerror(L,
218  "invalid option " LUA_QL("%%%c") " to " LUA_QL("lua_pushfstring"),
219  *(e + 1));
220  }
221  }
222  n += 2;
223  fmt = e+2;
224  }
225  luaD_checkstack(L, 1);
226  pushstr(L, fmt, strlen(fmt));
227  if (n > 0) luaV_concat(L, n + 1);
228  return svalue(L->top - 1);
229 }
230 
231 
232 const char *luaO_pushfstring (lua_State *L, const char *fmt, ...) {
233  const char *msg;
234  va_list argp;
235  va_start(argp, fmt);
236  msg = luaO_pushvfstring(L, fmt, argp);
237  va_end(argp);
238  return msg;
239 }
240 
241 
242 /* number of chars of a literal string without the ending \0 */
243 #define LL(x) (sizeof(x)/sizeof(char) - 1)
244 
245 #define RETS "..."
246 #define PRE "[string \""
247 #define POS "\"]"
248 
249 #define addstr(a,b,l) ( memcpy(a,b,(l) * sizeof(char)), a += (l) )
250 
251 void luaO_chunkid (char *out, const char *source, size_t bufflen) {
252  size_t l = strlen(source);
253  if (*source == '=') { /* 'literal' source */
254  if (l <= bufflen) /* small enough? */
255  memcpy(out, source + 1, l * sizeof(char));
256  else { /* truncate it */
257  addstr(out, source + 1, bufflen - 1);
258  *out = '\0';
259  }
260  }
261  else if (*source == '@') { /* file name */
262  if (l <= bufflen) /* small enough? */
263  memcpy(out, source + 1, l * sizeof(char));
264  else { /* add '...' before rest of name */
265  addstr(out, RETS, LL(RETS));
266  bufflen -= LL(RETS);
267  memcpy(out, source + 1 + l - bufflen, bufflen * sizeof(char));
268  }
269  }
270  else { /* string; format as [string "source"] */
271  const char *nl = strchr(source, '\n'); /* find first new line (if any) */
272  addstr(out, PRE, LL(PRE)); /* add prefix */
273  bufflen -= LL(PRE RETS POS) + 1; /* save space for prefix+suffix+'\0' */
274  if (l < bufflen && nl == NULL) { /* small one-line source? */
275  addstr(out, source, l); /* keep it */
276  }
277  else {
278  if (nl != NULL) l = nl - source; /* stop at first newline */
279  if (l > bufflen) l = bufflen;
280  addstr(out, source, l);
281  addstr(out, RETS, LL(RETS));
282  }
283  memcpy(out, POS, (LL(POS) + 1) * sizeof(char));
284  }
285 }
286 
const char * luaO_pushvfstring(lua_State *L, const char *fmt, va_list argp)
Definition: lobject.cpp:178
lua_Number luaO_arith(int op, lua_Number v1, lua_Number v2)
Definition: lobject.cpp:72
void luaV_concat(lua_State *L, int total)
Definition: lvm.cpp:293
l_noret luaG_runerror(lua_State *L, const char *fmt,...)
Definition: ldebug.cpp:585
#define NILCONSTANT
Definition: lobject.h:109
#define cast_num(i)
Definition: llimits.h:95
#define LUA_OPDIV
Definition: lua.h:186
static int exp1(LexState *ls)
Definition: lparser.cpp:1271
static lua_Number lua_strx2number(const char *s, char **endptr)
Definition: lobject.cpp:117
const GLfloat * c
Definition: glew.h:12741
#define LUA_OPSUB
Definition: lua.h:184
int luaO_ceillog2(unsigned int x)
Definition: lobject.cpp:54
#define POS
Definition: lobject.cpp:247
#define LUA_OPUNM
Definition: lua.h:189
GLfloat GLfloat v1
Definition: glew.h:1820
#define setnvalue(obj, x)
Definition: lobject.h:186
#define cast(t, exp)
Definition: llimits.h:92
GLfloat GLfloat GLfloat v2
Definition: glew.h:1824
#define LUA_OPPOW
Definition: lua.h:188
GLdouble l
Definition: glew.h:6966
int luaO_str2d(const char *s, size_t len, lua_Number *result)
Definition: lobject.cpp:157
StkId top
Definition: lstate.h:156
int luaO_fb2int(int x)
Definition: lobject.cpp:47
#define ltolower(c)
Definition: lctype.h:89
#define addstr(a, b, l)
Definition: lobject.cpp:249
unsigned char lu_byte
Definition: llimits.h:26
#define lisdigit(c)
Definition: lctype.h:84
#define LUA_OPADD
Definition: lua.h:183
GLuint64EXT * result
Definition: glew.h:10727
#define RETS
Definition: lobject.cpp:245
#define LUA_QL(x)
Definition: luaconf.h:198
#define LUAI_DDEF
Definition: luaconf.h:189
GLenum GLsizei len
Definition: glew.h:5662
static void pushstr(lua_State *L, const char *str, size_t l)
Definition: lobject.cpp:172
#define luaD_checkstack(L, n)
Definition: ldo.h:15
#define cast_uchar(i)
Definition: llimits.h:97
GLuint GLuint GLsizei count
Definition: glew.h:1221
#define l_mathop(x)
Definition: luaconf.h:421
#define lisxdigit(c)
Definition: lctype.h:87
int luaO_int2fb(unsigned int x)
Definition: lobject.cpp:35
#define LL(x)
Definition: lobject.cpp:243
#define lua_assert(c)
Definition: llimits.h:65
LUAI_DDEF const TValue luaO_nilobject_
Definition: lobject.cpp:27
size_t i
Definition: function.cpp:1057
static void msg(const char *act, debug_info &i, const char *to="", const char *result="")
Definition: debugger.cpp:112
GLint GLint GLint GLint GLint x
Definition: glew.h:1220
GLdouble GLdouble GLdouble r
Definition: glew.h:1374
static int isneg(const char **s)
Definition: lobject.cpp:97
const char * luaO_pushfstring(lua_State *L, const char *fmt,...)
Definition: lobject.cpp:232
int luaO_hexavalue(int c)
Definition: lobject.cpp:86
void luaO_chunkid(char *out, const char *source, size_t bufflen)
Definition: lobject.cpp:251
#define PRE
Definition: lobject.cpp:246
GLclampd n
Definition: glew.h:5903
#define cast_int(i)
Definition: llimits.h:96
#define lua_str2number(s, p)
Definition: luaconf.h:432
static lua_Number readhexa(const char **s, lua_Number r, int *count)
Definition: lobject.cpp:104
#define svalue(o)
Definition: lobject.h:424
#define e
TString * luaS_newlstr(lua_State *L, const char *str, size_t l)
Definition: lstring.cpp:155
GLdouble s
Definition: glew.h:1358
#define setsvalue2s
Definition: lobject.h:253
LUAI_UACNUMBER l_uacNumber
Definition: llimits.h:56
#define lisspace(c)
Definition: lctype.h:85
GLsizei GLsizei GLchar * source
Definition: glew.h:1800
LUA_NUMBER lua_Number
Definition: lua.h:102
#define LUA_OPMOD
Definition: lua.h:187
#define LUA_OPMUL
Definition: lua.h:185