[anjuta/cxxparser] cxxparser: test-complex-struct solved successfully.
- From: Massimo Cora' <mcora src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [anjuta/cxxparser] cxxparser: test-complex-struct solved successfully.
- Date: Thu, 6 Aug 2009 22:46:32 +0000 (UTC)
commit e97fd89812c89ea4ac127c10c8e733df5142df6d
Author: Massimo Corà <mcora src gnome org>
Date: Fri Aug 7 00:43:08 2009 +0200
cxxparser: test-complex-struct solved successfully.
plugins/symbol-db/cxxparser/engine-parser-priv.h | 5 +-
plugins/symbol-db/cxxparser/engine-parser.cpp | 259 +++++++++++++++++++-
plugins/symbol-db/cxxparser/engine-parser.h | 2 +
plugins/symbol-db/cxxparser/main.c | 8 +-
.../cxxparser/sample-db/test-complex-struct.c | 2 +-
5 files changed, 262 insertions(+), 14 deletions(-)
---
diff --git a/plugins/symbol-db/cxxparser/engine-parser-priv.h b/plugins/symbol-db/cxxparser/engine-parser-priv.h
index 0425a6f..cf3dee7 100644
--- a/plugins/symbol-db/cxxparser/engine-parser-priv.h
+++ b/plugins/symbol-db/cxxparser/engine-parser-priv.h
@@ -61,7 +61,10 @@ public:
const string& above_text,
string &out_type_name, // out
string &out_type_scope); // out
-
+
+ SymbolDBEngineIterator * switchTypedefToStruct (SymbolDBEngineIterator * test);
+
+ SymbolDBEngineIterator * switchMemberToContainer (SymbolDBEngineIterator * test);
// FIXME comments.
SymbolDBEngineIterator * processExpression (const string& stmt,
const string& above_text,
diff --git a/plugins/symbol-db/cxxparser/engine-parser.cpp b/plugins/symbol-db/cxxparser/engine-parser.cpp
index 11484c2..153b1d7 100644
--- a/plugins/symbol-db/cxxparser/engine-parser.cpp
+++ b/plugins/symbol-db/cxxparser/engine-parser.cpp
@@ -52,6 +52,8 @@ EngineParser::EngineParser ()
bool
EngineParser::nextToken (string &out_token, string &out_delimiter)
{
+ out_token.clear ();
+
int type(0);
int depth(0);
while ( (type = _tokenizer->yylex()) != 0 )
@@ -64,6 +66,7 @@ EngineParser::nextToken (string &out_token, string &out_delimiter)
if (depth == 0)
{
out_delimiter = _tokenizer->YYText();
+ trim (out_token);
return true;
} else
{
@@ -92,6 +95,7 @@ EngineParser::nextToken (string &out_token, string &out_delimiter)
break;
}
}
+ trim (out_token);
return false;
}
@@ -387,6 +391,71 @@ EngineParser::getCurrentSearchableScope (string &type_name, string &type_scope)
return curr_searchable_scope;
}
+/**
+ * @param test Must be searched with SYMINFO_KIND
+ * @return or the same test or a new struct. In that second case test is unreffed
+ *
+ */
+SymbolDBEngineIterator *
+EngineParser::switchTypedefToStruct (SymbolDBEngineIterator * test)
+{
+ SymbolDBEngineIteratorNode *node = SYMBOL_DB_ENGINE_ITERATOR_NODE (test);
+ SymbolDBEngineIterator *new_struct;
+ gint symbol_id = symbol_db_engine_iterator_node_get_symbol_id (node);
+
+ cout << "Switching typedef to struct " << endl;
+
+ new_struct = symbol_db_engine_get_parent_scope_by_symbol_id (_dbe,
+ symbol_id, NULL,
+ (SymExtraInfo)(SYMINFO_SIMPLE | SYMINFO_KIND));
+
+ if (new_struct != NULL)
+ {
+ /* kill the old one */
+ g_object_unref (test);
+
+ test = new_struct;
+ }
+ else
+ {
+ cout << "Couldn't find a parent for typedef. We'll return the same object" << endl;
+ }
+
+ return test;
+}
+
+SymbolDBEngineIterator *
+EngineParser::switchMemberToContainer (SymbolDBEngineIterator * test)
+{
+ SymbolDBEngineIteratorNode *node = SYMBOL_DB_ENGINE_ITERATOR_NODE (test);
+ SymbolDBEngineIterator *new_container;
+ const gchar* sym_type_name =
+ symbol_db_engine_iterator_node_get_symbol_extra_string (node, SYMINFO_TYPE_NAME);
+
+ cout << "Switching container with type_name " << sym_type_name << endl;
+ /* hopefully we'll find a new container for the type_name of test param */
+ new_container = symbol_db_engine_find_symbol_by_name_pattern_filtered (_dbe,
+ sym_type_name, SYMTYPE_SCOPE_CONTAINER, TRUE, SYMSEARCH_FILESCOPE_IGNORE,
+ NULL, -1, -1, (SymExtraInfo)(SYMINFO_SIMPLE | SYMINFO_KIND |
+ SYMINFO_TYPE_NAME));
+
+ if (new_container != NULL)
+ {
+ g_object_unref (test);
+
+ test = new_container;
+
+ cout << ".. found new conainer with n items " <<
+ symbol_db_engine_iterator_get_n_items (test) << endl;
+ }
+ else
+ {
+ cout << "Couldn't find a container to substitute sym_type_name " << sym_type_name << endl;
+ }
+
+ return test;
+}
+
SymbolDBEngineIterator *
EngineParser::processExpression(const string& stmt,
const string& above_text,
@@ -403,8 +472,7 @@ EngineParser::processExpression(const string& stmt,
_tokenizer->setText (stmt.c_str ());
/* get the fist one */
- nextToken (current_token, op);
- trim (current_token);
+ nextToken (current_token, op);
cout << "--------\nFirst token \"" << current_token << "\" with op \"" << op
<< "\"" << endl;
@@ -412,7 +480,7 @@ EngineParser::processExpression(const string& stmt,
/* parse the current sub-expression of a statement and fill up
* ExpressionResult object
*/
- result = parseExpression (current_token);
+ result = parseExpression (current_token);
/* fine. Get the type name and type scope given the above result for the first
* and most important token.
@@ -436,9 +504,9 @@ EngineParser::processExpression(const string& stmt,
cout << "Going to search for curr_searchable_scope with type_name " << type_name <<
" and type_scope " << type_scope << endl;
- /* at this time we're enough ready to issue a first query to out db.
+ /* at this time we're enough ready to issue a first query to our db.
* We absolutely need to find the searchable object scope of the first result
- * type. From this one we can iterate the tree of scopes and reach a result.
+ * type. By this one we can iterate the tree of scopes and reach a result.
*/
SymbolDBEngineIterator *curr_searchable_scope =
getCurrentSearchableScope (type_name, type_scope);
@@ -448,14 +516,96 @@ EngineParser::processExpression(const string& stmt,
cout << "curr_searchable_scope failed to process, check the problem please"
<< endl;
return NULL;
- }
-
+ }
+
/* fine. Have we more tokens left? */
while (nextToken (current_token, op))
{
+ cout << "--------\nNext token \"" << current_token << "\" with op \"" << op
+ << "\"" << endl;
+
+ /* parse the current sub-expression of a statement and fill up
+ * ExpressionResult object
+ */
+ result = parseExpression (current_token);
+/*
+ bool process_res = getTypeNameAndScopeByToken (result,
+ current_token,
+ op,
+ full_file_path,
+ linenum,
+ above_text,
+ type_name,
+ type_scope);
+*/
+ if (process_res == false)
+ {
+ cout << "Well, you haven't much luck on the NEXT token, the NEXT token failed and then " <<
+ "I cannot continue. " << endl;
+ return NULL;
+ }
+ /* check if the name of the result is valuable or not */
+ SymbolDBEngineIteratorNode *node;
+ int search_scope_id;
+ SymbolDBEngineIterator * iter;
+
+ node = SYMBOL_DB_ENGINE_ITERATOR_NODE (curr_searchable_scope);
+
+ search_scope_id =
+ symbol_db_engine_iterator_node_get_symbol_id (node);
+
+ iter = symbol_db_engine_find_symbol_in_scope (_dbe, result.m_name.c_str (),
+ search_scope_id,
+ SYMTYPE_UNDEF,
+ TRUE,
+ -1, -1, (SymExtraInfo)(SYMINFO_SIMPLE | SYMINFO_KIND |
+ SYMINFO_TYPE | SYMINFO_TYPE_NAME));
+
+ if (iter == NULL)
+ {
+ cout << "Warning, the result.m_name does not belong to scope" << endl;
+ // FIXME unref
+ return NULL;
+ }
+ else
+ {
+ const gchar *sym_kind;
+ cout << "Good element " << result.m_name << endl;
+
+
+ node = SYMBOL_DB_ENGINE_ITERATOR_NODE (iter);
+
+ sym_kind = symbol_db_engine_iterator_node_get_symbol_extra_string (node,
+ SymExtraInfo (SYMINFO_KIND));
+
+ cout << ".. it has sym_kind " << sym_kind << endl;
+
+ if (g_strcmp0 (sym_kind, "member") == 0)
+ {
+ iter = switchMemberToContainer (iter);
+ }
+
+ node = SYMBOL_DB_ENGINE_ITERATOR_NODE (iter);
+
+ /* check for any typedef */
+ if (g_strcmp0 (symbol_db_engine_iterator_node_get_symbol_extra_string (node,
+ SymExtraInfo (SYMINFO_KIND)),
+ "typedef") == 0)
+ {
+ iter = switchTypedefToStruct (iter);
+ }
+
+ /* remove the 'old' curr_searchable_scope and replace with
+ * this new one
+ */
+ g_object_unref (curr_searchable_scope);
+ curr_searchable_scope = iter;
+ continue;
+ }
}
-
+
+ cout << "returning curr_searchable_scope" << endl;
return curr_searchable_scope;
}
@@ -886,6 +1036,90 @@ engine_parser_init (SymbolDBEngine* manager)
}
//*/
+
+void
+engine_parser_test_get_variables ()
+{
+/*
+* this regexp catches things like:
+* a) std::vector<char*> exp1[124] [12], *exp2, expr;
+* b) QClass* expr1, expr2, expr;
+* c) int a,b; char r[12] = "test, argument", q[2] = { 't', 'e' }, expr;
+*
+* it CAN be fooled, if you really want it, but it should
+* work for 99% of all situations.
+*
+* QString
+* var;
+* in 2 lines does not work, because //-comments would often bring wrong results
+*/
+#define STRING "\\\".*\\\""
+#define BRACKETEXPR "\\{.*\\}"
+#define IDENT "[a-zA-Z_][a-zA-Z0-9_]*"
+#define WS "[ \t\n]*"
+#define PTR "[\\*&]?\\*?"
+#define INITIALIZER "=(" WS IDENT WS ")|=(" WS STRING WS ")|=(" WS BRACKETEXPR WS ")" WS
+#define ARRAY WS "\\[" WS "[0-9]*" WS "\\]" WS
+
+ char *res = NULL;
+ static char pattern[512] =
+// "(" IDENT "\\Z)" // the 'std' in example a)
+// "(::" IDENT ")*" // ::vector
+// "(" WS "<[^>;]*>)?" // <char *>
+ "(" WS PTR WS IDENT WS "(" ARRAY ")*" "(" INITIALIZER ")?," WS ")*" // other variables for the same ident (string i,j,k;)
+// "[ \t\\*&]*" // check again for pointer/reference type
+;
+ /* must add a 'termination' symbol to the regexp, otherwise
+ * 'exp' would match 'expr' */
+ char regexp[512];
+
+
+ char *statement = "char a, b";
+// snprintf(regexp, 512, "%s\\<%s\\>", pattern, "a");
+ g_snprintf (regexp, 512, "%s\\A%s\\Z", pattern, "b");
+ g_print ("checking with regexp %s\n", regexp);
+ GError* error = NULL;
+ GRegexCompileFlags compile_flags = (GRegexCompileFlags)(G_REGEX_EXTENDED);
+ GRegexMatchFlags match_flags = (GRegexMatchFlags)(0);
+
+ match_flags = (GRegexMatchFlags)(match_flags | G_REGEX_MATCH_NOTEMPTY);
+
+ GMatchInfo *match_info;
+ GRegex *regex = g_regex_new (regexp, compile_flags,
+ (GRegexMatchFlags)(match_flags), &error);
+ g_print ("we\n");
+ if (error != NULL)
+ g_print ("err = %s", error->message);
+ g_regex_match (regex, statement, (GRegexMatchFlags)(0), &match_info);
+ while (g_match_info_matches (match_info))
+ {
+ gchar *word = g_match_info_fetch (match_info, 0);
+ g_print ("Found: %s\n", word);
+ g_free (word);
+ g_match_info_next (match_info, NULL);
+ }
+
+#if 0
+ VariableList li;
+ std::map<std::string, std::string> ignoreTokens;
+ get_variables("char c, d, *e;", li, ignoreTokens, false);
+
+ /* here the trick is to start from the end of the found variables
+ * up to the begin. This because the local variable declaration should be found
+ * just above to the statement line
+ */
+ cout << "variables found are..." << endl;
+ for (VariableList::reverse_iterator iter = li.rbegin(); iter != li.rend(); iter++) {
+ Variable var = (*iter);
+ var.print ();
+
+ cout << "wh0a! we found the variable type to parse... it's \"" <<
+ var.m_type << "\" and type scope \"" << var.m_typeScope << "\"" <<
+ endl;
+
+ }
+#endif
+}
void
engine_parser_test_print_tokens (const char *str)
{
@@ -917,6 +1151,10 @@ engine_parser_process_expression (const char *stmt, const char * above_text,
}
SymbolDBEngineIteratorNode *node = SYMBOL_DB_ENGINE_ITERATOR_NODE (iter);
+ if (node != NULL)
+ {
+ cout << "parent id is " << symbol_db_engine_iterator_node_get_symbol_id (node) << endl;
+ }
// print the scope members
SymbolDBEngineIterator * children =
@@ -936,6 +1174,11 @@ engine_parser_process_expression (const char *stmt, const char * above_text,
symbol_db_engine_iterator_node_get_symbol_name (child) << endl;
}while (symbol_db_engine_iterator_move_next (children) == TRUE);
}
+ else
+ {
+ cout << "scope _has NOT_ children. " <<
+ symbol_db_engine_iterator_node_get_symbol_name (node) << endl;
+ }
#if 0
diff --git a/plugins/symbol-db/cxxparser/engine-parser.h b/plugins/symbol-db/cxxparser/engine-parser.h
index f7e6dde..18f97aa 100644
--- a/plugins/symbol-db/cxxparser/engine-parser.h
+++ b/plugins/symbol-db/cxxparser/engine-parser.h
@@ -33,6 +33,8 @@ void engine_parser_test_print_tokens (const char *str);
void engine_parser_parse_expression (const char*str);
+void engine_parser_test_get_variables ();
+
/**
* The function parse the C++ statement, try to get the type of objects to be
* completed and returns an iterator with those symbols.
diff --git a/plugins/symbol-db/cxxparser/main.c b/plugins/symbol-db/cxxparser/main.c
index 2d0c907..3702552 100644
--- a/plugins/symbol-db/cxxparser/main.c
+++ b/plugins/symbol-db/cxxparser/main.c
@@ -132,12 +132,12 @@ int main (int argc, char *argv[])
gda_init ();
main_loop = g_main_loop_new (NULL, FALSE);
-
+
g_test_init (&argc, &argv, NULL);
- g_test_add_func ("/simple_c/test-simple-struct", test_simple_struct);
- g_test_add_func ("/simple_c/test-cast-simple-struct", test_cast_simple_struct);
-// g_test_add_func ("/complex_c/test-complex-struct", test_complex_struct);
+// g_test_add_func ("/simple_c/test-simple-struct", test_simple_struct);
+// g_test_add_func ("/simple_c/test-cast-simple-struct", test_cast_simple_struct);
+ g_test_add_func ("/complex_c/test-complex-struct", test_complex_struct);
g_test_run ();
g_message ("test run finished");
diff --git a/plugins/symbol-db/cxxparser/sample-db/test-complex-struct.c b/plugins/symbol-db/cxxparser/sample-db/test-complex-struct.c
index c87fe50..704b251 100644
--- a/plugins/symbol-db/cxxparser/sample-db/test-complex-struct.c
+++ b/plugins/symbol-db/cxxparser/sample-db/test-complex-struct.c
@@ -1,4 +1,4 @@
-
+int var_alone;
typedef struct _asd {
char a;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]