The Battle for Wesnoth  1.13.4+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
lcorolib.cpp
Go to the documentation of this file.
1 /*
2 ** Coroutine Library
3 ** See Copyright Notice in lua.h
4 */
5 
6 
7 #include <stdlib.h>
8 
9 
10 #define lcorolib_c
11 #define LUA_LIB
12 
13 #include "lua.h"
14 
15 #include "lauxlib.h"
16 #include "lualib.h"
17 
18 
19 static int auxresume (lua_State *L, lua_State *co, int narg) {
20  int status;
21  if (!lua_checkstack(co, narg)) {
22  lua_pushliteral(L, "too many arguments to resume");
23  return -1; /* error flag */
24  }
25  if (lua_status(co) == LUA_OK && lua_gettop(co) == 0) {
26  lua_pushliteral(L, "cannot resume dead coroutine");
27  return -1; /* error flag */
28  }
29  lua_xmove(L, co, narg);
30  status = lua_resume(co, L, narg);
31  if (status == LUA_OK || status == LUA_YIELD) {
32  int nres = lua_gettop(co);
33  if (!lua_checkstack(L, nres + 1)) {
34  lua_pop(co, nres); /* remove results anyway */
35  lua_pushliteral(L, "too many results to resume");
36  return -1; /* error flag */
37  }
38  lua_xmove(co, L, nres); /* move yielded values */
39  return nres;
40  }
41  else {
42  lua_xmove(co, L, 1); /* move error message */
43  return -1; /* error flag */
44  }
45 }
46 
47 
48 static int luaB_coresume (lua_State *L) {
49  lua_State *co = lua_tothread(L, 1);
50  int r;
51  luaL_argcheck(L, co, 1, "coroutine expected");
52  r = auxresume(L, co, lua_gettop(L) - 1);
53  if (r < 0) {
54  lua_pushboolean(L, 0);
55  lua_insert(L, -2);
56  return 2; /* return false + error message */
57  }
58  else {
59  lua_pushboolean(L, 1);
60  lua_insert(L, -(r + 1));
61  return r + 1; /* return true + `resume' returns */
62  }
63 }
64 
65 
66 static int luaB_auxwrap (lua_State *L) {
68  int r = auxresume(L, co, lua_gettop(L));
69  if (r < 0) {
70  if (lua_isstring(L, -1)) { /* error object is a string? */
71  luaL_where(L, 1); /* add extra info */
72  lua_insert(L, -2);
73  lua_concat(L, 2);
74  }
75  return lua_error(L); /* propagate error */
76  }
77  return r;
78 }
79 
80 
81 static int luaB_cocreate (lua_State *L) {
82  lua_State *NL;
84  NL = lua_newthread(L);
85  lua_pushvalue(L, 1); /* move function to top */
86  lua_xmove(L, NL, 1); /* move function from L to NL */
87  return 1;
88 }
89 
90 
91 static int luaB_cowrap (lua_State *L) {
92  luaB_cocreate(L);
94  return 1;
95 }
96 
97 
98 static int luaB_yield (lua_State *L) {
99  return lua_yield(L, lua_gettop(L));
100 }
101 
102 
103 static int luaB_costatus (lua_State *L) {
104  lua_State *co = lua_tothread(L, 1);
105  luaL_argcheck(L, co, 1, "coroutine expected");
106  if (L == co) lua_pushliteral(L, "running");
107  else {
108  switch (lua_status(co)) {
109  case LUA_YIELD:
110  lua_pushliteral(L, "suspended");
111  break;
112  case LUA_OK: {
113  lua_Debug ar;
114  if (lua_getstack(co, 0, &ar) > 0) /* does it have frames? */
115  lua_pushliteral(L, "normal"); /* it is running */
116  else if (lua_gettop(co) == 0)
117  lua_pushliteral(L, "dead");
118  else
119  lua_pushliteral(L, "suspended"); /* initial state */
120  break;
121  }
122  default: /* some error occurred */
123  lua_pushliteral(L, "dead");
124  break;
125  }
126  }
127  return 1;
128 }
129 
130 
131 static int luaB_corunning (lua_State *L) {
132  int ismain = lua_pushthread(L);
133  lua_pushboolean(L, ismain);
134  return 2;
135 }
136 
137 
138 static const luaL_Reg co_funcs[] = {
139  {"create", luaB_cocreate},
140  {"resume", luaB_coresume},
141  {"running", luaB_corunning},
142  {"status", luaB_costatus},
143  {"wrap", luaB_cowrap},
144  {"yield", luaB_yield},
145  {NULL, NULL}
146 };
147 
148 
149 
151  luaL_newlib(L, co_funcs);
152  return 1;
153 }
154 
Definition: lua.h:398
LUA_API void lua_pushboolean(lua_State *L, int b)
Definition: lapi.cpp:571
LUALIB_API void luaL_checktype(lua_State *L, int narg, int t)
Definition: lauxlib.cpp:347
LUA_API int lua_gettop(lua_State *L)
Definition: lapi.cpp:154
static int auxresume(lua_State *L, lua_State *co, int narg)
Definition: lcorolib.cpp:19
#define LUA_TFUNCTION
Definition: lua.h:83
static int luaB_cocreate(lua_State *L)
Definition: lcorolib.cpp:81
LUA_API void lua_pushcclosure(lua_State *L, lua_CFunction fn, int n)
Definition: lapi.cpp:549
LUA_API int lua_getstack(lua_State *L, int level, lua_Debug *ar)
Definition: ldebug.cpp:82
#define luaL_argcheck(L, cond, numarg, extramsg)
Definition: lauxlib.h:113
#define lua_pop(L, n)
Definition: lua.h:322
#define lua_upvalueindex(i)
Definition: lua.h:40
LUAMOD_API int luaopen_coroutine(lua_State *L)
Definition: lcorolib.cpp:150
LUA_API int lua_isstring(lua_State *L, int idx)
Definition: lapi.cpp:268
#define LUA_YIELD
Definition: lua.h:45
static int luaB_yield(lua_State *L)
Definition: lcorolib.cpp:98
LUA_API lua_State * lua_tothread(lua_State *L, int idx)
Definition: lapi.cpp:431
LUALIB_API void luaL_where(lua_State *L, int level)
Definition: lauxlib.cpp:185
static int luaB_auxwrap(lua_State *L)
Definition: lcorolib.cpp:66
static int luaB_cowrap(lua_State *L)
Definition: lcorolib.cpp:91
LUA_API int lua_status(lua_State *L)
Definition: lapi.cpp:1006
static int luaB_costatus(lua_State *L)
Definition: lcorolib.cpp:103
#define lua_pushliteral(L, s)
Definition: lua.h:339
LUA_API int lua_pushthread(lua_State *L)
Definition: lapi.cpp:587
LUA_API void lua_xmove(lua_State *from, lua_State *to, int n)
Definition: lapi.cpp:106
#define LUAMOD_API
Definition: luaconf.h:163
#define lua_yield(L, n)
Definition: lua.h:272
static int luaB_coresume(lua_State *L)
Definition: lcorolib.cpp:48
LUA_API void lua_insert(lua_State *L, int idx)
Definition: lapi.cpp:187
GLdouble GLdouble GLdouble r
Definition: glew.h:1374
LUA_API void lua_pushvalue(lua_State *L, int idx)
Definition: lapi.cpp:229
static const luaL_Reg co_funcs[]
Definition: lcorolib.cpp:138
LUA_API int lua_resume(lua_State *L, lua_State *from, int nargs)
Definition: ldo.cpp:557
#define luaL_newlib(L, l)
Definition: lauxlib.h:111
static int luaB_corunning(lua_State *L)
Definition: lcorolib.cpp:131
LUA_API int lua_error(lua_State *L)
Definition: lapi.cpp:1099
#define LUA_OK
Definition: lua.h:44
LUA_API void lua_concat(lua_State *L, int n)
Definition: lapi.cpp:1125
LUA_API int lua_checkstack(lua_State *L, int size)
Definition: lapi.cpp:86
LUA_API lua_State * lua_newthread(lua_State *L)
Definition: lstate.cpp:236