fixed: lexer memory leak due to strdup
This commit is contained in:
parent
2de4f7b460
commit
1e2f3c263a
|
@ -148,6 +148,8 @@ static void build_target(ModuleFileStack *unit, const TargetConfig *target) {
|
|||
|
||||
AST_delete_node(ast);
|
||||
|
||||
lex_purge_str_cache();
|
||||
|
||||
print_file_statistics(file);
|
||||
}
|
||||
|
||||
|
|
|
@ -89,20 +89,20 @@
|
|||
"lineno" {DEBUG("\"%s\" tokenized with \'FunLineno\'", yytext); return(FunLineno);};
|
||||
"extsupport" {DEBUG("\"%s\" tokenized with \'FunExtsupport\'", yytext); return(FunExtsupport);};
|
||||
|
||||
[0-9]+ {DEBUG("\"%s\" tokenized with \'ValInt\'", yytext); yylval.string = strdup(yytext); return(ValInt); };
|
||||
[0-9]*\.[0-9]+ {DEBUG("\"%s\" tokenized with \'ValFloat\'", yytext); yylval.string = strdup(yytext); return(ValFloat);};
|
||||
[a-zA-Z_0-9]+ {DEBUG("\"%s\" tokenized with \'Ident\'", yytext); yylval.string = strdup(yytext); return(Ident); };
|
||||
[0-9]+ {DEBUG("\"%s\" tokenized with \'ValInt\'", yytext); yylval.string = lex_cached_strdup(yytext); return(ValInt); };
|
||||
[0-9]*\.[0-9]+ {DEBUG("\"%s\" tokenized with \'ValFloat\'", yytext); yylval.string = lex_cached_strdup(yytext); return(ValFloat);};
|
||||
[a-zA-Z_0-9]+ {DEBUG("\"%s\" tokenized with \'Ident\'", yytext); yylval.string = lex_cached_strdup(yytext); return(Ident); };
|
||||
|
||||
\"([^\"\n])*\" {
|
||||
yytext = yytext +1;
|
||||
yytext[yyleng - 2] = 0;
|
||||
|
||||
DEBUG("\"%s\" tokenized with \'ValStr\'", yytext); yylval.string = strdup(yytext); return(ValStr);};
|
||||
DEBUG("\"%s\" tokenized with \'ValStr\'", yytext); yylval.string = lex_cached_strdup(yytext); return(ValStr);};
|
||||
\"\"\"[^\"]*\"\"\" {
|
||||
yytext = yytext +3;
|
||||
yytext[yyleng - 4] = 0;
|
||||
|
||||
DEBUG("\"%s\" tokenized with \'ValMultistr\'", yytext); yylval.string = strdup(yytext); return(ValMultistr);};
|
||||
DEBUG("\"%s\" tokenized with \'ValMultistr\'", yytext); yylval.string = lex_cached_strdup(yytext); return(ValMultistr);};
|
||||
[ \r\t] { /* ignore whitespace */ };
|
||||
. { return yytext[0]; /* passthrough unknown token, let parser handle the error */ };
|
||||
%%
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include <lex/util.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <glib.h>
|
||||
|
||||
// implementation based on:
|
||||
// https://github.com/sunxfancy/flex-bison-examples/blob/master/error-handling/ccalc.c
|
||||
|
@ -16,12 +17,37 @@ static int nTokenStart = 0;
|
|||
static int nTokenLength = 0;
|
||||
static int nTokenNextStart = 0;
|
||||
|
||||
static GArray* stringCache = NULL;
|
||||
|
||||
char* lex_cached_strdup(char* string) {
|
||||
char* dup = strdup(string);
|
||||
|
||||
g_array_append_val(stringCache, dup);
|
||||
|
||||
return dup;
|
||||
}
|
||||
|
||||
void lex_purge_str_cache() {
|
||||
DEBUG("purging string cache...");
|
||||
|
||||
const guint count = stringCache->len;
|
||||
|
||||
for (guint i = 0; i < count; i++) {
|
||||
free(((char**) stringCache->data)[i]);
|
||||
}
|
||||
|
||||
g_array_remove_range(stringCache, 0, count);
|
||||
}
|
||||
|
||||
static void lex_deinit(void) {
|
||||
lex_purge_str_cache();
|
||||
g_array_free(stringCache, TRUE);
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
void lex_init(void) {
|
||||
buffer = malloc(MAX_READ_BUFFER_SIZE);
|
||||
stringCache = g_array_new(FALSE, FALSE, sizeof(char*));
|
||||
atexit(lex_deinit);
|
||||
}
|
||||
|
||||
|
|
|
@ -18,6 +18,10 @@ void lex_init(void);
|
|||
|
||||
void lex_reset(void);
|
||||
|
||||
char* lex_cached_strdup(char* string);
|
||||
|
||||
void lex_purge_str_cache();
|
||||
|
||||
/**
|
||||
* @brief Begin counting a new token. This will fill the global struct yylloc.
|
||||
* @param t the text of the token. Must be null terminated
|
||||
|
|
Loading…
Reference in New Issue