refactored optionsfrom as in an object-oriented way using the options_t class. Elimin...
authorAndreas Steffen <andreas.steffen@strongswan.org>
Mon, 4 Feb 2008 14:44:14 +0000 (14:44 -0000)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Mon, 4 Feb 2008 14:44:14 +0000 (14:44 -0000)
src/libstrongswan/utils/optionsfrom.c
src/libstrongswan/utils/optionsfrom.h

index ffa571b..39e38cc 100644 (file)
@@ -6,8 +6,10 @@
  */
 
 /*
- * Copyright (C) 1998, 1999  Henry Spencer.
- * 
+ * Copyright (C) 2007-2008 Andreas Steffen
+ *
+ * Hochschule fuer Technik Rapperswil
+ *
  * This library is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Library General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or (at your
@@ -18,6 +20,7 @@
  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
  * License for more details.
  *
+ * RCSID $Id$
  */
 
 #include <stdio.h>
 #include "optionsfrom.h"
 
 #define        MAX_USES         20             /* loop-detection limit */
-#define        SOME_ARGS        10             /* first guess at how many arguments we'll need */
+#define        MORE_ARGS        10             /* first guess at how many arguments we'll need */
 
 /*
  * Defined in header.
  */
-bool optionsfrom(const char *filename, int *argcp, char **argvp[], int optind)
-{
-       static int nuses = 0;
+
+typedef struct private_options_t private_options_t;
+
+/**
+ * Private data of a options_t object.
+ */
+struct private_options_t {
+       /**
+        * Public interface
+        */
+       options_t public;
+
+       /**
+        * reallocated argv array
+        */
        char **newargv;
+
+       /**
+        * number of free arguments in newargv
+        */
+       int room;
+
+       /**
+        * number of included option files
+       */
+       int nuses;
+
+       /**
+        * allocated space for option files
+        */
+       char *buffers[MAX_USES];
+};
+
+/**
+ * Defined in header
+ */
+bool from(private_options_t *this, char *filename, int *argcp, char **argvp[],
+                 int optind)
+{
        int newargc;
        int next;                       /* place for next argument */
-       int room;                       /* how many more new arguments we can hold */
+       char **newargv;
        size_t bytes;
-       chunk_t chunk, src, line, token;
+       chunk_t src, line, token;
        bool good = TRUE;
        int linepos = 0;
        FILE *fd;
 
        /* avoid endless loops with recursive --optionsfrom arguments */
-       nuses++;
-       if (nuses >= MAX_USES)
+       this->nuses++;
+       if (this->nuses >= MAX_USES)
        {
-               DBG1("optionsfrom called %d times - looping?", (*argvp)[0], nuses);
+               DBG1("optionsfrom called %d times by \"%s\" - looping?", this->nuses + 1, (*argvp)[0]);
                return FALSE;
        }
        
@@ -66,26 +104,31 @@ bool optionsfrom(const char *filename, int *argcp, char **argvp[], int optind)
 
        /* determine the file size */
        fseek(fd, 0, SEEK_END);
-       chunk.len = ftell(fd);
+       src.len = ftell(fd);
        rewind(fd);
 
        /* allocate one byte more just in case of a missing final newline */
-       chunk.ptr = malloc(chunk.len + 1);
+       src.ptr = this->buffers[this->nuses] = malloc(src.len + 1);
 
        /* read the whole file into a chunk */
-       bytes = fread(chunk.ptr, 1, chunk.len, fd);
+       bytes = fread(src.ptr, 1, src.len, fd);
        fclose(fd);
 
-       newargc = *argcp + SOME_ARGS;
-       newargv = malloc((newargc + 1) * sizeof(char *));
+       if (this->room)
+       {
+               newargc = *argcp;
+               newargv = malloc((newargc + 1 + this->room) * sizeof(char *));
+       }
+       else
+       {
+               newargc = *argcp + MORE_ARGS;
+               this->room = MORE_ARGS;
+               newargv = malloc((newargc + 1) * sizeof(char *));
+       }
        memcpy(newargv, *argvp, optind * sizeof(char *));
-       room = SOME_ARGS;
        next = optind;
        newargv[next] = NULL;
 
-       /* we keep the chunk pointer so that we can still free it */
-       src = chunk;
-
        while (fetchline(&src, &line) && good)
        {
                linepos++;
@@ -116,11 +159,11 @@ bool optionsfrom(const char *filename, int *argcp, char **argvp[], int optind)
                        }
 
                        /* do we have to allocate more memory for additional arguments? */
-                       if (room == 0)
+                       if (this->room == 0)
                        {
-                               newargc += SOME_ARGS;
-                               newargv = realloc(newargv, (newargc+1) * sizeof(char *));
-                               room = SOME_ARGS;
+                               newargc += MORE_ARGS;
+                               newargv = realloc(newargv, (newargc + 1) * sizeof(char *));
+                               this->room = MORE_ARGS;
                        }
 
                        /* terminate the token by replacing the delimiter with a null character */
@@ -129,20 +172,54 @@ bool optionsfrom(const char *filename, int *argcp, char **argvp[], int optind)
                        /* assign the token to the next argument */
                        newargv[next] = token.ptr;
                        next++;
-                       room--;
+                       this->room--;
                }
        }
 
-       if (!good)              /* error of some kind */
+       /* assign newargv to argv */
+       if (good)
        {
-               free(chunk.ptr);
-               free(newargv);
-               return FALSE;
+               memcpy(newargv + next, *argvp + optind, (*argcp + 1 - optind) * sizeof(char *));
+               *argcp += next - optind;
+               *argvp = newargv;
        }
 
-       memcpy(newargv + next, *argvp + optind, (*argcp + 1 - optind) * sizeof(char *));
-       *argcp += next - optind;
-       *argvp = newargv;
-       return TRUE;
+       /* keep a pointer to the latest newargv and free any earlier version */
+       free(this->newargv);
+       this->newargv = newargv;
+
+       return good;
+}
+
+/**
+ * Defined in header
+ */
+void destroy(private_options_t *this)
+{
+       while (this->nuses >= 0)
+       {
+               free(this->buffers[this->nuses--]);
+       }
+       free(this->newargv);
+       free(this);
 }
 
+/*
+ * Defined in header
+ */
+options_t *options_create(void)
+{
+       private_options_t *this = malloc_thing(private_options_t);
+
+       /* initialize */
+       this->newargv = NULL;
+       this->room = 0;
+       this->nuses = -1;
+       memset(this->buffers, '\0', MAX_USES);
+
+       /* public functions */
+       this->public.from = (bool (*) (options_t*,char*,int*,char***,int))from;
+       this->public.destroy = (void (*) (options_t*))destroy;
+
+       return &this->public;
+}
index d6b9efd..02f8ae7 100644 (file)
@@ -6,8 +6,9 @@
  */
 
 /*
- * Copyright (C) 1998, 1999  Henry Spencer.
- * Copyright (C) 2007 Andreas Steffen, Hochschule fuer Technik Rapperswil
+ * Copyright (C) 2007-2008 Andreas Steffen
+ *
+ * Hochschule fuer Technik Rapperswil
  *
  * 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
  * 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.
+ *
+ * RCSID $Id$
  */
 
 #ifndef OPTIONSFROM_H_
 #define OPTIONSFROM_H_
 
+typedef struct options_t options_t;
+
 /**
- * @brief Pick up more options from a file, in the middle of an option scan
+ * @brief options object.
  * 
- * @param filename                             file containing the options
- * @param argcp                                        pointer to argc
- * @param argvp                                        pointer to argv[]
- * @param optind                               current optind, number of next argument
- * @return                                             TRUE if optionsfrom parsing successful
+ * @b Constructors:
+ *  - options_create()
+ *
+ * @ingroup utils
+ */
+struct options_t {
+       /**
+        * @brief Check if the PKCS#7 contentType is data
+        *
+        * @param this                  calling object
+        * @param filename                      file containing the options
+        * @param argcp                         pointer to argc
+        * @param argvp                         pointer to argv[]
+        * @param optind                                current optind, number of next argument
+        * @return                                              TRUE if optionsfrom parsing successful
+        */
+       bool (*from) (options_t * this, char *filename, int *argcp, char **argvp[], int optind);
+
+       /**
+        * @brief Destroys the options_t object.
+        *
+        * @param this                  options_t object to destroy
+        */
+       void (*destroy) (options_t *this);
+};
+
+/**
+ * @brief Create an options object.
+ *
+ * @return                                             created options_t object
+ *
+ * @ingroup utils
  */
-bool optionsfrom(const char *filename, int *argcp, char **argvp[], int optind);
+options_t *options_create(void);
 
 #endif /*OPTIONSFROM_H_*/