SF.net SVN: geany-plugins:[1326] trunk/geanygendoc/src

colombanw at users.sourceforge.net colombanw at xxxxx
Sat May 1 17:48:14 UTC 2010


Revision: 1326
          http://geany-plugins.svn.sourceforge.net/geany-plugins/?rev=1326&view=rev
Author:   colombanw
Date:     2010-05-01 17:48:14 +0000 (Sat, 01 May 2010)

Log Message:
-----------
GeanyGenDoc: Fix tag scope detection for non-c-style languages

Don't use hard-coded "::" separator but try to find the right
separator for the file type.

Modified Paths:
--------------
    trunk/geanygendoc/src/ggd-tag-utils.c
    trunk/geanygendoc/src/ggd-tag-utils.h
    trunk/geanygendoc/src/ggd.c

Modified: trunk/geanygendoc/src/ggd-tag-utils.c
===================================================================
--- trunk/geanygendoc/src/ggd-tag-utils.c	2010-05-01 17:47:37 UTC (rev 1325)
+++ trunk/geanygendoc/src/ggd-tag-utils.c	2010-05-01 17:48:14 UTC (rev 1326)
@@ -28,6 +28,29 @@
 #include "ggd-plugin.h" /* to access Geany data/funcs */
 
 
+/* symbols_get_context_separator() borrowed from Geany since it isn't in the
+ * plugin API yet (API v183) */
+/* FIXME: replace calls to this function with Geany's
+ *        symbols_get_context_separator() when it gets into the plugin API */
+static const gchar *
+ggd_tag_utils_get_context_separator (filetype_id geany_ft)
+{
+  switch (geany_ft) {
+    case GEANY_FILETYPES_C:     /* for C++ .h headers or C structs */
+    case GEANY_FILETYPES_CPP:
+    case GEANY_FILETYPES_GLSL:  /* for structs */
+      return "::";
+
+    /* avoid confusion with other possible separators in group/section name */
+    case GEANY_FILETYPES_CONF:
+    case GEANY_FILETYPES_REST:
+      return ":::";
+
+    default:
+      return ".";
+  }
+}
+
 /*
  * tag_cmp_by_line:
  * @a: A #TMTag
@@ -190,6 +213,7 @@
 /**
  * ggd_tag_find_parent:
  * @tags: A #GPtrArray of #TMTag<!-- -->s containing @tag
+ * @geany_ft: The Geany's file type identifier for which tags were generated
  * @child: A #TMTag, child of the tag to find
  * 
  * Finds the parent tag of a #TMTag.
@@ -198,6 +222,7 @@
  */
 TMTag *
 ggd_tag_find_parent (const GPtrArray *tags,
+                     filetype_id      geany_ft,
                      const TMTag     *child)
 {
   TMTag *tag = NULL;
@@ -213,17 +238,22 @@
     const gchar  *tmp;
     guint         i;
     TMTag        *el;
+    const gchar  *separator;
+    gsize         separator_len;
     
-    /* scope is of the form a::b::c */
+    /* scope is of the form a<sep>b<sep>c */
     parent_name = child->atts.entry.scope;
-    while ((tmp = strstr (parent_name, "::")) != NULL) {
-      parent_name = &tmp[2];
+    separator = ggd_tag_utils_get_context_separator (geany_ft);
+    separator_len = strlen (separator);
+    while ((tmp = strstr (parent_name, separator)) != NULL) {
+      parent_name = &tmp[separator_len];
     }
     /* if parent have scope */
     if (parent_name != child->atts.entry.scope) {
       /* the parent scope is the "dirname" of the child's scope */
       parent_scope = g_strndup (child->atts.entry.scope,
-                                parent_name - child->atts.entry.scope - 2);
+                                parent_name - child->atts.entry.scope -
+                                  separator_len);
     }
     /*g_debug ("%s: parent_name = %s", G_STRFUNC, parent_name);
     g_debug ("%s: parent_scope = %s", G_STRFUNC, parent_scope);*/
@@ -333,6 +363,7 @@
 /**
  * ggd_tag_resolve_type_hierarchy:
  * @tags: The tag array that contains @tag
+ * @geany_ft: The Geany's file type identifier for which tags were generated
  * @tag: A #TMTag to which get the type hierarchy
  * 
  * Gets the type hierarchy of a tag as a string, each element separated by a
@@ -346,6 +377,7 @@
  */
 gchar *
 ggd_tag_resolve_type_hierarchy (const GPtrArray *tags,
+                                filetype_id      geany_ft,
                                 const TMTag     *tag)
 {
   gchar *scope = NULL;
@@ -358,12 +390,12 @@
   } else {
     TMTag *parent_tag;
     
-    parent_tag = ggd_tag_find_parent (tags, tag);
+    parent_tag = ggd_tag_find_parent (tags, geany_ft, tag);
     scope = g_strdup (ggd_tag_get_type_name (tag));
     if (parent_tag) {
       gchar *parent_scope;
       
-      parent_scope = ggd_tag_resolve_type_hierarchy (tags, parent_tag);
+      parent_scope = ggd_tag_resolve_type_hierarchy (tags, geany_ft, parent_tag);
       if (! parent_scope) {
         /*g_debug ("no parent scope");*/
       } else {
@@ -416,6 +448,7 @@
  * scope_child_matches:
  * @a: parent scope
  * @b: child scope
+ * @geany_ft: The Geany's file type identifier for which tags were generated
  * @maxdepth: maximum sub-child level that matches, or < 0 for all to match
  * 
  * Checks if scope @b is inside scope @a. @maxdepth make possible to only match
@@ -427,22 +460,27 @@
 static gboolean
 scope_child_matches (const gchar *a,
                      const gchar *b,
+                     filetype_id  geany_ft,
                      gint         maxdepth)
 {
   gboolean matches = FALSE;
   
+  /*g_debug ("trying to match %s against %s", b, a);*/
   if (a && b) {
     for (; *a && *b && *a == *b; a++, b++);
     if (! *a /* we're at the end of the prefix and it matched */) {
+      const gchar  *separator;
+      
+      separator = ggd_tag_utils_get_context_separator (geany_ft);
       if (maxdepth < 0) {
-        if (! *b || (b[0] == ':' && b[1] == ':')) {
+        if (! *b || strncmp (b, separator, strlen (separator)) == 0) {
           matches = TRUE;
         }
       } else {
         while (! matches && maxdepth >= 0) {
           const gchar *tmp;
           
-          tmp = strstr (b, "::");
+          tmp = strstr (b, separator);
           if (tmp) {
             b = &tmp[2];
             maxdepth --;
@@ -465,6 +503,7 @@
  * ggd_tag_find_children:
  * @tags: Array of tags that contains @parent
  * @parent: Tag for which get children
+ * @geany_ft: The Geany's file type identifier for which tags were generated
  * @depth: Maximum depth for children to be found (< 0 means infinite)
  * @filter: A logical OR of the TMTagType<!-- -->s to match
  * 
@@ -477,6 +516,7 @@
 GList *
 ggd_tag_find_children_filtered (const GPtrArray *tags,
                                 const TMTag     *parent,
+                                filetype_id      geany_ft,
                                 gint             depth,
                                 TMTagType        filter)
 {
@@ -489,12 +529,15 @@
   g_return_val_if_fail (parent != NULL, NULL);
   
   if (parent->atts.entry.scope) {
-    fake_scope = g_strconcat (parent->atts.entry.scope, parent->name, NULL);
+    fake_scope = g_strconcat (parent->atts.entry.scope,
+                              ggd_tag_utils_get_context_separator (geany_ft),
+                              parent->name, NULL);
   } else {
     fake_scope = g_strdup (parent->name);
   }
   GGD_PTR_ARRAY_FOR (tags, i, el) {
-    if (scope_child_matches (fake_scope, el->atts.entry.scope, depth) &&
+    if (scope_child_matches (fake_scope, el->atts.entry.scope,
+                             geany_ft, depth) &&
         el->type & filter) {
       children = g_list_insert_sorted_with_data (children, el,
                                                  tag_cmp_by_line,
@@ -510,6 +553,7 @@
  * ggd_tag_find_children:
  * @tags: Array of tags that contains @parent
  * @parent: Tag for which get children
+ * @geany_ft: The Geany's file type identifier for which tags were generated
  * @depth: Maximum depth for children to be found (< 0 means infinite)
  * 
  * Finds children tags of a #TMTag.
@@ -521,7 +565,9 @@
 GList *
 ggd_tag_find_children (const GPtrArray *tags,
                        const TMTag     *parent,
+                       filetype_id      geany_ft,
                        gint             depth)
 {
-  return ggd_tag_find_children_filtered (tags, parent, depth, tm_tag_max_t);
+  return ggd_tag_find_children_filtered (tags, parent, geany_ft,
+                                         depth, tm_tag_max_t);
 }

Modified: trunk/geanygendoc/src/ggd-tag-utils.h
===================================================================
--- trunk/geanygendoc/src/ggd-tag-utils.h	2010-05-01 17:47:37 UTC (rev 1325)
+++ trunk/geanygendoc/src/ggd-tag-utils.h	2010-05-01 17:48:14 UTC (rev 1326)
@@ -51,15 +51,19 @@
                                                gulong           line);
 TMTag        *ggd_tag_find_at_current_pos     (GeanyDocument *doc);
 TMTag        *ggd_tag_find_parent             (const GPtrArray *tags,
+                                               filetype_id      geany_ft,
                                                const TMTag     *child);
 GList        *ggd_tag_find_children_filtered  (const GPtrArray *tags,
                                                const TMTag     *parent,
+                                               filetype_id      geany_ft,
                                                gint             depth,
                                                TMTagType        filter);
 GList        *ggd_tag_find_children           (const GPtrArray *tags,
                                                const TMTag     *parent,
+                                               filetype_id      geany_ft,
                                                gint             depth);
 gchar        *ggd_tag_resolve_type_hierarchy  (const GPtrArray *tags,
+                                               filetype_id      geany_ft,
                                                const TMTag     *tag);
 TMTag        *ggd_tag_find_from_name          (const GPtrArray *tags,
                                                const gchar     *name);

Modified: trunk/geanygendoc/src/ggd.c
===================================================================
--- trunk/geanygendoc/src/ggd.c	2010-05-01 17:47:37 UTC (rev 1325)
+++ trunk/geanygendoc/src/ggd.c	2010-05-01 17:48:14 UTC (rev 1326)
@@ -143,11 +143,12 @@
 static CtplEnviron *
 get_env_for_tag (GgdFileType   *ft,
                  GgdDocSetting *setting,
-                 GPtrArray     *tag_array,
+                 GeanyDocument *doc,
                  const TMTag   *tag)
 {
   CtplEnviron *env;
   GList       *children = NULL;
+  GPtrArray   *tag_array = doc->tm_file->tags_array;
   
   env = ctpl_environ_new ();
   ctpl_environ_push_string (env, "cursor", GGD_CURSOR_IDENTIFIER);
@@ -171,7 +172,8 @@
     ctpl_environ_push_int (env, "returns", returns);
   }
   /* get direct children tags */
-  children = ggd_tag_find_children (tag_array, tag, 0);
+  children = ggd_tag_find_children (tag_array, tag,
+                                    FILETYPE_ID (doc->file_type), 0);
   if (setting->merge_children) {
     CtplValue *v;
     
@@ -224,7 +226,7 @@
 static gchar *
 get_comment (GgdFileType   *ft,
              GgdDocSetting *setting,
-             GPtrArray     *tag_array,
+             GeanyDocument *doc,
              const TMTag   *tag,
              gint          *cursor_offset)
 {
@@ -234,7 +236,7 @@
     GError      *err = NULL;
     CtplEnviron *env;
     
-    env = get_env_for_tag (ft, setting, tag_array, tag);
+    env = get_env_for_tag (ft, setting, doc, tag);
     ctpl_environ_merge (env, ft->user_env, FALSE);
     if (! ctpl_environ_add_from_string (env, GGD_OPT_environ, &err)) {
       msgwin_status_add (_("Failed to add global environment, skipping: %s"),
@@ -320,7 +322,6 @@
 /* inserts the comment for @tag in @sci according to @setting */
 static gboolean
 do_insert_comment (GeanyDocument   *doc,
-                   GPtrArray       *tag_array,
                    const TMTag     *tag,
                    GgdFileType     *ft,
                    GgdDocSetting   *setting)
@@ -329,8 +330,9 @@
   gchar            *comment;
   gint              cursor_offset = 0;
   ScintillaObject  *sci = doc->editor->sci;
+  GPtrArray        *tag_array = doc->tm_file->tags_array;
   
-  comment = get_comment (ft, setting, tag_array, tag, &cursor_offset);
+  comment = get_comment (ft, setting, doc, tag, &cursor_offset);
   if (comment) {
     gint pos;
     
@@ -368,21 +370,24 @@
  * Since a policy may forward documenting to a parent, tag that actually applies
  * is returned in @real_tag. */
 static GgdDocSetting *
-get_setting_from_tag (GgdDocType   *doctype,
-                      GPtrArray    *tag_array,
-                      const TMTag  *tag,
-                      const TMTag **real_tag)
+get_setting_from_tag (GgdDocType     *doctype,
+                      GeanyDocument  *doc,
+                      const TMTag    *tag,
+                      const TMTag   **real_tag)
 {
   GgdDocSetting  *setting;
   gchar          *hierarchy;
   gint            nth_child;
+  GPtrArray      *tag_array = doc->tm_file->tags_array;
+  filetype_id     geany_ft = FILETYPE_ID (doc->file_type);
   
-  hierarchy = ggd_tag_resolve_type_hierarchy (tag_array, tag);
+  hierarchy = ggd_tag_resolve_type_hierarchy (tag_array, geany_ft, tag);
+  /*g_debug ("type hierarchy for tag %s is: %s", tag->name, hierarchy);*/
   setting = ggd_doc_type_resolve_setting (doctype, hierarchy, &nth_child);
   *real_tag = tag;
   if (setting) {
     for (; nth_child > 0; nth_child--) {
-      *real_tag = ggd_tag_find_parent (tag_array, *real_tag);
+      *real_tag = ggd_tag_find_parent (tag_array, geany_ft, *real_tag);
     }
   }
   g_free (hierarchy);
@@ -449,23 +454,21 @@
 {
   gboolean          success = FALSE;
   GList            *node;
-  GPtrArray        *tag_array;
   ScintillaObject  *sci = doc->editor->sci;
   GHashTable       *tag_done_table; /* keeps the list of documented tags.
                                      * Useful since documenting a tag might
                                      * actually document another one */
   
   success = TRUE;
-  tag_array = doc->tm_file->tags_array;
   tag_done_table = g_hash_table_new (NULL, NULL);
   sci_start_undo_action (sci);
   for (node = sorted_tag_list; node; node = node->next) {
     GgdDocSetting  *setting;
     const TMTag    *tag = node->data;
     
-    setting = get_setting_from_tag (doctype, tag_array, tag, &tag);
+    setting = get_setting_from_tag (doctype, doc, tag, &tag);
     if (setting && ! g_hash_table_lookup (tag_done_table, tag)) {
-      if (! do_insert_comment (doc, tag_array, tag, filetype, setting)) {
+      if (! do_insert_comment (doc, tag, filetype, setting)) {
         success = FALSE;
         break;
       } else {
@@ -520,10 +523,11 @@
       GgdDocSetting  *setting;
       GList          *tag_list = NULL;
       
-      setting = get_setting_from_tag (doctype, tag_array, tag, &tag);
+      setting = get_setting_from_tag (doctype, doc, tag, &tag);
       if (setting && setting->autodoc_children) {
-        tag_list = ggd_tag_find_children_filtered (tag_array, tag, 0,
-                                                   setting->matches);
+        tag_list = ggd_tag_find_children_filtered (tag_array, tag,
+                                                   FILETYPE_ID (doc->file_type),
+                                                   0, setting->matches);
       }
       /* we assume that a parent always comes before any children, then simply add
        * it at the end */


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.



More information about the Plugins-Commits mailing list