* $Id: cfg.c,v 1.1.1.1 1999/11/21 08:16:12 lord Exp $
* Vadim Zaliva <lord@crocodile.org>
* http://www.crocodile.org/
* Copyright (C) 1999 Vadim Zaliva
* 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 of the License, 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.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
static int cfg_entry_cmp(const void *a
,const void *b
)
return(strcmp((*((struct Dict
**)a
))->name
, (*((struct Dict
**)b
))->name
));
static int cfg_entry_match(const void *a
,const void *b
)
return(strcmp((const char *)a
, (*((struct Dict
**)b
))->name
));
char *cfgfind(const char *name
,struct Cfg
*cfg
, int offset
)
res
=(struct Dict
**)bsearch(name
,
if(offset
>=(*res
)->nvalues
)
return (*res
)->value
[offset
];
int writecfg(const char *name
,struct Cfg
*cfg
)
if((f
=fopen(name
,"wb"))==NULL
)
for(i
=0;i
<cfg
->nelements
;i
++)
fprintf(f
,"%s\t",cfg
->dict
[i
]->name
);
for(j
=0;j
<cfg
->dict
[i
]->nvalues
;j
++)
if(cfg
->dict
[i
]->value
[j
])
fprintf(f
," %s",cfg
->dict
[i
]->value
[j
]); //TODO: quote values with spaces.
void freecfg(struct Cfg
*cfg
)
for(i
=0;i
<cfg
->nelements
;i
++)
for(j
=0;j
<cfg
->dict
[i
]->nvalues
;j
++)
if(cfg
->dict
[i
]->value
[j
])
free(cfg
->dict
[i
]->value
[j
]);
free(cfg
->dict
[i
]->value
);
free(cfg
->dict
[i
]->name
);
struct Cfg
*readcfg(const char *name
)
if((f
=fopen(name
,"rb"))==NULL
)
cfg
=malloc(sizeof(struct Cfg
));
/* Order of 'case' statements is important here! */
struct Dict
*tmp1
=malloc(sizeof(struct Dict
));
tmp1
->name
= strdup(tmp
);
cfg_add_entry(cfg
, tmp1
);
/* internal buffer overflow */
struct Dict
*last
=cfg
->dict
[cfg
->nelements
-1];
last
->value
=malloc((last
->nvalues
+1)*sizeof(char *));
for(i
=0;i
<last
->nvalues
;i
++)
last
->value
[last
->nvalues
]=strdup(tmp
);
/* internal buffer overflow */
/* internal buffer overflow */
* Should be called after each modification
* before attempting to retrieve any data.
void sortcfg (struct Cfg
*cfg
)
qsort((void *) cfg
->dict
,
* Adds new cfg entry to the end of the dictionary.
* you need to call sortcfg() before it could be
void cfg_add_entry (struct Cfg
*cfg
, struct Dict
*d
)
struct Dict
**last
=cfg
->dict
;
cfg
->dict
=malloc(sizeof(struct Dict
*)*(cfg
->nelements
+1));
memcpy(cfg
->dict
,last
,sizeof(struct Dict
*)*cfg
->nelements
);
cfg
->dict
[cfg
->nelements
]=d
;
cfg
->dict
= malloc(sizeof(struct Dict
*));
* Adds entry with given name and list of values.
* list should be terminated with NULL and contain
* only const char pointers.
void cfg_new_entry(struct Cfg
*cfg
, const char *name
, ...)
struct Dict
*tmp
=malloc(sizeof(struct Dict
));
tmp
->name
= strdup(name
);
while(va_arg(ap
, const char *)) n
++;
tmp
->value
= malloc(n
*sizeof(char *));
tmp
->value
[i
] = strdup(va_arg(ap
, const char *));
void cfg_new_ulong_entry (struct Cfg
*cfg
, const char *name
, unsigned long v
)
cfg_new_entry(cfg
, name
, tmp
, NULL
);
* add long extended to 'w' chars, with added trailing zeros.
void cfg_new_fmt_ulong_entry (struct Cfg
*cfg
, const char *name
, unsigned long v
, int w
)
sprintf(tmp
,"%0*lu",w
, v
);
cfg_new_entry(cfg
, name
, tmp
, NULL
);
struct Cfg
*res
=malloc(sizeof(struct Cfg
));