|
|
@ -1,268 +0,0 @@ |
|
|
|
#include "samd51j18a.h" |
|
|
|
#include "stdarg.h" |
|
|
|
#include "spfssf.h" |
|
|
|
#include "usb_util.h" |
|
|
|
|
|
|
|
int vspf(char *_Dest, const char *_Format, va_list va) |
|
|
|
{ |
|
|
|
//va_list va; //Variable argument list variable |
|
|
|
char *d = _Dest; //Pointer to dest |
|
|
|
|
|
|
|
//va_start(va,_Format); //Initialize the variable argument list |
|
|
|
while (*_Format) //While not end of format string |
|
|
|
{ |
|
|
|
if (*_Format == SPF_SPEC_START) //If current format string character is the specifier start character |
|
|
|
{ |
|
|
|
_Format++; //Skip over the character |
|
|
|
while (*_Format && *_Format <= 64) _Format++; //Forward past any options |
|
|
|
if (*_Format == SPF_SPEC_START) *d++ = *_Format; //If the character is the specifier start character, output the character and advance dest |
|
|
|
else if (*_Format == SPF_SPEC_LONG) //If the character is the long type |
|
|
|
{ |
|
|
|
_Format++; //Skip over the character |
|
|
|
if (*_Format == SPF_SPEC_DECIMAL) //If the character is the decimal type |
|
|
|
{ |
|
|
|
int64_t buf = va_arg(va,int64_t); //Get the next value from the va list |
|
|
|
//if (buf < 0) { *d++ = '-'; buf = -buf; } //If the given number is negative, add a negative sign to the dest and invert number |
|
|
|
//spf_uint2str_32_3t(&d,buf,32); //Perform the conversion |
|
|
|
d += UTIL_ltoa_radix(buf, d, 10); |
|
|
|
} |
|
|
|
else if (*_Format == SPF_SPEC_UNSIGNED) //If the character is the unsigned type |
|
|
|
{ |
|
|
|
uint64_t num = va_arg(va,uint64_t); //Get the next value from the va list |
|
|
|
//spf_uint2str_32_3t(&d,num,32); //Perform the conversion |
|
|
|
d += UTIL_ltoa_radix(num, d, 10); |
|
|
|
} |
|
|
|
else if (*_Format == SPF_SPEC_UHINT || *_Format == SPF_SPEC_UHINT_UP) //If the character is the unsigned type |
|
|
|
{ |
|
|
|
uint64_t buf = va_arg(va,uint64_t); //Get the next value from the va list |
|
|
|
//spf_uint2hex_32(&d,(unsigned long) buf); |
|
|
|
d += UTIL_ltoa_radix(buf, d, 16); |
|
|
|
} |
|
|
|
else //If the character was not a known type |
|
|
|
{ |
|
|
|
*d++ = SPF_SPEC_START; //Output the start specifier |
|
|
|
*d++ = SPF_SPEC_LONG; //Output the long type |
|
|
|
*d++ = *_Format; //Output the unknown type |
|
|
|
} |
|
|
|
} |
|
|
|
else if (*_Format == SPF_SPEC_DECIMAL) //If the character is the decimal type |
|
|
|
{ |
|
|
|
int buf = va_arg(va,int); //Get the next value from the va list |
|
|
|
//if (buf < 0) { *d++ = '-'; buf = -buf; } //If the given number is negative, add a negative sign to the dest and invert number |
|
|
|
//spf_uint2str_32_3t(&d,buf,16); //Perform the conversion |
|
|
|
d += UTIL_itoa(buf, d); |
|
|
|
} |
|
|
|
else if (*_Format == SPF_SPEC_INT) //If the character is the integer type |
|
|
|
{ |
|
|
|
int buf = va_arg(va,int); //Get the next value from the va list |
|
|
|
//if (buf < 0) { *d++ = '-'; buf = -buf; } //If the given number is negative, add a negative sign to the dest and inverted number |
|
|
|
//spf_uint2str_32_3t(&d,buf,16); //Perform the conversion |
|
|
|
d += UTIL_itoa(buf, d); |
|
|
|
} |
|
|
|
else if (*_Format == SPF_SPEC_UINT) //If the character is the unsigned integer type |
|
|
|
{ |
|
|
|
int buf = va_arg(va,int); //Get the next value from the va list |
|
|
|
//spf_uint2str_32_3t(&d,buf,16); //Perform the conversion |
|
|
|
d += UTIL_utoa(buf, d); |
|
|
|
} |
|
|
|
else if (*_Format == SPF_SPEC_STRING) //If the character is the string type |
|
|
|
{ |
|
|
|
char *buf = va_arg(va,char*); //Get the next value from the va list |
|
|
|
while (*buf) *d++ = *buf++; //Perform the conversion (simply output characters and adcance pointers) |
|
|
|
} |
|
|
|
else if (*_Format == SPF_SPEC_UHINT || *_Format == SPF_SPEC_UHINT_UP) //If the character is the short type |
|
|
|
{ |
|
|
|
int buf = va_arg(va,unsigned int); //Get the next value from the va list |
|
|
|
//spf_uint2hex_32(&d,(unsigned long) buf); //Perform the conversion |
|
|
|
d += UTIL_utoa(buf, d); |
|
|
|
} |
|
|
|
else //If the character type is unknown |
|
|
|
{ |
|
|
|
*d++ = SPF_SPEC_START; //Output the start specifier |
|
|
|
*d++ = *_Format; //Output the unknown type |
|
|
|
} |
|
|
|
} |
|
|
|
else *d++ = *_Format; //If the character is unknown, output it to dest and advance dest |
|
|
|
_Format++; //Advance the format buffer pointer to next character |
|
|
|
} |
|
|
|
//va_end(va); //End the variable argument list |
|
|
|
|
|
|
|
*d = '\0'; //Cap off the destination string with a zero |
|
|
|
|
|
|
|
return d - _Dest; //Return the length of the destintion buffer |
|
|
|
} |
|
|
|
|
|
|
|
int spf(char *_Dest, const char *_Format, ...) |
|
|
|
{ |
|
|
|
va_list va; //Variable argument list variable |
|
|
|
int result; |
|
|
|
|
|
|
|
va_start(va,_Format); //Initialize the variable argument list |
|
|
|
result = vspf(_Dest, _Format, va); |
|
|
|
va_end(va); |
|
|
|
return result; |
|
|
|
} |
|
|
|
|
|
|
|
//sscanf string to number (integer types) |
|
|
|
int64_t ssf_ston(const char **_Src, uint32_t count, uint32_t *conv_count) |
|
|
|
{ |
|
|
|
int64_t value = 0; //Return value accumulator |
|
|
|
uint32_t counter=count; //Counter to keep track of numbers converted |
|
|
|
const char* p; //Pointer to first non space character |
|
|
|
|
|
|
|
while (*(*_Src) == SSF_SKIP_SPACE) (*_Src)++; //Forward through the whitespace to next non whitespace |
|
|
|
|
|
|
|
p = (*_Src); //Set pointer to first non space character |
|
|
|
if (*p == '+' || *p == '-') (*_Src)++; //Skip over sign if any |
|
|
|
while (*(*_Src) >= ASCII_NUM_START && |
|
|
|
*(*_Src) <= ASCII_NUM_END && |
|
|
|
counter) //While the source character is a digit and counter is not zero |
|
|
|
{ |
|
|
|
value *= 10; //Multiply result by 10 to make room for next 1's place number |
|
|
|
value += *(*_Src)++ - ASCII_NUM_START; //Add source number to value |
|
|
|
counter--; //Decrement counter |
|
|
|
} |
|
|
|
if (counter - count == 0) return 0; //If no number conversion were performed, return 0 |
|
|
|
if (*p == '-') value = -value; //If the number given was negative, make the result negative |
|
|
|
|
|
|
|
if (conv_count) (*conv_count)++; //Increment the converted count |
|
|
|
return value; //Return the value |
|
|
|
} |
|
|
|
|
|
|
|
uint64_t ssf_hton(const char **_Src, uint32_t count,uint32_t *conv_count) |
|
|
|
{ |
|
|
|
int64_t value=0; //Return value accumulator |
|
|
|
uint32_t counter=count; //Counter to keep track of numbers converted |
|
|
|
//const char* p; //Pointer to first non space character |
|
|
|
char c; |
|
|
|
|
|
|
|
while (*(*_Src) == SSF_SKIP_SPACE) (*_Src)++; //Forward through the whitespace to next non whitespace |
|
|
|
|
|
|
|
//p = (*_Src); //Set pointer to first non space character |
|
|
|
|
|
|
|
while (counter) |
|
|
|
{ |
|
|
|
c = *(*_Src)++; |
|
|
|
if (c >= 'a' && c <= 'f') c -= ('a'-'A'); //toupper |
|
|
|
if (c < '0' || (c > '9' && c < 'A') || c > 'F') break; |
|
|
|
value *= 16; //Multiply result by 10 to make room for next 1's place number |
|
|
|
c = c - '0'; |
|
|
|
if (c > 9) c -= 7; |
|
|
|
value += c; //Add source number to value |
|
|
|
counter--; //Decrement counter |
|
|
|
} |
|
|
|
|
|
|
|
if (counter - count == 0) return 0; //If no number conversion were performed, return 0 |
|
|
|
//if (*p == '-') value = -value; //If the number given was negative, make the result negative |
|
|
|
|
|
|
|
if (conv_count) (*conv_count)++; //Increment the converted count |
|
|
|
return value; |
|
|
|
} |
|
|
|
|
|
|
|
//sscanf |
|
|
|
int ssf(const char *_Src, const char *_Format, ...) |
|
|
|
{ |
|
|
|
va_list va; //Variable argument list variable |
|
|
|
unsigned char looking_for=0; //Static char specified in format to be found in source |
|
|
|
uint32_t conv_count=0; //Count of conversions made |
|
|
|
|
|
|
|
va_start(va,_Format); //Initialize the variable argument list |
|
|
|
while (*_Format) //While the format string has not been fully read |
|
|
|
{ |
|
|
|
if (looking_for != 0) //If we are looking for a matching character in the source string |
|
|
|
{ |
|
|
|
while (*_Src != looking_for && *_Src) _Src++; //While the character is not found in the source string and not the end of the source |
|
|
|
// string, increment the pointer position |
|
|
|
if (*_Src == looking_for) _Src++; //If the character was found, step over it |
|
|
|
else break; //Else the end was reached and the scan is now invalid (Could not find static character) |
|
|
|
looking_for = 0; //Clear the looking for character |
|
|
|
} |
|
|
|
if (*_Format == SSF_SPEC_START) //If the current format character is the specifier start character |
|
|
|
{ |
|
|
|
_Format++; //Step over the specifier start character |
|
|
|
if (*_Format == SSF_SPEC_DECIMAL) //If the decimal specifier type is found |
|
|
|
{ |
|
|
|
int *value=va_arg(va,int*); //User given destination address |
|
|
|
//*value = (int)ssf_ston(&_Src,5,&conv_count); //Run conversion |
|
|
|
*value = (int)ssf_ston(&_Src,10,&conv_count); //Run conversion |
|
|
|
} |
|
|
|
else if (*_Format == SSF_SPEC_LONG) //If the long specifier type is found |
|
|
|
{ |
|
|
|
_Format++; //Skip over the specifier type |
|
|
|
if (*_Format == SSF_SPEC_DECIMAL) //If the decimal specifier type is found |
|
|
|
{ |
|
|
|
int64_t *value=va_arg(va,int64_t*); //User given destination address |
|
|
|
//*value = (int64_t)ssf_ston(&_Src,10,&conv_count); //Run conversion |
|
|
|
*value = (int64_t)ssf_ston(&_Src,19,&conv_count); //Run conversion |
|
|
|
} |
|
|
|
else if (*_Format == SSF_SPEC_UHINT) //If the decimal specifier type is found |
|
|
|
{ |
|
|
|
uint64_t *value=va_arg(va,uint64_t *); //User given destination address |
|
|
|
//*value = (uint64_t int)ssf_hton(&_Src,12,&conv_count); //Run conversion |
|
|
|
*value = (uint64_t)ssf_hton(&_Src,16,&conv_count); //Run conversion |
|
|
|
} |
|
|
|
} |
|
|
|
else if (*_Format == SSF_SPEC_SHORTINT) //If the short int specifier type is found |
|
|
|
{ |
|
|
|
_Format++; //Skip over the specifier type |
|
|
|
if (*_Format == SSF_SPEC_SHORTINT) //If the short int specifier type is found |
|
|
|
{ |
|
|
|
_Format++; //Skip over the specifier type |
|
|
|
if (*_Format == SSF_SPEC_DECIMAL) //If the decimal specifier type is found |
|
|
|
{ |
|
|
|
unsigned char *value=va_arg(va,unsigned char*); //User given destination address |
|
|
|
//*value = (unsigned char)ssf_ston(&_Src,3,&conv_count); //Run conversion |
|
|
|
*value = (unsigned char)ssf_ston(&_Src,5,&conv_count); //Run conversion |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
else if (*_Format == SSF_SPEC_STRING) //If the specifier type is string |
|
|
|
{ |
|
|
|
char *value=va_arg(va,char*); //User given destination address, max chars read pointer |
|
|
|
while (*_Src == SSF_SKIP_SPACE) _Src++; //Forward through the whitespace to next non whitespace |
|
|
|
while (*_Src != SSF_SKIP_SPACE && *_Src) *value++ = *_Src++; //While any character but space and not end of string and not end location, copy char to dest |
|
|
|
*value = 0; //Cap off the string pointer with zero |
|
|
|
conv_count++; //Increment the converted count |
|
|
|
} |
|
|
|
else if (*_Format == SSF_SPEC_VERSION) //If the specifier type is string |
|
|
|
{ |
|
|
|
char *value=va_arg(va,char*); //User given destination address, max chars read pointer |
|
|
|
while (*_Src == SSF_SKIP_SPACE) _Src++; //Forward through the whitespace to next non whitespace |
|
|
|
while (*_Src != SSF_DELIM_COMMA && *_Src) *value++ = *_Src++; //While any character but space and not end of string and not end location, copy char to dest |
|
|
|
*value = 0; //Cap off the string pointer with zero |
|
|
|
conv_count++; //Increment the converted count |
|
|
|
} |
|
|
|
else if (*_Format >= ASCII_NUM_START && *_Format <= ASCII_NUM_END) |
|
|
|
{ |
|
|
|
uint32_t len = (uint32_t)ssf_ston(&_Format,3,NULL); //Convert the given length |
|
|
|
if (*_Format == SSF_SPEC_STRING) //If the specifier type is string |
|
|
|
{ |
|
|
|
char *value=va_arg(va,char*),*e; //User given destination address, max chars read pointer |
|
|
|
while (*_Src == SSF_SKIP_SPACE) _Src++; //Forward through the whitespace to next non whitespace |
|
|
|
e = (char*)_Src+len; //Set a maximum length pointer location |
|
|
|
while (*_Src != SSF_SKIP_SPACE && *_Src && _Src != e) *value++ = *_Src++; //While any character but space and not end of string and not end location, copy char to dest |
|
|
|
*value = 0; //Cap off the string pointer with zero |
|
|
|
conv_count++; //Increment the converted count |
|
|
|
} |
|
|
|
else if (*_Format == SSF_SPEC_VERSION) //If the specifier type is string |
|
|
|
{ |
|
|
|
char *value=va_arg(va,char*),*e; //User given destination address, max chars read pointer |
|
|
|
while (*_Src == SSF_SKIP_SPACE) _Src++; //Forward through the whitespace to next non whitespace |
|
|
|
e = (char*)_Src+len; //Set a maximum length pointer location |
|
|
|
while (*_Src != SSF_DELIM_COMMA && *_Src && _Src != e) *value++ = *_Src++; //While any character but space and not end of string and not end location, copy char to dest |
|
|
|
*value = 0; //Cap off the string pointer with zero |
|
|
|
conv_count++; //Increment the converted count |
|
|
|
} |
|
|
|
} |
|
|
|
else if (*_Format == SSF_SPEC_START) looking_for = *_Format; //If another start specifier character is found, output a specifier character |
|
|
|
else break; //Scan is now invalid (Uknown type specified) |
|
|
|
} |
|
|
|
else if (*_Format == SSF_SKIP_SPACE) { } //If a space is found, ignore it |
|
|
|
else looking_for = *_Format; //If any other character is found, it is static and should be found in src as well |
|
|
|
_Format++; //Skip over current format character |
|
|
|
} |
|
|
|
|
|
|
|
va_end(va); //End the variable argument list |
|
|
|
return conv_count; //Return the number of conversions made |
|
|
|
} |
|
|
|
|