q66 pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=e9688e63a5ac0b08766b9c861ddb2ddd91944e98

commit e9688e63a5ac0b08766b9c861ddb2ddd91944e98
Author: Daniel Kolesa <d.kol...@osg.samsung.com>
Date:   Tue Jul 7 17:19:13 2015 +0100

    eolian/generator: add proper generation of references
    
    Adds proper generation of automatic references in docs.
    For now events are missing.
    
    @feature
---
 src/Makefile_Eolian.am                  |   2 +
 src/bin/eolian/docs_generator.c         | 106 +++++++++++++++++++++++++++++++-
 src/tests/eolian/data/docs.eo           |   9 ++-
 src/tests/eolian/data/docs_ref.h        | 100 ++++++++++++++++++++++++++++++
 src/tests/eolian/data/docs_ref_legacy.h |  92 +++++++++++++++++++++++++++
 src/tests/eolian/eolian_generation.c    |  20 ++++++
 src/tests/eolian/eolian_parsing.c       |   4 +-
 7 files changed, 328 insertions(+), 5 deletions(-)

diff --git a/src/Makefile_Eolian.am b/src/Makefile_Eolian.am
index a5635fd..50fcc4f 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 5446f40..2016488 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 339998c..9da0745 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 0000000..c549bcb
--- /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 0000000..39c0655
--- /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 7c35565..1e745e9 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 fa6681a..bdfbedb 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)));

-- 


Reply via email to