gencpp/project/dependencies/string_ops.cpp
Ed_ 5d7dfaf666 Heavy refactor..
Isolating large macros to their own directory (components/temp).
- Plan is to remove them soon with proper generation.

Added additional component files, separating the old data_structures header for a set of ast headers.
Header_end also had its inlines extracted out.
Necessary to complete the macro isolation.

ZPL parser dependencies were removed from the core library along with builder, its now generated in bootstrap as pare of making a gen_builder set of files.

Singleheader will be changed in next few commits to reflect this as well (By making builder deps and components a conditional option).

Tests are most likely all broken for now.
2023-08-03 11:01:43 -04:00

211 lines
3.0 KiB
C++

#pragma region String Ops
internal
sw _scan_zpl_i64( const char* text, s32 base, s64* value )
{
const char* text_begin = text;
s64 result = 0;
b32 negative = false;
if ( *text == '-' )
{
negative = true;
text++;
}
if ( base == 16 && str_compare( text, "0x", 2 ) == 0 )
text += 2;
for ( ;; )
{
s64 v;
if ( char_is_digit( *text ) )
v = *text - '0';
else if ( base == 16 && char_is_hex_digit( *text ) )
v = hex_digit_to_int( *text );
else
break;
result *= base;
result += v;
text++;
}
if ( value )
{
if ( negative )
result = -result;
*value = result;
}
return ( text - text_begin );
}
// TODO : Are these good enough for characters?
global const char _num_to_char_table[] =
"0123456789"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"@$";
s64 str_to_i64( const char* str, char** end_ptr, s32 base )
{
sw len;
s64 value;
if ( ! base )
{
if ( ( str_len( str ) > 2 ) && ( str_compare( str, "0x", 2 ) == 0 ) )
base = 16;
else
base = 10;
}
len = _scan_zpl_i64( str, base, &value );
if ( end_ptr )
*end_ptr = ( char* )str + len;
return value;
}
void i64_to_str( s64 value, char* string, s32 base )
{
char* buf = string;
b32 negative = false;
u64 v;
if ( value < 0 )
{
negative = true;
value = -value;
}
v = zpl_cast( u64 ) value;
if ( v != 0 )
{
while ( v > 0 )
{
*buf++ = _num_to_char_table[ v % base ];
v /= base;
}
}
else
{
*buf++ = '0';
}
if ( negative )
*buf++ = '-';
*buf = '\0';
str_reverse( string );
}
void u64_to_str( u64 value, char* string, s32 base )
{
char* buf = string;
if ( value )
{
while ( value > 0 )
{
*buf++ = _num_to_char_table[ value % base ];
value /= base;
}
}
else
{
*buf++ = '0';
}
*buf = '\0';
str_reverse( string );
}
f64 str_to_f64( const char* str, char** end_ptr )
{
f64 result, value, sign, scale;
s32 frac;
while ( char_is_space( *str ) )
{
str++;
}
sign = 1.0;
if ( *str == '-' )
{
sign = -1.0;
str++;
}
else if ( *str == '+' )
{
str++;
}
for ( value = 0.0; char_is_digit( *str ); str++ )
{
value = value * 10.0 + ( *str - '0' );
}
if ( *str == '.' )
{
f64 pow10 = 10.0;
str++;
while ( char_is_digit( *str ) )
{
value += ( *str - '0' ) / pow10;
pow10 *= 10.0;
str++;
}
}
frac = 0;
scale = 1.0;
if ( ( *str == 'e' ) || ( *str == 'E' ) )
{
u32 exp;
str++;
if ( *str == '-' )
{
frac = 1;
str++;
}
else if ( *str == '+' )
{
str++;
}
for ( exp = 0; char_is_digit( *str ); str++ )
{
exp = exp * 10 + ( *str - '0' );
}
if ( exp > 308 )
exp = 308;
while ( exp >= 50 )
{
scale *= 1e50;
exp -= 50;
}
while ( exp >= 8 )
{
scale *= 1e8;
exp -= 8;
}
while ( exp > 0 )
{
scale *= 10.0;
exp -= 1;
}
}
result = sign * ( frac ? ( value / scale ) : ( value * scale ) );
if ( end_ptr )
*end_ptr = zpl_cast( char* ) str;
return result;
}
#pragma endregion String Ops