Two of the functions I am writing (Next_Float and Next_Integer) are very similar except for the actual conversion line. Is there a way that I can make a Next_Number function take a function pointer to the corresponding conversion routine and put the converted number to a void pointer?
Only difference:
Code:
/* Code in Next_Float */
*Target = atof(&Parser->Buffer[Float_Start]);
/* Code in Next_Integer */
*Target = atoi(&Parser->Buffer[Integer_Start]);
/* Desired function */
int Next_Number(
Struct_Parser *Parser,
void *Target,
?????
);
Next_Float:
Code:
#define IS_CHARACTER(c) (c>' ')
#define IS_ESCAPE(c) (c<'\t'||(c<' '&&c>'\t')) /* Tab is not considered an escape character */
#define IS_WHITESPACE(c) (c==' '||c=='\t')
#define IS_DIGIT(c) (c>='0'&&c<='9')
#define IS_DIGIT_SIGN(c) (c=='-'||c=='+')
#define IS_DIGIT_SYMBOL(c) (c=='-'||c=='.'||c=='+')
#define IS_POSSIBLE_NUMBER(c) (IS_DIGIT(c)||IS_DIGIT_SYMBOL(c))
/*
---------------------------------------------------------------------------------------------------------------------------------------------------[]
*/
int Next_Float(
Struct_Parser *Parser,
float *Target
){
/* Indexes of the buffer where the number starts and ends */
int Float_Start;
/* Used by buffer for swaping values and storing a decimal count in the buffer check */
char Temp = 0;
/* Reset Skipped_Lines */
Parser->Skipped_Lines = 0;
Skip_Whitespace(Parser);
/* If we are at the end of the line get the next */
if(IS_ESCAPE(Parser->Buffer[Parser->Buffer_Index]) && !Fetch_Clear_Line(Parser))
return FAILURE;
/* Set the float starting position */
Float_Start = Parser->Buffer_Index;
/* Fetch characters from input that are valid digits or digit symbols */
for(;IS_POSSIBLE_NUMBER(Parser->Buffer[Parser->Buffer_Index]);Parser->Buffer_Index++);
/* Test for non-valid digit-symbol combinations */
switch(Parser->Buffer_Index - 1 - Float_Start){
/* '' */
case -1:
return FAILURE;
/* '+', '-', '.' */
case 0:
if(IS_DIGIT_SYMBOL(Parser->Buffer[Float_Start]))
return FAILURE;
break;
/* '+X', '-X', '.X', 'X+', 'X-', 'X.' */
case 1:
if(IS_DIGIT_SYMBOL(Parser->Buffer[Float_Start]) && IS_DIGIT_SYMBOL(Parser->Buffer[Float_Start + 1]))
return FAILURE;
break;
/* Any other combination */
default:
/* Loop through the buffer section that contains the possible float */
for(int i = Float_Start;i < Parser->Buffer_Index;i++){
/* Testing for non-valid digit-symbol combinations (where 'X' is a digit): 'X..', 'X+', 'X-' */
if(Temp > 1 || (i != Float_Start && IS_DIGIT_SIGN(Parser->Buffer[i])))
return FAILURE;
/* Increment the decimal count if one is found */
if(Parser->Buffer[i] == '.')
Temp++;
}
}
/* Null terminate the buffer passed the end of the float (preserving its
previous value in Temp */
Temp = Parser->Buffer[Parser->Buffer_Index];
Parser->Buffer[Parser->Buffer_Index] = '\0';
/* Convert the float within the buffer then restore the buffer and return */
*Target = atof(&Parser->Buffer[Float_Start]);
Parser->Buffer[Parser->Buffer_Index] = Temp;
return SUCCESS;
}
/*
---------------------------------------------------------------------------------------------------------------------------------------------------[]