Complete.Org: Mailing Lists: Archives: freeciv-dev: April 2004:
[Freeciv-Dev] Re: (PR#8504) Add function to get all section entries
Home

[Freeciv-Dev] Re: (PR#8504) Add function to get all section entries

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: undisclosed-recipients: ;
Subject: [Freeciv-Dev] Re: (PR#8504) Add function to get all section entries
From: "Raimar Falke" <i-freeciv-lists@xxxxxxxxxxxxx>
Date: Fri, 16 Apr 2004 08:05:56 -0700
Reply-to: rt@xxxxxxxxxxx

<URL: http://rt.freeciv.org/Ticket/Display.html?id=8504 >

On Fri, Apr 16, 2004 at 02:01:08AM -0700, Per I. Mathisen wrote:

New patch.

        Raimar

-- 
 email: rf13@xxxxxxxxxxxxxxxxx
 "Premature optimization is the root of all evil."
    -- D. E. Knuth in "Structured Programming with go to Statements"

Index: common/registry.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/registry.c,v
retrieving revision 1.60
diff -u -u -r1.60 registry.c
--- common/registry.c   1 Nov 2003 01:02:38 -0000       1.60
+++ common/registry.c   16 Apr 2004 15:04:59 -0000
@@ -354,7 +354,27 @@
   pentry->used = FALSE;
   return pentry;
 }
-       
+
+
+/**************************************************************************
+If there is a section by the given name, return it. Else return NULL.
+**************************************************************************/
+static struct section *find_section_by_name(struct section_file *sf,
+                                           const char *name)
+{
+  /*
+   * Search backwards since one (section_file_insert_internal) of the
+   * callers knowns that the requested section is most likely at the
+   * end.
+   */
+  section_list_iterate_rev(*sf->sections, psection) {
+    if (strcmp(psection->name, name) == 0) {
+      return psection;
+    }
+  } section_list_iterate_rev_end;
+
+  return NULL;
+}      
 
 /**************************************************************************
 ...
@@ -414,14 +434,7 @@
         This is slow if there are lots of sections; [cs]hould have a
         hash on section names.
       */
-      psection = NULL;
-      section_list_iterate(*sf->sections, asection) {
-       if (strcmp(asection->name, tok)==0) {
-         psection = asection;
-         break;
-       }
-      }
-      section_list_iterate_end;
+      psection = find_section_by_name(sf,tok);
       if (!psection) {
        psection = sbuf_malloc(sb, sizeof(struct section));
        psection->name = sbuf_strdup(sb, tok);
@@ -1113,6 +1126,7 @@
   char mod_fullpath[2*MAX_LEN_BUFFER];
   int len;
   struct entry *result;
+  struct section *psection;
 
   /* freelog(LOG_DEBUG, "looking up: %s", fullpath); */
   
@@ -1143,19 +1157,17 @@
                   MIN(pdelim - fullpath + 1, sizeof(sec_name)));
   sz_strlcpy(ent_name, pdelim+1);
 
-  section_list_iterate(*my_section_file->sections, psection) {
-    if (strcmp(psection->name, sec_name) == 0 ) {
-      entry_list_iterate(psection->entries, pentry) {
-       if (strcmp(pentry->name, ent_name) == 0) {
-         result = pentry;
-         result->used++;
-         return result;
-       }
+  psection = find_section_by_name(my_section_file, sec_name);
+  if (psection) {
+    entry_list_iterate(psection->entries, pentry) {
+      if (strcmp(pentry->name, ent_name) == 0) {
+       result = pentry;
+       result->used++;
+       return result;
       }
-      entry_list_iterate_end;
     }
+    entry_list_iterate_end;
   }
-  section_list_iterate_end;
 
   return NULL;
 }
@@ -1196,21 +1208,16 @@
     exit(EXIT_FAILURE);
   }
 
-  /* Do a reverse search of sections, since we're most likely
-   * to be adding to the lastmost section.
-   */
-  section_list_iterate_rev(*my_section_file->sections, psection) {
-    if(strcmp(psection->name, sec_name)==0) {
-      /* This DOES NOT check whether the entry already exists in
-       * the section, to avoid O(N^2) behaviour.
-       */
-      pentry = sbuf_malloc(sb, sizeof(struct entry));
-      pentry->name = sbuf_strdup(sb, ent_name);
-      entry_list_insert_back(&psection->entries, pentry);
-      return pentry;
-    }
+  psection = find_section_by_name(my_section_file, sec_name);
+  if (psection) {
+    /* This DOES NOT check whether the entry already exists in
+     * the section, to avoid O(N^2) behaviour.
+     */
+    pentry = sbuf_malloc(sb, sizeof(struct entry));
+    pentry->name = sbuf_strdup(sb, ent_name);
+    entry_list_insert_back(&psection->entries, pentry);
+    return pentry;
   }
-  section_list_iterate_rev_end;
 
   psection = sbuf_malloc(sb, sizeof(struct section));
   psection->name = sbuf_strdup(sb, sec_name);
@@ -1540,5 +1547,43 @@
     }
   }
   section_list_iterate_end;
+  return ret;
+}
+
+/***************************************************************
+  Returns pointer to list of strings giving all key in the given
+  section and sets the number of such sections in (*num).  If there
+  are none such, returns NULL and sets (*num) to zero.  The returned
+  pointer is malloced, and it is the responsibilty of the caller to
+  free this pointer, but the actual strings pointed to are part of the
+  section_file data, and should not be freed by the caller (nor used
+  after the section_file has been freed or changed).  The order of the
+  returned names is undefined.
+***************************************************************/
+char **secfile_get_section_entries(struct section_file *my_section_file,
+                                  const char *section, int *num)
+{
+  char **ret;
+  int i;
+  struct section *psection = find_section_by_name(my_section_file,section);
+
+  if (!psection) {
+    *num = 0;
+    return NULL;
+  }
+
+  *num = entry_list_size(&psection->entries);
+
+  if (*num == 0) {
+    return NULL;
+  }
+
+  ret = fc_malloc((*num) * sizeof(*ret));
+
+  i = 0;  
+  entry_list_iterate(psection->entries, pentry) {
+    ret[i++] = pentry->name;
+  } entry_list_iterate_end;
+
   return ret;
 }
Index: common/registry.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/registry.h,v
retrieving revision 1.23
diff -u -u -r1.23 registry.h
--- common/registry.h   6 Dec 2002 15:13:32 -0000       1.23
+++ common/registry.h   16 Apr 2004 15:04:59 -0000
@@ -106,6 +106,9 @@
 char **secfile_get_secnames_prefix(struct section_file *my_section_file,
                                   const char *prefix, int *num);
 
+char **secfile_get_section_entries(struct section_file *my_section_file,
+                                  const char *section, int *num);
+
 /* Only need use these explicitly on section_files constructed,
    not for ones generated by section_file_load:
 */

[Prev in Thread] Current Thread [Next in Thread]