Write PoC simpler header generator code
This commit is contained in:
parent
cee2573b00
commit
95272e77ee
345
Code/Dqn.h
345
Code/Dqn.h
@ -1,6 +1,7 @@
|
||||
#if defined(DQN_IMPLEMENTATION)
|
||||
#define STB_SPRINTF_IMPLEMENTATION
|
||||
#endif
|
||||
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
//
|
||||
// NOTE: stb_sprintf
|
||||
@ -595,6 +596,179 @@ struct Dqn_StringBuilder
|
||||
isize string_len;
|
||||
};
|
||||
|
||||
template <size_t N>
|
||||
FILE_SCOPE char *Dqn_StringBuilder__GetWriteBufferAndUpdateUsage(Dqn_StringBuilder<N> *builder, usize size_required)
|
||||
{
|
||||
char *result = builder->fixed_mem + builder->fixed_mem_used;
|
||||
usize space = Dqn_ArrayCount(builder->fixed_mem) - builder->fixed_mem_used;
|
||||
usize *usage = &builder->fixed_mem_used;
|
||||
|
||||
if (builder->last_mem_buf)
|
||||
{
|
||||
Dqn_StringBuilderBuffer *last_buf = builder->last_mem_buf;
|
||||
result = last_buf->mem + last_buf->used;
|
||||
space = last_buf->size - last_buf->used;
|
||||
usage = &last_buf->used;
|
||||
}
|
||||
|
||||
if (space < size_required)
|
||||
{
|
||||
DQN_ASSERT(builder->my_malloc);
|
||||
if (!builder->my_malloc)
|
||||
return nullptr;
|
||||
|
||||
// NOTE: Need to allocate new buf
|
||||
usize allocation_size = sizeof(*builder->last_mem_buf) + DQN_MAX(size_required, DQN_STRING_BUILDER_MIN_MEM_BUF_ALLOC_SIZE);
|
||||
void *memory = builder->my_malloc(allocation_size);
|
||||
auto *new_buf = reinterpret_cast<Dqn_StringBuilderBuffer *>(memory);
|
||||
*new_buf = {};
|
||||
new_buf->mem = static_cast<char *>(memory) + sizeof(*new_buf);
|
||||
new_buf->size = allocation_size;
|
||||
result = new_buf->mem;
|
||||
usage = &new_buf->used;
|
||||
|
||||
if (builder->last_mem_buf)
|
||||
{
|
||||
builder->last_mem_buf->next = new_buf;
|
||||
}
|
||||
else
|
||||
{
|
||||
builder->next_mem_buf = new_buf;
|
||||
builder->last_mem_buf = new_buf;
|
||||
}
|
||||
}
|
||||
|
||||
if (size_required > 0 && *usage > 0 && result[-1] == 0)
|
||||
{
|
||||
// NOTE: Not first time writing into buffer using sprintf, sprintf always writes a null terminator, so we must
|
||||
// subtract one
|
||||
(*usage)--;
|
||||
result--;
|
||||
}
|
||||
|
||||
*usage += size_required;
|
||||
return result;
|
||||
}
|
||||
|
||||
template <usize N>
|
||||
FILE_SCOPE void Dqn_StringBuilder__BuildOutput(Dqn_StringBuilder<N> const *builder, char *dest, isize dest_size)
|
||||
{
|
||||
// NOTE: No data appended to builder, just allocate am empty string. But
|
||||
// always allocate, so we avoid adding making nullptr part of the possible
|
||||
// return values and makes using Dqn_StringBuilder more complex.
|
||||
if (dest_size == 1)
|
||||
{
|
||||
dest[0] = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
char const *end = dest + dest_size;
|
||||
char *buf_ptr = dest;
|
||||
|
||||
memcpy(buf_ptr, builder->fixed_mem, builder->fixed_mem_used);
|
||||
buf_ptr += builder->fixed_mem_used;
|
||||
|
||||
isize remaining_space = end - buf_ptr;
|
||||
DQN_ASSERT(remaining_space >= 0);
|
||||
|
||||
for (Dqn_StringBuilderBuffer *string_buf = builder->next_mem_buf;
|
||||
string_buf && remaining_space > 0;
|
||||
string_buf = string_buf->next)
|
||||
{
|
||||
buf_ptr--; // We always copy the null terminator from the buffers, so if we know we have another buffer to copy from, remove the null terminator
|
||||
memcpy(buf_ptr, string_buf->mem, string_buf->used);
|
||||
buf_ptr += string_buf->used;
|
||||
|
||||
remaining_space = end - buf_ptr;
|
||||
DQN_ASSERT(remaining_space >= 0);
|
||||
}
|
||||
DQN_ASSERT(buf_ptr == dest + dest_size);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
//
|
||||
// NOTE: String Builder
|
||||
//
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
DQN_HEADER_COPY_PROTOTYPE_AND_COMMENT(
|
||||
"The necessary length to build the string, it returns the length including the null-terminator",
|
||||
template <usize N> isize,
|
||||
Dqn_StringBuilder_BuildLen(Dqn_StringBuilder<N> const *builder))
|
||||
{
|
||||
isize result = builder->string_len + 1;
|
||||
return result;
|
||||
}
|
||||
|
||||
DQN_HEADER_COPY_PROTOTYPE(
|
||||
template <usize N> void,
|
||||
Dqn_StringBuilder_BuildInBuffer(Dqn_StringBuilder<N> const *builder, char *dest, usize dest_size))
|
||||
{
|
||||
Dqn_StringBuilder__BuildOutput(builder, dest, dest_size);
|
||||
}
|
||||
|
||||
// len: Return the length of the allocated string including the null-terminator
|
||||
template <usize N>
|
||||
char *Dqn_StringBuilder_BuildFromMalloc(Dqn_StringBuilder<N> *builder, isize *len = nullptr)
|
||||
{
|
||||
isize len_w_null_terminator = Dqn_StringBuilder_BuildLen(builder);
|
||||
auto *result = static_cast<char *>(malloc(len_w_null_terminator));
|
||||
if (len) *len = len_w_null_terminator;
|
||||
Dqn_StringBuilder__BuildOutput(builder, result, len_w_null_terminator);
|
||||
return result;
|
||||
}
|
||||
|
||||
template <usize N>
|
||||
char *Dqn_StringBuilder_BuildFromArena(Dqn_StringBuilder<N> *builder, Dqn_MemArena *arena, isize *len = nullptr)
|
||||
{
|
||||
isize len_w_null_terminator = Dqn_StringBuilder_BuildLen(builder);
|
||||
char *result = MEM_ARENA_ALLOC_ARRAY(arena, char, len_w_null_terminator);
|
||||
if (len) *len = len_w_null_terminator;
|
||||
Dqn_StringBuilder__BuildOutput(builder, result, len_w_null_terminator);
|
||||
return result;
|
||||
}
|
||||
|
||||
template <usize N>
|
||||
void Dqn_StringBuilder_VFmtAppend(Dqn_StringBuilder<N> *builder, char const *fmt, va_list va)
|
||||
{
|
||||
if (!fmt) return;
|
||||
isize require = stbsp_vsnprintf(nullptr, 0, fmt, va) + 1;
|
||||
char *buf = Dqn_StringBuilder__GetWriteBufferAndUpdateUsage(builder, require);
|
||||
stbsp_vsnprintf(buf, static_cast<int>(require), fmt, va);
|
||||
builder->string_len += (require - 1); // -1 to exclude null terminator
|
||||
}
|
||||
|
||||
template <usize N>
|
||||
void Dqn_StringBuilder_FmtAppend(Dqn_StringBuilder<N> *builder, char const *fmt, ...)
|
||||
{
|
||||
va_list va;
|
||||
va_start(va, fmt);
|
||||
Dqn_StringBuilder_VFmtAppend(builder, fmt, va);
|
||||
va_end(va);
|
||||
}
|
||||
|
||||
template <usize N>
|
||||
void Dqn_StringBuilder_Append(Dqn_StringBuilder<N> *builder, char const *str, isize len = -1)
|
||||
{
|
||||
if (!str) return;
|
||||
if (len == -1) len = (isize)strlen(str);
|
||||
isize len_w_null_terminator = len + 1;
|
||||
char *buf = Dqn_StringBuilder__GetWriteBufferAndUpdateUsage(builder, len_w_null_terminator);
|
||||
Dqn_MemCopy(buf, str, len);
|
||||
builder->string_len += len;
|
||||
buf[len] = 0;
|
||||
}
|
||||
|
||||
template <usize N>
|
||||
void Dqn_StringBuilder_AppendChar(Dqn_StringBuilder<N> *builder, char ch)
|
||||
{
|
||||
char *buf = Dqn_StringBuilder__GetWriteBufferAndUpdateUsage(builder, 1 + 1 /*null terminator*/);
|
||||
*buf++ = ch;
|
||||
builder->string_len++;
|
||||
buf[1] = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
//
|
||||
// NOTE: (Memory) Slices
|
||||
@ -1171,177 +1345,6 @@ Dqn_MemArenaScopedRegion::~Dqn_MemArenaScopedRegion()
|
||||
this->arena->curr_mem_block->used = this->curr_mem_block_used;
|
||||
}
|
||||
|
||||
template <size_t N>
|
||||
FILE_SCOPE char *Dqn_StringBuilder__GetWriteBufferAndUpdateUsage(Dqn_StringBuilder<N> *builder, usize size_required)
|
||||
{
|
||||
char *result = builder->fixed_mem + builder->fixed_mem_used;
|
||||
usize space = Dqn_ArrayCount(builder->fixed_mem) - builder->fixed_mem_used;
|
||||
usize *usage = &builder->fixed_mem_used;
|
||||
|
||||
if (builder->last_mem_buf)
|
||||
{
|
||||
Dqn_StringBuilderBuffer *last_buf = builder->last_mem_buf;
|
||||
result = last_buf->mem + last_buf->used;
|
||||
space = last_buf->size - last_buf->used;
|
||||
usage = &last_buf->used;
|
||||
}
|
||||
|
||||
if (space < size_required)
|
||||
{
|
||||
DQN_ASSERT(builder->my_malloc);
|
||||
if (!builder->my_malloc)
|
||||
return nullptr;
|
||||
|
||||
// NOTE: Need to allocate new buf
|
||||
usize allocation_size = sizeof(*builder->last_mem_buf) + DQN_MAX(size_required, DQN_STRING_BUILDER_MIN_MEM_BUF_ALLOC_SIZE);
|
||||
void *memory = builder->my_malloc(allocation_size);
|
||||
auto *new_buf = reinterpret_cast<Dqn_StringBuilderBuffer *>(memory);
|
||||
*new_buf = {};
|
||||
new_buf->mem = static_cast<char *>(memory) + sizeof(*new_buf);
|
||||
new_buf->size = allocation_size;
|
||||
result = new_buf->mem;
|
||||
usage = &new_buf->used;
|
||||
|
||||
if (builder->last_mem_buf)
|
||||
{
|
||||
builder->last_mem_buf->next = new_buf;
|
||||
}
|
||||
else
|
||||
{
|
||||
builder->next_mem_buf = new_buf;
|
||||
builder->last_mem_buf = new_buf;
|
||||
}
|
||||
}
|
||||
|
||||
if (size_required > 0 && *usage > 0 && result[-1] == 0)
|
||||
{
|
||||
// NOTE: Not first time writing into buffer using sprintf, sprintf always writes a null terminator, so we must
|
||||
// subtract one
|
||||
(*usage)--;
|
||||
result--;
|
||||
}
|
||||
|
||||
*usage += size_required;
|
||||
return result;
|
||||
}
|
||||
|
||||
template <usize N>
|
||||
FILE_SCOPE void Dqn_StringBuilder__BuildOutput(Dqn_StringBuilder<N> const *builder, char *dest, isize dest_size)
|
||||
{
|
||||
// NOTE: No data appended to builder, just allocate am empty string. But
|
||||
// always allocate, so we avoid adding making nullptr part of the possible
|
||||
// return values and makes using Dqn_StringBuilder more complex.
|
||||
if (dest_size == 1)
|
||||
{
|
||||
dest[0] = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
char const *end = dest + dest_size;
|
||||
char *buf_ptr = dest;
|
||||
|
||||
memcpy(buf_ptr, builder->fixed_mem, builder->fixed_mem_used);
|
||||
buf_ptr += builder->fixed_mem_used;
|
||||
|
||||
isize remaining_space = end - buf_ptr;
|
||||
DQN_ASSERT(remaining_space >= 0);
|
||||
|
||||
for (Dqn_StringBuilderBuffer *string_buf = builder->next_mem_buf;
|
||||
string_buf && remaining_space > 0;
|
||||
string_buf = string_buf->next)
|
||||
{
|
||||
buf_ptr--; // We always copy the null terminator from the buffers, so if we know we have another buffer to copy from, remove the null terminator
|
||||
memcpy(buf_ptr, string_buf->mem, string_buf->used);
|
||||
buf_ptr += string_buf->used;
|
||||
|
||||
remaining_space = end - buf_ptr;
|
||||
DQN_ASSERT(remaining_space >= 0);
|
||||
}
|
||||
DQN_ASSERT(buf_ptr == dest + dest_size);
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
//
|
||||
// NOTE: String Builder
|
||||
//
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
// The necessary length to build the string, it returns the length including the null-terminator
|
||||
template <usize N>
|
||||
isize Dqn_StringBuilder_BuildLen(Dqn_StringBuilder<N> const *builder)
|
||||
{
|
||||
isize result = builder->string_len + 1;
|
||||
return result;
|
||||
}
|
||||
|
||||
template <usize N>
|
||||
void Dqn_StringBuilder_BuildInBuffer(Dqn_StringBuilder<N> const *builder, char *dest, usize dest_size)
|
||||
{
|
||||
Dqn_StringBuilder__BuildOutput(builder, dest, dest_size);
|
||||
}
|
||||
|
||||
// len: Return the length of the allocated string including the null-terminator
|
||||
template <usize N>
|
||||
char *Dqn_StringBuilder_BuildFromMalloc(Dqn_StringBuilder<N> *builder, isize *len = nullptr)
|
||||
{
|
||||
isize len_w_null_terminator = Dqn_StringBuilder_BuildLen(builder);
|
||||
auto *result = static_cast<char *>(malloc(len_w_null_terminator));
|
||||
if (len) *len = len_w_null_terminator;
|
||||
Dqn_StringBuilder__BuildOutput(builder, result, len_w_null_terminator);
|
||||
return result;
|
||||
}
|
||||
|
||||
template <usize N>
|
||||
char *Dqn_StringBuilder_BuildFromArena(Dqn_StringBuilder<N> *builder, Dqn_MemArena *arena, isize *len = nullptr)
|
||||
{
|
||||
isize len_w_null_terminator = Dqn_StringBuilder_BuildLen(builder);
|
||||
char *result = MEM_ARENA_ALLOC_ARRAY(arena, char, len_w_null_terminator);
|
||||
if (len) *len = len_w_null_terminator;
|
||||
Dqn_StringBuilder__BuildOutput(builder, result, len_w_null_terminator);
|
||||
return result;
|
||||
}
|
||||
|
||||
template <usize N>
|
||||
void Dqn_StringBuilder_VFmtAppend(Dqn_StringBuilder<N> *builder, char const *fmt, va_list va)
|
||||
{
|
||||
if (!fmt) return;
|
||||
isize require = stbsp_vsnprintf(nullptr, 0, fmt, va) + 1;
|
||||
char *buf = Dqn_StringBuilder__GetWriteBufferAndUpdateUsage(builder, require);
|
||||
stbsp_vsnprintf(buf, static_cast<int>(require), fmt, va);
|
||||
builder->string_len += (require - 1); // -1 to exclude null terminator
|
||||
}
|
||||
|
||||
template <usize N>
|
||||
void Dqn_StringBuilder_FmtAppend(Dqn_StringBuilder<N> *builder, char const *fmt, ...)
|
||||
{
|
||||
va_list va;
|
||||
va_start(va, fmt);
|
||||
Dqn_StringBuilder_VFmtAppend(builder, fmt, va);
|
||||
va_end(va);
|
||||
}
|
||||
|
||||
template <usize N>
|
||||
void Dqn_StringBuilder_Append(Dqn_StringBuilder<N> *builder, char const *str, isize len = -1)
|
||||
{
|
||||
if (!str) return;
|
||||
if (len == -1) len = (isize)strlen(str);
|
||||
isize len_w_null_terminator = len + 1;
|
||||
char *buf = Dqn_StringBuilder__GetWriteBufferAndUpdateUsage(builder, len_w_null_terminator);
|
||||
Dqn_MemCopy(buf, str, len);
|
||||
builder->string_len += len;
|
||||
buf[len] = 0;
|
||||
}
|
||||
|
||||
template <usize N>
|
||||
void Dqn_StringBuilder_AppendChar(Dqn_StringBuilder<N> *builder, char ch)
|
||||
{
|
||||
char *buf = Dqn_StringBuilder__GetWriteBufferAndUpdateUsage(builder, 1 + 1 /*null terminator*/);
|
||||
*buf++ = ch;
|
||||
builder->string_len++;
|
||||
buf[1] = 0;
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
//
|
||||
// NOTE: Vectors
|
||||
|
@ -1,3 +1,7 @@
|
||||
#define DQN_HEADER_COPY_PROTOTYPE_AND_COMMENT(func_comment, func_return, func_name_and_types) func_return func_name_and_types
|
||||
#define DQN_HEADER_COPY_PROTOTYPE(func_return, func_name_and_types) func_return func_name_and_types
|
||||
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#include "Dqn.h"
|
||||
|
||||
struct TestState
|
||||
@ -417,10 +421,175 @@ FILE_SCOPE void UnitTests()
|
||||
}
|
||||
}
|
||||
|
||||
char *Dqn_ReadFileWithArena(Dqn_MemArena *arena, char const *file, isize *file_size)
|
||||
{
|
||||
FILE *file_handle = fopen(file, "rb");
|
||||
fseek(file_handle, 0, SEEK_END);
|
||||
usize file_size_ = ftell(file_handle);
|
||||
rewind(file_handle);
|
||||
|
||||
auto *result = (char *)MEM_ARENA_ALLOC(arena, file_size_ + 1);
|
||||
DQN_ASSERT(result);
|
||||
result[file_size_] = 0;
|
||||
|
||||
if (fread(result, file_size_, 1, file_handle) != 1)
|
||||
{
|
||||
fprintf(stderr, "Failed to fread: %zu bytes into buffer from file: %s\n", file_size_, file);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (file_size) *file_size = file_size_;
|
||||
return result;
|
||||
}
|
||||
|
||||
char *Dqn_StrFind(char *buf, char const *find, isize buf_len = -1, isize find_len = -1)
|
||||
{
|
||||
if (find_len == 0) return nullptr;
|
||||
if (buf_len < 0) buf_len = (isize)strlen(buf);
|
||||
if (find_len < 0) find_len = (isize)strlen(find);
|
||||
|
||||
char *buf_end = buf + buf_len;
|
||||
char *result = nullptr;
|
||||
for (; *buf; ++buf)
|
||||
{
|
||||
isize remaining = static_cast<isize>(buf_end - buf);
|
||||
if (remaining < find_len) break;
|
||||
|
||||
if (strncmp(buf, find, find_len) == 0)
|
||||
{
|
||||
result = buf;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
char *Dqn_StrSkipWhitespace(char *buf)
|
||||
{
|
||||
while (buf && (buf[0] == '\r' || buf[0] == '\t' || buf[0] == '\n' || buf[0] == ' '))
|
||||
buf++;
|
||||
return buf;
|
||||
}
|
||||
|
||||
char *ParseFunctionReturnType(char *ptr, isize *len)
|
||||
{
|
||||
char *result = ptr;
|
||||
isize result_len = 0;
|
||||
for (int scope = 0; ptr; ptr++) // NOTE: Parse the function return type
|
||||
{
|
||||
if (ptr[0] == '<' || ptr[0] == '>')
|
||||
{
|
||||
if (ptr[0] == '<') scope++;
|
||||
else scope--;
|
||||
continue;
|
||||
}
|
||||
else if (ptr[0] == ',')
|
||||
{
|
||||
if (scope != 0) continue;
|
||||
result_len = static_cast<int>(ptr - result);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (len) *len = result_len;
|
||||
return result;
|
||||
}
|
||||
|
||||
char *ParseFunctionNameAndParameters(char *ptr, isize *len)
|
||||
{
|
||||
char *result = ptr;
|
||||
int result_len = 0;
|
||||
for (int scope = 0; ptr; ptr++) // NOTE: Parse the function name and parameters
|
||||
{
|
||||
if (ptr[0] == '(') scope++;
|
||||
else if (ptr[0] == ')')
|
||||
{
|
||||
if (scope-- != 0) continue;
|
||||
result_len = static_cast<int>(ptr - result);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
*len = result_len;
|
||||
return result;
|
||||
}
|
||||
|
||||
char *ParseFunctionComment(char *ptr, isize *len)
|
||||
{
|
||||
while (ptr[0] != '"') ptr++;
|
||||
ptr++;
|
||||
|
||||
char *result = ptr;
|
||||
isize result_len = 0;
|
||||
for (;;)
|
||||
{
|
||||
while (ptr[0] != '"')
|
||||
ptr++;
|
||||
|
||||
if (ptr[-1] != '\\')
|
||||
{
|
||||
result_len = ptr - result;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
*len = result_len;
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
int main(char *argv[], int argc)
|
||||
{
|
||||
(void)argv; (void)argc;
|
||||
UnitTests();
|
||||
|
||||
Dqn_MemArena arena = {};
|
||||
isize buf_size = 0;
|
||||
char *buf = Dqn_ReadFileWithArena(&arena, "../Code/Dqn.h", &buf_size);
|
||||
if (!buf)
|
||||
return -1;
|
||||
|
||||
char constexpr HEADER_COPY_PROTOTYPE[] = "DQN_HEADER_COPY_PROTOTYPE";
|
||||
char constexpr HEADER_COPY_PROTOTYPE_AND_COMMENT[] = "DQN_HEADER_COPY_PROTOTYPE_AND_COMMENT";
|
||||
|
||||
char *ptr = buf;
|
||||
char *ptr_end = buf + buf_size;
|
||||
isize ptr_len = buf_size;
|
||||
for (char *token = Dqn_StrFind(ptr, HEADER_COPY_PROTOTYPE, ptr_len, Dqn_CharCountI(HEADER_COPY_PROTOTYPE));
|
||||
token;
|
||||
ptr_len = ptr_end - ptr, token = Dqn_StrFind(ptr, HEADER_COPY_PROTOTYPE, ptr_len))
|
||||
{
|
||||
ptr = token;
|
||||
bool prototype_and_comment = (strncmp(token, HEADER_COPY_PROTOTYPE_AND_COMMENT, Dqn_CharCountI(HEADER_COPY_PROTOTYPE_AND_COMMENT)) == 0);
|
||||
if (prototype_and_comment)
|
||||
{
|
||||
ptr += Dqn_CharCount(HEADER_COPY_PROTOTYPE_AND_COMMENT) + 1 /*macro start parenthesis*/;
|
||||
|
||||
isize comment_len = 0;
|
||||
char *comment = ParseFunctionComment(ptr, &comment_len);
|
||||
ptr = comment + comment_len;
|
||||
while (ptr[0] != ',') ptr++;
|
||||
ptr++;
|
||||
|
||||
fprintf(stdout, "%.*s", (int)comment_len, comment);
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr += Dqn_CharCount(HEADER_COPY_PROTOTYPE) + 1 /*macro start parenthesis*/;
|
||||
}
|
||||
|
||||
isize func_type_len = 0;
|
||||
char *func_type = ParseFunctionReturnType(ptr, &func_type_len);
|
||||
|
||||
ptr = func_type + func_type_len + 1; // Ptr is at macro comma, skip the comma
|
||||
ptr = Dqn_StrSkipWhitespace(ptr);
|
||||
isize func_name_len = 0;
|
||||
char *func_name = ParseFunctionNameAndParameters(ptr, &func_name_len);
|
||||
|
||||
ptr = func_name + func_name_len + 1; // Ptr is at macro closing paren, skip the paren
|
||||
fprintf(stdout, "%.*s %.*s", (int)func_type_len, func_type, (int)func_name_len, func_name);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user