/* InputParser_GetWordFloat.. Same with InputParser_GetWord , if the result can be converted to a float number , it returns this number else 0.0 is returned */ float InputParser_GetWordFloat(struct InputParserC * ipc,unsigned int num) { if ( CheckWordNumOk(ipc,num) == 0 ) { return 0.0; } if (ipc->tokenlist[num].length == 0 ) { return 0.0; } float return_value=0.0; //Our string is a "string_segment" , and its last character ( which will be temporary become null ) is last_char_of_string_segment char * string_segment = ipc->str+ipc->tokenlist[num].token_start; char * last_char_of_string_segment = string_segment + ipc->tokenlist[num].length; char remember = 0; if (ipc->tokenlist[num].token_start + ipc->tokenlist[num].length < ipc->str_length) { remember = *last_char_of_string_segment; *last_char_of_string_segment = (char) 0; //Temporarily convert the string segment to a null terminated string } //else we are on the last part of the string so no reason to do the whole 0 remember thing.. sscanf(string_segment,"%f",&return_value); if (ipc->tokenlist[num].token_start + ipc->tokenlist[num].length < ipc->str_length) { *last_char_of_string_segment = remember; //Restore string.. } return return_value; }
/* InputParser_GetChar.. Returns character (pos) from token (num)..! */ char InputParser_GetWordChar(struct InputParserC * ipc,unsigned int num,unsigned int pos) { if ( CheckWordNumOk(ipc,num) == 0 ) { return 0; } if ( pos>=ipc->tokenlist[num].token_start+ipc->tokenlist[num].length ) { return 0; } return ipc->str[ipc->tokenlist[num].token_start + pos ]; }
/* InputParser_GetUpcaseWord.. Same with InputParser_GetWord , the result is converted to lowercase..! */ unsigned int InputParser_GetLowercaseWord(struct InputParserC * ipc,unsigned int num,char * wheretostore,unsigned int storagesize) { if ( CheckWordNumOk(ipc,num) == 0 ) { return 0; } if ( storagesize < ipc->tokenlist[num].length+1 ) /* +1 gia to \0 */ return 0; unsigned int i=0; for ( i = ipc->tokenlist[num].token_start; i<ipc->tokenlist[num].token_start+ipc->tokenlist[num].length; i++ ) wheretostore[i-ipc->tokenlist[num].token_start] = tolower(ipc->str[i]); wheretostore[ipc->tokenlist[num].length] = 0; return ipc->tokenlist[num].length; }
/* InputParser_GetChar.. Returns total length of token (num)..! */ unsigned int InputParser_GetWordLength(struct InputParserC * ipc,unsigned int num) { if ( CheckWordNumOk(ipc,num) == 0 ) { return 0; } return ipc->tokenlist[num].length; }
/* InputParser_GetWordInt.. Same with InputParser_GetWord , if the result can be converted to a number , it returns this number else 0 is returned */ signed int InputParser_GetWordInt(struct InputParserC * ipc,unsigned int num) { if ( CheckWordNumOk(ipc,num) == 0 ) { return 0; } return Str2Int_internal(ipc->str,ipc->tokenlist[num].token_start,ipc->tokenlist[num].length); }
/* InputParser_GetWordFloat.. Same with InputParser_GetWord , if the result can be converted to a float number , it returns this number else 0.0 is returned */ float InputParser_GetWordFloat(struct InputParserC * ipc,unsigned int num) { if ( CheckWordNumOk(ipc,num) == 0 ) { return 0.0; } if (ipc->tokenlist[num].length == 0 ) { return 0.0; } char remember = 0; char * string_segment = 0; char * last_char_of_string_segment = 0; unsigned char isLocallyAllocated = ipc->local_allocation; unsigned int tokenStart = ipc->tokenlist[num].token_start; unsigned int tokenLength = ipc->tokenlist[num].length; unsigned int stringLength = ipc->str_length; float return_value=0.0; //Our string is a "string_segment" , and its last character ( which will be temporary become null ) is last_char_of_string_segment if (!isLocallyAllocated) { string_segment = (char*) malloc( (tokenLength+1) * sizeof(char) ); if (string_segment==0) { fprintf(stderr,"InputParser_GetWordFloat could not allocate memory to return float value , returning NaN \n"); return NAN; } strncpy(string_segment,ipc->str+tokenStart,tokenLength); last_char_of_string_segment = string_segment + ipc->tokenlist[num].length; } else { string_segment = ipc->str+tokenStart; last_char_of_string_segment = string_segment + ipc->tokenlist[num].length; } if (tokenStart + tokenLength < stringLength) { remember = *last_char_of_string_segment; *last_char_of_string_segment = (char) 0; //Temporarily convert the string segment to a null terminated string } //else we are on the last part of the string so no reason to do the whole 0 remember thing.. #if USE_SCANF //fprintf(stderr,"Using sscanf to parse %s \n",string_segment); #warning "scanf without field width limits can crash with huge input data on libc versions older than 2.13-25. Add a field width specifier to fix this problem" /* Sample program that can crash: #include <stdio.h> int main() { int a; scanf("%i", &a); return 0; } To make it crash: perl -e 'print "5"x2100000' | ./a.out| */ sscanf(string_segment,"%f",&return_value); #else //fprintf(stderr,"Using atof to parse %s \n",string_segment); return_value=atof(string_segment); #endif // USE_SCANF if ( tokenStart + tokenLength < stringLength) { *last_char_of_string_segment = remember; //Restore string.. } if (!isLocallyAllocated) { free(string_segment); } return return_value; }