rpm  4.5
lobject.c
Go to the documentation of this file.
1 /*
2 ** $Id: lobject.c,v 1.1 2004/03/16 21:58:30 niemeyer Exp $
3 ** Some generic functions over Lua objects
4 ** See Copyright Notice in lua.h
5 */
6 
7 #include <ctype.h>
8 #include <stdarg.h>
9 #include <stdlib.h>
10 #include <string.h>
11 
12 #define lobject_c
13 
14 #include "lua.h"
15 
16 #include "ldo.h"
17 #include "lmem.h"
18 #include "lobject.h"
19 #include "lstate.h"
20 #include "lstring.h"
21 #include "lvm.h"
22 
23 
24 /* function to convert a string to a lua_Number */
25 #ifndef lua_str2number
26 #define lua_str2number(s,p) strtod((s), (p))
27 #endif
28 
29 
30 const TObject luaO_nilobject = {LUA_TNIL, {NULL}};
31 
32 
33 /*
34 ** converts an integer to a "floating point byte", represented as
35 ** (mmmmmxxx), where the real value is (xxx) * 2^(mmmmm)
36 */
37 int luaO_int2fb (unsigned int x) {
38  int m = 0; /* mantissa */
39  while (x >= (1<<3)) {
40  x = (x+1) >> 1;
41  m++;
42  }
43  return (m << 3) | cast(int, x);
44 }
45 
46 
47 int luaO_log2 (unsigned int x) {
48  static const lu_byte log_8[255] = {
49  0,
50  1,1,
51  2,2,2,2,
52  3,3,3,3,3,3,3,3,
53  4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
54  5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
55  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,
56  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,
57  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,
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  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
61  };
62  if (x >= 0x00010000) {
63  if (x >= 0x01000000) return log_8[((x>>24) & 0xff) - 1]+24;
64  else return log_8[((x>>16) & 0xff) - 1]+16;
65  }
66  else {
67  if (x >= 0x00000100) return log_8[((x>>8) & 0xff) - 1]+8;
68  else if (x) return log_8[(x & 0xff) - 1];
69  return -1; /* special `log' for 0 */
70  }
71 }
72 
73 
74 int luaO_rawequalObj (const TObject *t1, const TObject *t2) {
75  if (ttype(t1) != ttype(t2)) return 0;
76  else switch (ttype(t1)) {
77  case LUA_TNIL:
78  return 1;
79  case LUA_TNUMBER:
80  return nvalue(t1) == nvalue(t2);
81  case LUA_TBOOLEAN:
82  return bvalue(t1) == bvalue(t2); /* boolean true must be 1 !! */
83  case LUA_TLIGHTUSERDATA:
84  return pvalue(t1) == pvalue(t2);
85  default:
87  return gcvalue(t1) == gcvalue(t2);
88  }
89 }
90 
91 
92 int luaO_str2d (const char *s, lua_Number *result) {
93  char *endptr;
94  lua_Number res = lua_str2number(s, &endptr);
95  if (endptr == s) return 0; /* no conversion */
96  while (isspace((unsigned char)(*endptr))) endptr++;
97  if (*endptr != '\0') return 0; /* invalid trailing characters? */
98  *result = res;
99  return 1;
100 }
101 
102 
103 
104 static void pushstr (lua_State *L, const char *str)
105  /*@modifies L @*/
106 {
107  setsvalue2s(L->top, luaS_new(L, str));
108  incr_top(L);
109 }
110 
111 
112 /* this function handles only `%d', `%c', %f, and `%s' formats */
113 const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
114  int n = 1;
115  pushstr(L, "");
116  for (;;) {
117  const char *e = strchr(fmt, '%');
118  if (e == NULL) break;
119  setsvalue2s(L->top, luaS_newlstr(L, fmt, e-fmt));
120  incr_top(L);
121  switch (*(e+1)) {
122  case 's':
123  pushstr(L, va_arg(argp, char *));
124  break;
125  case 'c': {
126  char buff[2];
127  buff[0] = cast(char, va_arg(argp, int));
128  buff[1] = '\0';
129  pushstr(L, buff);
130  break;
131  }
132  case 'd':
133  setnvalue(L->top, cast(lua_Number, va_arg(argp, int)));
134  incr_top(L);
135  break;
136  case 'f':
137  setnvalue(L->top, cast(lua_Number, va_arg(argp, l_uacNumber)));
138  incr_top(L);
139  break;
140  case '%':
141  pushstr(L, "%");
142  break;
143  default: lua_assert(0);
144  }
145  n += 2;
146  fmt = e+2;
147  }
148  pushstr(L, fmt);
149  luaV_concat(L, n+1, L->top - L->base - 1);
150  L->top -= n;
151  return svalue(L->top - 1);
152 }
153 
154 
155 const char *luaO_pushfstring (lua_State *L, const char *fmt, ...) {
156  const char *msg;
157  va_list argp;
158  va_start(argp, fmt);
159  msg = luaO_pushvfstring(L, fmt, argp);
160  va_end(argp);
161  return msg;
162 }
163 
164 
165 void luaO_chunkid (char *out, const char *source, int bufflen) {
166  if (*source == '=') {
167  strncpy(out, source+1, bufflen); /* remove first char */
168  out[bufflen-1] = '\0'; /* ensures null termination */
169  }
170  else { /* out = "source", or "...source" */
171  if (*source == '@') {
172  int l;
173  source++; /* skip the `@' */
174  bufflen -= sizeof(" `...' ");
175  l = strlen(source);
176  strcpy(out, "");
177  if (l>bufflen) {
178  source += (l-bufflen); /* get last part of file name */
179  strcat(out, "...");
180  }
181  strcat(out, source);
182  }
183  else { /* out = [string "string"] */
184  int len = strcspn(source, "\n"); /* stop at first newline */
185  bufflen -= sizeof(" [string \"...\"] ");
186  if (len > bufflen) len = bufflen;
187  strcpy(out, "[string \"");
188  if (source[len] != '\0') { /* must truncate? */
189  strncat(out, source, len);
190  strcat(out, "...");
191  }
192  else
193  strcat(out, source);
194  strcat(out, "\"]");
195  }
196  }
197 }