eolian: introducing support for .eot files

.eot files are similar to .eo, but they can't contain classes; all .eot files found in include paths
are parsed and information is added into the database. They're there for typedefs and eventually also
enums, structs and constants.

@feature
This commit is contained in:
Daniel Kolesa 2014-06-24 13:45:51 +01:00
parent 18c6f486f6
commit 7a8ef6d02a
5 changed files with 86 additions and 23 deletions

View File

@ -321,6 +321,8 @@ int main(int argc, char **argv)
goto end;
}
eolian_all_eot_files_parse();
const char *filename;
EINA_LIST_FOREACH(files4gen, itr, filename)
{

View File

@ -120,11 +120,22 @@ typedef enum
* all the information related to this class.
*
* @param[in] filename Name of the file to parse.
* @see eolian_eot_file_parse
*
* @ingroup Eolian
*/
EAPI Eina_Bool eolian_eo_file_parse(const char *filename);
/*
* @brief Parse a given .eot file and fill the database.
*
* @param[in] filename Name of the file to parse.
* @see eolian_eo_file_parse
*
* @ingroup Eolian
*/
EAPI Eina_Bool eolian_eot_file_parse(const char *filepath);
/*
* @brief Init Eolian.
*
@ -140,7 +151,7 @@ EAPI int eolian_init(void);
EAPI int eolian_shutdown(void);
/*
* @brief Scan the given directory and search for .eo files.
* @brief Scan the given directory and search for .eo and .eot files.
*
* The found files are just open to extract the class name.
*
@ -152,17 +163,31 @@ EAPI int eolian_shutdown(void);
EAPI Eina_Bool eolian_directory_scan(const char *dir);
/*
* @brief Force parsing of all the files located in the directories
* @brief Force parsing of all the .eo files located in the directories
* given in eolian_directory_scan..
*
* @return EINA_TRUE on success, EINA_FALSE otherwise.
*
* @see eolian_directory_scan
* @see eolian_all_eot_files_parse
*
* @ingroup Eolian
*/
EAPI Eina_Bool eolian_all_eo_files_parse();
/*
* @brief Force parsing of all the .eot files located in the directories
* given in eolian_directory_scan..
*
* @return EINA_TRUE on success, EINA_FALSE otherwise.
*
* @see eolian_directory_scan
* @see eolian_all_eo_files_parse
*
* @ingroup Eolian
*/
EAPI Eina_Bool eolian_all_eot_files_parse();
/*
* @brief Show information about a given class.
*

View File

@ -859,20 +859,24 @@ parse_class(Eo_Lexer *ls, Eina_Bool allow_ctors, Eolian_Class_Type type)
}
static void
parse_unit(Eo_Lexer *ls)
parse_unit(Eo_Lexer *ls, Eina_Bool eot)
{
switch (ls->t.kw)
{
case KW_abstract:
if (eot) goto def;
parse_class(ls, EINA_TRUE, EOLIAN_CLASS_ABSTRACT);
goto found_class;
case KW_class:
if (eot) goto def;
parse_class(ls, EINA_TRUE, EOLIAN_CLASS_REGULAR);
goto found_class;
case KW_mixin:
if (eot) goto def;
parse_class(ls, EINA_FALSE, EOLIAN_CLASS_MIXIN);
goto found_class;
case KW_interface:
if (eot) goto def;
parse_class(ls, EINA_FALSE, EOLIAN_CLASS_INTERFACE);
goto found_class;
case KW_type:
@ -882,6 +886,7 @@ parse_unit(Eo_Lexer *ls)
ls->tmp.type_def = NULL;
break;
}
def:
default:
eo_lexer_syntax_error(ls, "invalid token");
break;
@ -893,10 +898,10 @@ found_class:
}
static void
parse_chunk(Eo_Lexer *ls)
parse_chunk(Eo_Lexer *ls, Eina_Bool eot)
{
while (ls->t.token != TOK_EOF)
parse_unit(ls);
parse_unit(ls, eot);
}
static char *_accessor_type_str[ACCESSOR_TYPE_LAST] = { "setter", "getter" };
@ -1039,11 +1044,11 @@ eo_parser_dump(Eo_Lexer *ls)
}
Eina_Bool
eo_parser_walk(Eo_Lexer *ls)
eo_parser_walk(Eo_Lexer *ls, Eina_Bool eot)
{
if (!setjmp(ls->err_jmp))
{
parse_chunk(ls);
parse_chunk(ls, eot);
return EINA_TRUE;
}
return EINA_FALSE;
@ -1256,7 +1261,7 @@ _db_fill_type(Eo_Type_Def *type_def)
}
Eina_Bool
eo_parser_database_fill(const char *filename)
eo_parser_database_fill(const char *filename, Eina_Bool eot)
{
Eina_List *k;
Eo_Node *nd;
@ -1272,12 +1277,14 @@ eo_parser_database_fill(const char *filename)
/* read first token */
eo_lexer_get(ls);
if (!eo_parser_walk(ls))
if (!eo_parser_walk(ls, eot))
{
eo_lexer_free(ls);
return EINA_FALSE;
}
if (eot) goto nodeloop;
EINA_LIST_FOREACH(ls->nodes, k, nd) if (nd->type == NODE_CLASS)
{
has_class = EINA_TRUE;
@ -1291,6 +1298,7 @@ eo_parser_database_fill(const char *filename)
return EINA_FALSE;
}
nodeloop:
EINA_LIST_FOREACH(ls->nodes, k, nd)
{
switch (nd->type)

View File

@ -3,8 +3,8 @@
#include "eo_lexer.h"
Eina_Bool eo_parser_walk (Eo_Lexer *ls);
void eo_parser_dump (Eo_Lexer *ls);
Eina_Bool eo_parser_database_fill(const char *filename);
Eina_Bool eo_parser_walk (Eo_Lexer *ls, Eina_Bool eot);
Eina_Bool eo_parser_database_fill(const char *filename, Eina_Bool eot);
#endif /* __EO_PARSER_H__ */

View File

@ -17,6 +17,7 @@
static Eina_List *_classes = NULL;
static Eina_Hash *_types = NULL;
static Eina_Hash *_filenames = NULL; /* Hash: filename without extension -> full path */
static Eina_Hash *_tfilenames = NULL;
static int _database_init_count = 0;
typedef struct
@ -177,6 +178,7 @@ database_init()
eina_init();
_types = eina_hash_stringshared_new(_type_hash_free_cb);
_filenames = eina_hash_string_small_new(free);
_tfilenames = eina_hash_string_small_new(free);
return ++_database_init_count;
}
@ -197,6 +199,7 @@ database_shutdown()
_class_del((_Class_Desc *)class);
eina_hash_free(_types);
eina_hash_free(_filenames);
eina_hash_free(_tfilenames);
eina_shutdown();
}
return _database_init_count;
@ -1368,6 +1371,16 @@ eolian_show(const Eolian_Class class)
}
#define EO_SUFFIX ".eo"
#define EOT_SUFFIX ".eot"
#define EO_SCAN_BODY(suffix, hash) \
if (eina_str_has_suffix(file, suffix)) \
{ \
int len = strlen(file); \
int idx = len - 1; \
while (idx >= 0 && file[idx] != '/' && file[idx] != '\\') idx--; \
eina_hash_add(hash, eina_stringshare_add_length(file+idx+1, len - idx - sizeof(suffix)), strdup(file)); \
}
EAPI Eina_Bool
eolian_directory_scan(const char *dir)
{
@ -1375,17 +1388,10 @@ eolian_directory_scan(const char *dir)
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] != '/' && file[idx] != '\\') idx--;
eina_hash_add(_filenames, eina_stringshare_add_length(file+idx+1, len - idx - sizeof(EO_SUFFIX)), strdup(file));
}
}
EINA_ITERATOR_FOREACH(dir_files, file) EO_SCAN_BODY(EO_SUFFIX, _filenames);
eina_iterator_free(dir_files);
dir_files = eina_file_ls(dir);
EINA_ITERATOR_FOREACH(dir_files, file) EO_SCAN_BODY(EOT_SUFFIX, _tfilenames);
return EINA_TRUE;
}
@ -1405,7 +1411,14 @@ _eolian_class_to_filename(const char *filename)
return ret;
}
EAPI Eina_Bool eolian_eo_file_parse(const char *filepath)
EAPI Eina_Bool
eolian_eot_file_parse(const char *filepath)
{
return eo_parser_database_fill(filepath, EINA_TRUE);
}
EAPI Eina_Bool
eolian_eo_file_parse(const char *filepath)
{
const Eina_List *itr;
Eolian_Class class = eolian_class_find_by_file(filepath);
@ -1413,7 +1426,7 @@ EAPI Eina_Bool eolian_eo_file_parse(const char *filepath)
Eolian_Implement impl;
if (!class)
{
if (!eo_parser_database_fill(filepath)) return EINA_FALSE;
if (!eo_parser_database_fill(filepath, EINA_FALSE)) return EINA_FALSE;
class = eolian_class_find_by_file(filepath);
if (!class)
{
@ -1456,6 +1469,21 @@ EAPI Eina_Bool eolian_eo_file_parse(const char *filepath)
return EINA_TRUE;
}
static Eina_Bool _tfile_parse(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNUSED, void *data, void *fdata)
{
Eina_Bool *ret = fdata;
if (*ret) *ret = eolian_eot_file_parse(data);
return *ret;
}
EAPI Eina_Bool
eolian_all_eot_files_parse()
{
Eina_Bool ret = EINA_TRUE;
eina_hash_foreach(_tfilenames, _tfile_parse, &ret);
return ret;
}
static Eina_Bool _file_parse(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNUSED, void *data, void *fdata)
{
Eina_Bool *ret = fdata;