#include "cfgopts.h"
void switch_type_and_write (struct Config_Tag ptr[], int count, FILE *outfile);
long fcopy(char *dest, char *source); // copy one file to another
static unsigned char line[1000], line_bak[1000];
static char *true_false[]={ "ERROR","FALSE","TRUE" };
/*---------------------------------------------------------------------/
/ reads from an input configuration (INI) file.
/---------------------------------------------------------------------*/
/*>>------[ input_config() ]-------------[ 08-02-95 14:02PM ]------/
/ return value:
/ int ; number of records read or -1 on error
/ parameters:
/ char *filename ; filename of INI style file
/ struct Config_Tag configs[]; Configuration structure
/ char *header ; INI header name (i.e. "[TEST]")
/-------------------------------------------------------------------<<*/
int input_config(char *filename, struct Config_Tag configs[], char *header)
{
struct Config_Tag *ptr;
int count=0,lineno=0,temp;
FILE *file;
char *fptr,*tok,*next;
file=fopen(filename,"r");
if ( file==NULL ) return ERROR; // return error designation.
if ( header!=NULL )
do
{
fptr=fgets(line,sizeof(line)-2,file); // get input line
}
while ( memcasecmp(line,header,strlen(header)) && !feof(file));
if ( !feof(file) ) do {
fptr=fgets(line,sizeof(line)-2,file); // get input line
if ( fptr==NULL ) continue;
lineno++;
if ( line[0]=='#' || line[0]==';' || line[0]=='/') continue; // skip comments
if ( line[0]=='[' ) continue; // skip next header
tok=strtok(line,"=\n\r"); // get first token
if ( tok!=NULL )
{
next=strtok(NULL,"=\n\r"); // get actual config information
for ( ptr=configs;ptr->buf;++ptr ) // scan for token
{
if ( !strcasecmp( tok , ptr->code ) ) // got a match?
{
if(!next) break;
switch ( ptr->type ) // check type
{
case Boolean_Tag:
if (!strcasecmp(next,"FALSE"))
*((Boolean_T *)(ptr->buf)) = FALSE;
else if (!strcasecmp(next,"TRUE"))
*((Boolean_T *)(ptr->buf)) = TRUE;
++count;
break;
case Byte_Tag:
sscanf(next, "%d", &temp);
*((char *)(ptr->buf))=(char)temp;
++count;
break;
case Word_Tag:
sscanf(next, "%hd", (short *)(ptr->buf));
++count;
break;
case DWord_Tag:
sscanf(next, "%ld", (long *)(ptr->buf));
++count;
break;
case OctWord_Tag:
sscanf(next, "%ho", (short *)(ptr->buf));
++count;
break;
case DOctWord_Tag:
sscanf(next, "%lo", (long *)(ptr->buf));
++count;
break;
case HexWord_Tag:
sscanf(next, "%hx", (short *)(ptr->buf));
++count;
break;
case DHexWord_Tag:
sscanf(next, "%lx", (long *)(ptr->buf));
++count;
break;
case Float_Tag:
sscanf(next, "%g", (float *)ptr->buf);
++count;
break;
case Double_Tag:
sscanf(next, "%lg", (double *)ptr->buf);
++count;
break;
case String_Tag:
if(ptr->size_buf <= strlen(next)) strcpy((char *)ptr->buf, "\0\0");
else strcpy((char *)ptr->buf, next);
++count;
break;
case Function_Tag:
case Error_Tag:
default:
printf("Error in Config file %s on line %d\n",filename,lineno);
break;
}
}
}
}
}
while ( fptr!=NULL && line[0]!='[');
fclose(file);
return count;
}
/*---------------------------------------------------------------------/
/ updates an input configuration (INI) file from a structure.
/---------------------------------------------------------------------*/
/*>>------[ update_config() ]-------------[ 08-02-95 14:02PM ]------/
/ return value:
/ int ; Number of records read & updated
/ parameters:
/ char *filename ; filename of INI file
/ struct Config_Tag configs[]; Configuration structure
/ char *header ; INI header name (i.e. "[TEST]")
/-------------------------------------------------------------------<<*/
int update_config(char *filename, struct Config_Tag configs[], char *header)
{
int count=0,lineno=0, section_not_found;
FILE *infile,*outfile;
char *fptr,*tok;
infile=fopen(filename,"r");
if ( infile==NULL ) { // file not found, creating new onw
outfile=fopen("temp_PHX.$$$","w");
if ( outfile==NULL )
return ERROR; // return error designation.
if ( header!=NULL ) fprintf(outfile,"%s\n",header);
switch_type_and_write(configs, count, outfile);
fclose(outfile);
fcopy(filename,"temp_PHX.$$$");
remove("temp_PHX.$$$");
return count;
}
outfile=fopen("temp_PHX.$$$","w");
if ( outfile==NULL ) {
fclose(infile);
return ERROR; // return error designation.
}
if ( header!=NULL )
{
do
{
fptr=fgets(line,sizeof(line)-2,infile); // get input line
if(fptr) fprintf(outfile,"%s",line);
section_not_found=memcasecmp(line,header,strlen(header));
}
while ( section_not_found && !feof(infile));
}
if ( feof(infile) ) {
fprintf(outfile,"\n");
if ( header!=NULL && section_not_found ) fprintf(outfile,"\n%s\n",header);
switch_type_and_write(configs, count, outfile);
}
else {
do
{
fptr=fgets(line,sizeof(line)-2,infile); // get input line
if ( fptr==NULL )
{ // eof reached, lets write it
switch_type_and_write(configs, count, outfile);
break;
}
lineno++;
if ( line[0]=='#' || line[0]=='\r' || line[0]=='\n' || line[0]==';' || line[0]=='/') {
fprintf(outfile,"%s",line);
continue; // skip comments
}
else if ( line[0]=='[' ) { // new section found, last section was empty
switch_type_and_write(configs, count, outfile);
fprintf(outfile,"%s",line);
do
{ // write the rest of the file
fptr=fgets(line,sizeof(line)-2,infile);
if (fptr) fprintf(outfile,"%s",line);
}
while (!feof(infile));
break;
}
strcpy(line_bak, line);
tok=strtok(line,"=\n\r"); // get first token
if ( tok!=NULL )
{
if ( !strcasecmp( tok , configs->code ) ) // got a match?
{
switch_type_and_write(configs, count, outfile);
do
{ // write the rest of the file
fptr=fgets(line,sizeof(line)-2,infile);
if (fptr) fprintf(outfile,"%s",line);
}
while (!feof(infile));
break;
}
fprintf(outfile,"%s",line_bak);
}
}
while ( fptr!=NULL );
}
fclose(infile);
fclose(outfile);
fcopy(filename,"temp_PHX.$$$");
remove("temp_PHX.$$$");
return count;
}
void GetPrivateProfileString(char *INIsection, char *INIkey, char *INIdefault, char *INIbuffer, int INIbuflen, char *INIpath)
{
struct Config_Tag cfgStr[] = {
{ INIkey, String_Tag, INIbuffer, INIbuflen },
{ NULL, Error_Tag, NULL, 0 } /* Terminating record */
};
unsigned char INIsect2[250];
INIbuffer[0]=0;
INIsect2[0]='[';
strcpy(INIsect2+1, INIsection);
strcat(INIsect2, "]");
input_config(INIpath, cfgStr, INIsect2);
if(INIbuffer[0]==0) strcpy(INIbuffer, INIdefault);
if(INIbuffer[0]==0x22 && INIbuffer[strlen(INIbuffer)-1]==0x22) // kill ""
{
INIbuffer[strlen(INIbuffer)-1]=0;
strcpy(INIbuffer, INIbuffer+1);
}
}
void WritePrivateProfileString(char *INIsection, char *INIkey, char *INIvalue, char *INIpath)
{
unsigned char INIsect2[250];
struct Config_Tag cfgStr[] = {
{ INIkey, String_Tag, INIvalue }
};
INIsect2[0]='[';
strcpy(INIsect2+1, INIsection);
strcat(INIsect2, "]");
update_config(INIpath, cfgStr, INIsect2);
}
/*
* copy one file to another. Returns the (positive)
* number of bytes copied, or -1 if an error occurred.
*/
#define BUFFER_SIZE 1024
/*---------------------------------------------------------------------/
/ copy one file to another.
/---------------------------------------------------------------------*/
/*>>------[ fcopy() ]-------------[ 08-02-95 14:02PM ]------/
/ return value:
/ long ; Number of bytes copied or -1 on error
/ parameters:
/ char *dest ; Destination file name
/ char *source ; Source file name
/-------------------------------------------------------------------<<*/
long fcopy(char *dest, char *source)
{
FILE *d, *s;
char *buffer;
size_t incount;
long totcount = 0L;
s = fopen(source, "rb");
if(s == NULL)
return -1L;
d = fopen(dest, "wb");
if(d == NULL)
{
fclose(s);
return -1L;
}
buffer = (char *)malloc(BUFFER_SIZE);
if(buffer == NULL)
{
fclose(s);
fclose(d);
return -1L;
}
incount = fread(buffer, sizeof(char), BUFFER_SIZE, s);
while(!feof(s))
{
totcount += (long)incount;
fwrite(buffer, sizeof(char), incount, d);
incount = fread(buffer, sizeof(char), BUFFER_SIZE, s);
}
totcount += (long)incount;
fwrite(buffer, sizeof(char), incount, d);
free(buffer);
fclose(s);
fclose(d);
return totcount;
}
int memcasecmp (const void *vs1, const void *vs2, size_t n)
{
unsigned int i;
unsigned char const *s1 = (unsigned char const *) vs1;
unsigned char const *s2 = (unsigned char const *) vs2;
for (i = 0; i < n; i++)
{
unsigned char u1 = *s1++;
unsigned char u2 = *s2++;
if (TOUPPER (u1) != TOUPPER (u2))
return TOUPPER (u1) - TOUPPER (u2);
}
return 0;
}
void switch_type_and_write (struct Config_Tag ptr[], int count, FILE *outfile)
{
int temp;
fprintf(outfile,"%s=",ptr->code);
switch ( ptr->type ) // check type
{
case Boolean_Tag:
fprintf(outfile,"%s\n",
true_false[*((Boolean_T *)(ptr->buf))+1]);
++count;
return;
case Byte_Tag:
temp=(int)*((char *)(ptr->buf));
fprintf(outfile, "%hd\n", temp);
++count;
return;
case Word_Tag:
fprintf(outfile, "%hd\n", *((short *)(ptr->buf)));
++count;
return;
case DWord_Tag:
fprintf(outfile, "%ld\n", *((long *)(ptr->buf)));
++count;
return;
case OctWord_Tag:
fprintf(outfile, "%ho\n", *((short *)(ptr->buf)));
++count;
return;
case DOctWord_Tag:
fprintf(outfile, "%lo\n", *((long *)(ptr->buf)));
++count;
return;
case HexWord_Tag:
fprintf(outfile, "%hx\n", *((short *)(ptr->buf)));
++count;
return;
case DHexWord_Tag:
fprintf(outfile, "%lx\n", *((long *)(ptr->buf)));
++count;
return;
case Float_Tag:
fprintf(outfile, "%hg\n", *((float *)ptr->buf));
++count;
return;
case Double_Tag:
fprintf(outfile, "%lg\n", *((double *)ptr->buf));
++count;
return;
case String_Tag:
fprintf(outfile, "%s\n",(char *)ptr->buf);
++count;
return;
}
}
syntax highlighted by Code2HTML, v. 0.9.1