Eolian/Generator: only requests .eo files parsing when needed.

Before this change, all the .eo files of the directories given with -I
option were parsed. Most of this information was not necessary at all,
since only the classes belonging to the inheritance of the class given
as parameter were needed.
Now, during the parsing of the given class, the inherits classes are
searched and parsed.

A condition is needed to make it work well. To find a filename for a
class, we consider the lowercase of the class name as the filename we
have to parse.
e.g, Elm_Button -> elm_button -> elm_button.eo

It considerably reduces the generation time.

A fix in the tests was needed.
This commit is contained in:
Daniel Zaoui 2014-04-27 10:03:39 +03:00
parent e42b68534b
commit 7f90088232
5 changed files with 74 additions and 29 deletions

View File

@ -7,8 +7,6 @@
#include "eo1_generator.h"
#include "common_funcs.h"
#define EO_SUFFIX ".eo"
static char*
_include_guard_enclose(const char *fname, const char *fbody)
{
@ -220,19 +218,11 @@ int main(int argc, char **argv)
case 'I':
{
const char *dir = optarg;
Eina_Iterator *dir_files;
char *file;
/* Get all files from directory. Not recursively!!! */
dir_files = eina_file_ls(dir);
EINA_ITERATOR_FOREACH(dir_files, file)
if (!eolian_directory_scan(dir))
{
if (eina_str_has_suffix(file, EO_SUFFIX))
{
/* Allocated string will be freed during deletion of "included_files" list. */
included_files = eina_list_append(included_files, strdup(file));
}
ERR("Failed to scan %s", dir);
goto end;
}
eina_iterator_free(dir_files);
break;
}
default: help = EINA_TRUE;
@ -264,15 +254,6 @@ int main(int argc, char **argv)
}
const char *filename;
EINA_LIST_FOREACH(included_files, itr, filename)
{
if (!eolian_eo_file_parse(filename))
{
ERR("Error during parsing file %s\n", filename);
goto end;
}
}
EINA_LIST_FOREACH(files4gen, itr, filename)
{
if (!eolian_eo_file_parse(filename))

View File

@ -145,6 +145,18 @@ EAPI int eolian_init(void);
*/
EAPI int eolian_shutdown(void);
/*
* @brief Scan the given directory and search for .eo files.
*
* The found files are just open to extract the class name.
*
* @param[in] dir the directory to scan
* @return EINA_TRUE on success, EINA_FALSE otherwise.
*
* @ingroup Eolian
*/
EAPI Eina_Bool eolian_directory_scan(const char *dir);
/*
* @brief Show information about a given class.
*

View File

@ -54,9 +54,3 @@ EAPI int eolian_shutdown(void)
return _eolian_init_counter;
}
EAPI Eina_Bool eolian_eo_file_parse(const char *filename)
{
if (eolian_class_find_by_file(filename)) return EINA_TRUE;
return eo_tokenizer_database_fill(filename);
}

View File

@ -1,4 +1,5 @@
#include <Eina.h>
#include "eo_lexer.h"
#include "eolian_database.h"
#define PROP_GET_RETURN_DFLT_VAL "property_get_return_dflt_val"
@ -14,6 +15,7 @@
#define EOLIAN_PROP_SET_RETURN_COMMENT "property_set_return_comment"
static Eina_Hash *_classes = NULL;
static Eina_Hash *_filenames = NULL; /* Hash: filename without extension -> full path */
static int _database_init_count = 0;
typedef struct
@ -189,6 +191,8 @@ database_init()
eina_init();
if (!_classes)
_classes = eina_hash_stringshared_new(_hash_free_cb);
if (!_filenames)
_filenames = eina_hash_string_small_new(free);
return ++_database_init_count;
}
@ -205,6 +209,7 @@ database_shutdown()
if (_database_init_count == 0)
{
eina_hash_free(_classes);
eina_hash_free(_filenames);
eina_shutdown();
}
return _database_init_count;
@ -1244,3 +1249,56 @@ eolian_show(const char *class_name)
}
return EINA_TRUE;
}
#define EO_SUFFIX ".eo"
EAPI Eina_Bool
eolian_directory_scan(const char *dir)
{
if (!dir) return EINA_FALSE;
char *file;
/* Get all files from directory. Not recursively!!! */
Eina_Iterator *dir_files = eina_file_ls(dir);
EINA_ITERATOR_FOREACH(dir_files, file)
{
if (eina_str_has_suffix(file, EO_SUFFIX))
{
int len = strlen(file);
int idx = len - 1;
while (idx >= 0 && file[idx] != '/') idx--;
eina_hash_add(_filenames, eina_stringshare_add_length(file+idx+1, len - idx - sizeof(EO_SUFFIX)), strdup(file));
}
}
eina_iterator_free(dir_files);
return EINA_TRUE;
}
EAPI Eina_Bool eolian_eo_file_parse(const char *filepath)
{
const Eina_List *itr;
const char *class_name = eolian_class_find_by_file(filepath);
if (!class_name)
{
if (!eo_tokenizer_database_fill(filepath)) return EINA_FALSE;
class_name = eolian_class_find_by_file(filepath);
if (!class_name)
{
ERR("No class for file %s", filepath);
return EINA_FALSE;
}
}
EINA_LIST_FOREACH(eolian_class_inherits_list_get(class_name), itr, class_name)
{
char *filename = strdup(class_name);
eina_str_tolower(&filename);
filepath = eina_hash_find(_filenames, filename);
if (!filepath)
{
ERR("Unable to find class %s", class_name);
return EINA_FALSE;
}
if (!eolian_eo_file_parse(filepath)) return EINA_FALSE;
free(filename);
}
return EINA_TRUE;
}

View File

@ -25,7 +25,7 @@ START_TEST(eolian_ctor_dtor)
eolian_init();
/* Parsing */
fail_if(!eolian_eo_file_parse(PACKAGE_DATA_DIR"/data/base.eo"));
fail_if(!eolian_directory_scan(PACKAGE_DATA_DIR"/data"));
fail_if(!eolian_eo_file_parse(PACKAGE_DATA_DIR"/data/ctor_dtor.eo"));
/* Class ctor/dtor */