Some refactors (see description)

- Renamed macro gen_time to GEN_TIME
- Moved scanner and editor to their own headers, I'm going to consider them extensions.
- I'm preparing to setup the library to build on multiple compiler platforms: clang, gcc, msvc.
This commit is contained in:
Edward R. Gonzalez 2023-07-18 23:33:00 -04:00
parent e501941c5c
commit 231ae5f5d6
12 changed files with 5079 additions and 4717 deletions

View File

@ -9,7 +9,7 @@
"_DEBUG",
"UNICODE",
"_UNICODE",
"gen_time"
"GEN_TIME"
],
"windowsSdkVersion": "10.0.19041.0",
"compilerPath": "C:/Users/Ed/scoop/apps/llvm/current/bin/clang++.exe",

View File

@ -1,10 +1,15 @@
// ReSharper disable CppClangTidyClangDiagnosticSwitchEnum
#ifdef gen_time
#if ! defined(GEN_DONT_ENFORCE_GEN_TIME_GUARD) && ! defined(GEN_TIME)
#error Gen.hpp : GEN_TIME not defined
#endif
#include "gen.push_ignores.inline.hpp"
//! If its desired to roll your own dependencies, define GEN_ROLL_OWN_DEPENDENCIES before including this file.
//! Dependencies are derived from the c-zpl library: https://github.com/zpl-c/zpl
#ifndef GEN_ROLL_OWN_DEPENDENCIES
# include "gen_dep.cpp"
# include "gen.dep.cpp"
#endif
#include "gen.hpp"
@ -753,7 +758,7 @@ namespace gen
if ( NumEntries - 1 > 0)
{
for ( CodeParam param : (CodeParam){ (AST_Param*)Next } )
for ( CodeParam param : CodeParam { (AST_Param*) Next } )
{
result.append_fmt( ", %s", param.to_string() );
}
@ -6536,16 +6541,6 @@ namespace gen
Buffer.free();
}
#pragma endregion Builder
#pragma region Editor
#ifdef GEN_FEATURE_EDITOR
#endif
#pragma endregion Editor
#pragma region Scanner
#ifdef GEN_FEATURE_SCANNER
#endif
#pragma endregion Scanner
}
// End: gen_time
#endif
#include "gen.pop_ignores.inline.hpp"

View File

@ -1,6 +1,5 @@
#include "gen_dep.hpp"
#ifdef gen_time
// This file is intended to be included within gen.cpp (There is no pragma diagnostic ignores)
#include "gen.dep.hpp"
// NOTE: Ensure we use standard methods for these calls if we use GEN_PICO
#pragma region Macros & Includes
@ -39,7 +38,6 @@
# undef VC_EXTRALEAN
# endif
# endif
#pragma endregion Macros & Includes
#ifdef GEN_BENCHMARK
// Timing includes
@ -62,9 +60,12 @@
# include <timezoneapi.h>
#endif
#endif
#pragma endregion Macros & Includes
namespace gen {
namespace gen
{
#pragma region Debug
void assert_handler( char const* condition, char const* file, s32 line, char const* msg, ... )
{
@ -2048,7 +2049,279 @@ namespace gen
#pragma endregion ADT
#pragma region CSV
#ifdef GEN_CSV_DEBUG
# define GEN_CSV_ASSERT( msg ) GEN_PANIC( msg )
#else
# define GEN_CSV_ASSERT( msg )
#endif
u8 csv_parse_delimiter( CSV_Object* root, char* text, AllocatorInfo allocator, b32 has_header, char delim )
{
CSV_Error err = ECSV_Error__NONE;
GEN_ASSERT_NOT_NULL( root );
GEN_ASSERT_NOT_NULL( text );
zero_item( root );
adt_make_branch( root, allocator, NULL, has_header ? false : true );
char *p = text, *b = p, *e = p;
sw colc = 0, total_colc = 0;
do
{
char d = 0;
p = zpl_cast( char* ) str_trim( p, false );
if ( *p == 0 )
break;
ADT_Node row_item = { 0 };
row_item.type = EADT_TYPE_STRING;
#ifndef ZPL_PARSER_DISABLE_ANALYSIS
row_item.name_style = EADT_NAME_STYLE_NO_QUOTES;
#endif
/* handle string literals */
if ( *p == '"' )
{
p = b = e = p + 1;
row_item.string = b;
#ifndef ZPL_PARSER_DISABLE_ANALYSIS
row_item.name_style = EADT_NAME_STYLE_DOUBLE_QUOTE;
#endif
do
{
e = zpl_cast( char* ) str_skip( e, '"' );
if ( *e && *( e + 1 ) == '"' )
{
e += 2;
}
else
break;
} while ( *e );
if ( *e == 0 )
{
GEN_CSV_ASSERT( "unmatched quoted string" );
err = ECSV_Error__UNEXPECTED_END_OF_INPUT;
return err;
}
*e = 0;
p = zpl_cast( char* ) str_trim( e + 1, true );
d = *p;
/* unescape escaped quotes (so that unescaped text escapes :) */
{
char* ep = b;
do
{
if ( *ep == '"' && *( ep + 1 ) == '"' )
{
mem_move( ep, ep + 1, str_len( ep ) );
}
ep++;
} while ( *ep );
}
}
else if ( *p == delim )
{
d = *p;
row_item.string = "";
}
else if ( *p )
{
/* regular data */
b = e = p;
row_item.string = b;
do
{
e++;
} while ( *e && *e != delim && *e != '\n' );
if ( *e )
{
p = zpl_cast( char* ) str_trim( e, true );
while ( char_is_space( *( e - 1 ) ) )
{
e--;
}
d = *p;
*e = 0;
}
else
{
d = 0;
p = e;
}
/* check if number and process if so */
b32 skip_number = false;
char* num_p = b;
do
{
if ( ! char_is_hex_digit( *num_p ) && ( ! str_find( "+-.eExX", *num_p ) ) )
{
skip_number = true;
break;
}
} while ( *num_p++ );
if ( ! skip_number )
{
adt_str_to_number( &row_item );
}
}
if ( colc >= root->nodes.num() )
{
adt_append_arr( root, NULL );
}
root->nodes[ colc ].nodes.append( row_item );
if ( d == delim )
{
colc++;
p++;
}
else if ( d == '\n' || d == 0 )
{
/* check if number of rows is not mismatched */
if ( total_colc < colc )
total_colc = colc;
else if ( total_colc != colc )
{
GEN_CSV_ASSERT( "mismatched rows" );
err = ECSV_Error__MISMATCHED_ROWS;
return err;
}
colc = 0;
if ( d != 0 )
p++;
}
} while ( *p );
if ( root->nodes.num() == 0 )
{
GEN_CSV_ASSERT( "unexpected end of input. stream is empty." );
err = ECSV_Error__UNEXPECTED_END_OF_INPUT;
return err;
}
/* consider first row as a header. */
if ( has_header )
{
for ( sw i = 0; i < root->nodes.num(); i++ )
{
CSV_Object* col = root->nodes + i;
CSV_Object* hdr = col->nodes;
col->name = hdr->string;
col->nodes.remove_at( 0 );
}
}
return err;
}
void csv_free( CSV_Object* obj )
{
adt_destroy_branch( obj );
}
void _csv_write_record( FileInfo* file, CSV_Object* node )
{
switch ( node->type )
{
case EADT_TYPE_STRING :
{
#ifndef ZPL_PARSER_DISABLE_ANALYSIS
switch ( node->name_style )
{
case EADT_NAME_STYLE_DOUBLE_QUOTE :
{
str_fmt_file( file, "\"" );
adt_print_string( file, node, "\"", "\"" );
str_fmt_file( file, "\"" );
}
break;
case EADT_NAME_STYLE_NO_QUOTES :
{
#endif
str_fmt_file( file, "%s", node->string );
#ifndef ZPL_PARSER_DISABLE_ANALYSIS
}
break;
}
#endif
}
break;
case EADT_TYPE_REAL :
case EADT_TYPE_INTEGER :
{
adt_print_number( file, node );
}
break;
}
}
void _csv_write_header( FileInfo* file, CSV_Object* header )
{
CSV_Object temp = *header;
temp.string = temp.name;
temp.type = EADT_TYPE_STRING;
_csv_write_record( file, &temp );
}
void csv_write_delimiter( FileInfo* file, CSV_Object* obj, char delimiter )
{
GEN_ASSERT_NOT_NULL( file );
GEN_ASSERT_NOT_NULL( obj );
GEN_ASSERT( obj->nodes );
sw cols = obj->nodes.num();
if ( cols == 0 )
return;
sw rows = obj->nodes[ 0 ].nodes.num();
if ( rows == 0 )
return;
b32 has_headers = obj->nodes[ 0 ].name != NULL;
if ( has_headers )
{
for ( sw i = 0; i < cols; i++ )
{
_csv_write_header( file, &obj->nodes[ i ] );
if ( i + 1 != cols )
{
str_fmt_file( file, "%c", delimiter );
}
}
str_fmt_file( file, "\n" );
}
for ( sw r = 0; r < rows; r++ )
{
for ( sw i = 0; i < cols; i++ )
{
_csv_write_record( file, &obj->nodes[ i ].nodes[ r ] );
if ( i + 1 != cols )
{
str_fmt_file( file, "%c", delimiter );
}
}
str_fmt_file( file, "\n" );
}
}
String csv_write_string_delimiter( AllocatorInfo a, CSV_Object* obj, char delimiter )
{
FileInfo tmp;
file_stream_new( &tmp, a );
csv_write_delimiter( &tmp, obj, delimiter );
sw fsize;
u8* buf = file_stream_buf( &tmp, &fsize );
String output = String::make_length( a, ( char* )buf, fsize );
file_close( &tmp );
return output;
}
#pragma endregion CSV
#pragma region Hashing
@ -2507,6 +2780,11 @@ namespace gen
return err;
}
FileError file_open( FileInfo* f, char const* filename )
{
return file_open_mode( f, EFileMode_READ, filename );
}
FileError file_open_mode( FileInfo* f, FileMode mode, char const* filename )
{
FileInfo file_ =
@ -2547,6 +2825,33 @@ namespace gen
return size;
}
FileContents file_read_contents( AllocatorInfo a, b32 zero_terminate, char const* filepath )
{
FileContents result;
FileInfo file ;
result.allocator = a;
if ( file_open( &file, filepath ) == EFileError_NONE )
{
sw fsize = zpl_cast( sw ) file_size( &file );
if ( fsize > 0 )
{
result.data = alloc( a, zero_terminate ? fsize + 1 : fsize );
result.size = fsize;
file_read_at( &file, result.data, result.size, 0 );
if ( zero_terminate )
{
u8* str = zpl_cast( u8* ) result.data;
str[ fsize ] = '\0';
}
}
file_close( &file );
}
return result;
}
struct _memory_fd
{
u8 magic;
@ -2776,8 +3081,8 @@ namespace gen
}
#pragma endregion String
#ifdef GEN_BENCHMARK
#pragma region Timing
#ifdef GEN_BENCHMARK
#if defined( GEN_COMPILER_MSVC ) && ! defined( __clang__ )
u64 read_cpu_time_stamp_counter( void )
{
@ -2934,11 +3239,8 @@ namespace gen
{
return ( f64 )( time_rel_ms() * 1e-3 );
}
#pragma endregion Timing
#endif
#pragma endregion Timing
// namespace gen
}
// gen_time
#endif

2914
project/gen.dep.hpp Normal file

File diff suppressed because it is too large Load Diff

73
project/gen.editor.hpp Normal file
View File

@ -0,0 +1,73 @@
#pragma once
#include "gen.hpp"
namespace gen {
struct Policy
{
// Nothing for now.
};
enum class SymbolType : u32
{
Code,
Line,
Marker
};
struct Editor
{
enum RequestType : u32
{
Add,
Replace,
Remove
};
struct SymbolData
{
Policy Policy;
SymbolInfo Info;
};
struct RequestEntry
{
union {
SymbolData Symbol;
String Specification;
};
RequestType Type;
};
struct Receipt
{
StringCached File;
Code Found;
Code Written;
bool Result;
};
static AllocatorInfo Allocator;
static void set_allocator( AllocatorInfo allocator );
Array(FileInfo) Files;
String Buffer;
Array(RequestEntry) Requests;
void add_files( s32 num, char const** files );
void add ( SymbolInfo definition, Policy policy, Code to_inject );
void remove ( SymbolInfo definition, Policy policy );
void replace( SymbolInfo definition, Policy policy, Code to_replace);
# ifdef GEN_FEATURE_EDITOR_REFACTOR
void refactor( char const* file_path, char const* specification_path );
# endif
bool process_requests( Array(Receipt) out_receipts );
};
// namespace gen
};

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,7 @@
#if __clang__
# pragma clang diagnostic pop
#endif
#if __GNUC__
# pragma GCC diagnostic pop
#endif

View File

@ -0,0 +1,17 @@
#if __clang__
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wunused-const-variable"
# pragma clang diagnostic ignored "-Wswitch"
# pragma clang diagnostic ignored "-Wunused-variable"
# pragma clang diagnostic ignored "-Wunknown-pragmas"
# pragma clang diagnostic ignored "-Wvarargs"
# pragma clang diagnostic ignored "-Wunused-function"
#endif
#if __GNUC__
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wunknown-pragmas"
# pragma GCC diagnostic ignored "-Wcomment"
# pragma GCC diagnostic ignored "-Wswitch"
# pragma GCC diagnostic ignored "-Wunused-variable"
#endif

43
project/gen.scanner.hpp Normal file
View File

@ -0,0 +1,43 @@
#pragma once
#include "gen.hpp"
namespace gen {
struct SymbolInfo
{
StringCached File;
char const* Marker;
Code Signature;
};
struct Scanner
{
struct RequestEntry
{
SymbolInfo Info;
};
struct Receipt
{
StringCached File;
Code Defintion;
bool Result;
};
AllocatorInfo MemAlloc;
static void set_allocator( AllocatorInfo allocator );
Array(FileInfo) Files;
String Buffer;
Array(RequestEntry) Requests;
void add_files( s32 num, char const** files );
void add( SymbolInfo signature, Policy policy );
bool process_requests( Array(Receipt) out_receipts );
};
k
}

File diff suppressed because it is too large Load Diff

View File

@ -22,6 +22,6 @@ endif
# add_project_arguments('-E', language : ['c', 'cpp'])
# add_global_arguments( '-E', language : ['cpp'])
add_project_arguments('-Dgen_time', language : ['c', 'cpp'])
add_project_arguments('-DGEN_TIME', language : ['c', 'cpp'])
executable( 'gencpp', sources, include_directories : includes )