options.c: Save a few bytes

Use a string repository, instead of a fixed size buffer for each option value.

Also check realloc() error
This commit is contained in:
Thomas Bernard 2012-02-05 01:31:27 +01:00
parent 4e79d6b983
commit 65e277883b
3 changed files with 66 additions and 18 deletions

View File

@ -1,7 +1,9 @@
$Id: Changelog.txt,v 1.253 2012/02/04 23:34:38 nanard Exp $ $Id: Changelog.txt,v 1.254 2012/02/05 00:29:49 nanard Exp $
2012/02/05: 2012/02/05:
Compile ok with -ansi flag. Compile ok with -ansi flag.
Save a few bytes in options.c using a string repository, instead of a fixed size
buffer for each option value.
2012/02/04: 2012/02/04:
Added friendl_name= option to config file Added friendl_name= option to config file

View File

@ -1,4 +1,4 @@
/* $Id: options.c,v 1.22 2012/02/04 23:05:21 nanard Exp $ */ /* $Id: options.c,v 1.23 2012/02/05 00:29:49 nanard Exp $ */
/* MiniUPnP project /* MiniUPnP project
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
* author: Ryan Wagoner * author: Ryan Wagoner
@ -16,6 +16,7 @@
#include "upnpglobalvars.h" #include "upnpglobalvars.h"
struct option * ary_options = NULL; struct option * ary_options = NULL;
static char * string_repo = NULL;
int num_options = 0; int num_options = 0;
static const struct { static const struct {
@ -73,6 +74,9 @@ readoptionsfile(const char * fname)
int linenum = 0; int linenum = 0;
int i; int i;
enum upnpconfigoptions id; enum upnpconfigoptions id;
size_t string_repo_len = 0;
size_t len;
void *tmp;
if(!fname || (strlen(fname) == 0)) if(!fname || (strlen(fname) == 0))
return -1; return -1;
@ -100,6 +104,7 @@ readoptionsfile(const char * fname)
{ {
*t = '\0'; *t = '\0';
t--; t--;
/* remove spaces at the end of the line */
while((t >= buffer) && isspace(*t)) while((t >= buffer) && isspace(*t))
{ {
*t = '\0'; *t = '\0';
@ -118,8 +123,15 @@ readoptionsfile(const char * fname)
/* check for UPnP permissions rule */ /* check for UPnP permissions rule */
if(0 == memcmp(name, "allow", 5) || 0 == memcmp(name, "deny", 4)) if(0 == memcmp(name, "allow", 5) || 0 == memcmp(name, "deny", 4))
{ {
upnppermlist = realloc(upnppermlist, tmp = realloc(upnppermlist, sizeof(struct upnpperm) * (num_upnpperm+1));
sizeof(struct upnpperm) * (num_upnpperm+1)); if(tmp == NULL)
{
fprintf(stderr, "memory allocation error. Permission line in file %s line %d\n",
fname, linenum);
}
else
{
upnppermlist = tmp;
/* parse the rule */ /* parse the rule */
if(read_permission_line(upnppermlist + num_upnpperm, name) >= 0) if(read_permission_line(upnppermlist + num_upnpperm, name) >= 0)
{ {
@ -130,6 +142,7 @@ readoptionsfile(const char * fname)
fprintf(stderr, "parsing error file %s line %d : %s\n", fprintf(stderr, "parsing error file %s line %d : %s\n",
fname, linenum, name); fname, linenum, name);
} }
}
continue; continue;
} }
if(!(equals = strchr(name, '='))) if(!(equals = strchr(name, '=')))
@ -165,22 +178,51 @@ readoptionsfile(const char * fname)
if(id == UPNP_INVALID) if(id == UPNP_INVALID)
{ {
fprintf(stderr, "parsing error file %s line %d : %s=%s\n", fprintf(stderr, "invalid option in file %s line %d : %s=%s\n",
fname, linenum, name, value); fname, linenum, name, value);
} }
else else
{ {
tmp = realloc(ary_options, (num_options + 1) * sizeof(struct option));
if(tmp == NULL)
{
fprintf(stderr, "memory allocation error. Option in file %s line %d.\n",
fname, linenum);
}
else
{
ary_options = tmp;
len = strlen(value) + 1; /* +1 for terminating '\0' */
tmp = realloc(string_repo, string_repo_len + len);
if(tmp == NULL)
{
fprintf(stderr, "memory allocation error, Option value in file %s line %d : %s=%s\n",
fname, linenum, name, value);
}
else
{
string_repo = tmp;
memcpy(string_repo + string_repo_len, value, len);
ary_options[num_options].id = id;
/* save the offset instead of the absolute address because realloc() could
* change it */
ary_options[num_options].value = (const char *)string_repo_len;
num_options += 1; num_options += 1;
ary_options = (struct option *) realloc(ary_options, num_options * sizeof(struct option)); string_repo_len += len;
}
ary_options[num_options-1].id = id; }
strncpy(ary_options[num_options-1].value, value, MAX_OPTION_VALUE_LEN);
} }
} }
fclose(hfile); fclose(hfile);
for(i = 0; i < num_options; i++)
{
/* add start address of string_repo to get right pointer */
ary_options[i].value = string_repo + (size_t)ary_options[i].value;
}
return 0; return 0;
} }
@ -193,6 +235,11 @@ freeoptions(void)
ary_options = NULL; ary_options = NULL;
num_options = 0; num_options = 0;
} }
if(string_repo)
{
free(string_repo);
string_repo = NULL;
}
if(upnppermlist) if(upnppermlist)
{ {
free(upnppermlist); free(upnppermlist);

View File

@ -1,4 +1,4 @@
/* $Id: options.h,v 1.17 2012/02/04 23:05:21 nanard Exp $ */ /* $Id: options.h,v 1.18 2012/02/05 00:29:49 nanard Exp $ */
/* MiniUPnP project /* MiniUPnP project
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
* author: Ryan Wagoner * author: Ryan Wagoner
@ -62,11 +62,10 @@ readoptionsfile(const char * fname);
void void
freeoptions(void); freeoptions(void);
#define MAX_OPTION_VALUE_LEN (80)
struct option struct option
{ {
enum upnpconfigoptions id; enum upnpconfigoptions id;
char value[MAX_OPTION_VALUE_LEN]; const char * value;
}; };
extern struct option * ary_options; extern struct option * ary_options;