dub 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (142) hide show
  1. data/.gitignore +8 -0
  2. data/History.txt +5 -0
  3. data/LICENSE +20 -0
  4. data/README.rdoc +53 -0
  5. data/Rakefile +58 -0
  6. data/dub.gemspec +194 -0
  7. data/lib/dub/argument.rb +261 -0
  8. data/lib/dub/entities_unescape.rb +16 -0
  9. data/lib/dub/function.rb +111 -0
  10. data/lib/dub/function_group.rb +74 -0
  11. data/lib/dub/generator.rb +15 -0
  12. data/lib/dub/group.rb +10 -0
  13. data/lib/dub/klass.rb +231 -0
  14. data/lib/dub/lua/class.cpp.erb +75 -0
  15. data/lib/dub/lua/class_gen.rb +78 -0
  16. data/lib/dub/lua/function.cpp.erb +4 -0
  17. data/lib/dub/lua/function_gen.rb +223 -0
  18. data/lib/dub/lua/group.cpp.erb +10 -0
  19. data/lib/dub/lua/lua_cpp_helper.h +141 -0
  20. data/lib/dub/lua/namespace.cpp.erb +35 -0
  21. data/lib/dub/lua/namespace_gen.rb +86 -0
  22. data/lib/dub/lua.rb +24 -0
  23. data/lib/dub/member_extraction.rb +88 -0
  24. data/lib/dub/namespace.rb +276 -0
  25. data/lib/dub/parser.rb +46 -0
  26. data/lib/dub/templates/lua_template.erb +21 -0
  27. data/lib/dub/version.rb +3 -0
  28. data/lib/dub.rb +26 -0
  29. data/test/argument_test.rb +423 -0
  30. data/test/fixtures/app/CMakeLists.txt +54 -0
  31. data/test/fixtures/app/Doxyfile +1600 -0
  32. data/test/fixtures/app/bindings/all_lua.cpp +299 -0
  33. data/test/fixtures/app/include/matrix.h +123 -0
  34. data/test/fixtures/app/make_lua_bindings.rb +13 -0
  35. data/test/fixtures/app/vendor/lua/CMakeLists.txt +25 -0
  36. data/test/fixtures/app/vendor/lua/COPYRIGHT +34 -0
  37. data/test/fixtures/app/vendor/lua/HISTORY +183 -0
  38. data/test/fixtures/app/vendor/lua/INSTALL +99 -0
  39. data/test/fixtures/app/vendor/lua/Makefile +183 -0
  40. data/test/fixtures/app/vendor/lua/README +37 -0
  41. data/test/fixtures/app/vendor/lua/lapi.c +1080 -0
  42. data/test/fixtures/app/vendor/lua/lapi.h +16 -0
  43. data/test/fixtures/app/vendor/lua/lauxlib.c +653 -0
  44. data/test/fixtures/app/vendor/lua/lauxlib.h +174 -0
  45. data/test/fixtures/app/vendor/lua/lbaselib.c +643 -0
  46. data/test/fixtures/app/vendor/lua/lcode.c +839 -0
  47. data/test/fixtures/app/vendor/lua/lcode.h +76 -0
  48. data/test/fixtures/app/vendor/lua/ldblib.c +397 -0
  49. data/test/fixtures/app/vendor/lua/ldebug.c +622 -0
  50. data/test/fixtures/app/vendor/lua/ldebug.h +33 -0
  51. data/test/fixtures/app/vendor/lua/ldo.c +516 -0
  52. data/test/fixtures/app/vendor/lua/ldo.h +57 -0
  53. data/test/fixtures/app/vendor/lua/ldump.c +164 -0
  54. data/test/fixtures/app/vendor/lua/lfunc.c +174 -0
  55. data/test/fixtures/app/vendor/lua/lfunc.h +34 -0
  56. data/test/fixtures/app/vendor/lua/lgc.c +711 -0
  57. data/test/fixtures/app/vendor/lua/lgc.h +110 -0
  58. data/test/fixtures/app/vendor/lua/liblua.a +0 -0
  59. data/test/fixtures/app/vendor/lua/linit.c +38 -0
  60. data/test/fixtures/app/vendor/lua/liolib.c +532 -0
  61. data/test/fixtures/app/vendor/lua/llex.c +461 -0
  62. data/test/fixtures/app/vendor/lua/llex.h +81 -0
  63. data/test/fixtures/app/vendor/lua/llimits.h +128 -0
  64. data/test/fixtures/app/vendor/lua/lmathlib.c +263 -0
  65. data/test/fixtures/app/vendor/lua/lmem.c +86 -0
  66. data/test/fixtures/app/vendor/lua/lmem.h +49 -0
  67. data/test/fixtures/app/vendor/lua/loadlib.c +664 -0
  68. data/test/fixtures/app/vendor/lua/lobject.c +214 -0
  69. data/test/fixtures/app/vendor/lua/lobject.h +381 -0
  70. data/test/fixtures/app/vendor/lua/lopcodes.c +102 -0
  71. data/test/fixtures/app/vendor/lua/lopcodes.h +268 -0
  72. data/test/fixtures/app/vendor/lua/loslib.c +244 -0
  73. data/test/fixtures/app/vendor/lua/lparser.c +1337 -0
  74. data/test/fixtures/app/vendor/lua/lparser.h +82 -0
  75. data/test/fixtures/app/vendor/lua/lstate.c +214 -0
  76. data/test/fixtures/app/vendor/lua/lstate.h +168 -0
  77. data/test/fixtures/app/vendor/lua/lstring.c +111 -0
  78. data/test/fixtures/app/vendor/lua/lstring.h +31 -0
  79. data/test/fixtures/app/vendor/lua/lstrlib.c +868 -0
  80. data/test/fixtures/app/vendor/lua/ltable.c +588 -0
  81. data/test/fixtures/app/vendor/lua/ltable.h +40 -0
  82. data/test/fixtures/app/vendor/lua/ltablib.c +278 -0
  83. data/test/fixtures/app/vendor/lua/ltm.c +75 -0
  84. data/test/fixtures/app/vendor/lua/ltm.h +54 -0
  85. data/test/fixtures/app/vendor/lua/lua.c +695 -0
  86. data/test/fixtures/app/vendor/lua/lua.h +385 -0
  87. data/test/fixtures/app/vendor/lua/lua_dub_helper.h +77 -0
  88. data/test/fixtures/app/vendor/lua/luac +0 -0
  89. data/test/fixtures/app/vendor/lua/luac.c +200 -0
  90. data/test/fixtures/app/vendor/lua/luaconf.h +762 -0
  91. data/test/fixtures/app/vendor/lua/lualib.h +53 -0
  92. data/test/fixtures/app/vendor/lua/lundump.c +223 -0
  93. data/test/fixtures/app/vendor/lua/lundump.h +36 -0
  94. data/test/fixtures/app/vendor/lua/lvm.c +765 -0
  95. data/test/fixtures/app/vendor/lua/lvm.h +36 -0
  96. data/test/fixtures/app/vendor/lua/lzio.c +82 -0
  97. data/test/fixtures/app/vendor/lua/lzio.h +67 -0
  98. data/test/fixtures/app/vendor/lua/matrix.h +102 -0
  99. data/test/fixtures/app/vendor/lua/print.c +227 -0
  100. data/test/fixtures/app/vendor/lua/test/README +26 -0
  101. data/test/fixtures/app/vendor/lua/test/bisect.lua +27 -0
  102. data/test/fixtures/app/vendor/lua/test/cf.lua +16 -0
  103. data/test/fixtures/app/vendor/lua/test/echo.lua +5 -0
  104. data/test/fixtures/app/vendor/lua/test/env.lua +7 -0
  105. data/test/fixtures/app/vendor/lua/test/factorial.lua +32 -0
  106. data/test/fixtures/app/vendor/lua/test/fib.lua +40 -0
  107. data/test/fixtures/app/vendor/lua/test/fibfor.lua +13 -0
  108. data/test/fixtures/app/vendor/lua/test/globals.lua +13 -0
  109. data/test/fixtures/app/vendor/lua/test/hello.lua +3 -0
  110. data/test/fixtures/app/vendor/lua/test/life.lua +111 -0
  111. data/test/fixtures/app/vendor/lua/test/luac.lua +7 -0
  112. data/test/fixtures/app/vendor/lua/test/printf.lua +7 -0
  113. data/test/fixtures/app/vendor/lua/test/readonly.lua +12 -0
  114. data/test/fixtures/app/vendor/lua/test/sieve.lua +29 -0
  115. data/test/fixtures/app/vendor/lua/test/sort.lua +66 -0
  116. data/test/fixtures/app/vendor/lua/test/table.lua +12 -0
  117. data/test/fixtures/app/vendor/lua/test/trace-calls.lua +32 -0
  118. data/test/fixtures/app/vendor/lua/test/trace-globals.lua +38 -0
  119. data/test/fixtures/app/vendor/lua/test/xd.lua +14 -0
  120. data/test/fixtures/app/xml/classdub_1_1_matrix.xml +239 -0
  121. data/test/fixtures/app/xml/classdub_1_1_t_mat.xml +233 -0
  122. data/test/fixtures/app/xml/combine.xslt +15 -0
  123. data/test/fixtures/app/xml/compound.xsd +814 -0
  124. data/test/fixtures/app/xml/dir_53661a2bdeb1d55e60581a7e15deb763.xml +12 -0
  125. data/test/fixtures/app/xml/index.xml +42 -0
  126. data/test/fixtures/app/xml/index.xsd +66 -0
  127. data/test/fixtures/app/xml/matrix_8h.xml +149 -0
  128. data/test/fixtures/app/xml/namespacedub.xml +41 -0
  129. data/test/fixtures/classcv_1_1_mat.xml +1996 -0
  130. data/test/fixtures/classcv_1_1_point__.xml +341 -0
  131. data/test/fixtures/classcv_1_1_size__.xml +270 -0
  132. data/test/fixtures/group___magic_type.xml +406 -0
  133. data/test/fixtures/namespacecv.xml +12659 -0
  134. data/test/function_group_test.rb +15 -0
  135. data/test/function_test.rb +252 -0
  136. data/test/group_test.rb +155 -0
  137. data/test/helper.rb +34 -0
  138. data/test/klass_test.rb +297 -0
  139. data/test/lua_function_gen_test.rb +179 -0
  140. data/test/namespace_test.rb +220 -0
  141. data/test/parser_test.rb +36 -0
  142. metadata +216 -0
@@ -0,0 +1,268 @@
1
+ /*
2
+ ** $Id: lopcodes.h,v 1.125 2006/03/14 19:04:44 roberto Exp $
3
+ ** Opcodes for Lua virtual machine
4
+ ** See Copyright Notice in lua.h
5
+ */
6
+
7
+ #ifndef lopcodes_h
8
+ #define lopcodes_h
9
+
10
+ #include "llimits.h"
11
+
12
+
13
+ /*===========================================================================
14
+ We assume that instructions are unsigned numbers.
15
+ All instructions have an opcode in the first 6 bits.
16
+ Instructions can have the following fields:
17
+ `A' : 8 bits
18
+ `B' : 9 bits
19
+ `C' : 9 bits
20
+ `Bx' : 18 bits (`B' and `C' together)
21
+ `sBx' : signed Bx
22
+
23
+ A signed argument is represented in excess K; that is, the number
24
+ value is the unsigned value minus K. K is exactly the maximum value
25
+ for that argument (so that -max is represented by 0, and +max is
26
+ represented by 2*max), which is half the maximum for the corresponding
27
+ unsigned argument.
28
+ ===========================================================================*/
29
+
30
+
31
+ enum OpMode {iABC, iABx, iAsBx}; /* basic instruction format */
32
+
33
+
34
+ /*
35
+ ** size and position of opcode arguments.
36
+ */
37
+ #define SIZE_C 9
38
+ #define SIZE_B 9
39
+ #define SIZE_Bx (SIZE_C + SIZE_B)
40
+ #define SIZE_A 8
41
+
42
+ #define SIZE_OP 6
43
+
44
+ #define POS_OP 0
45
+ #define POS_A (POS_OP + SIZE_OP)
46
+ #define POS_C (POS_A + SIZE_A)
47
+ #define POS_B (POS_C + SIZE_C)
48
+ #define POS_Bx POS_C
49
+
50
+
51
+ /*
52
+ ** limits for opcode arguments.
53
+ ** we use (signed) int to manipulate most arguments,
54
+ ** so they must fit in LUAI_BITSINT-1 bits (-1 for sign)
55
+ */
56
+ #if SIZE_Bx < LUAI_BITSINT-1
57
+ #define MAXARG_Bx ((1<<SIZE_Bx)-1)
58
+ #define MAXARG_sBx (MAXARG_Bx>>1) /* `sBx' is signed */
59
+ #else
60
+ #define MAXARG_Bx MAX_INT
61
+ #define MAXARG_sBx MAX_INT
62
+ #endif
63
+
64
+
65
+ #define MAXARG_A ((1<<SIZE_A)-1)
66
+ #define MAXARG_B ((1<<SIZE_B)-1)
67
+ #define MAXARG_C ((1<<SIZE_C)-1)
68
+
69
+
70
+ /* creates a mask with `n' 1 bits at position `p' */
71
+ #define MASK1(n,p) ((~((~(Instruction)0)<<n))<<p)
72
+
73
+ /* creates a mask with `n' 0 bits at position `p' */
74
+ #define MASK0(n,p) (~MASK1(n,p))
75
+
76
+ /*
77
+ ** the following macros help to manipulate instructions
78
+ */
79
+
80
+ #define GET_OPCODE(i) (cast(OpCode, ((i)>>POS_OP) & MASK1(SIZE_OP,0)))
81
+ #define SET_OPCODE(i,o) ((i) = (((i)&MASK0(SIZE_OP,POS_OP)) | \
82
+ ((cast(Instruction, o)<<POS_OP)&MASK1(SIZE_OP,POS_OP))))
83
+
84
+ #define GETARG_A(i) (cast(int, ((i)>>POS_A) & MASK1(SIZE_A,0)))
85
+ #define SETARG_A(i,u) ((i) = (((i)&MASK0(SIZE_A,POS_A)) | \
86
+ ((cast(Instruction, u)<<POS_A)&MASK1(SIZE_A,POS_A))))
87
+
88
+ #define GETARG_B(i) (cast(int, ((i)>>POS_B) & MASK1(SIZE_B,0)))
89
+ #define SETARG_B(i,b) ((i) = (((i)&MASK0(SIZE_B,POS_B)) | \
90
+ ((cast(Instruction, b)<<POS_B)&MASK1(SIZE_B,POS_B))))
91
+
92
+ #define GETARG_C(i) (cast(int, ((i)>>POS_C) & MASK1(SIZE_C,0)))
93
+ #define SETARG_C(i,b) ((i) = (((i)&MASK0(SIZE_C,POS_C)) | \
94
+ ((cast(Instruction, b)<<POS_C)&MASK1(SIZE_C,POS_C))))
95
+
96
+ #define GETARG_Bx(i) (cast(int, ((i)>>POS_Bx) & MASK1(SIZE_Bx,0)))
97
+ #define SETARG_Bx(i,b) ((i) = (((i)&MASK0(SIZE_Bx,POS_Bx)) | \
98
+ ((cast(Instruction, b)<<POS_Bx)&MASK1(SIZE_Bx,POS_Bx))))
99
+
100
+ #define GETARG_sBx(i) (GETARG_Bx(i)-MAXARG_sBx)
101
+ #define SETARG_sBx(i,b) SETARG_Bx((i),cast(unsigned int, (b)+MAXARG_sBx))
102
+
103
+
104
+ #define CREATE_ABC(o,a,b,c) ((cast(Instruction, o)<<POS_OP) \
105
+ | (cast(Instruction, a)<<POS_A) \
106
+ | (cast(Instruction, b)<<POS_B) \
107
+ | (cast(Instruction, c)<<POS_C))
108
+
109
+ #define CREATE_ABx(o,a,bc) ((cast(Instruction, o)<<POS_OP) \
110
+ | (cast(Instruction, a)<<POS_A) \
111
+ | (cast(Instruction, bc)<<POS_Bx))
112
+
113
+
114
+ /*
115
+ ** Macros to operate RK indices
116
+ */
117
+
118
+ /* this bit 1 means constant (0 means register) */
119
+ #define BITRK (1 << (SIZE_B - 1))
120
+
121
+ /* test whether value is a constant */
122
+ #define ISK(x) ((x) & BITRK)
123
+
124
+ /* gets the index of the constant */
125
+ #define INDEXK(r) ((int)(r) & ~BITRK)
126
+
127
+ #define MAXINDEXRK (BITRK - 1)
128
+
129
+ /* code a constant index as a RK value */
130
+ #define RKASK(x) ((x) | BITRK)
131
+
132
+
133
+ /*
134
+ ** invalid register that fits in 8 bits
135
+ */
136
+ #define NO_REG MAXARG_A
137
+
138
+
139
+ /*
140
+ ** R(x) - register
141
+ ** Kst(x) - constant (in constant table)
142
+ ** RK(x) == if ISK(x) then Kst(INDEXK(x)) else R(x)
143
+ */
144
+
145
+
146
+ /*
147
+ ** grep "ORDER OP" if you change these enums
148
+ */
149
+
150
+ typedef enum {
151
+ /*----------------------------------------------------------------------
152
+ name args description
153
+ ------------------------------------------------------------------------*/
154
+ OP_MOVE,/* A B R(A) := R(B) */
155
+ OP_LOADK,/* A Bx R(A) := Kst(Bx) */
156
+ OP_LOADBOOL,/* A B C R(A) := (Bool)B; if (C) pc++ */
157
+ OP_LOADNIL,/* A B R(A) := ... := R(B) := nil */
158
+ OP_GETUPVAL,/* A B R(A) := UpValue[B] */
159
+
160
+ OP_GETGLOBAL,/* A Bx R(A) := Gbl[Kst(Bx)] */
161
+ OP_GETTABLE,/* A B C R(A) := R(B)[RK(C)] */
162
+
163
+ OP_SETGLOBAL,/* A Bx Gbl[Kst(Bx)] := R(A) */
164
+ OP_SETUPVAL,/* A B UpValue[B] := R(A) */
165
+ OP_SETTABLE,/* A B C R(A)[RK(B)] := RK(C) */
166
+
167
+ OP_NEWTABLE,/* A B C R(A) := {} (size = B,C) */
168
+
169
+ OP_SELF,/* A B C R(A+1) := R(B); R(A) := R(B)[RK(C)] */
170
+
171
+ OP_ADD,/* A B C R(A) := RK(B) + RK(C) */
172
+ OP_SUB,/* A B C R(A) := RK(B) - RK(C) */
173
+ OP_MUL,/* A B C R(A) := RK(B) * RK(C) */
174
+ OP_DIV,/* A B C R(A) := RK(B) / RK(C) */
175
+ OP_MOD,/* A B C R(A) := RK(B) % RK(C) */
176
+ OP_POW,/* A B C R(A) := RK(B) ^ RK(C) */
177
+ OP_UNM,/* A B R(A) := -R(B) */
178
+ OP_NOT,/* A B R(A) := not R(B) */
179
+ OP_LEN,/* A B R(A) := length of R(B) */
180
+
181
+ OP_CONCAT,/* A B C R(A) := R(B).. ... ..R(C) */
182
+
183
+ OP_JMP,/* sBx pc+=sBx */
184
+
185
+ OP_EQ,/* A B C if ((RK(B) == RK(C)) ~= A) then pc++ */
186
+ OP_LT,/* A B C if ((RK(B) < RK(C)) ~= A) then pc++ */
187
+ OP_LE,/* A B C if ((RK(B) <= RK(C)) ~= A) then pc++ */
188
+
189
+ OP_TEST,/* A C if not (R(A) <=> C) then pc++ */
190
+ OP_TESTSET,/* A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */
191
+
192
+ OP_CALL,/* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */
193
+ OP_TAILCALL,/* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */
194
+ OP_RETURN,/* A B return R(A), ... ,R(A+B-2) (see note) */
195
+
196
+ OP_FORLOOP,/* A sBx R(A)+=R(A+2);
197
+ if R(A) <?= R(A+1) then { pc+=sBx; R(A+3)=R(A) }*/
198
+ OP_FORPREP,/* A sBx R(A)-=R(A+2); pc+=sBx */
199
+
200
+ OP_TFORLOOP,/* A C R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2));
201
+ if R(A+3) ~= nil then R(A+2)=R(A+3) else pc++ */
202
+ OP_SETLIST,/* A B C R(A)[(C-1)*FPF+i] := R(A+i), 1 <= i <= B */
203
+
204
+ OP_CLOSE,/* A close all variables in the stack up to (>=) R(A)*/
205
+ OP_CLOSURE,/* A Bx R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n)) */
206
+
207
+ OP_VARARG/* A B R(A), R(A+1), ..., R(A+B-1) = vararg */
208
+ } OpCode;
209
+
210
+
211
+ #define NUM_OPCODES (cast(int, OP_VARARG) + 1)
212
+
213
+
214
+
215
+ /*===========================================================================
216
+ Notes:
217
+ (*) In OP_CALL, if (B == 0) then B = top. C is the number of returns - 1,
218
+ and can be 0: OP_CALL then sets `top' to last_result+1, so
219
+ next open instruction (OP_CALL, OP_RETURN, OP_SETLIST) may use `top'.
220
+
221
+ (*) In OP_VARARG, if (B == 0) then use actual number of varargs and
222
+ set top (like in OP_CALL with C == 0).
223
+
224
+ (*) In OP_RETURN, if (B == 0) then return up to `top'
225
+
226
+ (*) In OP_SETLIST, if (B == 0) then B = `top';
227
+ if (C == 0) then next `instruction' is real C
228
+
229
+ (*) For comparisons, A specifies what condition the test should accept
230
+ (true or false).
231
+
232
+ (*) All `skips' (pc++) assume that next instruction is a jump
233
+ ===========================================================================*/
234
+
235
+
236
+ /*
237
+ ** masks for instruction properties. The format is:
238
+ ** bits 0-1: op mode
239
+ ** bits 2-3: C arg mode
240
+ ** bits 4-5: B arg mode
241
+ ** bit 6: instruction set register A
242
+ ** bit 7: operator is a test
243
+ */
244
+
245
+ enum OpArgMask {
246
+ OpArgN, /* argument is not used */
247
+ OpArgU, /* argument is used */
248
+ OpArgR, /* argument is a register or a jump offset */
249
+ OpArgK /* argument is a constant or register/constant */
250
+ };
251
+
252
+ LUAI_DATA const lu_byte luaP_opmodes[NUM_OPCODES];
253
+
254
+ #define getOpMode(m) (cast(enum OpMode, luaP_opmodes[m] & 3))
255
+ #define getBMode(m) (cast(enum OpArgMask, (luaP_opmodes[m] >> 4) & 3))
256
+ #define getCMode(m) (cast(enum OpArgMask, (luaP_opmodes[m] >> 2) & 3))
257
+ #define testAMode(m) (luaP_opmodes[m] & (1 << 6))
258
+ #define testTMode(m) (luaP_opmodes[m] & (1 << 7))
259
+
260
+
261
+ LUAI_DATA const char *const luaP_opnames[NUM_OPCODES+1]; /* opcode names */
262
+
263
+
264
+ /* number of list items to accumulate before a SETLIST instruction */
265
+ #define LFIELDS_PER_FLUSH 50
266
+
267
+
268
+ #endif
@@ -0,0 +1,244 @@
1
+ /*
2
+ ** $Id: loslib.c,v 1.20 2006/09/19 13:57:08 roberto Exp $
3
+ ** Standard Operating System library
4
+ ** See Copyright Notice in lua.h
5
+ */
6
+
7
+
8
+ #include <errno.h>
9
+ #include <locale.h>
10
+ #include <stdlib.h>
11
+ #include <string.h>
12
+ #include <time.h>
13
+
14
+ #define loslib_c
15
+ #define LUA_LIB
16
+
17
+ #include "lua.h"
18
+
19
+ #include "lauxlib.h"
20
+ #include "lualib.h"
21
+
22
+
23
+ static int os_pushresult (lua_State *L, int i, const char *filename) {
24
+ int en = errno; /* calls to Lua API may change this value */
25
+ if (i) {
26
+ lua_pushboolean(L, 1);
27
+ return 1;
28
+ }
29
+ else {
30
+ lua_pushnil(L);
31
+ lua_pushfstring(L, "%s: %s", filename, strerror(en));
32
+ lua_pushinteger(L, en);
33
+ return 3;
34
+ }
35
+ }
36
+
37
+
38
+ static int os_execute (lua_State *L) {
39
+ lua_pushinteger(L, system(luaL_optstring(L, 1, NULL)));
40
+ return 1;
41
+ }
42
+
43
+
44
+ static int os_remove (lua_State *L) {
45
+ const char *filename = luaL_checkstring(L, 1);
46
+ return os_pushresult(L, remove(filename) == 0, filename);
47
+ }
48
+
49
+
50
+ static int os_rename (lua_State *L) {
51
+ const char *fromname = luaL_checkstring(L, 1);
52
+ const char *toname = luaL_checkstring(L, 2);
53
+ return os_pushresult(L, rename(fromname, toname) == 0, fromname);
54
+ }
55
+
56
+
57
+ static int os_tmpname (lua_State *L) {
58
+ char buff[LUA_TMPNAMBUFSIZE];
59
+ int err;
60
+ lua_tmpnam(buff, err);
61
+ if (err)
62
+ return luaL_error(L, "unable to generate a unique filename");
63
+ lua_pushstring(L, buff);
64
+ return 1;
65
+ }
66
+
67
+
68
+ static int os_getenv (lua_State *L) {
69
+ lua_pushstring(L, getenv(luaL_checkstring(L, 1))); /* if NULL push nil */
70
+ return 1;
71
+ }
72
+
73
+
74
+ static int os_clock (lua_State *L) {
75
+ lua_pushnumber(L, ((lua_Number)clock())/(lua_Number)CLOCKS_PER_SEC);
76
+ return 1;
77
+ }
78
+
79
+
80
+ /*
81
+ ** {======================================================
82
+ ** Time/Date operations
83
+ ** { year=%Y, month=%m, day=%d, hour=%H, min=%M, sec=%S,
84
+ ** wday=%w+1, yday=%j, isdst=? }
85
+ ** =======================================================
86
+ */
87
+
88
+ static void setfield (lua_State *L, const char *key, int value) {
89
+ lua_pushinteger(L, value);
90
+ lua_setfield(L, -2, key);
91
+ }
92
+
93
+ static void setboolfield (lua_State *L, const char *key, int value) {
94
+ if (value < 0) /* undefined? */
95
+ return; /* does not set field */
96
+ lua_pushboolean(L, value);
97
+ lua_setfield(L, -2, key);
98
+ }
99
+
100
+ static int getboolfield (lua_State *L, const char *key) {
101
+ int res;
102
+ lua_getfield(L, -1, key);
103
+ res = lua_isnil(L, -1) ? -1 : lua_toboolean(L, -1);
104
+ lua_pop(L, 1);
105
+ return res;
106
+ }
107
+
108
+
109
+ static int getfield (lua_State *L, const char *key, int d) {
110
+ int res;
111
+ lua_getfield(L, -1, key);
112
+ if (lua_isnumber(L, -1))
113
+ res = (int)lua_tointeger(L, -1);
114
+ else {
115
+ if (d < 0)
116
+ return luaL_error(L, "field " LUA_QS " missing in date table", key);
117
+ res = d;
118
+ }
119
+ lua_pop(L, 1);
120
+ return res;
121
+ }
122
+
123
+
124
+ static int os_date (lua_State *L) {
125
+ const char *s = luaL_optstring(L, 1, "%c");
126
+ time_t t = luaL_opt(L, (time_t)luaL_checknumber, 2, time(NULL));
127
+ struct tm *stm;
128
+ if (*s == '!') { /* UTC? */
129
+ stm = gmtime(&t);
130
+ s++; /* skip `!' */
131
+ }
132
+ else
133
+ stm = localtime(&t);
134
+ if (stm == NULL) /* invalid date? */
135
+ lua_pushnil(L);
136
+ else if (strcmp(s, "*t") == 0) {
137
+ lua_createtable(L, 0, 9); /* 9 = number of fields */
138
+ setfield(L, "sec", stm->tm_sec);
139
+ setfield(L, "min", stm->tm_min);
140
+ setfield(L, "hour", stm->tm_hour);
141
+ setfield(L, "day", stm->tm_mday);
142
+ setfield(L, "month", stm->tm_mon+1);
143
+ setfield(L, "year", stm->tm_year+1900);
144
+ setfield(L, "wday", stm->tm_wday+1);
145
+ setfield(L, "yday", stm->tm_yday+1);
146
+ setboolfield(L, "isdst", stm->tm_isdst);
147
+ }
148
+ else {
149
+ char cc[3];
150
+ luaL_Buffer b;
151
+ cc[0] = '%'; cc[2] = '\0';
152
+ luaL_buffinit(L, &b);
153
+ for (; *s; s++) {
154
+ if (*s != '%' || *(s + 1) == '\0') /* no conversion specifier? */
155
+ luaL_addchar(&b, *s);
156
+ else {
157
+ size_t reslen;
158
+ char buff[200]; /* should be big enough for any conversion result */
159
+ cc[1] = *(++s);
160
+ reslen = strftime(buff, sizeof(buff), cc, stm);
161
+ luaL_addlstring(&b, buff, reslen);
162
+ }
163
+ }
164
+ luaL_pushresult(&b);
165
+ }
166
+ return 1;
167
+ }
168
+
169
+
170
+ static int os_time (lua_State *L) {
171
+ time_t t;
172
+ if (lua_isnoneornil(L, 1)) /* called without args? */
173
+ t = time(NULL); /* get current time */
174
+ else {
175
+ struct tm ts;
176
+ luaL_checktype(L, 1, LUA_TTABLE);
177
+ lua_settop(L, 1); /* make sure table is at the top */
178
+ ts.tm_sec = getfield(L, "sec", 0);
179
+ ts.tm_min = getfield(L, "min", 0);
180
+ ts.tm_hour = getfield(L, "hour", 12);
181
+ ts.tm_mday = getfield(L, "day", -1);
182
+ ts.tm_mon = getfield(L, "month", -1) - 1;
183
+ ts.tm_year = getfield(L, "year", -1) - 1900;
184
+ ts.tm_isdst = getboolfield(L, "isdst");
185
+ t = mktime(&ts);
186
+ }
187
+ if (t == (time_t)(-1))
188
+ lua_pushnil(L);
189
+ else
190
+ lua_pushnumber(L, (lua_Number)t);
191
+ return 1;
192
+ }
193
+
194
+
195
+ static int os_difftime (lua_State *L) {
196
+ lua_pushnumber(L, difftime((time_t)(luaL_checknumber(L, 1)),
197
+ (time_t)(luaL_optnumber(L, 2, 0))));
198
+ return 1;
199
+ }
200
+
201
+ /* }====================================================== */
202
+
203
+
204
+ static int os_setlocale (lua_State *L) {
205
+ static const int cat[] = {LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY,
206
+ LC_NUMERIC, LC_TIME};
207
+ static const char *const catnames[] = {"all", "collate", "ctype", "monetary",
208
+ "numeric", "time", NULL};
209
+ const char *l = luaL_optstring(L, 1, NULL);
210
+ int op = luaL_checkoption(L, 2, "all", catnames);
211
+ lua_pushstring(L, setlocale(cat[op], l));
212
+ return 1;
213
+ }
214
+
215
+
216
+ static int os_exit (lua_State *L) {
217
+ exit(luaL_optint(L, 1, EXIT_SUCCESS));
218
+ return 0; /* to avoid warnings */
219
+ }
220
+
221
+ static const luaL_Reg syslib[] = {
222
+ {"clock", os_clock},
223
+ {"date", os_date},
224
+ {"difftime", os_difftime},
225
+ {"execute", os_execute},
226
+ {"exit", os_exit},
227
+ {"getenv", os_getenv},
228
+ {"remove", os_remove},
229
+ {"rename", os_rename},
230
+ {"setlocale", os_setlocale},
231
+ {"time", os_time},
232
+ {"tmpname", os_tmpname},
233
+ {NULL, NULL}
234
+ };
235
+
236
+ /* }====================================================== */
237
+
238
+
239
+
240
+ LUALIB_API int luaopen_os (lua_State *L) {
241
+ luaL_register(L, LUA_OSLIBNAME, syslib);
242
+ return 1;
243
+ }
244
+