Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
55721bc7c40eaef02141539d3c5aba3c0f43e98e
[simgrid.git] / src / bindings / lua / lua_utils.c
1 /* Copyright (c) 2010. The SimGrid Team.
2  * All rights reserved.                                                     */
3
4 /* This program is free software; you can redistribute it and/or modify it
5  * under the terms of the license (GNU LGPL) which comes with this package. */
6
7 /* SimGrid Lua helper functions                                             */
8
9 #include "lua_utils.h"
10 #include "xbt.h"
11 #include "xbt/log.h"
12
13 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(lua_utils, lua, "Lua helper functions");
14
15 /**
16  * @brief Returns a string representation of a value in the Lua stack.
17  *
18  * This function is for debugging purposes.
19  * It always returns the same pointer.
20  *
21  * @param L the Lua state
22  * @param index index in the stack
23  * @return a string representation of the value at this index
24  */
25 const char* sglua_tostring(lua_State* L, int index) {
26
27   static char buff[64];
28
29   switch (lua_type(L, index)) {
30
31     case LUA_TNIL:
32       sprintf(buff, "nil");
33       break;
34
35     case LUA_TNUMBER:
36       sprintf(buff, "%.3f", lua_tonumber(L, index));
37       break;
38
39     case LUA_TBOOLEAN:
40       sprintf(buff, "%s", lua_toboolean(L, index) ? "true" : "false");
41       break;
42
43     case LUA_TSTRING:
44       snprintf(buff, 63, "'%s'", lua_tostring(L, index));
45       break;
46
47     case LUA_TFUNCTION:
48       if (lua_iscfunction(L, index)) {
49         sprintf(buff, "C-function");
50       }
51       else {
52         sprintf(buff, "function");
53       }
54       break;
55
56     case LUA_TTABLE:
57       sprintf(buff, "table(%p)", lua_topointer(L, index));
58       break;
59
60     case LUA_TLIGHTUSERDATA:
61     case LUA_TUSERDATA:
62       sprintf(buff, "userdata(%p)", lua_touserdata(L, index));
63       break;
64
65     case LUA_TTHREAD:
66       sprintf(buff, "thread");
67       break;
68   }
69   return buff;
70 }
71
72 /**
73  * @brief Returns a string representation of a key-value pair.
74  *
75  * This function is for debugging purposes.
76  * It always returns the same pointer.
77  *
78  * @param L the Lua state
79  * @param key_index index of the key
80  * @param value_index index of the value
81  * @return a string representation of the key-value pair
82  */
83 const char* sglua_keyvalue_tostring(lua_State* L, int key_index, int value_index) {
84
85   static char buff[64];
86   /* value_tostring also always returns the same pointer */
87   int len = snprintf(buff, 63, "[%s] -> ", sglua_tostring(L, key_index));
88   snprintf(buff + len, 63 - len, "%s", sglua_tostring(L, value_index));
89   return buff;
90 }
91
92 /**
93  * @brief Returns a string composed of the specified number of spaces.
94  *
95  * This function can be used to indent strings for debugging purposes.
96  * It always returns the same pointer.
97  *
98  * @param length length of the string
99  * @return a string of this length with only spaces
100  */
101 const char* sglua_get_spaces(int length) {
102
103   static char spaces[128];
104
105   xbt_assert(length < 128);
106   memset(spaces, ' ', length);
107   spaces[length] = '\0';
108   return spaces;
109 }
110
111 /**
112  * @brief Dumps the Lua stack if debug logs are enabled.
113  * @param msg a message to print
114  * @param L a Lua state
115  */
116 void sglua_stack_dump(const char* msg, lua_State* L)
117 {
118   if (XBT_LOG_ISENABLED(lua_utils, xbt_log_priority_debug)) {
119     char buff[2048];
120     char* p = buff;
121     int i;
122     int top = lua_gettop(L);
123
124     //if (1) return;
125
126     fflush(stdout);
127
128     p[0] = '\0';
129     for (i = 1; i <= top; i++) {  /* repeat for each level */
130
131       p += sprintf(p, "%s", sglua_tostring(L, i));
132       p += sprintf(p, " ");       /* put a separator */
133     }
134     XBT_DEBUG("%s%s", msg, buff);
135   }
136 }
137
138 /**
139  * @brief Writes the specified data into a memory buffer.
140  *
141  * This function is a valid lua_Writer that writes into a memory buffer passed
142  * as userdata.
143  * TODO: use a dynar as userdata
144  *
145  * @param L a lua state
146  * @param source some data
147  * @param sz number of bytes of data
148  * @param user_data the memory buffer to write
149  */
150 int sglua_memory_writer(lua_State* L, const void* source, size_t size,
151     void* userdata) {
152
153   buffer_t buffer = (buffer_t) userdata;
154   while (buffer->capacity < buffer->size + size) {
155     buffer->capacity *= 2;
156     buffer->data = xbt_realloc(buffer->data, buffer->capacity);
157   }
158   memcpy(buffer->data + buffer->size, source, size);
159   buffer->size += size;
160
161   return 0;
162 }