Logo AND Algorithmique Numérique Distribuée

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