Complete.Org: Mailing Lists: Archives: freeciv-dev: July 1999:
[Freeciv-Dev] patch: speclist
Home

[Freeciv-Dev] patch: speclist

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: freeciv-dev@xxxxxxxxxxx
Subject: [Freeciv-Dev] patch: speclist
From: David Pfitzner <dwp@xxxxxxxxxxxxxx>
Date: Sat, 17 Jul 1999 00:05:24 +1000 (EST)

The city_list and unit_list stuff is good, in that it gives
genlists with some type checking.  But it only applies to
unit lists and city lists, and doing it for other types 
would be get a bit tedious.

This patch provides some header files which handle most
of that tedium.  Currently, they are just used to provide
the same city_list and unit_list stuff, with less duplication.

("speclist provides generalised special-case genlists" !!)

(Please, no C++ advocacy; yes, I realise this is arguably 
trying to be templates etc...)

Regards,
-- David
diff -N -u -r --exclude-from exclude freeciv-cvs/common/Makefile.am 
fc-adv/common/Makefile.am
--- freeciv-cvs/common/Makefile.am      Wed Jul 14 21:18:10 1999
+++ fc-adv/common/Makefile.am   Fri Jul 16 00:32:36 1999
@@ -37,6 +37,8 @@
                shared.h        \
                spaceship.c     \
                spaceship.h     \
+               speclist.h      \
+               speclist_c.h    \
                tech.c          \
                tech.h          \
                timing.c        \
diff -N -u -r --exclude-from exclude freeciv-cvs/common/Makefile.in 
fc-adv/common/Makefile.in
--- freeciv-cvs/common/Makefile.in      Wed Jul 14 21:18:10 1999
+++ fc-adv/common/Makefile.in   Fri Jul 16 00:32:52 1999
@@ -84,7 +84,7 @@
 
 INCLUDES = 
 
-libcivcommon_a_SOURCES =               attribute.h                     
capability.c                    capability.h                    capstr.c        
                capstr.h                        city.c                          
city.h                          diptreaty.c                     diptreaty.h     
                events.h                        game.c                          
game.h                          genlist.c                       genlist.h       
                log.c                           log.h                           
map.c                           map.h                           packets.c       
                packets.h                       player.c                        
player.h                        mem.c                           mem.h           
                registry.c                      registry.h                      
sbuffer.c                       sbuffer.h                       shared.c        
                shared.h                        spaceship.c                     
spaceship.h                     tech.c                          tech.h          
                timing.c                        timing.h                        
unit.c                          unit.h                          version.h
+libcivcommon_a_SOURCES =               attribute.h                     
capability.c                    capability.h                    capstr.c        
                capstr.h                        city.c                          
city.h                          diptreaty.c                     diptreaty.h     
                events.h                        game.c                          
game.h                          genlist.c                       genlist.h       
                log.c                           log.h                           
map.c                           map.h                           packets.c       
                packets.h                       player.c                        
player.h                        mem.c                           mem.h           
                registry.c                      registry.h                      
sbuffer.c                       sbuffer.h                       shared.c        
                shared.h                        spaceship.c                     
spaceship.h                     speclist.h                      speclist_c.h    
                tech.c                          tech.h                          
timing.c                        timing.h                        unit.c          
                unit.h                          version.h
 
 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
 CONFIG_HEADER = ../config.h
diff -N -u -r --exclude-from exclude freeciv-cvs/common/city.c 
fc-adv/common/city.c
--- freeciv-cvs/common/city.c   Tue Jun 22 23:03:25 1999
+++ fc-adv/common/city.c        Fri Jul 16 00:32:37 1999
@@ -22,6 +22,11 @@
 
 #include "city.h"
 
+/* get 'struct city_list' functions: */
+#define SPECLIST_TAG city
+#define SPECLIST_TYPE struct city
+#include "speclist_c.h"
+
 static int improvement_upkeep_asmiths(struct city *pcity, int i, int asmiths);
 
 /****************************************************************
@@ -1375,23 +1380,6 @@
 /**************************************************************************
 ...
 **************************************************************************/
-void city_list_init(struct city_list *This)
-{
-  genlist_init(&This->list);
-}
-
-/**************************************************************************
-...
-**************************************************************************/
-struct city *city_list_get(struct city_list *This, int index)
-{
-  return (struct city *)genlist_get(&This->list, index);
-}
-
-
-/**************************************************************************
-...
-**************************************************************************/
 struct city *city_list_find_id(struct city_list *This, int id)
 {
   if(id) {
@@ -1422,39 +1410,6 @@
   return 0;
 }
 
-
-/**************************************************************************
-...
-**************************************************************************/
-void city_list_insert(struct city_list *This, struct city *pcity)
-{
-  genlist_insert(&This->list, pcity, 0);
-}
-
-
-/**************************************************************************
-...
-**************************************************************************/
-int city_list_size(struct city_list *This)
-{
-  return genlist_size(&This->list);
-}
-
-/**************************************************************************
-...
-**************************************************************************/
-void city_list_unlink(struct city_list *This, struct city *pcity)
-{
-  genlist_unlink(&This->list, pcity);
-}
-
-/**************************************************************************
-...
-**************************************************************************/
-void city_list_insert_back(struct city_list *This, struct city *pcity)
-{
-  genlist_insert(&This->list, pcity, -1);
-}
 
 /**************************************************************************
 Comparison function for qsort for city _pointers_, sorting by city name.
diff -N -u -r --exclude-from exclude freeciv-cvs/common/city.h 
fc-adv/common/city.h
--- freeciv-cvs/common/city.h   Sun Jul 11 23:03:16 1999
+++ fc-adv/common/city.h        Fri Jul 16 00:32:37 1999
@@ -88,15 +88,8 @@
 #define city_map_iterate(x, y) \
   for (y=0;y<CITY_MAP_SIZE;y++) \
     for (x=0;x<CITY_MAP_SIZE;x++) \
-      if (! ((x == 0 || x == 4) && (y == 0 || y == 4)))                        
              
-#define city_list_iterate(citylist, pcity) { \
-  struct genlist_iterator myiter; \
-  struct city *pcity; \
-  genlist_iterator_init(&myiter, &citylist.list, 0); \
-  for(; ITERATOR_PTR(myiter);) { \
-    pcity=(struct city *)ITERATOR_PTR(myiter); \
-    ITERATOR_NEXT(myiter); 
-#define city_list_iterate_end }}
+      if (! ((x == 0 || x == 4) && (y == 0 || y == 4)))
+
 
 struct ai_choice {
   int choice;            /* what the advisor wants */
@@ -175,9 +168,15 @@
   struct ai_city ai;
 };
 
-struct city_list {
-  struct genlist list;
-};
+/* get 'struct city_list' and related functions: */
+#define SPECLIST_TAG city
+#define SPECLIST_TYPE struct city
+#include "speclist.h"
+
+#define city_list_iterate(citylist, pcity) \
+    TYPED_LIST_ITERATE(struct city, citylist, pcity)
+#define city_list_iterate_end  LIST_ITERATE_END
+
 
 extern struct improvement_type improvement_types[B_LAST];
 
@@ -241,15 +240,8 @@
 int city_num_trade_routes(struct city *pcity);
 
 /* list functions */
-void city_list_init(struct city_list *This);
-struct city *city_list_get(struct city_list *This, int index);
 struct city *city_list_find_id(struct city_list *This, int id);
 struct city *city_list_find_name(struct city_list *This, char *name);
-
-void city_list_insert(struct city_list *This, struct city *pcity);
-int city_list_size(struct city_list *This);
-void city_list_unlink(struct city_list *This, struct city *pcity);
-void city_list_insert_back(struct city_list *This, struct city *pcity);
 
 int city_name_compare(const void *p1, const void *p2);
 
diff -N -u -r --exclude-from exclude freeciv-cvs/common/genlist.h 
fc-adv/common/genlist.h
--- freeciv-cvs/common/genlist.h        Sat Jun 12 17:40:10 1999
+++ fc-adv/common/genlist.h     Fri Jul 16 00:32:37 1999
@@ -53,4 +53,21 @@
 #define ITERATOR_PREV(X) ((X).link=(X).link->prev)
 
 
+/* This is to iterate for a type defined like:
+     struct unit_list { struct genlist list; };
+   where the pointers in the list are really pointers to "atype".
+   Eg, see speclist.h, which is what this is really for.
+*/
+#define TYPED_LIST_ITERATE(atype, typed_list, var) {       \
+  struct genlist_iterator myiter;                          \
+  atype *var;                                              \
+  genlist_iterator_init(&myiter, &(typed_list).list, 0);   \
+  for(; ITERATOR_PTR(myiter);) {                           \
+    var=(atype *)ITERATOR_PTR(myiter);                     \
+    ITERATOR_NEXT(myiter);
+
+/* Balance for above: */ 
+#define LIST_ITERATE_END  }}
+
+
 #endif  /* FC__GENLIST_H */
diff -N -u -r --exclude-from exclude freeciv-cvs/common/speclist.h 
fc-adv/common/speclist.h
--- freeciv-cvs/common/speclist.h       Thu Jan  1 10:00:00 1970
+++ fc-adv/common/speclist.h    Fri Jul 16 00:40:34 1999
@@ -0,0 +1,90 @@
+/********************************************************************** 
+ Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+***********************************************************************/
+
+/* speclists: "specific genlists", by dwp.
+   (A generalisation of previous city_list and unit_list stuff.)
+   
+   This file is used to implement a "specific" genlist.
+   That is, a (sometimes) type-checked genlist.  (Or at least a
+   genlist with related functions with distinctly typed parameters.)
+   (Or, maybe, what you end up doing when you don't use C++ ?)
+   
+   Before including this file, you must define the following:
+     SPECLIST_TAG - this tag will be used to form names for functions etc.
+   You may also define:  
+     SPECLIST_TYPE - the typed genlist will contain pointers to this type;
+   If SPECLIST_TYPE is not defined, then 'struct SPECLIST_TAG' is used.
+   At the end of this file, these (and other defines) are undef-ed.
+
+   Assuming SPECLIST_TAG were 'foo', and SPECLIST_TYPE were 'foo_t',
+   including this file would provide a struct definition for:
+      struct foo_list;
+   and prototypes for the following functions:
+      void foo_list_init(struct foo_list *This);
+      int  foo_list_size(struct foo_list *This);
+      foo_t *foo_list_get(struct foo_list *This, int index);
+      void foo_list_insert(struct foo_list *This, foo_t *pfoo);
+      void foo_list_insert_back(struct foo_list *This, foo_t *pfoo);
+      void foo_list_unlink(struct foo_list *This, foo_t *pfoo);
+      void foo_list_unlink_all(struct foo_list *This);
+
+   You should also define yourself:  (this file cannot do this for you)
+   
+   #define foo_list_iterate(foolist, pfoo) \
+       TYPED_LIST_ITERATE(foo_t, foolist, pfoo)
+   #define foo_list_iterate_end  LIST_ITERATE_END
+
+   Also, in a single .c file, you should include speclist_c.h,
+   with the same SPECLIST_TAG and SPECLIST_TYPE defined, to
+   provide the function implementations.
+
+   Note this is not protected against multiple inclusions; this is
+   so that you can have multiple different speclists.  For each
+   speclist, this file should be included _once_, inside a .h file
+   which _is_ itself protected against multiple inclusions.
+*/
+
+#include "genlist.h"
+
+#ifndef SPECLIST_TAG
+#error Must define a SPECLIST_TAG to use this header
+#endif
+#ifndef SPECLIST_TYPE
+#define SPECLIST_TYPE struct SPECLIST_TAG
+#endif
+
+#define SPECLIST_PASTE_(x,y) x ## y
+#define SPECLIST_PASTE(x,y) SPECLIST_PASTE_(x,y)
+
+#define SPECLIST_LIST struct SPECLIST_PASTE(SPECLIST_TAG, _list)
+
+#define SPECLIST_FOO(suffix) SPECLIST_PASTE(SPECLIST_TAG, suffix)
+
+SPECLIST_LIST {
+  struct genlist list;
+};
+
+void SPECLIST_FOO(_list_init) (SPECLIST_LIST *this);
+int  SPECLIST_FOO(_list_size) (SPECLIST_LIST *this);
+SPECLIST_TYPE *SPECLIST_FOO(_list_get) (SPECLIST_LIST *this, int index);
+void SPECLIST_FOO(_list_insert) (SPECLIST_LIST *this, SPECLIST_TYPE *pfoo);
+void SPECLIST_FOO(_list_insert_back) (SPECLIST_LIST *this, SPECLIST_TYPE 
*pfoo);
+void SPECLIST_FOO(_list_unlink) (SPECLIST_LIST *this, SPECLIST_TYPE *pfoo);
+void SPECLIST_FOO(_list_unlink_all) (SPECLIST_LIST *this);
+
+#undef SPECLIST_TAG
+#undef SPECLIST_TYPE
+#undef SPECLIST_PASTE_
+#undef SPECLIST_PASTE
+#undef SPECLIST_LIST
+#undef SPECLIST_FOO
diff -N -u -r --exclude-from exclude freeciv-cvs/common/speclist_c.h 
fc-adv/common/speclist_c.h
--- freeciv-cvs/common/speclist_c.h     Thu Jan  1 10:00:00 1970
+++ fc-adv/common/speclist_c.h  Fri Jul 16 00:44:39 1999
@@ -0,0 +1,82 @@
+/********************************************************************** 
+ Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+***********************************************************************/
+
+/* See comments in speclist.h about how to use this file.  Notice this
+   is kind of a .c file (it provides function bodies), but it should
+   only be used included, so its also kind of a .h file.  The name
+   speclist_c.h is intended to indicate this, and it also makes
+   automake do the right thing. (?)
+
+   Some of the following is duplicated from speclist.h, because speclist.h
+   undefs its defines to avoid pollution.  However the file which includes
+   this _must_ also include speclist.h appropriately so that the list type
+   is defined.  With the usual arrangement of .c and .h files this normally
+   happens anyway, so this restriction may be considered beneficial.
+*/
+
+#ifndef SPECLIST_TAG
+#error Must define a SPECLIST_TAG to use this header
+#endif
+
+#ifndef SPECLIST_TYPE
+#define SPECLIST_TYPE struct SPECLIST_TAG
+#endif
+
+#define SPECLIST_PASTE_(x,y) x ## y
+#define SPECLIST_PASTE(x,y) SPECLIST_PASTE_(x,y)
+
+#define SPECLIST_LIST struct SPECLIST_PASTE(SPECLIST_TAG, _list)
+
+#define SPECLIST_FOO(suffix) SPECLIST_PASTE(SPECLIST_TAG, suffix)
+
+void SPECLIST_FOO(_list_init) (SPECLIST_LIST *this)
+{
+  genlist_init(&this->list);
+}
+
+int SPECLIST_FOO(_list_size) (SPECLIST_LIST *this)
+{
+  return genlist_size(&this->list);
+}
+
+SPECLIST_TYPE *SPECLIST_FOO(_list_get) (SPECLIST_LIST *this, int index)
+{
+  return genlist_get(&this->list, index);
+}
+
+void SPECLIST_FOO(_list_insert) (SPECLIST_LIST *this, SPECLIST_TYPE *pfoo)
+{
+  genlist_insert(&this->list, pfoo, 0);
+}
+
+void SPECLIST_FOO(_list_insert_back) (SPECLIST_LIST *this, SPECLIST_TYPE *pfoo)
+{
+  genlist_insert(&this->list, pfoo, -1);
+}
+
+void SPECLIST_FOO(_list_unlink) (SPECLIST_LIST *this, SPECLIST_TYPE *pfoo)
+{
+  genlist_unlink(&this->list, pfoo);
+}
+
+void SPECLIST_FOO(_list_unlink_all) (SPECLIST_LIST *this)
+{
+  genlist_unlink_all(&this->list);
+}
+
+#undef SPECLIST_TAG
+#undef SPECLIST_TYPE
+#undef SPECLIST_PASTE_
+#undef SPECLIST_PASTE
+#undef SPECLIST_LIST
+#undef SPECLIST_FOO
diff -N -u -r --exclude-from exclude freeciv-cvs/common/unit.c 
fc-adv/common/unit.c
--- freeciv-cvs/common/unit.c   Sat Jun 12 17:40:11 1999
+++ fc-adv/common/unit.c        Fri Jul 16 00:32:37 1999
@@ -24,6 +24,12 @@
 
 #include "unit.h"
 
+/* get 'struct unit_list' functions: */
+#define SPECLIST_TAG unit
+#define SPECLIST_TYPE struct unit
+#include "speclist_c.h"
+
+
 struct unit_type unit_types[U_LAST];
 /* the unit_types array is now setup in:
    server/ruleset.c (for the server)
@@ -887,22 +893,6 @@
 /**************************************************************************
 ...
 **************************************************************************/
-void unit_list_init(struct unit_list *This)
-{
-  genlist_init(&This->list);
-}
-
-/**************************************************************************
-...
-**************************************************************************/
-struct unit *unit_list_get(struct unit_list *This, int index)
-{
-  return (struct unit *)genlist_get(&This->list, index);
-}
-
-/**************************************************************************
-...
-**************************************************************************/
 struct unit *unit_list_find(struct unit_list *This, int id)
 {
   struct genlist_iterator myiter;
@@ -914,47 +904,6 @@
       return ITERATOR_PTR(myiter);
 
   return 0;
-}
-
-/**************************************************************************
-...
-**************************************************************************/
-void unit_list_insert(struct unit_list *This, struct unit *punit)
-{
-  genlist_insert(&This->list, punit, 0);
-}
-
-/**************************************************************************
-...
-**************************************************************************/
-void unit_list_insert_back(struct unit_list *This, struct unit *punit)
-{
-  genlist_insert(&This->list, punit, -1);
-}
-
-
-/**************************************************************************
-...
-**************************************************************************/
-int unit_list_size(struct unit_list *This)
-{
-  return genlist_size(&This->list);
-}
-
-/**************************************************************************
-...
-**************************************************************************/
-void unit_list_unlink(struct unit_list *This, struct unit *punit)
-{
-  genlist_unlink(&This->list, punit);
-}
-
-/**************************************************************************
-...
-**************************************************************************/
-void unit_list_unlink_all(struct unit_list *This)
-{
-  genlist_unlink_all(&This->list);
 }
 
 /**************************************************************************
diff -N -u -r --exclude-from exclude freeciv-cvs/common/unit.h 
fc-adv/common/unit.h
--- freeciv-cvs/common/unit.h   Wed Jul 14 21:14:19 1999
+++ fc-adv/common/unit.h        Fri Jul 16 00:32:37 1999
@@ -205,30 +205,20 @@
 };
 
 
-struct unit_list {
-  struct genlist list;
-};
+/* get 'struct unit_list' and related functions: */
+#define SPECLIST_TAG unit
+#define SPECLIST_TYPE struct unit
+#include "speclist.h"
 
-#define unit_list_iterate(unitlist, punit) { \
-  struct genlist_iterator myiter; \
-  struct unit *punit; \
-  genlist_iterator_init(&myiter, &unitlist.list, 0); \
-  for(; ITERATOR_PTR(myiter);) { \
-    punit=(struct unit *)ITERATOR_PTR(myiter); \
-    ITERATOR_NEXT(myiter); 
-#define unit_list_iterate_end }}
+#define unit_list_iterate(unitlist, punit) \
+    TYPED_LIST_ITERATE(struct unit, unitlist, punit)
+#define unit_list_iterate_end  LIST_ITERATE_END
 
 extern struct unit_type unit_types[U_LAST];
 
-void unit_list_init(struct unit_list *This);
-struct unit *unit_list_get(struct unit_list *This, int index);
-struct unit *unit_list_find(struct unit_list *This, int id);
-void unit_list_insert(struct unit_list *This, struct unit *punit);
-void unit_list_insert_back(struct unit_list *This, struct unit *punit);
-int unit_list_size(struct unit_list *This);
-void unit_list_unlink(struct unit_list *This, struct unit *punit);
-void unit_list_unlink_all(struct unit_list *This);
 char *unit_name(enum unit_type_id id);
+
+struct unit *unit_list_find(struct unit_list *This, int id);
 
 void unit_list_sort_ord_map(struct unit_list *This);
 void unit_list_sort_ord_city(struct unit_list *This);

[Prev in Thread] Current Thread [Next in Thread]
  • [Freeciv-Dev] patch: speclist, David Pfitzner <=