eolian: stub header generator

This adds functionality into eolian_gen to generate a "stub header".
The main use for this is to deal with cyclic dependencies between Eo files.
This commit is contained in:
Daniel Kolesa 2014-08-26 17:08:26 +01:00
parent 18410e17ef
commit d09262b011
3 changed files with 60 additions and 10 deletions

View File

@ -116,7 +116,7 @@ _generate_eo_header_file(char *filename, const char *eo_filename)
Eina_Strbuf *buffer = eina_strbuf_new(); Eina_Strbuf *buffer = eina_strbuf_new();
if (!types_header_generate(eo_filename, buffer)) if (!types_header_generate(eo_filename, buffer, EINA_TRUE))
{ {
ERR("Failed to generate types of file %s", eo_filename); ERR("Failed to generate types of file %s", eo_filename);
goto end; goto end;
@ -154,6 +154,36 @@ end:
return ret; return ret;
} }
static Eina_Bool
_generate_stub_header_file(char *filename, const char *eo_filename)
{
Eina_Bool ret = EINA_FALSE;
Eina_Strbuf *buffer = eina_strbuf_new();
if (!types_header_generate(eo_filename, buffer, EINA_FALSE))
{
ERR("Failed to generate types of file %s", eo_filename);
goto end;
}
Eina_Strbuf *ctbuf = eina_strbuf_new();
if (types_class_typedef_generate(eo_filename, ctbuf))
{
eina_strbuf_append_char(ctbuf, '\n');
eina_strbuf_prepend(buffer, eina_strbuf_string_get(ctbuf));
}
eina_strbuf_free(ctbuf);
buffer = _include_guard_enclose(_filename_get(filename), "STUBS", buffer);
if (_write_file(filename, buffer, EINA_FALSE))
ret = EINA_TRUE;
end:
eina_strbuf_free(buffer);
return ret;
}
static Eina_Bool static Eina_Bool
_generate_c_file(char *filename, const char *eo_filename, Eina_Bool legacy_support) _generate_c_file(char *filename, const char *eo_filename, Eina_Bool legacy_support)
{ {
@ -221,7 +251,7 @@ _generate_legacy_header_file(char *filename, const char *eo_filename)
Eina_Strbuf *buffer = eina_strbuf_new(); Eina_Strbuf *buffer = eina_strbuf_new();
if (!types_header_generate(eo_filename, buffer)) if (!types_header_generate(eo_filename, buffer, EINA_TRUE))
{ {
ERR("Failed to generate types of file %s", eo_filename); ERR("Failed to generate types of file %s", eo_filename);
goto end; goto end;
@ -262,6 +292,7 @@ enum
{ {
NO_WAY_GEN, NO_WAY_GEN,
H_GEN, H_GEN,
H_STUB_GEN,
C_GEN, C_GEN,
C_IMPL_GEN C_IMPL_GEN
}; };
@ -301,6 +332,7 @@ int main(int argc, char **argv)
{"gh", no_argument, &gen_opt, H_GEN}, {"gh", no_argument, &gen_opt, H_GEN},
{"gc", no_argument, &gen_opt, C_GEN}, {"gc", no_argument, &gen_opt, C_GEN},
{"gi", no_argument, &gen_opt, C_IMPL_GEN}, {"gi", no_argument, &gen_opt, C_IMPL_GEN},
{"gs", no_argument, &gen_opt, H_STUB_GEN},
{"output", required_argument, 0, 'o'}, {"output", required_argument, 0, 'o'},
{"legacy", no_argument, &legacy_support, 1}, {"legacy", no_argument, &legacy_support, 1},
{"include", required_argument, 0, 'I'}, {"include", required_argument, 0, 'I'},
@ -341,6 +373,7 @@ int main(int argc, char **argv)
printf(" --output/-o Force output filename to 'outfile'\n"); printf(" --output/-o Force output filename to 'outfile'\n");
printf(" --eo Set generator to eo mode. Must be specified\n"); printf(" --eo Set generator to eo mode. Must be specified\n");
printf(" --gh Generate C header file [.h]\n"); printf(" --gh Generate C header file [.h]\n");
printf(" --gs Generate C type stubs [.h]\n");
printf(" --gc Generate C source file [.c]\n"); printf(" --gc Generate C source file [.c]\n");
printf(" --gi Generate C implementation source file [.c]. The output will be a series of functions that have to be filled.\n"); printf(" --gi Generate C implementation source file [.c]. The output will be a series of functions that have to be filled.\n");
printf(" --legacy Generate legacy\n"); printf(" --legacy Generate legacy\n");
@ -400,6 +433,12 @@ int main(int argc, char **argv)
ret = ( _generate_eo_header_file(output_filename, eo_file_basename) ? 0 : 1 ); ret = ( _generate_eo_header_file(output_filename, eo_file_basename) ? 0 : 1 );
break; break;
} }
case H_STUB_GEN:
{
INF("Generating stubs header file %s\n", output_filename);
ret = _generate_stub_header_file(output_filename, eo_file_basename) ? 0 : 1;
break;
}
case C_GEN: case C_GEN:
{ {
INF("Generating source file %s\n", output_filename); INF("Generating source file %s\n", output_filename);

View File

@ -37,7 +37,7 @@ _desc_generate(const char *desc, Eina_Strbuf *buf)
} }
static Eina_Strbuf * static Eina_Strbuf *
_type_generate(const Eolian_Type *tp, Eina_Bool in_typedef) _type_generate(const Eolian_Type *tp, Eina_Bool in_typedef, Eina_Bool full)
{ {
Eina_Strbuf *buf = eina_strbuf_new(); Eina_Strbuf *buf = eina_strbuf_new();
_desc_generate(eolian_type_description_get(tp), buf); _desc_generate(eolian_type_description_get(tp), buf);
@ -50,8 +50,13 @@ _type_generate(const Eolian_Type *tp, Eina_Bool in_typedef)
Eolian_Type_Type base_tp_type = eolian_type_type_get(base_tp); Eolian_Type_Type base_tp_type = eolian_type_type_get(base_tp);
if (base_tp_type == EOLIAN_TYPE_STRUCT || base_tp_type == EOLIAN_TYPE_ENUM) if (base_tp_type == EOLIAN_TYPE_STRUCT || base_tp_type == EOLIAN_TYPE_ENUM)
{ {
if (!full && !eolian_type_name_get(base_tp))
{
eina_strbuf_free(buf);
return NULL;
}
const char *name = eolian_type_name_get(tp); const char *name = eolian_type_name_get(tp);
Eina_Strbuf *struct_buf = _type_generate(base_tp, EINA_TRUE); Eina_Strbuf *struct_buf = _type_generate(base_tp, EINA_TRUE, full);
eina_strbuf_append_printf(buf, "typedef %s%s%s", eina_strbuf_append_printf(buf, "typedef %s%s%s",
eina_strbuf_string_get(struct_buf), eina_strbuf_string_get(struct_buf),
name?" ":"", name?name:""); name?" ":"", name?name:"");
@ -71,7 +76,7 @@ _type_generate(const Eolian_Type *tp, Eina_Bool in_typedef)
{ {
const Eolian_Struct_Type_Field *member; const Eolian_Struct_Type_Field *member;
char *name = _concat_name(tp); char *name = _concat_name(tp);
if ((in_typedef && name) || tp_type == EOLIAN_TYPE_STRUCT_OPAQUE) if ((in_typedef && name) || tp_type == EOLIAN_TYPE_STRUCT_OPAQUE || !full)
{ {
eina_strbuf_append_printf(buf, "struct %s", name); eina_strbuf_append_printf(buf, "struct %s", name);
free(name); free(name);
@ -99,6 +104,8 @@ _type_generate(const Eolian_Type *tp, Eina_Bool in_typedef)
{ {
const Eolian_Enum_Type_Field *member; const Eolian_Enum_Type_Field *member;
char *name = _concat_name(tp); char *name = _concat_name(tp);
if (!full)
break;
if (in_typedef) if (in_typedef)
{ {
eina_strbuf_append_printf(buf, "enum %s", name); eina_strbuf_append_printf(buf, "enum %s", name);
@ -165,7 +172,7 @@ _type_generate(const Eolian_Type *tp, Eina_Bool in_typedef)
} }
Eina_Bool Eina_Bool
types_header_generate(const char *eo_filename, Eina_Strbuf *buf) types_header_generate(const char *eo_filename, Eina_Strbuf *buf, Eina_Bool full)
{ {
const Eolian_Type *tp; const Eolian_Type *tp;
@ -173,7 +180,7 @@ types_header_generate(const char *eo_filename, Eina_Strbuf *buf)
Eina_Iterator *itr = eolian_type_aliases_get_by_file(eo_filename); Eina_Iterator *itr = eolian_type_aliases_get_by_file(eo_filename);
EINA_ITERATOR_FOREACH(itr, tp) EINA_ITERATOR_FOREACH(itr, tp)
{ {
Eina_Strbuf *type_buf = _type_generate(tp, EINA_TRUE); Eina_Strbuf *type_buf = _type_generate(tp, EINA_TRUE, full);
if (type_buf) if (type_buf)
{ {
eina_strbuf_append(buf, eina_strbuf_string_get(type_buf)); eina_strbuf_append(buf, eina_strbuf_string_get(type_buf));
@ -187,7 +194,7 @@ types_header_generate(const char *eo_filename, Eina_Strbuf *buf)
itr = eolian_type_structs_get_by_file(eo_filename); itr = eolian_type_structs_get_by_file(eo_filename);
EINA_ITERATOR_FOREACH(itr, tp) EINA_ITERATOR_FOREACH(itr, tp)
{ {
Eina_Strbuf *type_buf = _type_generate(tp, EINA_FALSE); Eina_Strbuf *type_buf = _type_generate(tp, EINA_FALSE, full);
if (type_buf) if (type_buf)
{ {
eina_strbuf_append(buf, eina_strbuf_string_get(type_buf)); eina_strbuf_append(buf, eina_strbuf_string_get(type_buf));
@ -197,11 +204,14 @@ types_header_generate(const char *eo_filename, Eina_Strbuf *buf)
} }
eina_iterator_free(itr); eina_iterator_free(itr);
if (!full)
return EINA_TRUE;
/* Generation of enums */ /* Generation of enums */
itr = eolian_type_enums_get_by_file(eo_filename); itr = eolian_type_enums_get_by_file(eo_filename);
EINA_ITERATOR_FOREACH(itr, tp) EINA_ITERATOR_FOREACH(itr, tp)
{ {
Eina_Strbuf *type_buf = _type_generate(tp, EINA_FALSE); Eina_Strbuf *type_buf = _type_generate(tp, EINA_FALSE, EINA_TRUE);
if (type_buf) if (type_buf)
{ {
eina_strbuf_append(buf, eina_strbuf_string_get(type_buf)); eina_strbuf_append(buf, eina_strbuf_string_get(type_buf));

View File

@ -8,11 +8,12 @@
* *
* @param[in] eo_filename Eo filename * @param[in] eo_filename Eo filename
* @param[inout] buf buffer to fill * @param[inout] buf buffer to fill
* @param[in]full whether to generate full type definitions
* *
* @return EINA_TRUE on success, EINA_FALSE on error. * @return EINA_TRUE on success, EINA_FALSE on error.
* *
*/ */
Eina_Bool types_header_generate(const char *eo_filename, Eina_Strbuf *buf); Eina_Bool types_header_generate(const char *eo_filename, Eina_Strbuf *buf, Eina_Bool full);
Eina_Bool types_class_typedef_generate(const char *eo_filename, Eina_Strbuf *buf); Eina_Bool types_class_typedef_generate(const char *eo_filename, Eina_Strbuf *buf);