From 7a036fc7324c2253384401d1a66886e37b58823c Mon Sep 17 00:00:00 2001
From: Per Cederqvist <ceder@lysator.liu.se>
Date: Wed, 1 Feb 2006 21:31:24 +0000
Subject: [PATCH] Configuration cleanup: use constructor/destructor semantics.
 * src/server/conf-file.h (struct datatype): Replaced the freer attribute with
 ctor and dtor attributes.  All users updated. Added some documentation.
 (free_config): New function. * src/server/conf-file.c (init_init): Call the
 constructors for all parameters. (free_config): New function, that calls the
 destructors for all parameters. (ctor_string): New static function.
 (dtor_string): New static function, which replaces unassign_string.
 (assign_string): Expect the object to already be constructed.
 (unassign_string): Removed. (cf_string): Use ctor_string and dtor_string. *
 src/server/server-config.c (cf_log_param): Updated for new struct datatype.
 (cf_jubel): Ditto. (cf_ident_param): Ditto. (free_configuration): Use
 free_config to do the work.

---
 ChangeLog                  | 21 +++++++++++++
 src/server/conf-file.c     | 62 +++++++++++++++++++++++++-------------
 src/server/conf-file.h     | 13 +++++++-
 src/server/server-config.c | 17 +++--------
 4 files changed, 78 insertions(+), 35 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 39150c317..22dd99c84 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,26 @@
 2006-02-01  Per Cederqvist  <ceder@lysator.liu.se>
 
+	Configuration cleanup: use constructor/destructor semantics.
+	* src/server/conf-file.h (struct datatype): Replaced the freer
+	attribute with ctor and dtor attributes.  All users updated.
+	Added some documentation.
+	(free_config): New function.
+	* src/server/conf-file.c (init_init): Call the constructors for
+	all parameters.
+	(free_config): New function, that calls the destructors for all
+	parameters.
+	(ctor_string): New static function. 
+	(dtor_string): New static function, which replaces
+	unassign_string.
+	(assign_string): Expect the object to already be constructed.
+	(unassign_string): Removed.
+	(cf_string): Use ctor_string and dtor_string.
+	* src/server/server-config.c (cf_log_param): Updated for new
+	struct datatype.
+	(cf_jubel): Ditto.
+	(cf_ident_param): Ditto.
+	(free_configuration): Use free_config to do the work.
+
 	Namespace cleanup.
 	* src/server/conf-file.c: Moved all struct datatype objects to the
 	end of the file, to avoid having to forward-declare all of the
diff --git a/src/server/conf-file.c b/src/server/conf-file.c
index b57852918..c4f0da49f 100644
--- a/src/server/conf-file.c
+++ b/src/server/conf-file.c
@@ -72,7 +72,8 @@ init_init(const struct parameter *par)
     int ix;
 
     for (npar = 0; par[npar].name != NULL; npar++)
-      ;
+	if (par[npar].tp->ctor != NULL)
+	    par[npar].tp->ctor(&par[npar]);
 
     assert (assignment_count == NULL);
     assignment_count = smalloc(npar * sizeof (*assignment_count));
@@ -240,6 +241,17 @@ read_config(const char *config_file,
 	return OK;
 }
 
+void
+free_config(const struct parameter *par)
+{
+    int i;
+
+    for (i = 0; par[i].name != NULL; ++i)
+        if (par[i].tp->dtor != NULL)
+            (*par[i].tp->dtor)(&par[i]);
+}
+
+
 static Success
 assign_text_no(const char *val, 
 	       const struct parameter *par)
@@ -323,10 +335,29 @@ assign_uint(const char *val,
     return OK;
 }
 
+static void
+ctor_string(const struct parameter *par)
+{
+    *(char**)par->value = NULL;
+}
+
+static void
+dtor_string(const struct parameter *par)
+{
+    if (*(char**)par->value != NULL)
+    {
+	sfree(*(char**)par->value);
+	*(char**)par->value = NULL;
+    }
+}
+
 static Success
 assign_string(const char *val, 
 	      const struct parameter *par)
 {
+    if (*(char**)par->value != NULL)
+	sfree(*(char**)par->value);
+
     if (val == NULL)
 	*(char**)par->value = NULL;
     else
@@ -489,49 +520,38 @@ assign_timeval(const char *val,
 }
 
 
-static void
-unassign_string(const struct parameter *par)
-{
-    if (*(char**)par->value != NULL)
-    {
-        sfree(*(char**)par->value);
-        *(char**)par->value = NULL;
-    }
-}
-
-
 const struct datatype cf_text_no = {
-    assign_text_no, NULL,
+    assign_text_no, NULL, NULL,
 };
 
 const struct datatype cf_conf_no = {
-    assign_conf_no, NULL
+    assign_conf_no, NULL, NULL,
 };
 
 const struct datatype cf_int = {
-    assign_int, NULL
+    assign_int, NULL, NULL,
 };
 
 const struct datatype cf_ulong = {
-    assign_ulong, NULL
+    assign_ulong, NULL, NULL,
 };
 
 const struct datatype cf_uint = {
-    assign_uint, NULL
+    assign_uint, NULL, NULL,
 };
 
 const struct datatype cf_string = {
-    assign_string, unassign_string
+    assign_string, ctor_string, dtor_string,
 };
 
 const struct datatype cf_bool = {
-    assign_bool, NULL
+    assign_bool, NULL, NULL,
 };
 
 const struct datatype cf_double = {
-    assign_double, NULL
+    assign_double, NULL, NULL,
 };
 
 const struct datatype cf_timeval = {
-    assign_timeval, NULL
+    assign_timeval, NULL, NULL,
 };
diff --git a/src/server/conf-file.h b/src/server/conf-file.h
index b15c3fed5..b7c183c3e 100644
--- a/src/server/conf-file.h
+++ b/src/server/conf-file.h
@@ -32,8 +32,18 @@
 struct parameter;
 
 struct datatype {
+    /* Assign a value to the parameter pointed to by par.  The value
+       comes from the val. */
     Success (*assigner)(const char *val, const struct parameter *par);
-    void    (*freer)(const struct parameter *par);
+
+    /* Constructor: initialize the parameter pointed to by par.  May
+       allocate memory.  However, the memory pointed to by par must
+       already be allocated.   NULL if no construction is needed. */
+    void    (*ctor)(const struct parameter *par);
+
+    /* Destructor: undo whatever the constructor did.  NULL if no
+       destruction is needed. */
+    void    (*dtor)(const struct parameter *par);
 };
 
 struct parameter {
@@ -48,6 +58,7 @@ struct parameter {
 };
 
 Success read_config(const char *config_file, const struct parameter *par);
+void free_config(const struct parameter *par);
 
 extern const struct datatype cf_text_no;
 extern const struct datatype cf_conf_no;
diff --git a/src/server/server-config.c b/src/server/server-config.c
index 1ac8a2361..1de5201bc 100644
--- a/src/server/server-config.c
+++ b/src/server/server-config.c
@@ -75,15 +75,15 @@ static Success jubel(const char *val, const struct parameter *par);
 static Success ident_param(const char *val, const struct parameter *par);
 
 static const struct datatype cf_log_param = {
-    log_param, NULL,
+    log_param, NULL, NULL,
 };
 
 static const struct datatype cf_jubel = {
-    jubel, NULL,
+    jubel, NULL, NULL,
 };
 
 static const struct datatype cf_ident_param = {
-    ident_param, NULL,
+    ident_param, NULL, NULL,
 };
 
     
@@ -894,16 +894,7 @@ read_configuration(const char *conf_file)
 void
 free_configuration(void)
 {
-    int i = 0;
-
-    while (parameters[i].name != NULL)
-    {
-        if (parameters[i].tp->freer != NULL)
-        {
-            (*parameters[i].tp->freer)(&parameters[i]);
-        }
-        i += 1;
-    }
+    free_config(parameters);
 }
 
 #ifdef DEBUG_CALLS
-- 
GitLab