It supports comments, funky tabulation and spacing around the '='.
These will be available in BioLib eventually. In the meantime, please don't use them for your own stuff untill I have a chance to properly licence them.
[spoiler]
Code: Select all
//////////////////////////////////////////////////////
// ReadINI - Reads an INI value to a buffer from a file
// Written by BioHazard on May 30th 2006 -- Version 6
//// USAGE /////////////////////////////////////////////
// section : The INI section to start reading at
// entry : The entry to read to [out]
// buf : Adress of a char* for the string to go into
// ini : Path to the file to be opened
//// RETURN ////////////////////////////////////////////
// 0 : No problems
// 1 : [ini] could not be opened for reading
// 2 : Temp strings failed to allocate
// 3 : [section] could not be found
// 4 : [entry] could not be found under [section]
// 5 : Couldn't find key/value seperator ('=')
// 6 : [out] failed to allocate
/// REMARKS ////////////////////////////////////////////
// ! Any lines over 2147483647 chars will be mis-read
// * Don't malloc() the output string, this function
// will free() it an malloc() it automagically.
unsigned char Bio_ReadINI(char *section,char *key,char **out,char *ini){
FILE *fptr=0;
char *tmp=0,*cmp=0;
// Open the file and set up
if(!(fptr=fopen(ini,"r"))){return 1;} // Die if the file doesn't open
tmp=calloc((strlen(section)+2>strlen(key)?strlen(section)+2:strlen(key))+1,sizeof(char));
cmp=calloc((strlen(section)+2>strlen(key)?strlen(section)+2:strlen(key))+1,sizeof(char));
if(!tmp||!cmp){free(tmp);return 2;} // Check for allocations
// Get to the section
cmp[0]='[';strcat(cmp,section);strcat(cmp,"]"); // Put the section in []'s
while(strcmp(tmp,cmp)&&!feof(fptr)){
Bio_SkipChar(fptr,0);
fgets(tmp,strlen(section)+3,fptr);
if(!strrchr(tmp,'\n')){while(fgetc(fptr)!='\n'&&!feof(fptr));} // Skip the rest of the line
if(feof(fptr)){free(tmp);free(cmp);return 3;} // Check if [section] can't be found
}free(cmp);
// Get to the key
while(!feof(fptr)){
Bio_SkipChar(fptr,0);
fgets(tmp,strlen(key)+1,fptr);
if(tmp[0]=='['||feof(fptr)){free(tmp);return 4;} // Check for new section
// Read the value
if(!strcmp(tmp,key)){
free(tmp); // We're done with tmp
// Skip the = and the space around it
Bio_SkipChar(fptr,0);
if(fgetc(fptr)!='='){fclose(fptr);return 5;} // Check for expected '='
Bio_SkipChar(fptr,0);
// Yay! Read the result!
if(!Bio_ReadLine(fptr,out)){
fclose(fptr);return 7;
}break; // Done!
}if(!strrchr(tmp,'\n')){while(fgetc(fptr)!='\n'&&!feof(fptr));} // Skip the rest of the line
}fclose(fptr);return 0; // Finish up
}
/////////////////////////////////////////////////////////
// LineLen - Returns the length of the next line of a file
// By BioHazard, May 26th 2006 -- Version 2
/// ARGUMENTS /////////////////////////////////////////////
// file : Pointer to the file to get the char count from
/// RETURN ////////////////////////////////////////////////
// Number of characters on the next line of [flie]
/// REMARKS ///////////////////////////////////////////////
// ! Any lines over 2147483647 chars will be mis-reported
signed long Bio_LineLen(FILE *file){
signed long i=0;
do{i++;}while(fgetc(file)!='\n'&&!feof(file));
fseek(file,-i-(feof(file)?-1:1),SEEK_CUR);
return i;
}
//////////////////////////////////////////////////////
// ReadLine - Reads the next line of a file to a string
// By BioHazard, May 26th 2006 -- Version 3
/// ARGUMENTS //////////////////////////////////////////
// file : Pointer to the file to get the line from
// buf : Pointer to a char* for the string to go into
/// RETURN /////////////////////////////////////////////
// Number of characters copied to [buf]
/// REMARKS ////////////////////////////////////////////
// ! Any lines over 2147483647 chars will be mis-read
// * Don't malloc() the output string, this function
// will free() it an realloc() it automagically.
signed long Bio_ReadLine(FILE *file,char **buf){
signed long i=Bio_LineLen(file);
if(*buf){free(*buf);}
if(!(*buf=calloc(i+1,sizeof(char)))){return 0;}
fgets(*buf,i,file);
fgetc(file);
return i;
}
/////////////////////////////////////////////
// SkipChar - Skips certain chars in a file
// By BioHazard, May 30th 2006 -- Version 1
/// ARGUMENTS /////////////////////////////////
// file : File who's chars are to be skipped
// mask : Specific chars to skip
/// REMARKS ///////////////////////////////////
// * If [mask] is 0, " \t\n\r" (spaces) is used
void Bio_SkipChar(FILE *file,char *mask){
while(strchr(mask?mask:" \t\n\r",fgetc(file))&&!feof(file));
if(!feof(file)){fseek(file,-1,SEEK_CUR);}
}