summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Kolesa <d.kolesa@osg.samsung.com>2015-07-07 17:19:13 +0100
committerDaniel Kolesa <d.kolesa@osg.samsung.com>2015-07-07 17:19:13 +0100
commite9688e63a5ac0b08766b9c861ddb2ddd91944e98 (patch)
tree273222363316d449f0ba70071e20134a0d2ae178
parent70b70437317fbefd19270eb5fb11ca09dd90c92b (diff)
downloadefl-e9688e63a5ac0b08766b9c861ddb2ddd91944e98.tar.gz
eolian/generator: add proper generation of references
Adds proper generation of automatic references in docs. For now events are missing. @feature
-rw-r--r--src/Makefile_Eolian.am2
-rw-r--r--src/bin/eolian/docs_generator.c106
-rw-r--r--src/tests/eolian/data/docs.eo9
-rw-r--r--src/tests/eolian/data/docs_ref.h100
-rw-r--r--src/tests/eolian/data/docs_ref_legacy.h92
-rw-r--r--src/tests/eolian/eolian_generation.c20
-rw-r--r--src/tests/eolian/eolian_parsing.c4
7 files changed, 328 insertions, 5 deletions
diff --git a/src/Makefile_Eolian.am b/src/Makefile_Eolian.am
index a5635fd179..50fcc4febd 100644
--- a/src/Makefile_Eolian.am
+++ b/src/Makefile_Eolian.am
@@ -138,4 +138,6 @@ tests/eolian/data/override_ref.c \
tests/eolian/data/class_simple_ref_eo.h \
tests/eolian/data/class_simple_ref_legacy.h \
tests/eolian/data/import_types_ref.h \
+tests/eolian/data/docs_ref.h \
+tests/eolian/data/docs_ref_legacy.h \
$(EOLIAN_TESTS_EOS)
diff --git a/src/bin/eolian/docs_generator.c b/src/bin/eolian/docs_generator.c
index 5446f40049..201648891b 100644
--- a/src/bin/eolian/docs_generator.c
+++ b/src/bin/eolian/docs_generator.c
@@ -22,6 +22,98 @@ _indent_line(Eina_Strbuf *buf, int ind)
#define DOC_LIMIT(ind) ((ind > DOC_LINE_TEST) ? (ind + DOC_LINE_OVER) \
: DOC_LINE_LIMIT)
+static void
+_generate_ref(const char *refn, Eina_Strbuf *wbuf)
+{
+ const Eolian_Declaration *decl = eolian_declaration_get_by_name(refn);
+ if (decl)
+ {
+ char *n = strdup(eolian_declaration_name_get(decl));
+ char *p = n;
+ while ((p = strchr(p, '.'))) *p = '_';
+ eina_strbuf_append(wbuf, n);
+ free(n);
+ return;
+ }
+
+ /* not a plain declaration, so it must be struct/enum field or func */
+ const char *sfx = strrchr(refn, '.');
+ if (!sfx) goto noref;
+
+ Eina_Stringshare *bname = eina_stringshare_add_length(refn, sfx - refn);
+
+ const Eolian_Type *tp = eolian_type_struct_get_by_name(bname);
+ if (tp)
+ {
+ if (!eolian_type_struct_field_get(tp, sfx + 1)) goto noref;
+ _generate_ref(bname, wbuf);
+ eina_strbuf_append(wbuf, sfx);
+ eina_stringshare_del(bname);
+ return;
+ }
+
+ tp = eolian_type_enum_get_by_name(bname);
+ if (tp)
+ {
+ const Eolian_Enum_Type_Field *efl = eolian_type_enum_field_get(tp, sfx + 1);
+ if (!efl) goto noref;
+ _generate_ref(bname, wbuf);
+ Eina_Stringshare *str = eolian_type_enum_field_c_name_get(efl);
+ eina_strbuf_append_char(wbuf, '.');
+ eina_strbuf_append(wbuf, str);
+ eina_stringshare_del(str);
+ eina_stringshare_del(bname);
+ return;
+ }
+
+ const Eolian_Class *cl = eolian_class_get_by_name(bname);
+ const Eolian_Function *fn = NULL;
+ Eolian_Function_Type ftype = EOLIAN_UNRESOLVED;
+ if (!cl)
+ {
+ const char *mname;
+ if (!strcmp(sfx, ".get")) ftype = EOLIAN_PROP_GET;
+ else if (!strcmp(sfx, ".set")) ftype = EOLIAN_PROP_SET;
+ if (ftype != EOLIAN_UNRESOLVED)
+ {
+ eina_stringshare_del(bname);
+ mname = sfx - 1;
+ while ((mname != refn) && (*mname != '.')) --mname;
+ if (mname == refn) goto noref;
+ bname = eina_stringshare_add_length(refn, mname - refn);
+ cl = eolian_class_get_by_name(bname);
+ eina_stringshare_del(bname);
+ }
+ if (cl)
+ {
+ char *meth = strndup(mname + 1, sfx - mname - 1);
+ fn = eolian_class_function_get_by_name(cl, meth, ftype);
+ if (ftype == EOLIAN_UNRESOLVED)
+ ftype = eolian_function_type_get(fn);
+ free(meth);
+ }
+ }
+ else
+ {
+ fn = eolian_class_function_get_by_name(cl, sfx + 1, ftype);
+ ftype = eolian_function_type_get(fn);
+ }
+
+ if (!fn) goto noref;
+
+ Eina_Stringshare *fcn = eolian_function_full_c_name_get(fn);
+ eina_strbuf_append(wbuf, fcn);
+ eina_stringshare_del(fcn);
+ if ((ftype == EOLIAN_PROP_GET) || (ftype == EOLIAN_PROPERTY))
+ eina_strbuf_append(wbuf, "_get");
+ else if (ftype == EOLIAN_PROP_SET)
+ eina_strbuf_append(wbuf, "_set");
+
+ return;
+noref:
+ eina_strbuf_append(wbuf, refn);
+}
+
int
_append_section(const char *desc, int ind, int curl, Eina_Strbuf *buf,
Eina_Strbuf *wbuf)
@@ -40,9 +132,17 @@ _append_section(const char *desc, int ind, int curl, Eina_Strbuf *buf,
}
else if (*desc == '@')
{
- desc++;
- if (isalpha(*desc))
- eina_strbuf_append(wbuf, "@ref ");
+ const char *ref = ++desc;
+ if (isalpha(*desc) || (*desc == '_'))
+ {
+ eina_strbuf_append(wbuf, "@ref ");
+ while (isalnum(*desc) || (*desc == '.') || (*desc == '_'))
+ ++desc;
+ if (*(desc - 1) == '.') --desc;
+ Eina_Stringshare *refn = eina_stringshare_add_length(ref, desc - ref);
+ _generate_ref(refn, wbuf);
+ eina_stringshare_del(refn);
+ }
else
eina_strbuf_append_char(wbuf, '@');
}
diff --git a/src/tests/eolian/data/docs.eo b/src/tests/eolian/data/docs.eo
index 339998c363..9da0745301 100644
--- a/src/tests/eolian/data/docs.eo
+++ b/src/tests/eolian/data/docs.eo
@@ -35,11 +35,18 @@ struct Opaque; [[Opaque struct docs. See @Foo for another struct.]]
class Docs {
[[Docs for class.
- More docs for class. @.prop.
+ More docs for class. Testing references now.
@Foo
@Bar
@Alias
@pants
+ @.meth
+ @.prop
+ @.prop.get
+ @.prop.set
+ @Foo.field1
+ @Bar.foo
+ @Docs
]]
methods {
meth {
diff --git a/src/tests/eolian/data/docs_ref.h b/src/tests/eolian/data/docs_ref.h
new file mode 100644
index 0000000000..c549bcbaea
--- /dev/null
+++ b/src/tests/eolian/data/docs_ref.h
@@ -0,0 +1,100 @@
+#ifndef _EOLIAN_OUTPUT_H_
+#define _EOLIAN_OUTPUT_H_
+
+#ifndef _DOCS_EO_CLASS_TYPE
+#define _DOCS_EO_CLASS_TYPE
+
+typedef Eo Docs;
+
+#endif
+
+#ifndef _DOCS_EO_TYPES
+#define _DOCS_EO_TYPES
+
+/**
+ * @brief This is struct Foo. It does stuff.
+ *
+ * This is a longer description for struct Foo.
+ *
+ * This is another paragraph.
+ *
+ * @since 1.66
+ */
+typedef struct _Foo
+{
+ int field1; /** Field documentation. */
+ float field2;
+ short field3; /** Another field documentation. */
+} Foo;
+
+/** Docs for enum Bar. */
+typedef enum
+{
+ BAR_BLAH = 0,
+ BAR_FOO = 1, /** Docs for foo. */
+ BAR_BAR = 2 /** Docs for bar. */
+} Bar;
+
+/**
+ * @brief Docs for typedef.
+ *
+ * More docs for typedef. See @ref Bar.
+ *
+ * @since 2.0
+ */
+typedef Bar Alias;
+
+/** Opaque struct docs. See @ref Foo for another struct. */
+typedef struct _Opaque Opaque;
+
+
+#endif
+/**
+ * @brief Docs for class.
+ *
+ * More docs for class. Testing references now. @ref Foo @ref Bar @ref Alias
+ * @ref pants @ref docs_meth @ref docs_prop_get @ref docs_prop_get
+ * @ref docs_prop_set @ref Foo.field1 @ref Bar.BAR_FOO @ref Docs
+ */
+#define DOCS_CLASS docs_class_get()
+
+EAPI const Eo_Class *docs_class_get(void) EINA_CONST;
+
+/**
+ * @brief Property common documentation.
+ *
+ * Set documentation.
+ *
+ * @param[in] val Value documentation.
+ *
+ * @since 1.18
+ */
+EOAPI void docs_prop_set(int val);
+
+/**
+ * @brief Property common documentation.
+ *
+ * Get documentation.
+ *
+ * @return Value documentation.
+ *
+ * @since 1.18
+ */
+EOAPI int docs_prop_get(void);
+
+/**
+ * @brief Method documentation.
+ *
+ * @param[out] b
+ * @param[out] c Another param documentation.
+ *
+ * @return Return documentation.
+ */
+EOAPI int docs_meth(int a, float *b, long *c);
+
+EOAPI extern const Eo_Event_Description _DOCS_EVENT_CLICKED;
+
+/** Event docs. */
+#define DOCS_EVENT_CLICKED (&(_DOCS_EVENT_CLICKED))
+
+#endif
diff --git a/src/tests/eolian/data/docs_ref_legacy.h b/src/tests/eolian/data/docs_ref_legacy.h
new file mode 100644
index 0000000000..39c06555f2
--- /dev/null
+++ b/src/tests/eolian/data/docs_ref_legacy.h
@@ -0,0 +1,92 @@
+#ifndef _EOLIAN_OUTPUT_H_
+#define _EOLIAN_OUTPUT_H_
+
+#ifndef _DOCS_EO_CLASS_TYPE
+#define _DOCS_EO_CLASS_TYPE
+
+typedef Eo Docs;
+
+#endif
+
+#ifndef _DOCS_EO_TYPES
+#define _DOCS_EO_TYPES
+
+/**
+ * @brief This is struct Foo. It does stuff.
+ *
+ * This is a longer description for struct Foo.
+ *
+ * This is another paragraph.
+ *
+ * @since 1.66
+ */
+typedef struct _Foo
+{
+ int field1; /** Field documentation. */
+ float field2;
+ short field3; /** Another field documentation. */
+} Foo;
+
+/** Docs for enum Bar. */
+typedef enum
+{
+ BAR_BLAH = 0,
+ BAR_FOO = 1, /** Docs for foo. */
+ BAR_BAR = 2 /** Docs for bar. */
+} Bar;
+
+/**
+ * @brief Docs for typedef.
+ *
+ * More docs for typedef. See @ref Bar.
+ *
+ * @since 2.0
+ */
+typedef Bar Alias;
+
+/** Opaque struct docs. See @ref Foo for another struct. */
+typedef struct _Opaque Opaque;
+
+
+#endif
+/**
+ * @brief Docs for class.
+ *
+ * More docs for class. Testing references now. @ref Foo @ref Bar @ref Alias
+ * @ref pants @ref docs_meth @ref docs_prop_get @ref docs_prop_get
+ * @ref docs_prop_set @ref Foo.field1 @ref Bar.BAR_FOO @ref Docs
+ */
+
+/**
+ * @brief Property common documentation.
+ *
+ * Set documentation.
+ *
+ * @param[in] val Value documentation.
+ *
+ * @since 1.18
+ */
+EAPI void docs_prop_set(Docs *obj, int val);
+
+/**
+ * @brief Property common documentation.
+ *
+ * Get documentation.
+ *
+ * @return Value documentation.
+ *
+ * @since 1.18
+ */
+EAPI int docs_prop_get(const Docs *obj);
+
+/**
+ * @brief Method documentation.
+ *
+ * @param[out] b
+ * @param[out] c Another param documentation.
+ *
+ * @return Return documentation.
+ */
+EAPI int docs_meth(Docs *obj, int a, float *b, long *c);
+
+#endif
diff --git a/src/tests/eolian/eolian_generation.c b/src/tests/eolian/eolian_generation.c
index 7c35565e8b..1e745e9f6d 100644
--- a/src/tests/eolian/eolian_generation.c
+++ b/src/tests/eolian/eolian_generation.c
@@ -192,6 +192,25 @@ START_TEST(eolian_import)
}
END_TEST
+START_TEST(eolian_docs)
+{
+ char output_filepath[PATH_MAX] = "";
+ snprintf(output_filepath, PATH_MAX, "%s/eolian_output.h",
+#ifdef HAVE_EVIL
+ (char *)evil_tmpdir_get()
+#else
+ "/tmp"
+#endif
+ );
+ remove(output_filepath);
+ fail_if(0 != _eolian_gen_execute(PACKAGE_DATA_DIR"/data/docs.eo", "--eo --gh", output_filepath));
+ fail_if(!_files_compare(PACKAGE_DATA_DIR"/data/docs_ref.h", output_filepath));
+ remove(output_filepath);
+ fail_if(0 != _eolian_gen_execute(PACKAGE_DATA_DIR"/data/docs.eo", "--legacy --gh", output_filepath));
+ fail_if(!_files_compare(PACKAGE_DATA_DIR"/data/docs_ref_legacy.h", output_filepath));
+}
+END_TEST
+
void eolian_generation_test(TCase *tc)
{
tcase_add_test(tc, eolian_types_generation);
@@ -200,5 +219,6 @@ void eolian_generation_test(TCase *tc)
tcase_add_test(tc, eolian_dev_impl_code);
tcase_add_test(tc, eolian_functions_descriptions);
tcase_add_test(tc, eolian_import);
+ tcase_add_test(tc, eolian_docs);
}
diff --git a/src/tests/eolian/eolian_parsing.c b/src/tests/eolian/eolian_parsing.c
index fa6681a2af..bdfbedb1ac 100644
--- a/src/tests/eolian/eolian_parsing.c
+++ b/src/tests/eolian/eolian_parsing.c
@@ -1199,7 +1199,9 @@ START_TEST(eolian_docs)
fail_if(strcmp(eolian_documentation_summary_get(doc),
"Docs for class."));
fail_if(strcmp(eolian_documentation_description_get(doc),
- "More docs for class. @Docs.prop. @Foo @Bar @Alias @pants"));
+ "More docs for class. Testing references now. "
+ "@Foo @Bar @Alias @pants @Docs.meth @Docs.prop "
+ "@Docs.prop.get @Docs.prop.set @Foo.field1 @Bar.foo @Docs"));
fail_if(!(fid = eolian_class_function_get_by_name(class, "meth", EOLIAN_METHOD)));
fail_if(!(doc = eolian_function_documentation_get(fid, EOLIAN_METHOD)));