2023-08-28 20:46:50 -07:00
|
|
|
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
2023-08-21 17:30:13 -07:00
|
|
|
#pragma once
|
2023-08-21 20:02:20 -07:00
|
|
|
#include "interface.parsing.cpp"
|
2023-08-28 20:46:50 -07:00
|
|
|
#endif
|
2023-08-21 17:30:13 -07:00
|
|
|
|
2024-10-27 15:58:37 -07:00
|
|
|
ssize token_fmt_va( char* buf, usize buf_size, s32 num_tokens, va_list va )
|
2023-07-24 14:45:27 -07:00
|
|
|
{
|
|
|
|
char const* buf_begin = buf;
|
2024-11-30 22:39:21 -08:00
|
|
|
ssize remaining = buf_size;
|
2023-07-24 14:45:27 -07:00
|
|
|
|
2024-12-13 16:16:52 -08:00
|
|
|
local_persist StringTable tok_map;
|
|
|
|
do_once() {
|
|
|
|
tok_map = hashtable_init(Str, _ctx->Allocator_DyanmicContainers );
|
|
|
|
}
|
|
|
|
// Populate token pairs
|
2023-07-24 14:45:27 -07:00
|
|
|
{
|
|
|
|
s32 left = num_tokens - 1;
|
|
|
|
|
|
|
|
while ( left-- )
|
|
|
|
{
|
|
|
|
char const* token = va_arg( va, char const* );
|
2024-12-13 16:16:52 -08:00
|
|
|
Str value = va_arg( va, Str );
|
2023-07-24 14:45:27 -07:00
|
|
|
|
2024-12-12 09:55:15 -08:00
|
|
|
u32 key = crc32( token, c_str_len(token) );
|
2024-12-04 21:40:51 -08:00
|
|
|
hashtable_set( tok_map, key, value );
|
2023-07-24 14:45:27 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
char const* fmt = va_arg( va, char const* );
|
|
|
|
char current = *fmt;
|
|
|
|
|
|
|
|
while ( current )
|
|
|
|
{
|
2024-10-27 15:58:37 -07:00
|
|
|
ssize len = 0;
|
2023-07-24 14:45:27 -07:00
|
|
|
|
|
|
|
while ( current && current != '<' && remaining )
|
|
|
|
{
|
|
|
|
* buf = * fmt;
|
|
|
|
buf++;
|
|
|
|
fmt++;
|
|
|
|
remaining--;
|
|
|
|
|
|
|
|
current = * fmt;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( current == '<' )
|
|
|
|
{
|
|
|
|
char const* scanner = fmt + 1;
|
|
|
|
|
|
|
|
s32 tok_len = 0;
|
|
|
|
|
|
|
|
while ( *scanner != '>' )
|
|
|
|
{
|
|
|
|
tok_len++;
|
|
|
|
scanner++;
|
|
|
|
}
|
|
|
|
|
|
|
|
char const* token = fmt + 1;
|
|
|
|
|
|
|
|
u32 key = crc32( token, tok_len );
|
2024-12-12 09:55:15 -08:00
|
|
|
Str* value = hashtable_get(tok_map, key );
|
2023-07-24 14:45:27 -07:00
|
|
|
|
|
|
|
if ( value )
|
|
|
|
{
|
2024-10-27 15:58:37 -07:00
|
|
|
ssize left = value->Len;
|
2023-07-24 14:45:27 -07:00
|
|
|
char const* str = value->Ptr;
|
|
|
|
|
|
|
|
while ( left-- )
|
|
|
|
{
|
|
|
|
* buf = * str;
|
|
|
|
buf++;
|
|
|
|
str++;
|
|
|
|
remaining--;
|
|
|
|
}
|
|
|
|
|
|
|
|
scanner++;
|
|
|
|
fmt = scanner;
|
|
|
|
current = * fmt;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
* buf = * fmt;
|
|
|
|
buf++;
|
|
|
|
fmt++;
|
|
|
|
remaining--;
|
|
|
|
|
|
|
|
current = * fmt;
|
|
|
|
}
|
|
|
|
}
|
2024-12-04 21:40:51 -08:00
|
|
|
hashtable_clear(tok_map);
|
2024-10-27 15:58:37 -07:00
|
|
|
ssize result = buf_size - remaining;
|
2023-07-24 14:45:27 -07:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2024-12-12 09:55:15 -08:00
|
|
|
Code untyped_str( Str content )
|
2023-07-24 14:45:27 -07:00
|
|
|
{
|
2023-08-01 11:02:54 -07:00
|
|
|
if ( content.Len == 0 )
|
|
|
|
{
|
|
|
|
log_failure( "untyped_str: empty string" );
|
2024-12-01 21:03:38 -08:00
|
|
|
return InvalidCode;
|
2023-08-01 11:02:54 -07:00
|
|
|
}
|
|
|
|
|
2023-07-24 14:45:27 -07:00
|
|
|
Code
|
2023-07-24 17:59:20 -07:00
|
|
|
result = make_code();
|
2024-12-13 16:16:52 -08:00
|
|
|
result->Name = cache_str( content );
|
2024-12-03 12:19:39 -08:00
|
|
|
result->Type = CT_Untyped;
|
2023-07-24 14:45:27 -07:00
|
|
|
result->Content = result->Name;
|
|
|
|
|
2024-12-09 20:19:19 -08:00
|
|
|
if ( result->Name.Len == 0 )
|
2023-08-01 11:02:54 -07:00
|
|
|
{
|
|
|
|
log_failure( "untyped_str: could not cache string" );
|
2024-12-01 21:03:38 -08:00
|
|
|
return InvalidCode;
|
2023-08-01 11:02:54 -07:00
|
|
|
}
|
|
|
|
|
2023-07-24 14:45:27 -07:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
Code untyped_fmt( char const* fmt, ...)
|
|
|
|
{
|
2023-08-01 11:02:54 -07:00
|
|
|
if ( fmt == nullptr )
|
|
|
|
{
|
|
|
|
log_failure( "untyped_fmt: null format string" );
|
2024-12-01 21:03:38 -08:00
|
|
|
return InvalidCode;
|
2023-08-01 11:02:54 -07:00
|
|
|
}
|
|
|
|
|
2023-07-24 14:45:27 -07:00
|
|
|
local_persist thread_local
|
2023-07-24 17:59:20 -07:00
|
|
|
char buf[GEN_PRINTF_MAXLEN] = { 0 };
|
2023-07-24 14:45:27 -07:00
|
|
|
|
|
|
|
va_list va;
|
|
|
|
va_start(va, fmt);
|
2024-12-12 09:55:15 -08:00
|
|
|
ssize length = c_str_fmt_va(buf, GEN_PRINTF_MAXLEN, fmt, va);
|
2023-07-24 14:45:27 -07:00
|
|
|
va_end(va);
|
2024-12-13 16:16:52 -08:00
|
|
|
Str content = { buf, length };
|
2024-12-09 20:19:19 -08:00
|
|
|
|
2023-07-24 14:45:27 -07:00
|
|
|
Code
|
2023-07-24 17:59:20 -07:00
|
|
|
result = make_code();
|
2024-12-03 12:19:39 -08:00
|
|
|
result->Type = CT_Untyped;
|
2024-12-13 16:16:52 -08:00
|
|
|
result->Content = cache_str( content );
|
2023-07-24 14:45:27 -07:00
|
|
|
|
2024-12-09 20:19:19 -08:00
|
|
|
if ( result->Name.Len == 0 )
|
2023-08-01 11:02:54 -07:00
|
|
|
{
|
|
|
|
log_failure( "untyped_fmt: could not cache string" );
|
2024-12-01 21:03:38 -08:00
|
|
|
return InvalidCode;
|
2023-08-01 11:02:54 -07:00
|
|
|
}
|
|
|
|
|
2023-07-24 14:45:27 -07:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2024-12-09 20:19:19 -08:00
|
|
|
Code untyped_token_fmt( s32 num_tokens, char const* fmt, ... )
|
2023-07-24 14:45:27 -07:00
|
|
|
{
|
2023-08-01 11:02:54 -07:00
|
|
|
if ( num_tokens == 0 )
|
|
|
|
{
|
|
|
|
log_failure( "untyped_token_fmt: zero tokens" );
|
2024-12-01 21:03:38 -08:00
|
|
|
return InvalidCode;
|
2023-08-01 11:02:54 -07:00
|
|
|
}
|
|
|
|
|
2023-07-24 14:45:27 -07:00
|
|
|
local_persist thread_local
|
2023-07-24 17:59:20 -07:00
|
|
|
char buf[GEN_PRINTF_MAXLEN] = { 0 };
|
2023-07-24 14:45:27 -07:00
|
|
|
|
|
|
|
va_list va;
|
2024-12-09 20:19:19 -08:00
|
|
|
va_start(va, fmt);
|
2024-10-27 15:58:37 -07:00
|
|
|
ssize length = token_fmt_va(buf, GEN_PRINTF_MAXLEN, num_tokens, va);
|
2023-07-24 14:45:27 -07:00
|
|
|
va_end(va);
|
|
|
|
|
2024-12-13 10:20:16 -08:00
|
|
|
Str buf_str = { buf, length };
|
2024-12-09 20:19:19 -08:00
|
|
|
|
2023-07-24 14:45:27 -07:00
|
|
|
Code
|
2023-07-24 17:59:20 -07:00
|
|
|
result = make_code();
|
2024-12-03 12:19:39 -08:00
|
|
|
result->Type = CT_Untyped;
|
2024-12-13 16:16:52 -08:00
|
|
|
result->Content = cache_str( buf_str );
|
2023-07-24 14:45:27 -07:00
|
|
|
|
2024-12-09 20:19:19 -08:00
|
|
|
if ( result->Name.Len == 0 )
|
2023-08-01 11:02:54 -07:00
|
|
|
{
|
|
|
|
log_failure( "untyped_fmt: could not cache string" );
|
2024-12-01 21:03:38 -08:00
|
|
|
return InvalidCode;
|
2023-08-01 11:02:54 -07:00
|
|
|
}
|
|
|
|
|
2023-07-24 14:45:27 -07:00
|
|
|
return result;
|
|
|
|
}
|