Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
further try at getting lua working (not quite there yet)
[simgrid.git] / src / bindings / lua / Msglua.c
1 #include <stdio.h>
2 #include <lua5.1/lauxlib.h>
3 #include <lua5.1/lualib.h>
4
5 // Msg Includes
6 #include <stdio.h>
7 #include "msg/msg.h"
8 #include "msg/datatypes.h"
9 #include "xbt/sysdep.h"        
10 #include "xbt/log.h"
11 #include "xbt/asserts.h"
12
13
14
15
16 /*
17 =============================================
18
19         Example Lua Bindings for Msg
20
21 =============================================
22  */
23
24
25 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smx_lua,simix,
26     "Messages specific for this lua example");
27
28
29 #define TASK "Msg.Task"
30 #define HOST "Msg.Host"
31 #define PROCESS "Msg.Process"
32
33 typedef m_task_t Task;
34 typedef m_host_t Host;
35 typedef m_process_t Process;
36
37
38 static void stackDump (lua_State *L) {
39   char buff[2048];
40   char *p=buff;
41   int i;
42   int top = lua_gettop(L);
43   void *ptr;
44   fflush(stdout);
45   p+=sprintf(p,"STACK(top=%d): ",top);
46   for (i = 1; i <= top; i++) {  /* repeat for each level */
47     int t = lua_type(L, i);
48     switch (t) {
49
50     case LUA_TSTRING:  /* strings */
51       p+=sprintf(p,"`%s'", lua_tostring(L, i));
52       break;
53
54     case LUA_TBOOLEAN:  /* booleans */
55       p+=sprintf(p,lua_toboolean(L, i) ? "true" : "false");
56       break;
57
58     case LUA_TNUMBER:  /* numbers */
59       p+=sprintf(p,"%g", lua_tonumber(L, i));
60       break;
61
62     default:  /* other values */
63       if ((ptr = luaL_checkudata(L,i,TASK))) {
64         p+=sprintf(p,"task");
65       } else {
66         p+=printf(p,"%s", lua_typename(L, t));
67       }
68       break;
69
70     }
71     p+=sprintf(p,"  ");  /* put a separator */
72   }
73   INFO1("%s",buff);
74 }
75
76 //**********************************************************TASK SECTION***************************************************
77
78
79 static Task toTask(lua_State *L,int index)
80 {
81   Task *pi = (Task*) lua_touserdata(L,index);
82   if(pi == NULL) luaL_typerror(L,index,TASK);
83   return *pi;
84 }
85 /**
86  *checkTask ensures that a userdata on the stack is the correct type, and returns the Task pointer inside the userdata
87  */
88
89 static Task checkTask (lua_State *L,int index)
90 {
91   Task *pi,tk;
92   luaL_checktype(L,index,LUA_TUSERDATA);
93   pi = (Task*)luaL_checkudata(L,index,TASK);
94   if(pi == NULL ) luaL_typerror(L,index,TASK);
95   tk = *pi;
96   if(!tk)
97     luaL_error(L,"null Task");
98   return  tk;
99 }
100
101 /**
102  *pushTask leaves a new userdata on top of the stack, sets its metatable, and sets the Task pointer inside the userdata.
103  */
104
105 static Task *pushTask (lua_State *L,Task tk)
106 {
107   Task *pi = (Task*)lua_newuserdata(L,sizeof(Task));
108   *pi=tk;
109   luaL_getmetatable(L,TASK);
110   lua_setmetatable(L,-2);
111   return pi;
112
113 }
114
115 /**
116  *Task.new is a constructor that returns a userdata containing a pointer the Task to be manipulated
117  */
118
119
120 static int Task_new(lua_State* L)
121 {
122   const char *name=luaL_checkstring(L,1);
123   int comp_size = luaL_checkint(L,2);
124   int msg_size = luaL_checkint(L,3);
125   // We Will Set The Data as a Null for The Moment
126   pushTask(L,MSG_task_create(name,comp_size,msg_size,NULL));
127   INFO0("Created task");fflush(stdout);fflush(stderr);
128   return 1;
129
130 }
131
132 /**
133  * Function to return the Task Name
134  */
135
136
137 static int Task_name(lua_State *L)
138 {
139   Task tk = checkTask(L,1);
140   lua_pushstring(L,MSG_task_get_name(tk));
141   return 1;
142 }
143
144
145 /**
146  * Function to return the Computing Size of a Task
147  */
148
149 static int Task_comp(lua_State *L)
150 {
151   Task tk = checkTask(L,1);
152   lua_pushnumber(L,MSG_task_get_compute_duration (tk));
153   return 1;
154 }
155
156
157 /**
158  *Function to Excute a Task
159  */
160
161 static int Task_execute(lua_State *L)
162 {
163   Task tk = checkTask(L,1);
164   int res = MSG_task_execute(tk);
165   lua_pushnumber(L,res);
166   return 1;
167 }
168
169 /**
170  *Function ro Desroy a Task
171  */
172 static int Task_destroy(lua_State *L)
173 {
174   Task tk = checkTask(L,1);
175   int res = MSG_task_destroy(tk);
176   lua_pushnumber(L,res);
177   return 1;
178 }
179
180
181
182
183
184
185 //***************************************************************  HOST SECTION  ***************************************************************************
186
187
188
189 static Host toHost(lua_State *L,int index)
190 {
191   Host *pi = (Host*) lua_touserdata(L,index);
192   if(pi == NULL) luaL_typerror(L,index,HOST);
193   return *pi;
194 }
195
196
197
198 static Host checkHost (lua_State *L,int index)
199 {
200   Host *pi,ht;
201   luaL_checktype(L,index,LUA_TUSERDATA);
202   pi = (Host*)luaL_checkudata(L,index,HOST);
203   if(pi == NULL ) luaL_typerror(L,index,HOST);
204   ht = *pi;
205   if(!ht)
206     luaL_error(L,"null Host");
207   return  ht;
208 }
209
210
211
212 static Host *pushHost (lua_State *L,Host ht)
213 {
214   Host *pi = (Host*)lua_newuserdata(L,sizeof(Host));
215   *pi=ht;
216   luaL_getmetatable(L,HOST);
217   lua_setmetatable(L,-2);
218   return pi;
219
220 }
221
222
223 static int Host_new(lua_State* L)
224 {
225   const char *host_name=luaL_checkstring(L,1);
226   pushHost(L,MSG_get_host_by_name(host_name));
227   return 1;
228 }
229
230
231
232 static int Host_name(lua_State* L)
233 {
234   Host ht = checkHost(L,1);
235   lua_pushstring(L,MSG_host_get_name(ht));
236   return 1;
237 }
238
239
240 //*******************************************************   PROCESS SECTION      ***************************************************************************
241 static Process toProcess(lua_State *L,int index)
242 {
243   Process *pi = (Process*) lua_touserdata(L,index);
244   if(pi == NULL) luaL_typerror(L,index,PROCESS);
245   return *pi;
246 }
247
248
249
250 static Process checkProcess (lua_State *L,int index)
251 {
252   Process *pi,ps;
253   luaL_checktype(L,index,LUA_TUSERDATA);
254   pi = (Process*)luaL_checkudata(L,index,PROCESS);
255   if(pi == NULL ) luaL_typerror(L,index,PROCESS);
256   ps = *pi;
257   if(!ps)
258     luaL_error(L,"null Process");
259   return  ps;
260 }
261
262
263
264 static Process *pushProcess (lua_State *L,Process ps)
265 {
266   Process *pi = (Process*)lua_newuserdata(L,sizeof(Process));
267   *pi=ps;
268   luaL_getmetatable(L,PROCESS);
269   lua_setmetatable(L,-2);
270   return pi;
271
272 }
273
274 /*
275 m_process_t MSG_process_create          (       const char *     name,
276                 xbt_main_func_t         code,
277                 void *          data,
278                 m_host_t        host     
279         )       
280  */
281
282
283
284 static int Process_new(lua_State* L)
285 {
286   const char *name=luaL_checkstring(L,1);
287   //int code = luaL_checkint(L,2);
288   //xbt_main_func_t << code
289   // We Will Set The Data as a Null for The Moment
290   Host ht = checkHost(L,4);
291   pushProcess(L,MSG_process_create(name,NULL,NULL,ht));
292   return 1;
293
294 }
295
296
297 static int Process_kill(lua_State *L)
298 {
299   Process ps = checkProcess (L,1);
300   MSG_process_kill(ps);
301   return 0;
302 }
303
304
305
306 //**********************************************************MSG Operating System Functions******************************************************************
307 /**
308  * Function to Send a Task
309  */
310 static int Task_send(lua_State *L)      {
311   Task tk = checkTask(L,1);
312   const char *mailbox = luaL_checkstring(L,2);
313   stackDump(L);fflush(stdout);fflush(stderr);
314   int res = MSG_task_send(tk,mailbox);
315   res++;//FIXME: check it instead of avoiding the warning
316   stackDump(L);
317   return 0;
318 }
319 /**
320  * Function Recieve a Task
321  */
322 static int Task_recv(lua_State *L)      {
323   Task tk = NULL;
324   //stackDump(L);
325   const char *mailbox = luaL_checkstring(L,1);
326   int res = MSG_task_receive(&tk,mailbox);
327   res++;//FIXME: check it instead of avoiding the warning
328   INFO1("Task Name : >>>%s",MSG_task_get_name(tk));
329   pushTask(L,tk);
330   //    stackDump(L);
331   return 1;
332 }
333
334 //*******************************************************   PLATFORM & APPLICATION SECTION  ****************************************************************
335
336
337 //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> WE WONT NEED IT (!!??)
338 /**
339  * Launch Application Function
340  */
341
342 static int launch_application(lua_State *L)
343 {
344
345   const char * file = luaL_checkstring(L,1);
346   MSG_launch_application(file);
347   return 0;
348
349 }
350
351 /**
352  * Create Environment Function
353  */
354
355 static int create_environment(lua_State *L)
356 {
357
358   const char *file = luaL_checkstring(L,1);
359   MSG_create_environment(file);
360   return 0;
361
362 }
363
364
365 //******************************************************************       REGISTERING          ************************************************************
366 /**
367  *Registering Into Lua
368  */
369
370
371 static const luaL_reg Task_methods[] = {
372     {"new",             Task_new},
373     {"name",    Task_name},
374     {"comp",    Task_comp},
375     {"execute", Task_execute},
376     {"destroy", Task_destroy},
377     {"send",            Task_send},
378     {"recv",            Task_recv},
379     {0,0}
380 };
381
382
383 static const luaL_reg Host_methods[] = {
384     {"new",             Host_new},
385     {"name",    Host_name},
386     {0,0}
387 };
388
389
390 static const luaL_reg Process_methods[] = {
391     {"new",             Process_new},
392     {"kill",    Process_kill},
393     {0,0}
394 };
395
396
397
398
399 /**
400  * Task_meta
401  */
402 static int Task_gc(lua_State *L)
403 {
404   Task tk=toTask(L,1);
405   if (tk) MSG_task_destroy(tk);
406   //printf("GoodBye Task(%p)\n",lua_touserdata(L,1));
407   return 0;
408 }
409
410 static int Task_tostring(lua_State *L)
411 {
412   lua_pushfstring(L,"Task :%p",lua_touserdata(L,1));
413   return 1;
414 }
415
416
417 static const luaL_reg Task_meta[] = {
418     {"__gc",    Task_gc},
419     {"__tostring",      Task_tostring},
420     {0,0}
421 };
422
423
424
425
426 /**
427  * Host_meta
428  */
429 static int Host_gc(lua_State *L)
430 {
431   Host ht=toHost(L,1);
432   if (ht) ht=NULL;
433   printf("GoodBye Host(%p)\n",lua_touserdata(L,1));
434   return 0;
435 }
436
437 static int Host_tostring(lua_State *L)
438 {
439   lua_pushfstring(L,"Host :%p",lua_touserdata(L,1));
440   return 1;
441 }
442
443
444 static const luaL_reg Host_meta[] = {
445     {"__gc",    Host_gc},
446     {"__tostring",      Host_tostring},
447     {0,0}
448 };
449
450
451 /**
452  * Process_meta
453  */
454 static int Process_gc(lua_State *L)
455 {
456   Process ps=toProcess(L,1);
457   if (ps) MSG_process_kill(ps) ;
458   printf("GoodBye Process(%p)\n",lua_touserdata(L,1));
459   return 0;
460 }
461
462 static int Process_tostring(lua_State *L)
463 {
464   lua_pushfstring(L,"Process :%p",lua_touserdata(L,1));
465   return 1;
466 }
467
468
469 static const luaL_reg Process_meta[] = {
470     {"__gc",    Process_gc},
471     {"__tostring",      Process_tostring},
472     {0,0}
473 };
474
475
476 /**
477  *The metatable for the userdata is put in the registry, and the __index field points to the table of methods so that the object:method() syntax will work. The methods table is stored in the table of globals so that scripts can add methods written in Lua.
478  */
479
480 /**
481  * Register Task, Host, and Process
482  */
483
484 int MSG_register(lua_State *L);// FIXME: better location
485 int MSG_register(lua_State *L) {
486   luaL_openlib(L,TASK,Task_methods,0); //create methods table,add it to the globals
487   luaL_newmetatable(L,TASK); //create metatable for Task,add it to the Lua registry
488   luaL_openlib(L,0,Task_meta,0);// fill metatable
489   lua_pushliteral(L,"__index");
490   lua_pushvalue(L,-3);  //dup methods table
491   lua_rawset(L,-3);     //matatable.__index = methods
492   lua_pushliteral(L,"__metatable");
493   lua_pushvalue(L,-3);  //dup methods table
494   lua_rawset(L,-3);     //hide metatable:metatable.__metatable = methods
495   lua_pop(L,1);         //drop metatable
496   /* HOST */
497   luaL_openlib(L,HOST,Host_methods,0);
498   luaL_newmetatable(L,HOST);
499   luaL_openlib(L,0,Host_meta,0);
500   lua_pushliteral(L,"__index");
501   lua_pushvalue(L,-3);
502   lua_rawset(L,-3);
503   lua_pushliteral(L,"__metatable");
504   lua_pushvalue(L,-3);
505   lua_rawset(L,-3);
506   lua_pop(L,1);
507   /* Process */
508   luaL_openlib(L,PROCESS,Process_methods,0);
509   luaL_newmetatable(L,PROCESS);
510   luaL_openlib(L,0,Host_meta,0);
511   lua_pushliteral(L,"__index");
512   lua_pushvalue(L,-3);
513   lua_rawset(L,-3);
514   lua_pushliteral(L,"__metatable");
515   lua_pushvalue(L,-3);
516   lua_rawset(L,-3);
517   lua_pop(L,1);
518   return 1;
519 }
520