[anjuta/cxxparser] cxxparser: added some logic to process multiple tokens but yet not working
- From: Massimo Cora' <mcora src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [anjuta/cxxparser] cxxparser: added some logic to process multiple tokens but yet not working
- Date: Fri, 31 Jul 2009 23:27:33 +0000 (UTC)
commit ae14a1cb1ba436e8a92b0aa171eee323c56dc4d7
Author: Massimo Corà <mcora src gnome org>
Date: Fri Jul 31 21:44:15 2009 +0200
cxxparser: added some logic to process multiple tokens but yet not working
plugins/symbol-db/cxxparser/compile_cmd_line | 1 -
plugins/symbol-db/cxxparser/engine-parser.cpp | 282 ++++++++++++--------
plugins/symbol-db/cxxparser/main.c | 72 +++---
.../cxxparser/sample-db/test-complex-struct.c | 18 ++
4 files changed, 219 insertions(+), 154 deletions(-)
---
diff --git a/plugins/symbol-db/cxxparser/engine-parser.cpp b/plugins/symbol-db/cxxparser/engine-parser.cpp
index 46de909..eb8f612 100644
--- a/plugins/symbol-db/cxxparser/engine-parser.cpp
+++ b/plugins/symbol-db/cxxparser/engine-parser.cpp
@@ -194,11 +194,22 @@ EngineParser::processExpression(const string& stmt,
string &out_type_scope,
string &out_oper)
{
- bool evaluation_succeed = false;
-
+ bool evaluation_succeed = false;
+ int loop_num = 0;
+
+ /* scope that'll follow the expression tokens.
+ * it'll be consistent and'll change it's value as long as the
+ * expression is being solved
+ *
+ * The initial status is obviously a global status, so put it to NULL.
+ */
+ SymbolDBEngineIterator *curr_searchable_scope = NULL;
+
string current_token;
string op;
string scope_name;
+ string prev_token_type_name = "";
+ string prev_token_type_scope = "";
ExpressionResult result;
_tokenizer->setText (stmt.c_str ());
@@ -206,8 +217,32 @@ EngineParser::processExpression(const string& stmt,
while (nextToken (current_token, op))
{
trim (current_token);
+
+ if (loop_num > 0)
+ {
+ // FIXME: case of more results
+ /* seems like we're at the second, or nth, loop */
+ curr_searchable_scope =
+ symbol_db_engine_find_symbol_by_name_pattern_filtered (
+ _dbe, prev_token_type_name.c_str (),
+ SYMTYPE_SCOPE_CONTAINER, TRUE,
+ SYMSEARCH_FILESCOPE_IGNORE, NULL, -1 ,
+ -1, SYMINFO_SIMPLE);
+ do {
+ SymbolDBEngineIteratorNode *node;
+
+ node = SYMBOL_DB_ENGINE_ITERATOR_NODE (curr_searchable_scope);
+
+ cout << "Current Searchable Scope " <<
+ symbol_db_engine_iterator_node_get_symbol_name (node) << endl;
- cout << "--------\nCurrent token ->" << current_token << "<- with op " << op << endl;
+ } while (symbol_db_engine_iterator_move_next (curr_searchable_scope) == TRUE);
+
+ /* reset it to first position */
+ symbol_db_engine_iterator_first (curr_searchable_scope);
+ }
+
+ cout << "--------\nCurrent token \"" << current_token << "\" with op " << op << endl;
out_oper = op;
/* parse the current sub-expression of a statement and fill up
@@ -215,7 +250,7 @@ EngineParser::processExpression(const string& stmt,
*/
result = parseExpression (current_token);
- //parsing failed?
+ /* is parsing failed? */
if (result.m_name.empty()) {
cout << "Failed to parse " << current_token << " from " << stmt << endl;
evaluation_succeed = false;
@@ -225,11 +260,46 @@ EngineParser::processExpression(const string& stmt,
// DEBUG PRINT
result.print ();
+
+ /* check if the name of the result if valuable or not */
+ // FIXME: move away this function.
+ if (loop_num > 0)
+ {
+ 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, SYMINFO_SIMPLE);
+
+ if (iter == NULL)
+ {
+ cout << "Warning, the result.m_name does not belong to scope" << endl;
+ evaluation_succeed = false;
+ break;
+ }
+ else
+ {
+ cout << "Good element " << result.m_name << endl;
+ }
+
+ // FIXME iter?
+ }
+
+
// no tokens before this, what we need to do now, is find the TagEntry
// that corresponds to the result
if (result.m_isaType)
{
- cout << "Found a cast expression" << endl;
+ cout << "*** Found a cast expression" << endl;
/*
* Handle type (usually when casting is found)
*/
@@ -247,17 +317,19 @@ EngineParser::processExpression(const string& stmt,
break;
}
- out_type_scope = result.m_scope.empty() ? "<global>" : result.m_scope.c_str();
+ out_type_scope = result.m_scope.empty() ? "" : result.m_scope.c_str();
out_type_name = result.m_name.c_str();
evaluation_succeed = true;
}
else if (result.m_isThis)
{
+ cout << "*** Found 'this'" << endl;
+
/*
* special handle for 'this' keyword
*/
- out_type_scope = result.m_scope.empty() ? "<global>" : result.m_scope.c_str();
- if (scope_name == "<global>")
+ out_type_scope = result.m_scope.empty() ? "" : result.m_scope.c_str();
+ if (scope_name.empty ())
{
cout << "'this' can not be used in the global scope" << endl;
evaluation_succeed = false;
@@ -291,19 +363,43 @@ EngineParser::processExpression(const string& stmt,
{
/*
* Found an identifier (can be a local variable, a global one etc)
- */
-
- cout << "found an identifier or local variable..." << endl;
+ */
+ cout << "*** Found an identifier or local variable..." << endl;
+
+ /* we have a previous global type with global scope (empty means global) */
+ if (prev_token_type_scope.empty () == true &&
+ prev_token_type_name.empty () == false)
+ {
+ cout << "prev_tok scope empty | prev_tok name NOT emtpy (" <<
+ prev_token_type_name << ")" << endl;
+
+ SymbolDBEngineIterator *iter =
+ symbol_db_engine_find_symbol_by_name_pattern_filtered (
+ _dbe, out_type_name.c_str (), SYMTYPE_UNDEF, TRUE,
+ SYMSEARCH_FILESCOPE_IGNORE, NULL, -1 ,
+ -1, SYMINFO_SIMPLE);
+
+ }
/* TODO */
- // get the scope iterator
- SymbolDBEngineIterator *iter = symbol_db_engine_get_scope_chain_by_file_line (_dbe,
- full_file_path.c_str (), linenum, SYMINFO_SIMPLE);
+ else if (prev_token_type_scope.empty () == false)
+ {
+ cout << "prev_tok scope NOT empty " << endl;
+ }
+
+
+
+ SymbolDBEngineIterator *iter =
+ symbol_db_engine_get_scope_chain_by_file_line (_dbe,
+ full_file_path.c_str (), linenum, SYMINFO_SIMPLE);
+
+ cout << "checking for completion scope..";
// it's a global one if it's NULL or if it has just only one element
if (iter == NULL || symbol_db_engine_iterator_get_n_items (iter) <= 1)
{
- cout << "...we've a global scope" << endl;
+ cout << "...we've a global completion scope" << endl;
+
}
else
{
@@ -312,7 +408,7 @@ EngineParser::processExpression(const string& stmt,
{
SymbolDBEngineIteratorNode *node =
SYMBOL_DB_ENGINE_ITERATOR_NODE (iter);
- cout << "got scope name: " <<
+ cout << "got completion scope name: " <<
symbol_db_engine_iterator_node_get_symbol_name (node) << endl;
} while (symbol_db_engine_iterator_move_next (iter) == TRUE);
}
@@ -320,21 +416,24 @@ EngineParser::processExpression(const string& stmt,
/* optimize scope'll clear the scopes leaving the local variables */
string optimized_scope = optimizeScope(above_text);
- cout << "here it is the optimized scope " << optimized_scope << endl;
+ cout << "here it is the optimized buffer scope " << optimized_scope << endl;
VariableList li;
std::map<std::string, std::string> ignoreTokens;
get_variables(optimized_scope, li, ignoreTokens, false);
- // FIXME: start enumerating from the end.
+ /* 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::iterator iter = li.begin(); iter != li.end(); iter++) {
+ for (VariableList::reverse_iterator iter = li.rbegin(); iter != li.rend(); iter++) {
Variable var = (*iter);
- var.print ();
+ var.print ();
if (current_token == var.m_name) {
- cout << "wh0a! we found the variable type to parse... it's ->" <<
- var.m_type << "<-" << endl;
+ cout << "wh0a! we found the variable type to parse... it's \"" <<
+ var.m_type << "\"" << endl;
out_type_name = var.m_type;
out_type_scope = var.m_typeScope;
@@ -342,17 +441,21 @@ EngineParser::processExpression(const string& stmt,
evaluation_succeed = true;
break;
}
- }
-
- /* TODO */
- /* get the derivation list of the typename */
+ }
+
+ /* if we reach this point it's likely that we missed the right var type */
+ cout << "## Wrong detection of the variable type" << endl;
}
-#if 0
- parentTypeName = typeName;
- parentTypeScope = typeScope;
-#endif
+ /* save the current type_name and type_scope */
+ cout << "** Saving prev_token_type_name \"" << out_type_name <<
+ "\" prev_token_type_scope \"" << out_type_scope << "\"" << endl;
+ prev_token_type_name = out_type_name;
+ prev_token_type_scope = out_type_scope;
+
current_token.clear ();
+ /* increase the loop number */
+ loop_num++;
}
return evaluation_succeed;
@@ -375,19 +478,22 @@ EngineParser::optimizeScope(const string& srcString)
bool changedLine = false;
bool prepLine = false;
int curline = 0;
- while (true) {
+ while (true)
+ {
type = _tokenizer->yylex();
// Eof ?
- if (type == 0) {
+ if (type == 0)
+ {
if (!currScope.empty())
scope_stack.push_back(currScope);
break;
}
// eat up all tokens until next line
- if ( prepLine && _tokenizer->lineno() == curline) {
+ if ( prepLine && _tokenizer->lineno() == curline)
+ {
currScope += " ";
currScope += _tokenizer->YYText();
continue;
@@ -397,50 +503,52 @@ EngineParser::optimizeScope(const string& srcString)
// Get the current line number, it will help us detect preprocessor lines
changedLine = (_tokenizer->lineno() > curline);
- if (changedLine) {
+ if (changedLine)
+ {
currScope += "\n";
}
curline = _tokenizer->lineno();
- switch (type) {
+ switch (type)
+ {
case (int)'(':
- currScope += "\n";
+ currScope += "\n";
scope_stack.push_back(currScope);
currScope = "(\n";
break;
case (int)'{':
- currScope += "\n";
+ currScope += "\n";
scope_stack.push_back(currScope);
currScope = "{\n";
break;
case (int)')':
- // Discard the current scope since it is completed
- if ( !scope_stack.empty() ) {
- currScope = scope_stack.back();
- scope_stack.pop_back();
- currScope += "()";
- } else
- currScope.clear();
+ // Discard the current scope since it is completed
+ if ( !scope_stack.empty() ) {
+ currScope = scope_stack.back();
+ scope_stack.pop_back();
+ currScope += "()";
+ } else
+ currScope.clear();
break;
case (int)'}':
- // Discard the current scope since it is completed
- if ( !scope_stack.empty() ) {
- currScope = scope_stack.back();
- scope_stack.pop_back();
- currScope += "\n{}\n";
- } else {
- currScope.clear();
- }
+ // Discard the current scope since it is completed
+ if ( !scope_stack.empty() ) {
+ currScope = scope_stack.back();
+ scope_stack.pop_back();
+ currScope += "\n{}\n";
+ } else {
+ currScope.clear();
+ }
break;
case (int)'#':
- if (changedLine) {
- // We are at the start of a new line
- // consume everything until new line is found or end of text
- currScope += " ";
- currScope += _tokenizer->YYText();
- prepLine = true;
- break;
- }
+ if (changedLine) {
+ // We are at the start of a new line
+ // consume everything until new line is found or end of text
+ currScope += " ";
+ currScope += _tokenizer->YYText();
+ prepLine = true;
+ break;
+ }
default:
currScope += " ";
currScope += _tokenizer->YYText();
@@ -467,36 +575,6 @@ EngineParser::optimizeScope(const string& srcString)
return srcString;
}
-/*
-string
-EngineParser::GetScopeName(const string &in, std::vector<string> *additionlNS)
-{
- std::string lastFunc, lastFuncSig;
- std::vector<std::string> moreNS;
-// FunctionList fooList;
-
- const char *buf = in.c_str ();
-
-// TagsManager *mgr = GetTagsManager();
- //std::map<std::string, std::string> ignoreTokens = mgr->GetCtagsOptions().GetPreprocessorAsMap();
-
- std::map<std::string, std::string> foo_map;
-
- std::string scope_name = get_scope_name(buf, moreNS, foo_map);
- string scope = scope_name;
- if (scope.empty()) {
- scope = "<global>";
- }
- if (additionlNS) {
- for (size_t i=0; i<moreNS.size(); i++) {
- additionlNS->push_back(moreNS.at(i).c_str());
- }
- }
- return scope;
-}
-*/
-
-
/************ C FUNCTIONS ************/
void
@@ -517,26 +595,6 @@ engine_parser_parse_expression (const char*str)
{
EngineParser::getInstance ()->testParseExpression (str);
}
-/*
-void
-engine_parser_get_local_variables (const char *str)
-{
- string res = EngineParser::getInstance ()->optimizeScope (str);
-
- VariableList li;
- std::map<std::string, std::string> ignoreTokens;
-
- get_variables (res, li, ignoreTokens, true);
-
- for (VariableList::iterator iter = li.begin(); iter != li.end(); iter++) {
- Variable var = *iter;
- var.Print();
- }
-
- // printf("total time: %d\n", end-start);
- printf("matches found: %d\n", li.size());
-}
-*/
SymbolDBEngineIterator *
engine_parser_process_expression (const char *stmt, const char * above_text,
@@ -552,7 +610,7 @@ engine_parser_process_expression (const char *stmt, const char * above_text,
if (result == false)
{
cout << "Hey, something went wrong in processExpression, bailing out" << endl;
- return NULL;
+ return NULL;
}
SymbolDBEngine * dbe = EngineParser::getInstance ()->getSymbolManager ();
@@ -563,7 +621,7 @@ engine_parser_process_expression (const char *stmt, const char * above_text,
SymbolDBEngineIterator *iter =
symbol_db_engine_find_symbol_by_name_pattern_filtered (
- dbe, out_type_name.c_str (), TRUE, NULL, TRUE, -1, NULL, -1 ,
+ dbe, out_type_name.c_str (), SYMTYPE_UNDEF, TRUE, SYMSEARCH_FILESCOPE_IGNORE, NULL, -1 ,
-1, SYMINFO_SIMPLE);
if (iter != NULL) {
diff --git a/plugins/symbol-db/cxxparser/main.c b/plugins/symbol-db/cxxparser/main.c
index 8fa2b0e..c5f2f23 100644
--- a/plugins/symbol-db/cxxparser/main.c
+++ b/plugins/symbol-db/cxxparser/main.c
@@ -27,42 +27,9 @@
#include "engine-parser.h"
-static gchar *
-load_file(const gchar *fileName)
-{
- FILE *fp;
- glong len;
- gchar *buf = NULL;
-
- fp = fopen(fileName, "rb");
- if (!fp) {
- printf("failed to open file 'test.h': %s\n", strerror(errno));
- return NULL;
- }
-
- //read the whole file
- fseek(fp, 0, SEEK_END); //go to end
- len = ftell(fp); //get position at end (length)
- fseek(fp, 0, SEEK_SET); //go to begining
- buf = (gchar *)malloc(len+1); //malloc buffer
-
- //read into buffer
- glong bytes = fread(buf, sizeof(gchar), len, fp);
- printf("read: %ld\n", bytes);
- if (bytes != len) {
- fclose(fp);
- printf("failed to read from file 'test.h': %s\n", strerror(errno));
- return NULL;
- }
-
- buf[len] = 0; // make it null terminated string
- fclose(fp);
- return buf;
-}
-
#define SAMPLE_DB_ABS_PATH "/home/pescio/gitroot/anjuta/plugins/symbol-db/cxxparser/sample-db/"
-#define ANJUTA_TAGS "/home/pescio/svnroot/svninstalled/usr/bin/anjuta-tags"
+#define ANJUTA_TAGS "anjuta-tags"
@@ -87,12 +54,35 @@ load_file(const gchar *fileName)
engine_parser_init (dbe); \
}
+
+/******************************************************************************/
+static void
+on_test_complex_struct_scan_end (SymbolDBEngine* dbe, gpointer user_data)
+{
+ gchar *associated_source_file = SAMPLE_DB_ABS_PATH"test-complex-struct.c";
+ gchar *file_content;
+ g_file_get_contents (associated_source_file, &file_content, NULL, NULL);
+
+ engine_parser_process_expression ("((foo*)var)->asd_struct->", file_content,
+ associated_source_file, 18);
+
+ g_free (file_content);
+}
+
+static void
+test_complex_struct ()
+{
+ INIT_C_TEST("test-complex-struct", on_test_complex_struct_scan_end);
+}
+
+/******************************************************************************/
static void
on_test_cast_simple_struct_scan_end (SymbolDBEngine* dbe, gpointer user_data)
{
g_message ("dbe %p user data is %p", dbe, user_data);
gchar *associated_source_file = SAMPLE_DB_ABS_PATH"test-cast-simple-struct.c";
- gchar *file_content = load_file (associated_source_file);
+ gchar *file_content;
+ g_file_get_contents (associated_source_file, &file_content, NULL, NULL);
engine_parser_process_expression ("((foo)var).", file_content,
associated_source_file, 15);
@@ -100,20 +90,19 @@ on_test_cast_simple_struct_scan_end (SymbolDBEngine* dbe, gpointer user_data)
g_free (file_content);
}
-
static void
test_cast_simple_struct ()
{
INIT_C_TEST("test-cast-simple-struct", on_test_cast_simple_struct_scan_end);
}
-
-
+/******************************************************************************/
static void
on_test_simple_struct_scan_end (SymbolDBEngine* dbe, gpointer user_data)
{
gchar *associated_source_file = SAMPLE_DB_ABS_PATH"test-simple-struct.c";
- gchar *file_content = load_file (associated_source_file);
+ gchar *file_content;
+ g_file_get_contents (associated_source_file, &file_content, NULL, NULL);
engine_parser_process_expression ("var.", file_content, associated_source_file, 9);
@@ -146,8 +135,9 @@ int main (int argc, char *argv[])
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 ("/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
new file mode 100644
index 0000000..c87fe50
--- /dev/null
+++ b/plugins/symbol-db/cxxparser/sample-db/test-complex-struct.c
@@ -0,0 +1,18 @@
+
+
+typedef struct _asd {
+ char a;
+ int b;
+} asd;
+
+typedef struct _foo {
+ char c;
+ void *d;
+
+ asd *asd_struct;
+} foo;
+
+
+int main () {
+ asd *var;
+ ((foo*)var)->asd_struct->
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]