1 |
commit: 96ad12582fcae25e1fc49d3848a77a27952df15a |
2 |
Author: Petteri Räty <petsku <AT> petteriraty <DOT> eu> |
3 |
AuthorDate: Fri Jun 3 16:57:32 2011 +0000 |
4 |
Commit: Petteri Räty <betelgeuse <AT> gentoo <DOT> org> |
5 |
CommitDate: Mon Jun 6 07:06:20 2011 +0000 |
6 |
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/libbash.git;a=commit;h=96ad1258 |
7 |
|
8 |
Core: fix memory leaks in bash_ast::init_parser |
9 |
|
10 |
If init_parser threw an exception the already allocated memory wasn't |
11 |
freed. Now we use our own wrapper antlr_pointer to make sure the memory |
12 |
always gets freed. |
13 |
|
14 |
--- |
15 |
src/core/bash_ast.cpp | 35 +++++++++++++---------------------- |
16 |
src/core/bash_ast.h | 24 ++++++++++++++---------- |
17 |
2 files changed, 27 insertions(+), 32 deletions(-) |
18 |
|
19 |
diff --git a/src/core/bash_ast.cpp b/src/core/bash_ast.cpp |
20 |
index 8f06311..b0ef4f8 100644 |
21 |
--- a/src/core/bash_ast.cpp |
22 |
+++ b/src/core/bash_ast.cpp |
23 |
@@ -52,47 +52,38 @@ bash_ast::bash_ast(const std::string& script_path, |
24 |
init_parser(script, script_path); |
25 |
} |
26 |
|
27 |
-bash_ast::~bash_ast() |
28 |
-{ |
29 |
- nodes->free(nodes); |
30 |
- parser->free(parser); |
31 |
- token_stream->free(token_stream); |
32 |
- lexer->free(lexer); |
33 |
- input->close(input); |
34 |
-} |
35 |
- |
36 |
void bash_ast::init_parser(const std::string& script, const std::string& script_path) |
37 |
{ |
38 |
- input = antlr3NewAsciiStringInPlaceStream( |
39 |
+ input.reset(antlr3NewAsciiStringInPlaceStream( |
40 |
reinterpret_cast<pANTLR3_UINT8>(const_cast<char*>(script.c_str())), |
41 |
// We do not support strings longer than the max value of ANTLR3_UNIT32 |
42 |
boost::numeric_cast<ANTLR3_UINT32>(script.size()), |
43 |
- NULL); |
44 |
+ NULL)); |
45 |
|
46 |
- if(input == NULL) |
47 |
+ if(!input) |
48 |
throw interpreter_exception("Unable to open file " + script + " due to malloc() failure"); |
49 |
|
50 |
input->fileName = input->strFactory->newStr( |
51 |
input->strFactory, |
52 |
reinterpret_cast<pANTLR3_UINT8>(const_cast<char*>(script_path.c_str()))); |
53 |
|
54 |
- lexer = libbashLexerNew(input); |
55 |
- if ( lexer == NULL ) |
56 |
+ lexer.reset(libbashLexerNew(input.get())); |
57 |
+ if(!lexer) |
58 |
throw interpreter_exception("Unable to create the lexer due to malloc() failure"); |
59 |
|
60 |
- token_stream = antlr3CommonTokenStreamSourceNew( |
61 |
- ANTLR3_SIZE_HINT, lexer->pLexer->rec->state->tokSource); |
62 |
- if (token_stream == NULL) |
63 |
+ token_stream.reset(antlr3CommonTokenStreamSourceNew( |
64 |
+ ANTLR3_SIZE_HINT, lexer->pLexer->rec->state->tokSource)); |
65 |
+ if(!token_stream) |
66 |
throw interpreter_exception("Out of memory trying to allocate token stream"); |
67 |
|
68 |
- parser = libbashParserNew(token_stream); |
69 |
- if (parser == NULL) |
70 |
+ parser.reset(libbashParserNew(token_stream.get())); |
71 |
+ if(!parser) |
72 |
throw interpreter_exception("Out of memory trying to allocate parser"); |
73 |
|
74 |
- ast = parse(parser); |
75 |
+ ast = parse(parser.get()); |
76 |
if(parser->pParser->rec->getNumberOfSyntaxErrors(parser->pParser->rec)) |
77 |
throw interpreter_exception("Something wrong happened while parsing"); |
78 |
- nodes = antlr3CommonTreeNodeStreamNewTree(ast, ANTLR3_SIZE_HINT); |
79 |
+ nodes.reset(antlr3CommonTreeNodeStreamNewTree(ast, ANTLR3_SIZE_HINT)); |
80 |
} |
81 |
|
82 |
std::string bash_ast::get_dot_graph() |
83 |
@@ -127,7 +118,7 @@ std::string bash_ast::get_tokens(std::function<std::string(ANTLR3_UINT32)> token |
84 |
// output line number for the first line |
85 |
result << line_counter++ << "\t"; |
86 |
|
87 |
- pANTLR3_VECTOR token_list = token_stream->getTokens(token_stream); |
88 |
+ pANTLR3_VECTOR token_list = token_stream->getTokens(token_stream.get()); |
89 |
unsigned token_size = token_list->size(token_list); |
90 |
|
91 |
for(unsigned i = 0u; i != token_size; ++i) |
92 |
|
93 |
diff --git a/src/core/bash_ast.h b/src/core/bash_ast.h |
94 |
index d5d7f83..aa045bf 100644 |
95 |
--- a/src/core/bash_ast.h |
96 |
+++ b/src/core/bash_ast.h |
97 |
@@ -40,17 +40,25 @@ struct libbashLexer_Ctx_struct; |
98 |
struct libbashParser_Ctx_struct; |
99 |
class interpreter; |
100 |
|
101 |
+template<typename T> |
102 |
+class antlr_pointer: public std::unique_ptr<T, std::function<void(T*)>> |
103 |
+{ |
104 |
+ typedef std::unique_ptr<T, std::function<void(T*)>> parent; |
105 |
+public: |
106 |
+ antlr_pointer(T* p = 0) : parent(p, [](T* to_delete) { to_delete->free(to_delete); }) {}; |
107 |
+}; |
108 |
+ |
109 |
/// \class bash_ast |
110 |
/// \brief a wrapper class that helps interpret from istream and string |
111 |
class bash_ast: public boost::noncopyable |
112 |
{ |
113 |
- pANTLR3_INPUT_STREAM input; |
114 |
+ antlr_pointer<ANTLR3_INPUT_STREAM_struct> input; |
115 |
std::string script; |
116 |
- libbashLexer_Ctx_struct* lexer; |
117 |
- pANTLR3_COMMON_TOKEN_STREAM token_stream; |
118 |
- libbashParser_Ctx_struct* parser; |
119 |
+ antlr_pointer<libbashLexer_Ctx_struct> lexer; |
120 |
+ antlr_pointer<ANTLR3_COMMON_TOKEN_STREAM_struct> token_stream; |
121 |
+ antlr_pointer<libbashParser_Ctx_struct> parser; |
122 |
pANTLR3_BASE_TREE ast; |
123 |
- pANTLR3_COMMON_TREE_NODE_STREAM nodes; |
124 |
+ antlr_pointer<ANTLR3_COMMON_TREE_NODE_STREAM_struct> nodes; |
125 |
std::function<pANTLR3_BASE_TREE(libbashParser_Ctx_struct*)> parse; |
126 |
|
127 |
void init_parser(const std::string& script, const std::string& script_path); |
128 |
@@ -62,8 +70,6 @@ public: |
129 |
bash_ast(const std::string& script_path, |
130 |
std::function<pANTLR3_BASE_TREE(libbashParser_Ctx_struct*)> p=parser_start); |
131 |
|
132 |
- ~bash_ast(); |
133 |
- |
134 |
static void walker_start(plibbashWalker tree_parser); |
135 |
|
136 |
static int walker_arithmetics(plibbashWalker tree_parser); |
137 |
@@ -81,9 +87,7 @@ public: |
138 |
interpret_with(interpreter& walker, Functor walk) |
139 |
{ |
140 |
set_interpreter(&walker); |
141 |
- std::unique_ptr<libbashWalker_Ctx_struct, std::function<void(plibbashWalker)>> p_tree_parser( |
142 |
- libbashWalkerNew(nodes), |
143 |
- [](plibbashWalker tree_parser) { tree_parser->free(tree_parser); }); |
144 |
+ antlr_pointer<libbashWalker_Ctx_struct> p_tree_parser(libbashWalkerNew(nodes.get())); |
145 |
return walk(p_tree_parser.get()); |
146 |
} |