Break this function!

Stuff you want Bio to see. [Home]

Moderator: BioHazard

Locked
User avatar
BioHazard
Posts: 408
Joined: Mon Jul 25, 2005 10:02
Location: Middle of California where there is no air.
Contact:

Break this function!

Post by BioHazard »

See if you guys can write an INI file this function can't read.

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);}
}
[/spoiler]
User avatar
BioHazard
Posts: 408
Joined: Mon Jul 25, 2005 10:02
Location: Middle of California where there is no air.
Contact:

Post by BioHazard »

You know, maybe I should make it possible to test for the 99% of you without compilers? ;)

http://biohazard.drdteam.org/temp/INITest.zip
User avatar
TheDarkArchon
Posts: 1000
Joined: Wed Jul 06, 2005 11:58
Location: What's that fucking smell
Contact:

Post by TheDarkArchon »

Doesn't read XWE's INI files
User avatar
BioHazard
Posts: 408
Joined: Mon Jul 25, 2005 10:02
Location: Middle of California where there is no air.
Contact:

Post by BioHazard »

XWE doesn't follow the INI standard. (Is there an INI standard? XWE certainly isin't "normal")
User avatar
BioHazard
Posts: 408
Joined: Mon Jul 25, 2005 10:02
Location: Middle of California where there is no air.
Contact:

Post by BioHazard »

I guess since nobody has reported anything, I can call it finished.
User avatar
Graf Zahl
GZDoom Developer
GZDoom Developer
Posts: 7148
Joined: Wed Jul 20, 2005 9:48
Location: Germany
Contact:

Post by Graf Zahl »

It might be a good idea to use more spaces and line breaks.

The code is incredibly hard to read.
User avatar
DoomRater
Posts: 397
Joined: Tue Jul 19, 2005 4:14
Location: Programmer's Room, talking to Will Harvey
Contact:

Post by DoomRater »

Any reason Bio_LineLen() is a signed Long? Wouldn't an Unsigned Long do the job better?
User avatar
BioHazard
Posts: 408
Joined: Mon Jul 25, 2005 10:02
Location: Middle of California where there is no air.
Contact:

Post by BioHazard »

In my testing, longs are always signed, even when you specify unsigned. Maybe I was wrong?
Locked

Return to “Bio's Site-Place”