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);
|
AST_delete_node(ast);
|
||||||
|
|
||||||
|
lex_purge_str_cache();
|
||||||
|
|
||||||
print_file_statistics(file);
|
print_file_statistics(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -89,20 +89,20 @@
|
||||||
"lineno" {DEBUG("\"%s\" tokenized with \'FunLineno\'", yytext); return(FunLineno);};
|
"lineno" {DEBUG("\"%s\" tokenized with \'FunLineno\'", yytext); return(FunLineno);};
|
||||||
"extsupport" {DEBUG("\"%s\" tokenized with \'FunExtsupport\'", yytext); return(FunExtsupport);};
|
"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]+ {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 = strdup(yytext); return(ValFloat);};
|
[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 = strdup(yytext); return(Ident); };
|
[a-zA-Z_0-9]+ {DEBUG("\"%s\" tokenized with \'Ident\'", yytext); yylval.string = lex_cached_strdup(yytext); return(Ident); };
|
||||||
|
|
||||||
\"([^\"\n])*\" {
|
\"([^\"\n])*\" {
|
||||||
yytext = yytext +1;
|
yytext = yytext +1;
|
||||||
yytext[yyleng - 2] = 0;
|
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 = yytext +3;
|
||||||
yytext[yyleng - 4] = 0;
|
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 */ };
|
[ \r\t] { /* ignore whitespace */ };
|
||||||
. { return yytext[0]; /* passthrough unknown token, let parser handle the error */ };
|
. { return yytext[0]; /* passthrough unknown token, let parser handle the error */ };
|
||||||
%%
|
%%
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#include <lex/util.h>
|
#include <lex/util.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <glib.h>
|
||||||
|
|
||||||
// implementation based on:
|
// implementation based on:
|
||||||
// https://github.com/sunxfancy/flex-bison-examples/blob/master/error-handling/ccalc.c
|
// 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 nTokenLength = 0;
|
||||||
static int nTokenNextStart = 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) {
|
static void lex_deinit(void) {
|
||||||
|
lex_purge_str_cache();
|
||||||
|
g_array_free(stringCache, TRUE);
|
||||||
free(buffer);
|
free(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void lex_init(void) {
|
void lex_init(void) {
|
||||||
buffer = malloc(MAX_READ_BUFFER_SIZE);
|
buffer = malloc(MAX_READ_BUFFER_SIZE);
|
||||||
|
stringCache = g_array_new(FALSE, FALSE, sizeof(char*));
|
||||||
atexit(lex_deinit);
|
atexit(lex_deinit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,10 @@ void lex_init(void);
|
||||||
|
|
||||||
void lex_reset(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.
|
* @brief Begin counting a new token. This will fill the global struct yylloc.
|
||||||
* @param t the text of the token. Must be null terminated
|
* @param t the text of the token. Must be null terminated
|
||||||
|
|
Loading…
Reference in New Issue