Skip to content

Commit 8491772

Browse files
committed
Merge branch 'debugger'
This add a very basic implementation of debug info. Right now the only info that this command will find are global function names. The plan is to first parse table syntax, ie. `foo.bar.baz`, and actually go down the stack until we react that `baz` function of table bar of table foo. Next would be ordered tables since that will be a bit more trick which the name tables are similar to just the `laco_line_to_words` only with dots instead of spaces.
2 parents 2acc4c5 + d959397 commit 8491772

File tree

6 files changed

+95
-4
lines changed

6 files changed

+95
-4
lines changed

src/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ include_directories("${laco_SOURCE_DIR}/src" "${DEPS_DIR}/linenoise")
44

55
set(SOURCE ${DEPS_DIR}/linenoise/linenoise.c
66
main.c util.c util/print.c
7+
commands/debugger.c
78
flags.c commands.c laco.c)
89

910
add_executable(laco ${SOURCE})

src/commands.c

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,23 @@
22

33
#include <stdbool.h>
44
#include <stdio.h>
5+
#include <stdlib.h>
6+
#include <string.h>
57

68
#include "util.h"
9+
#include "commands/debugger.h"
710

811
static const char* quit_matches[] = {"quit", "q"};
912
static const char* help_matches[] = {"help", "?"};
1013

14+
/* Debugger commands */
15+
static const char* debug_info_matches[] = {"info"};
16+
1117
static void print_commands_help() {
1218
puts(" Commands available:\n");
13-
puts(" :quit, :q \tExit laco");
14-
puts(" :help, :? \tDisplay this list of commands");
19+
puts(" :quit, :q \tExit laco");
20+
puts(" :help, :? \tDisplay this list of commands");
21+
puts(" :info <name> \tShow information on given function");
1522
}
1623

1724
static inline bool is_quit(const char* command) {
@@ -22,17 +29,31 @@ static inline bool is_help(const char* command) {
2229
return laco_is_match(help_matches, command);
2330
}
2431

32+
static inline bool is_debug_info(const char* command) {
33+
return laco_is_match(debug_info_matches, command);
34+
}
35+
2536
void laco_handle_command(struct LacoState* laco, char* line) {
2637
if(laco != NULL && line != NULL) {
27-
const char* command = line + 1;
38+
char* command_line = strdup(line + 1);
39+
char** command_words = laco_line_to_words(command_line);
40+
41+
/* Alias for */
42+
const char* command = command_words[0];
43+
const char** arguments = (const char**) command_words + 1;
2844

2945
if(is_quit(command)) {
3046
laco_kill(laco, 0, "Exiting laco...");
3147
} else if(is_help(command)) {
3248
print_commands_help();
49+
} else if(is_debug_info(command)) {
50+
laco_print_debug_info(laco, arguments[0]);
3351
}
3452

35-
/* Make it seem like this was an empty line */
53+
free(command_line);
54+
free(command_words);
55+
56+
/* Make it seems like this was an empty line */
3657
line[0] = '\0';
3758
}
3859
}

src/commands/debugger.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#include "debugger.h"
2+
3+
#include <stdio.h>
4+
#include <lua.h>
5+
6+
#include "laco.h"
7+
8+
void laco_print_debug_info(struct LacoState* laco,
9+
const char* function_name) {
10+
lua_State* L = laco_get_laco_lua_state(laco);
11+
lua_Debug debug_info = {0};
12+
13+
lua_getfield(L, LUA_GLOBALSINDEX, function_name);
14+
15+
lua_getinfo(L, ">Sl", &debug_info);
16+
17+
printf(
18+
"What: \t%s\n"
19+
"Source file: \t%s\n"
20+
"Line defined on: \t%d\n"
21+
"Current line: \t%d\n",
22+
debug_info.what, debug_info.source,
23+
debug_info.linedefined, debug_info.currentline);
24+
}

src/commands/debugger.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#ifndef LACO_DEBUGGER_H
2+
#define LACO_DEBUGGER_H
3+
4+
struct LacoState;
5+
6+
/**
7+
* Prints out debug info of a give function name.
8+
*/
9+
void laco_print_debug_info(struct LacoState* laco,
10+
const char* function_name);
11+
12+
#endif /* LACO_DEBUGGER_H */

src/util.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,14 @@ static bool pushline(LacoState* laco, bool isFirstLine) {
100100
return result;
101101
}
102102

103+
static inline void ignore_extra_spaces(char** string_ptr) {
104+
if(*string_ptr == NULL) return;
105+
106+
while(**string_ptr == ' ') {
107+
*string_ptr += 1;
108+
}
109+
}
110+
103111
/* External API */
104112

105113
int laco_load_line(LacoState* laco) {
@@ -170,3 +178,22 @@ int laco_is_match(const char** matches, const char* test_string) {
170178

171179
return false;
172180
}
181+
182+
char** laco_line_to_words(char* line) {
183+
if(line == NULL) return NULL;
184+
185+
char** result = calloc(16, sizeof(char*));
186+
size_t i = 0;
187+
188+
while(1) {
189+
result[i] = strsep(&line, " ");
190+
191+
if(result[i] == NULL) break;
192+
193+
ignore_extra_spaces(&line);
194+
195+
i += 1;
196+
}
197+
198+
return result;
199+
}

src/util.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,10 @@ void laco_report_error(struct LacoState* laco, int status);
3838
*/
3939
int laco_is_match(const char** matches, const char* test_string);
4040

41+
/**
42+
* Takes a line, seperated by spaces, and changes it into an array of the
43+
* words that make up the line. The last value of this array will be NULL.
44+
*/
45+
char** laco_line_to_words(char* line);
46+
4147
#endif /* LACO_UTIL_H */

0 commit comments

Comments
 (0)