1 /* Copyright (c) 2010. The SimGrid Team.
2 * All rights reserved. */
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. */
7 /* SimGrid Lua helper functions */
10 #include "lua_utils.h"
14 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(lua_utils, bindings, "Lua helper functions");
17 * @brief Returns a string representation of a value in the Lua stack.
19 * This function is for debugging purposes.
20 * It always returns the same pointer.
22 * @param L the Lua state
23 * @param index index in the stack
24 * @return a string representation of the value at this index
26 const char* sglua_tostring(lua_State* L, int index) {
30 switch (lua_type(L, index)) {
37 sprintf(buff, "%.3f", lua_tonumber(L, index));
41 sprintf(buff, "%s", lua_toboolean(L, index) ? "true" : "false");
45 snprintf(buff, 63, "'%s'", lua_tostring(L, index));
49 if (lua_iscfunction(L, index)) {
50 sprintf(buff, "C-function");
53 sprintf(buff, "function");
58 sprintf(buff, "table(%p)", lua_topointer(L, index));
61 case LUA_TLIGHTUSERDATA:
63 sprintf(buff, "userdata(%p)", lua_touserdata(L, index));
67 sprintf(buff, "thread");
74 * @brief Returns a string representation of a key-value pair.
76 * This function is for debugging purposes.
77 * It always returns the same pointer.
79 * @param L the Lua state
80 * @param key_index index of the key
81 * @param value_index index of the value
82 * @return a string representation of the key-value pair
84 const char* sglua_keyvalue_tostring(lua_State* L, int key_index, int value_index) {
87 /* value_tostring also always returns the same pointer */
88 int len = snprintf(buff, 63, "[%s] -> ", sglua_tostring(L, key_index));
89 snprintf(buff + len, 63 - len, "%s", sglua_tostring(L, value_index));
94 * @brief Returns a string composed of the specified number of spaces.
96 * This function can be used to indent strings for debugging purposes.
97 * It always returns the same pointer.
99 * @param length length of the string
100 * @return a string of this length with only spaces
102 const char* sglua_get_spaces(int length) {
104 static char spaces[128];
106 xbt_assert(length < 128);
108 memset(spaces, ' ', length);
110 spaces[length] = '\0';
115 * @brief Dumps the Lua stack if debug logs are enabled.
116 * @param msg a message to print
117 * @param L a Lua state
119 void sglua_stack_dump(const char* msg, lua_State* L)
121 if (XBT_LOG_ISENABLED(lua_utils, xbt_log_priority_debug)) {
125 int top = lua_gettop(L);
132 for (i = 1; i <= top; i++) { /* repeat for each level */
134 p += sprintf(p, "%s", sglua_tostring(L, i));
135 p += sprintf(p, " "); /* put a separator */
137 XBT_DEBUG("%s%s", msg, buff);
142 * \brief Like luaL_checkudata, with additional debug logs.
144 * This function is for debugging purposes only.
146 * \param L a lua state
147 * \param ud index of the userdata to check in the stack
148 * \param tname key of the metatable of this userdata in the registry
150 void* sglua_checkudata_debug(lua_State* L, int ud, const char* tname)
152 XBT_DEBUG("Checking the userdata: ud = %d", ud);
153 sglua_stack_dump("my_checkudata: ", L);
154 void* p = lua_touserdata(L, ud);
155 lua_getfield(L, LUA_REGISTRYINDEX, tname);
156 const void* correct_mt = lua_topointer(L, -1);
158 int has_mt = lua_getmetatable(L, ud);
159 XBT_DEBUG("Checking the userdata: has metatable ? %d", has_mt);
160 const void* actual_mt = NULL;
162 actual_mt = lua_topointer(L, -1);
165 XBT_DEBUG("Checking the task's metatable: expected %p, found %p", correct_mt, actual_mt);
166 sglua_stack_dump("my_checkudata: ", L);
168 if (p == NULL || !lua_getmetatable(L, ud) || !lua_rawequal(L, -1, -2))
169 luaL_typerror(L, ud, tname);
175 * @brief Writes the specified data into a memory buffer.
177 * This function is a valid lua_Writer that writes into a memory buffer passed
180 * @param L a lua state
181 * @param source some data
182 * @param sz number of bytes of data
183 * @param user_data the memory buffer to write
185 int sglua_memory_writer(lua_State* L, const void* source, size_t size,
188 sglua_buffer_t buffer = (sglua_buffer_t) userdata;
189 while (buffer->capacity < buffer->size + size) {
190 buffer->capacity *= 2;
191 buffer->data = xbt_realloc(buffer->data, buffer->capacity);
193 memcpy(buffer->data + buffer->size, source, size);
194 buffer->size += size;