mirror of
https://github.com/Ed94/refactor.git
synced 2024-12-21 22:44:45 -08:00
Merge pull request #2 from Ed94/includes_n_multi-file
Update main with feature updates in includes_n_multi-file
This commit is contained in:
commit
2419f407a8
4
.gitignore
vendored
4
.gitignore
vendored
@ -2,4 +2,6 @@
|
||||
|
||||
build/*
|
||||
|
||||
zpl.refactored.h
|
||||
Test/*.h
|
||||
Test/*.hpp
|
||||
Test/*.cpp
|
||||
|
27
.vscode/launch.json
vendored
27
.vscode/launch.json
vendored
@ -13,13 +13,34 @@
|
||||
"-src=./thirdparty/zpl.h",
|
||||
"-dst=./Test/zpl.refactored.h",
|
||||
|
||||
"-spec=./Test/zpl.h.refactor"
|
||||
"-spec=./Test/zpl.refactor"
|
||||
],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "${workspaceRoot}",
|
||||
"environment": [],
|
||||
"console": "integratedTerminal"
|
||||
}
|
||||
},
|
||||
// {
|
||||
// "name": "Refactor ZPL files",
|
||||
// "type": "cppvsdbg",
|
||||
// "request": "launch",
|
||||
// "program": "${workspaceFolder}/build/refactor.exe",
|
||||
// "args": [
|
||||
// "-num=2",
|
||||
|
||||
// "-src=./thirdparty/zpl.h",
|
||||
// "./thirdparty/file.h",
|
||||
|
||||
// "-dst=./Test/zpl.refactored.h",
|
||||
// "./thirdparty/file.refactored.h",
|
||||
|
||||
// "-spec=./Test/zpl.refactor"
|
||||
// ],
|
||||
// "stopAtEntry": false,
|
||||
// "cwd": "${workspaceRoot}",
|
||||
// "environment": [],
|
||||
// "console": "integratedTerminal"
|
||||
// },
|
||||
{
|
||||
"name": "Refactor refactor.c",
|
||||
"type": "cppvsdbg",
|
||||
@ -29,7 +50,7 @@
|
||||
"-source=./refactor.cpp",
|
||||
"-destination=./Test/refactor.cpp",
|
||||
|
||||
"-specification=./Test/zpl.h.refactor"
|
||||
"-specification=./Test/zpl.refactor"
|
||||
],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "${workspaceRoot}",
|
||||
|
41
Readme.md
41
Readme.md
@ -1,28 +1,49 @@
|
||||
# refactor
|
||||
|
||||
A code identifier refactoring app. Intended for c/c++ like identifiers.
|
||||
Refactor c/c++ files (and problably others) with ease.
|
||||
|
||||
Parameters :
|
||||
## Parameters :
|
||||
|
||||
* `-num` : Used if more than one source file is provided (if used, number of destination files provided MUST MATCH).
|
||||
* `-src` : Source file to refactor
|
||||
* `-dst` : Destination file after the refactor (omit to use the same as source)
|
||||
* `-spec` : Specification containing rules to use for the refactor.
|
||||
* `-debug` : Use only if on debug build and desire to attach to process.
|
||||
|
||||
Syntax :
|
||||
## Syntax :
|
||||
|
||||
* `not` Omit word or namespace.
|
||||
* `include` Preprocessor include <file> related identifiers.
|
||||
* `word` Fixed sized identifier.
|
||||
* `namespace` Variable sized identifiers, mainly intended to redefine c-namespace of an identifier.
|
||||
* `,` is used to delimit arguments to word or namespace.
|
||||
* `,` is used to delimit arguments (if doing a find and replace).
|
||||
* `L-Value` is the signature to modify.
|
||||
* `R-Value` is the substitute ( only available if rule does not use `not` keyword )
|
||||
|
||||
The only keyword here excluisve to c/c++ is the `include` as it does search specifically for `#include <L-Value>`.
|
||||
However, the rest of the categorical keywords (word, namespace), can really be used for any langauge.
|
||||
|
||||
There is no semantic awareness this is truely just a simple find and replace, but with some filters specifiable, and
|
||||
words/namespaces only being restricted to the rules for C/C++ identifiers (alphanumeric or underscores only)
|
||||
|
||||
The main benefit for using this over alts is its problably more ergonomic and performant for large refactors on libraries that
|
||||
you may want to have automated in a script.
|
||||
|
||||
There are other programs more robust for doing that sort of thing but I was not able to find something this simple.
|
||||
|
||||
### Note
|
||||
|
||||
* Building for debug provides some nice output with context on a per-line basis.
|
||||
* Release will only show errors for asserts (that will kill the refactor early).
|
||||
* If the refactor crashes, the files previously written to will retain their changes.
|
||||
Make sure to have the code backed up on a VCS or in some other way.
|
||||
* This was compiled using meson with ninja and clang on windows 11. The ZPL library used however should work fine on the other major os platforms and compiler venders.
|
||||
* The scripts used for building and otherwise are in the scripts directory and are all in powershell (with exception to the meson.build). Techncially there should be a powershell package available on other platorms but worst case it should be pretty easy to port these scripts to w/e shell script you'd perfer.
|
||||
|
||||
TODO:
|
||||
|
||||
* Possibly come up with a better name.
|
||||
* Cleanup memory usage (it hogs quite a bit for what it does..)
|
||||
* Split lines of file and refactor it that way instead (better debug, problably negligable performance loss, worst case can have both depending on build type)
|
||||
* Accept multiple files at once `-files`
|
||||
* Add support for `macro` keyword (single out macro identifiers)
|
||||
* Add support for `include` keyword (single out include definitions)
|
||||
* Add support for auto-translating a namespace in a macro to a cpp namespace
|
||||
* Test to see how much needs to be ported for other platforms (if at all)
|
||||
* Setup as api.
|
||||
* Provide binaries in the release page for github. (debug and release builds)
|
||||
* Directive to ignore comments (with a way to specify the comment signature). Right now comments that meet the signature of words or namespaces are refactored.
|
||||
|
@ -1,137 +0,0 @@
|
||||
/*
|
||||
BLOAT.
|
||||
|
||||
ZPL requires ZPL_IMPLEMENTATION whereever this library is included.
|
||||
|
||||
This file assumes it will be included in one compilation unit.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if __clang__
|
||||
# pragma clang diagnostic ignored "-Wunused-const-variable"
|
||||
# pragma clang diagnostic ignored "-Wswitch"
|
||||
# pragma clang diagnostic ignored "-Wunused-variable"
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#pragma region ZPL INCLUDE
|
||||
#if __clang__
|
||||
# pragma clang diagnostic push
|
||||
# pragma clang diagnostic ignored "-Wmissing-braces"
|
||||
# pragma clang diagnostic ignored "-Wbraced-scalar-init"
|
||||
#endif
|
||||
|
||||
// # define ZPL_HEAP_ANALYSIS
|
||||
# define ZPL_NO_MATH_H
|
||||
# define ZPL_DISABLE_C_DECLS
|
||||
# define ZPL_WRAP_IN_NAMESPACE
|
||||
# define ZPL_CUSTOM_MODULES
|
||||
# define ZPL_MODULE_ESSENTIALS
|
||||
# define ZPL_MODULE_CORE
|
||||
# define ZPL_MODULE_TIMER
|
||||
// # define ZPL_MODULE_HASHING
|
||||
// # define ZPL_MODULE_REGEX
|
||||
// # define ZPL_MODULE_EVENT
|
||||
// # define ZPL_MODULE_DLL
|
||||
# define ZPL_MODULE_OPTS
|
||||
// # define ZPL_MODULE_PROCESS
|
||||
// # define ZPL_MODULE_MATH
|
||||
// # define ZPL_MODULE_THREADING
|
||||
// # define ZPL_MODULE_JOBS
|
||||
// # define ZPL_MODULE_PARSER
|
||||
// extern "C" {
|
||||
#include "zpl.refactored.h"
|
||||
// }
|
||||
|
||||
#if __clang__
|
||||
# pragma clang diagnostic pop
|
||||
#endif
|
||||
#pragma endregion ZPL INCLUDE
|
||||
|
||||
|
||||
|
||||
#define bit( Value_ ) ( 1 << Value_ )
|
||||
#define bitfield_is_equal( Field_, Mask_ ) ( ( Mask_ & Field_ ) == Mask_ )
|
||||
#define ct constexpr
|
||||
#define gen( ... ) template< __VA_ARGS__ >
|
||||
#define forceinline ZPL_ALWAYS_INLINE
|
||||
#define print_nl( _) zpl_printf("\n")
|
||||
#define cast( Type_, Value_ ) ( ( Type_ ), ( Value_ ) )
|
||||
#define scast( Type_, Value_ ) static_cast< Type_ >( Value_ )
|
||||
#define rcast( Type_, Value_ ) reinterpret_cast< Type_ >( Value_ )
|
||||
#define pcast( Type_, Value_ ) ( * (Type_*)( & Value_ ) )
|
||||
|
||||
#define do_once() \
|
||||
do \
|
||||
{ \
|
||||
static \
|
||||
bool Done = true; \
|
||||
if ( Done ) \
|
||||
return; \
|
||||
Done = false; \
|
||||
} \
|
||||
while(0) \
|
||||
|
||||
|
||||
ct char const* Msg_Invalid_Value = "INVALID VALUE PROVIDED";
|
||||
|
||||
|
||||
namespace Memory
|
||||
{
|
||||
zpl::arena Global_Arena {};
|
||||
#define g_allocator arena_allocator( & Memory::Global_Arena)
|
||||
|
||||
void setup()
|
||||
{
|
||||
arena_init_from_allocator( & Global_Arena, heap(), megabytes(10) );
|
||||
|
||||
if ( Global_Arena.total_size == 0 )
|
||||
{
|
||||
zpl::assert_crash( "Failed to reserve memory for Tests:: Global_Arena" );
|
||||
}
|
||||
}
|
||||
|
||||
void cleanup()
|
||||
{
|
||||
arena_free( & Global_Arena);
|
||||
}
|
||||
}
|
||||
|
||||
zpl::sw log_fmt(char const *fmt, ...)
|
||||
{
|
||||
#if Build_Debug
|
||||
zpl::sw res;
|
||||
va_list va;
|
||||
va_start(va, fmt);
|
||||
res = zpl::printf_va(fmt, va);
|
||||
va_end(va);
|
||||
return res;
|
||||
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void fatal(char const *fmt, ...)
|
||||
{
|
||||
local_persist thread_local
|
||||
char buf[ZPL_PRINTF_MAXLEN] = { 0 };
|
||||
|
||||
va_list va;
|
||||
|
||||
#if Build_Debug
|
||||
va_start(va, fmt);
|
||||
zpl::snprintf_va(buf, ZPL_PRINTF_MAXLEN, fmt, va);
|
||||
va_end(va);
|
||||
|
||||
zpl::assert_crash(buf);
|
||||
#else
|
||||
va_start(va, fmt);
|
||||
zpl::printf_err_va( fmt, va);
|
||||
va_end(va);
|
||||
|
||||
zpl::exit(1);
|
||||
#endif
|
||||
}
|
@ -4,7 +4,7 @@ project( 'refactor', 'c', 'cpp', default_options : ['buildtype=debug'] )
|
||||
|
||||
if get_option('buildtype').startswith('debug')
|
||||
|
||||
add_project_arguments('-DBuild_Debug', language : 'cpp')
|
||||
add_project_arguments('-DBuild_Debug', language : ['c', 'cpp'])
|
||||
|
||||
endif
|
||||
|
||||
|
71
Test/project.refactor
Normal file
71
Test/project.refactor
Normal file
@ -0,0 +1,71 @@
|
||||
__VERSION 1
|
||||
|
||||
// not : Ignore
|
||||
// include : #includes
|
||||
// word : Alphanumeric or underscore
|
||||
// namespace : Prefix search and replace (c-namspaces).
|
||||
// regex : Unavailable in __VERSION 1.
|
||||
|
||||
// Precedence (highest to lowest):
|
||||
// word, namespace, regex
|
||||
|
||||
// Comments
|
||||
not comments
|
||||
|
||||
// Includes
|
||||
include zpl.h, zpl.refactored.h
|
||||
include Bloat.hpp, Bloat.refactored.hpp
|
||||
include Bloat.cpp, Bloat.refactored.cpp
|
||||
include IO.hpp, IO.refactored.hpp
|
||||
include IO.cpp, IO.refactored.cpp
|
||||
include Spec.hpp, Spec.refactored.hpp
|
||||
include Spec.cpp, Spec.refactored.cpp
|
||||
|
||||
// Remove the zpl namespace.
|
||||
namespace zpl_
|
||||
|
||||
// Don't expose zpl internals
|
||||
not namespace zpl__
|
||||
|
||||
// Macro exposure
|
||||
//namespace ZPL_
|
||||
//not word ZPL_IMPLEMENTATION
|
||||
|
||||
// Name conflicts
|
||||
word opts, options
|
||||
|
||||
word zpl_strncmp, str_compare
|
||||
word zpl_strcmp, str_compare
|
||||
|
||||
// Undesired typedefs
|
||||
word zpl_i8, s8
|
||||
word zpl_i16, s16
|
||||
word zpl_i32, s32
|
||||
word zpl_i64, s64
|
||||
word zpl_u8, u8
|
||||
word zpl_u16, u16
|
||||
word zpl_u32, u32
|
||||
word zpl_u64, u64
|
||||
word zpl_intptr, sptr
|
||||
word zpl_uintptr, uptr
|
||||
word zpl_usize, uw
|
||||
word zpl_isize, sw
|
||||
|
||||
// Conflicts with std. (Uncomment if using c externs)
|
||||
not word zpl_memchr
|
||||
not word zpl_memmove
|
||||
not word zpl_memset
|
||||
not word zpl_memswap
|
||||
not word zpl_memcopy
|
||||
not word zpl_printf
|
||||
not word zpl_printf_va
|
||||
not word zpl_printf_err
|
||||
not word zpl_printf_err_va
|
||||
not word zpl_fprintf
|
||||
not word zpl_fprintf_va
|
||||
not word zpl_snprintf
|
||||
not word zpl_snprintf_va
|
||||
not word zpl_strchr
|
||||
not word zpl_strlen
|
||||
not word zpl_strnlen
|
||||
not word zpl_exit
|
@ -1,770 +0,0 @@
|
||||
#define ZPL_IMPLEMENTATION
|
||||
#include "bloat.refactored.hpp"
|
||||
|
||||
|
||||
namespace File
|
||||
{
|
||||
using namespace zpl;
|
||||
|
||||
string Source = nullptr;
|
||||
string Destination = nullptr;
|
||||
file_contents Content {};
|
||||
|
||||
arena Buffer;
|
||||
|
||||
void cleanup()
|
||||
{
|
||||
arena_free( & Buffer );
|
||||
}
|
||||
|
||||
void read()
|
||||
{
|
||||
file file_src = {};
|
||||
|
||||
Content.allocator = g_allocator;
|
||||
|
||||
file_error error_src = file_open( & file_src, Source );
|
||||
|
||||
if ( error_src == ZPL_FILE_ERROR_NONE )
|
||||
{
|
||||
sw fsize = zpl_cast(sw) file_size( & file_src);
|
||||
|
||||
if ( fsize > 0 )
|
||||
{
|
||||
arena_init_from_allocator( & Buffer, heap(), (fsize + fsize % 64) * 4 );
|
||||
|
||||
Content.data = alloc( arena_allocator( & Buffer), fsize);
|
||||
Content.size = fsize;
|
||||
|
||||
file_read_at ( & file_src, Content.data, Content.size, 0);
|
||||
}
|
||||
|
||||
file_close( & file_src);
|
||||
}
|
||||
|
||||
if ( Content.data == nullptr )
|
||||
{
|
||||
fatal( "Unable to open source file: %s\n", Source );
|
||||
}
|
||||
}
|
||||
|
||||
void write(string refactored)
|
||||
{
|
||||
if ( refactored == nullptr)
|
||||
return;
|
||||
|
||||
file file_dest {};
|
||||
file_error error = file_create( & file_dest, Destination );
|
||||
|
||||
if ( error != ZPL_FILE_ERROR_NONE )
|
||||
{
|
||||
fatal( "Unable to open destination file: %s\n", Destination );
|
||||
}
|
||||
|
||||
file_write( & file_dest, refactored, string_length(refactored) );
|
||||
}
|
||||
}
|
||||
|
||||
namespace Spec
|
||||
{
|
||||
using namespace zpl;
|
||||
|
||||
string File;
|
||||
|
||||
enum Tok
|
||||
{
|
||||
Not,
|
||||
Namespace,
|
||||
Word,
|
||||
|
||||
Num_Tok
|
||||
};
|
||||
|
||||
ct
|
||||
char const* str_tok( Tok tok )
|
||||
{
|
||||
ct
|
||||
char const* tok_to_str[ Tok::Num_Tok ] =
|
||||
{
|
||||
"not",
|
||||
"namespace",
|
||||
"word",
|
||||
};
|
||||
|
||||
return tok_to_str[ tok ];
|
||||
}
|
||||
|
||||
ct
|
||||
char strlen_tok( Tok tok )
|
||||
{
|
||||
ct
|
||||
const u8 tok_to_len[ Tok::Num_Tok ] =
|
||||
{
|
||||
3,
|
||||
9,
|
||||
4,
|
||||
};
|
||||
|
||||
return tok_to_len[ tok ];
|
||||
}
|
||||
|
||||
forceinline
|
||||
bool is_tok( Tok tok, string str, u32 length )
|
||||
{
|
||||
char const* tok_str = str_tok(tok);
|
||||
const u8 tok_len = strlen_tok(tok);
|
||||
|
||||
if ( tok_len != length)
|
||||
return false;
|
||||
|
||||
s32 result = str_compare( tok_str, str, tok_len );
|
||||
|
||||
return result == 0;
|
||||
}
|
||||
|
||||
struct Entry
|
||||
{
|
||||
string Sig = nullptr; // Signature
|
||||
string Sub = nullptr; // Substitute
|
||||
};
|
||||
|
||||
arena Buffer {};
|
||||
zpl_array(Entry) Word_Ignores;
|
||||
zpl_array(Entry) Namespace_Ignores;
|
||||
zpl_array(Entry) Words;
|
||||
zpl_array(Entry) Namespaces;
|
||||
|
||||
u32 Sig_Smallest = kilobytes(1);
|
||||
|
||||
forceinline
|
||||
void find_next_token( string& token, char*& line, u32& length )
|
||||
{
|
||||
string_clear( token );
|
||||
length = 0;
|
||||
while ( char_is_alphanumeric( line[length] ) || line[length] == '_' )
|
||||
{
|
||||
length++;
|
||||
}
|
||||
|
||||
if ( length == 0 )
|
||||
{
|
||||
fatal("Failed to find valid initial token");
|
||||
}
|
||||
|
||||
token = string_append_length( token, line, length );
|
||||
line += length;
|
||||
}
|
||||
|
||||
void process()
|
||||
{
|
||||
char* content;
|
||||
|
||||
zpl_array(char*) lines;
|
||||
|
||||
// Get the contents of the file.
|
||||
{
|
||||
file file {};
|
||||
file_error error = file_open( & file, File);
|
||||
|
||||
if ( error != ZPL_FILE_ERROR_NONE )
|
||||
{
|
||||
fatal("Could not open the specification file: %s", File);
|
||||
}
|
||||
|
||||
sw fsize = scast( sw, file_size( & file ) );
|
||||
|
||||
if ( fsize <= 0 )
|
||||
{
|
||||
fatal("No content in specificaiton to process");
|
||||
}
|
||||
|
||||
arena_init_from_allocator( & Buffer, heap(), (fsize + fsize % 64) * 10 + kilobytes(1) );
|
||||
|
||||
char* content = rcast( char*, alloc( arena_allocator( & Buffer), fsize + 1) );
|
||||
|
||||
file_read( & file, content, fsize);
|
||||
|
||||
content[fsize] = 0;
|
||||
|
||||
lines = str_split_lines( arena_allocator( & Buffer ), content, false );
|
||||
|
||||
file_close( & file );
|
||||
}
|
||||
|
||||
sw left = array_count( lines );
|
||||
|
||||
if ( left == 0 )
|
||||
{
|
||||
fatal("Spec::process: lines array imporoperly setup");
|
||||
}
|
||||
|
||||
// Skip the first line as its the version number and we only support __VERSION 1.
|
||||
left--;
|
||||
lines++;
|
||||
|
||||
array_init( Word_Ignores, arena_allocator( & Buffer));
|
||||
array_init( Namespace_Ignores, arena_allocator( & Buffer));
|
||||
array_init( Words, arena_allocator( & Buffer));
|
||||
array_init( Namespaces, arena_allocator( & Buffer));
|
||||
|
||||
// Limiting the maximum output of a token to 1 KB
|
||||
string token = string_make_reserve( arena_allocator( & Buffer), kilobytes(1));
|
||||
|
||||
while ( left-- )
|
||||
{
|
||||
char* line = * lines;
|
||||
|
||||
// Ignore line if its a comment
|
||||
if ( line[0] == '/' && line[1] == '/')
|
||||
{
|
||||
lines++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Remove indent
|
||||
{
|
||||
while ( char_is_space( line[0] ) )
|
||||
line++;
|
||||
|
||||
if ( line[0] == '\0' )
|
||||
{
|
||||
lines++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
u32 length = 0;
|
||||
|
||||
// Find a valid token
|
||||
find_next_token( token, line, length );
|
||||
|
||||
Tok type = Tok::Num_Tok;
|
||||
bool ignore = false;
|
||||
Entry entry {};
|
||||
|
||||
// Will be reguarded as an ignore.
|
||||
if ( is_tok( Tok::Not, token, length ))
|
||||
{
|
||||
ignore = true;
|
||||
|
||||
while ( char_is_space( line[0] ) )
|
||||
line++;
|
||||
|
||||
if ( line[0] == '\0' )
|
||||
{
|
||||
lines++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Find the category token
|
||||
find_next_token( token, line, length );
|
||||
}
|
||||
|
||||
if ( is_tok( Tok::Namespace, token, length ) )
|
||||
{
|
||||
type = Tok::Namespace;
|
||||
}
|
||||
else if ( is_tok( Tok::Word, token, length ) )
|
||||
{
|
||||
type = Tok::Word;
|
||||
}
|
||||
|
||||
// Parse line.
|
||||
{
|
||||
// Find first argument
|
||||
{
|
||||
|
||||
while ( char_is_space( line[0] ) )
|
||||
line++;
|
||||
|
||||
if ( line[0] == '\0' )
|
||||
{
|
||||
lines++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
find_next_token( token, line, length );
|
||||
|
||||
// First argument is signature.
|
||||
entry.Sig = string_make_length( g_allocator, token, length );
|
||||
|
||||
if ( length < Sig_Smallest )
|
||||
Sig_Smallest = length;
|
||||
|
||||
if ( line[0] == '\0' || ignore )
|
||||
{
|
||||
switch ( type )
|
||||
{
|
||||
case Tok::Namespace:
|
||||
if ( ignore)
|
||||
array_append( Namespace_Ignores, entry );
|
||||
|
||||
else
|
||||
array_append( Namespaces, entry );
|
||||
break;
|
||||
|
||||
case Tok::Word:
|
||||
if ( ignore)
|
||||
{
|
||||
array_append( Word_Ignores, entry );
|
||||
u32 test = array_count( Word_Ignores );
|
||||
}
|
||||
|
||||
|
||||
else
|
||||
array_append( Words, entry );
|
||||
break;
|
||||
}
|
||||
|
||||
lines++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Look for second argument indicator
|
||||
{
|
||||
bool bSkip = false;
|
||||
|
||||
while ( line[0] != ',' )
|
||||
{
|
||||
if ( line[0] == '\0' )
|
||||
{
|
||||
switch ( type )
|
||||
{
|
||||
case Tok::Namespace:
|
||||
array_append( Namespaces, entry );
|
||||
break;
|
||||
|
||||
case Tok::Word:
|
||||
array_append( Words, entry );
|
||||
break;
|
||||
}
|
||||
|
||||
bSkip = true;
|
||||
break;
|
||||
}
|
||||
|
||||
line++;
|
||||
}
|
||||
|
||||
if ( bSkip )
|
||||
{
|
||||
lines++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Eat the argument delimiter.
|
||||
line++;
|
||||
|
||||
// Remove spacing
|
||||
{
|
||||
bool bSkip = true;
|
||||
|
||||
while ( char_is_space( line[0] ) )
|
||||
line++;
|
||||
|
||||
if ( line[0] == '\0' )
|
||||
{
|
||||
switch ( type )
|
||||
{
|
||||
case Tok::Namespace:
|
||||
array_append( Namespaces, entry );
|
||||
break;
|
||||
|
||||
case Tok::Word:
|
||||
array_append( Words, entry );
|
||||
break;
|
||||
}
|
||||
|
||||
lines++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
find_next_token( token, line, length );
|
||||
|
||||
// Second argument is substitute.
|
||||
entry.Sub = string_make_length( g_allocator, token, length );
|
||||
|
||||
switch ( type )
|
||||
{
|
||||
case Tok::Namespace:
|
||||
array_append( Namespaces, entry );
|
||||
lines++;
|
||||
continue;
|
||||
|
||||
case Tok::Word:
|
||||
array_append( Words, entry );
|
||||
lines++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
log_fmt("Specification Line: %d is missing valid keyword", array_count(lines) - left);
|
||||
lines++;
|
||||
}
|
||||
}
|
||||
|
||||
void cleanup()
|
||||
{
|
||||
arena_free( & Buffer );
|
||||
}
|
||||
}
|
||||
|
||||
using namespace zpl;
|
||||
|
||||
struct Token
|
||||
{
|
||||
u32 Start;
|
||||
u32 End;
|
||||
|
||||
string Sig;
|
||||
string Sub;
|
||||
};
|
||||
|
||||
void refactor()
|
||||
{
|
||||
sw buffer_size = File::Content.size;
|
||||
|
||||
zpl_array(Token) tokens;
|
||||
array_init( tokens, g_allocator);
|
||||
|
||||
char* content = rcast( char*, File::Content.data );
|
||||
|
||||
string current = string_make( g_allocator, "");
|
||||
string preview = string_make( g_allocator, "");
|
||||
|
||||
sw left = File::Content.size;
|
||||
sw line = 0;
|
||||
|
||||
while ( left )
|
||||
{
|
||||
if ( content[0] == '\n' )
|
||||
{
|
||||
line++;
|
||||
}
|
||||
|
||||
// Word Ignores
|
||||
{
|
||||
Spec::Entry* ignore = Spec::Word_Ignores;
|
||||
|
||||
sw ignores_left = array_count( Spec::Word_Ignores);
|
||||
|
||||
do
|
||||
{
|
||||
if ( ignore->Sig[0] != content[0] )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
string_clear( current );
|
||||
|
||||
u32 sig_length = string_length( ignore->Sig );
|
||||
current = string_append_length( current, content, sig_length );
|
||||
|
||||
if ( string_are_equal( ignore->Sig, current ) )
|
||||
{
|
||||
char before = content[-1];
|
||||
char after = content[sig_length];
|
||||
|
||||
if ( char_is_alphanumeric( before ) || before == '_'
|
||||
|| char_is_alphanumeric( after ) || after == '_' )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
log_fmt("\nIgnored %-81s line %d", current, line );
|
||||
|
||||
content += sig_length;
|
||||
left -= sig_length;
|
||||
goto Skip;
|
||||
}
|
||||
}
|
||||
while ( ignore++, --ignores_left );
|
||||
}
|
||||
|
||||
// Namespace Ignores
|
||||
{
|
||||
Spec::Entry* ignore = Spec::Namespace_Ignores;
|
||||
|
||||
sw ignores_left = array_count( Spec::Namespace_Ignores);
|
||||
|
||||
do
|
||||
{
|
||||
if ( ignore->Sig[0] != content[0] )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
string_clear( current );
|
||||
|
||||
u32 sig_length = string_length( ignore->Sig );
|
||||
current = string_append_length( current, content, sig_length );
|
||||
|
||||
if ( string_are_equal( ignore->Sig, current ) )
|
||||
{
|
||||
u32 length = sig_length;
|
||||
char* ns_content = content + sig_length;
|
||||
|
||||
while ( char_is_alphanumeric( ns_content[0] ) || ns_content[0] == '_' )
|
||||
{
|
||||
length++;
|
||||
ns_content++;
|
||||
}
|
||||
|
||||
string_clear( preview );
|
||||
preview = string_append_length( preview, content, length );
|
||||
log_fmt("\nIgnored %-40s %-40s line %d", preview, ignore->Sig, line);
|
||||
|
||||
content += length;
|
||||
left -= length;
|
||||
goto Skip;
|
||||
}
|
||||
}
|
||||
while ( ignore++, --ignores_left );
|
||||
}
|
||||
|
||||
// Words to match
|
||||
{
|
||||
Spec::Entry* word = Spec::Words;
|
||||
|
||||
sw words_left = array_count ( Spec::Words);
|
||||
|
||||
do
|
||||
{
|
||||
if ( word->Sig[0] != content[0] )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
string_clear( current );
|
||||
|
||||
sw sig_length = string_length( word->Sig);
|
||||
current = string_append_length( current, content, sig_length );
|
||||
|
||||
if ( string_are_equal( word->Sig, current ) )
|
||||
{
|
||||
char before = content[-1];
|
||||
char after = content[sig_length];
|
||||
|
||||
if ( char_is_alphanumeric( before ) || before == '_'
|
||||
|| char_is_alphanumeric( after ) || after == '_' )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Token entry {};
|
||||
|
||||
entry.Start = File::Content.size - left;
|
||||
entry.End = entry.Start + sig_length;
|
||||
entry.Sig = word->Sig;
|
||||
|
||||
if ( word->Sub != nullptr )
|
||||
{
|
||||
entry.Sub = word->Sub;
|
||||
buffer_size += string_length( entry.Sub) - sig_length;
|
||||
}
|
||||
|
||||
array_append( tokens, entry );
|
||||
|
||||
log_fmt("\nFound %-81s line %d", current, line);
|
||||
|
||||
content += sig_length;
|
||||
left -= sig_length;
|
||||
goto Skip;
|
||||
}
|
||||
}
|
||||
while ( word++, --words_left );
|
||||
}
|
||||
|
||||
// Namespaces to match
|
||||
{
|
||||
Spec::Entry* nspace = Spec::Namespaces;
|
||||
|
||||
sw nspaces_left = array_count( Spec::Namespaces);
|
||||
|
||||
do
|
||||
{
|
||||
if ( nspace->Sig[0] != content[0] )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
string_clear( current );
|
||||
|
||||
u32 sig_length = string_length( nspace->Sig );
|
||||
current = string_append_length( current, content, sig_length );
|
||||
|
||||
if ( string_are_equal( nspace->Sig, current ) )
|
||||
{
|
||||
u32 length = sig_length;
|
||||
char* ns_content = content + sig_length;
|
||||
|
||||
while ( char_is_alphanumeric( ns_content[0] ) || ns_content[0] == '_' )
|
||||
{
|
||||
length++;
|
||||
ns_content++;
|
||||
}
|
||||
|
||||
Token entry {};
|
||||
|
||||
entry.Start = File::Content.size - left;
|
||||
entry.End = entry.Start + length;
|
||||
entry.Sig = nspace->Sig;
|
||||
|
||||
buffer_size += sig_length;
|
||||
|
||||
if ( nspace->Sub != nullptr )
|
||||
{
|
||||
entry.Sub = nspace->Sub;
|
||||
buffer_size += string_length( entry.Sub ) - length;
|
||||
}
|
||||
|
||||
array_append( tokens, entry );
|
||||
|
||||
string_clear( preview );
|
||||
preview = string_append_length( preview, content, length);
|
||||
log_fmt("\nFound %-40s %-40s line %d", preview, nspace->Sig, line);
|
||||
|
||||
content += length;
|
||||
left -= length;
|
||||
}
|
||||
}
|
||||
while ( nspace++, --nspaces_left );
|
||||
}
|
||||
|
||||
content++;
|
||||
left--;
|
||||
|
||||
Skip:
|
||||
continue;
|
||||
}
|
||||
|
||||
left = array_count( tokens);
|
||||
content = rcast( char*, File::Content.data);
|
||||
|
||||
// Generate the refactored file content.
|
||||
arena buffer;
|
||||
string refactored = nullptr;
|
||||
{
|
||||
Token* entry = tokens;
|
||||
|
||||
if ( entry == nullptr)
|
||||
return;
|
||||
|
||||
arena_init_from_allocator( & buffer, heap(), buffer_size * 2 );
|
||||
|
||||
string
|
||||
new_string = string_make_reserve( arena_allocator( & buffer), kilobytes(1) );
|
||||
refactored = string_make_reserve( arena_allocator( & buffer), buffer_size );
|
||||
|
||||
sw previous_end = 0;
|
||||
|
||||
while ( left-- )
|
||||
{
|
||||
sw segment_length = entry->Start - previous_end;
|
||||
|
||||
sw sig_length = string_length( entry->Sig );
|
||||
|
||||
// Append between tokens
|
||||
refactored = string_append_length( refactored, content, segment_length );
|
||||
content += segment_length + sig_length;
|
||||
|
||||
segment_length = entry->End - entry->Start - sig_length;
|
||||
|
||||
// Append token
|
||||
if ( entry->Sub )
|
||||
refactored = string_append( refactored, entry->Sub );
|
||||
|
||||
refactored = string_append_length( refactored, content, segment_length );
|
||||
content += segment_length;
|
||||
|
||||
previous_end = entry->End;
|
||||
entry++;
|
||||
}
|
||||
|
||||
entry--;
|
||||
|
||||
if ( entry->End < File::Content.size )
|
||||
{
|
||||
refactored = string_append_length( refactored, content, File::Content.size - entry->End );
|
||||
}
|
||||
}
|
||||
|
||||
// Write refactored content to destination.
|
||||
File::write( refactored );
|
||||
|
||||
arena_free( & buffer );
|
||||
}
|
||||
|
||||
|
||||
inline
|
||||
void parse_options( int num, char** arguments )
|
||||
{
|
||||
opts opts;
|
||||
opts_init( & opts, g_allocator, "refactor");
|
||||
opts_add( & opts, "source" , "src" , "File to refactor" , ZPL_OPTS_STRING);
|
||||
opts_add( & opts, "destination" , "dst" , "File post refactor" , ZPL_OPTS_STRING);
|
||||
opts_add( & opts, "specification", "spec", "Specification for refactoring", ZPL_OPTS_STRING);
|
||||
|
||||
if (opts_compile( & opts, num, arguments))
|
||||
{
|
||||
if ( opts_has_arg( & opts, "src" ) )
|
||||
{
|
||||
string opt = opts_string( & opts, "src", "INVALID PATH" );
|
||||
|
||||
File::Source = string_make( g_allocator, "" );
|
||||
File::Source = string_append( File::Source, opt );
|
||||
}
|
||||
else
|
||||
{
|
||||
fatal( "-source not provided\n" );
|
||||
}
|
||||
|
||||
if ( opts_has_arg( & opts, "dst" ) )
|
||||
{
|
||||
string opt = opts_string( & opts, "dst", "INVALID PATH" );
|
||||
|
||||
File::Destination = string_make( g_allocator, "" );
|
||||
File::Destination = string_append( File::Destination, opt );
|
||||
}
|
||||
else if ( File::Source )
|
||||
{
|
||||
File::Destination = string_make( g_allocator, "" );
|
||||
File::Destination = string_append( File::Destination, File::Source );
|
||||
}
|
||||
|
||||
if ( opts_has_arg( & opts, "spec" ) )
|
||||
{
|
||||
string opt = opts_string( & opts, "spec", "INVALID PATH" );
|
||||
|
||||
Spec::File = string_make( g_allocator, "" );
|
||||
Spec::File = string_append( Spec::File, opt );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fatal( "Failed to parse arguments\n" );
|
||||
}
|
||||
|
||||
opts_free( & opts);
|
||||
}
|
||||
|
||||
int main( int num, char** arguments)
|
||||
{
|
||||
Memory::setup();
|
||||
|
||||
parse_options( num, arguments );
|
||||
|
||||
if ( Spec::File )
|
||||
Spec::process();
|
||||
|
||||
File::read();
|
||||
|
||||
refactor();
|
||||
|
||||
Spec:: cleanup();
|
||||
File:: cleanup();
|
||||
Memory::cleanup();
|
||||
}
|
@ -1,14 +1,27 @@
|
||||
__VERSION 1
|
||||
|
||||
// not : Ignore
|
||||
// word : Alphanumeric or underscore
|
||||
// regex : Unavailable in __VERSION 1.
|
||||
// not : Ignore
|
||||
// include : #includes
|
||||
// word : Alphanumeric or underscore
|
||||
// namespace : Prefix search and replace (c-namspaces).
|
||||
// regex : Unavailable in __VERSION 1.
|
||||
|
||||
// Precedence (highest to lowest):
|
||||
// word, namespace, regex
|
||||
|
||||
// Comments
|
||||
not comments
|
||||
|
||||
// Header files
|
||||
not word zpl_hedley
|
||||
not include zpl_hedley.h
|
||||
not include allocator.h
|
||||
not include array.h
|
||||
not include header/essentials/collections/array.h
|
||||
not include header/essentials/collections/list.h
|
||||
not include header/core/file.h
|
||||
not include header/opts.h
|
||||
not include source/core/file.c
|
||||
not include source/opts.c
|
||||
|
||||
// Removes the namespace.
|
||||
namespace zpl_
|
||||
@ -16,30 +29,32 @@ namespace zpl_
|
||||
// Don't expose internals
|
||||
not namespace zpl__
|
||||
|
||||
not word ZPL_IMPLEMENTATION
|
||||
// Macro exposure
|
||||
//namespace ZPL_
|
||||
//not word ZPL_IMPLEMENTATION
|
||||
|
||||
word cast, zpl_cast
|
||||
word zpl_strncmp, str_compare
|
||||
word zpl_strcmp, str_compare
|
||||
|
||||
// Undesired typedefs
|
||||
word zpl_i8, s8
|
||||
word zpl_i16, s16
|
||||
word zpl_i32, s32
|
||||
word zpl_i64, s64
|
||||
word zpl_u8, u8
|
||||
word zpl_u16, u16
|
||||
word zpl_u32, u32
|
||||
word zpl_u64, u64
|
||||
word zpl_intptr, sptr
|
||||
word zpl_i8, s8
|
||||
word zpl_i16, s16
|
||||
word zpl_i32, s32
|
||||
word zpl_i64, s64
|
||||
word zpl_u8, u8
|
||||
word zpl_u16, u16
|
||||
word zpl_u32, u32
|
||||
word zpl_u64, u64
|
||||
word zpl_intptr, sptr
|
||||
word zpl_uintptr, uptr
|
||||
word zpl_usize, uw
|
||||
word zpl_isize, sw
|
||||
word zpl_usize, uw
|
||||
word zpl_isize, sw
|
||||
|
||||
// Undesired exposures.
|
||||
//not word zpl_allocator
|
||||
//not word zpl_arena
|
||||
not word zpl_array
|
||||
//not word zpl_array
|
||||
//not word zpl_file
|
||||
//not word zpl_list
|
||||
//not word zpl_pool
|
||||
@ -47,6 +62,7 @@ not word zpl_array
|
||||
|
||||
// Conflicts with refactor
|
||||
word arena, a_arena
|
||||
word array, a_array
|
||||
word alloc, a_allocator
|
||||
word file, a_file
|
||||
word file_size, fsize
|
||||
@ -55,20 +71,20 @@ word opts, a_opts
|
||||
word pool, a_pool
|
||||
|
||||
// Conflicts with std. (Uncomment if using c externs)
|
||||
//not word zpl_memchr
|
||||
//not word zpl_memmove
|
||||
//not word zpl_memset
|
||||
//not word zpl_memswap
|
||||
//not word zpl_memcopy
|
||||
//not word zpl_printf
|
||||
//not word zpl_printf_va
|
||||
//not word zpl_printf_err
|
||||
//not word zpl_printf_err_va
|
||||
//not word zpl_fprintf
|
||||
//not word zpl_fprintf_va
|
||||
//not word zpl_snprintf
|
||||
//not word zpl_snprintf_va
|
||||
//not word zpl_strchr
|
||||
//not word zpl_strlen
|
||||
//not word zpl_strnlen
|
||||
//not word zpl_exit
|
||||
not word zpl_memchr
|
||||
not word zpl_memmove
|
||||
not word zpl_memset
|
||||
not word zpl_memswap
|
||||
not word zpl_memcopy
|
||||
not word zpl_printf
|
||||
not word zpl_printf_va
|
||||
not word zpl_printf_err
|
||||
not word zpl_printf_err_va
|
||||
not word zpl_fprintf
|
||||
not word zpl_fprintf_va
|
||||
not word zpl_snprintf
|
||||
not word zpl_snprintf_va
|
||||
not word zpl_strchr
|
||||
not word zpl_strlen
|
||||
not word zpl_strnlen
|
||||
not word zpl_exit
|
||||
|
167
project/Bloat.cpp
Normal file
167
project/Bloat.cpp
Normal file
@ -0,0 +1,167 @@
|
||||
#define BLOAT_IMPL
|
||||
#include "Bloat.hpp"
|
||||
|
||||
|
||||
|
||||
namespace Memory
|
||||
{
|
||||
static zpl_arena Global_Arena {};
|
||||
|
||||
void setup()
|
||||
{
|
||||
zpl_arena_init_from_allocator( & Global_Arena, zpl_heap(), Initial_Reserve );
|
||||
|
||||
if ( Global_Arena.total_size == 0 )
|
||||
{
|
||||
zpl_assert_crash( "Failed to reserve memory for Tests:: Global_Arena" );
|
||||
}
|
||||
}
|
||||
|
||||
void resize( uw new_size )
|
||||
{
|
||||
void* new_memory = zpl_resize( zpl_heap(), Global_Arena.physical_start, Global_Arena.total_size, new_size );
|
||||
|
||||
if ( new_memory == nullptr )
|
||||
{
|
||||
fatal("Failed to resize global arena!");
|
||||
}
|
||||
|
||||
Global_Arena.physical_start = new_memory;
|
||||
Global_Arena.total_size = new_size;
|
||||
}
|
||||
|
||||
void cleanup()
|
||||
{
|
||||
zpl_arena_free( & Global_Arena);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool opts_custom_add(zpl_opts* opts, zpl_opts_entry *t, char* b)
|
||||
{
|
||||
if (t->type != ZPL_OPTS_STRING)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
t->text = zpl_string_append_length(t->text, " ", 1);
|
||||
t->text = zpl_string_appendc( t->text, b );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
b32 opts_custom_compile(zpl_opts *opts, int argc, char **argv)
|
||||
{
|
||||
zpl_b32 had_errors = false;
|
||||
|
||||
for (int i = 1; i < argc; ++i)
|
||||
{
|
||||
char* arg = argv[i];
|
||||
|
||||
if (*arg)
|
||||
{
|
||||
arg = (char*)zpl_str_trim(arg, false);
|
||||
|
||||
if (*arg == '-')
|
||||
{
|
||||
zpl_opts_entry* entry = 0;
|
||||
zpl_b32 checkln = false;
|
||||
if ( *(arg + 1) == '-')
|
||||
{
|
||||
checkln = true;
|
||||
++arg;
|
||||
}
|
||||
|
||||
char *b = arg + 1, *e = b;
|
||||
|
||||
while (zpl_char_is_alphanumeric(*e) || *e == '-' || *e == '_') {
|
||||
++e;
|
||||
}
|
||||
|
||||
entry = zpl__opts_find(opts, b, (e - b), checkln);
|
||||
|
||||
if (entry)
|
||||
{
|
||||
char *ob = b;
|
||||
b = e;
|
||||
|
||||
/**/
|
||||
if (*e == '=')
|
||||
{
|
||||
if (entry->type == ZPL_OPTS_FLAG)
|
||||
{
|
||||
*e = '\0';
|
||||
zpl__opts_push_error(opts, ob, ZPL_OPTS_ERR_EXTRA_VALUE);
|
||||
had_errors = true;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
b = e = e + 1;
|
||||
}
|
||||
else if (*e == '\0')
|
||||
{
|
||||
char *sp = argv[i+1];
|
||||
|
||||
if (sp && *sp != '-' && (zpl_array_count(opts->positioned) < 1 || entry->type != ZPL_OPTS_FLAG))
|
||||
{
|
||||
if (entry->type == ZPL_OPTS_FLAG)
|
||||
{
|
||||
zpl__opts_push_error(opts, b, ZPL_OPTS_ERR_EXTRA_VALUE);
|
||||
had_errors = true;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
arg = sp;
|
||||
b = e = sp;
|
||||
++i;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (entry->type != ZPL_OPTS_FLAG)
|
||||
{
|
||||
zpl__opts_push_error(opts, ob, ZPL_OPTS_ERR_MISSING_VALUE);
|
||||
had_errors = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
entry->met = true;
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
e = (char *)zpl_str_control_skip(e, '\0');
|
||||
zpl__opts_set_value(opts, entry, b);
|
||||
|
||||
if ( (i + 1) < argc )
|
||||
{
|
||||
for ( b = argv[i + 1]; i < argc && b[0] != '-'; i++, b = argv[i + 1] )
|
||||
{
|
||||
opts_custom_add(opts, entry, b );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
zpl__opts_push_error(opts, b, ZPL_OPTS_ERR_OPTION);
|
||||
had_errors = true;
|
||||
}
|
||||
}
|
||||
else if (zpl_array_count(opts->positioned))
|
||||
{
|
||||
zpl_opts_entry *l = zpl_array_back(opts->positioned);
|
||||
zpl_array_pop(opts->positioned);
|
||||
zpl__opts_set_value(opts, l, arg);
|
||||
}
|
||||
else
|
||||
{
|
||||
zpl__opts_push_error(opts, arg, ZPL_OPTS_ERR_VALUE);
|
||||
had_errors = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return !had_errors;
|
||||
}
|
146
project/IO.cpp
Normal file
146
project/IO.cpp
Normal file
@ -0,0 +1,146 @@
|
||||
#include "IO.hpp"
|
||||
|
||||
|
||||
namespace IO
|
||||
{
|
||||
using array_string = zpl_array( zpl_string );
|
||||
|
||||
namespace StaticData
|
||||
{
|
||||
array_string Sources = nullptr;
|
||||
array_string Destinations = nullptr;
|
||||
zpl_string Specification = nullptr;
|
||||
|
||||
// Current source and destination index.
|
||||
// Used to keep track of which file get_next_source or write refer to.
|
||||
sw Current = -1;
|
||||
char* Current_Content = nullptr;
|
||||
uw Current_Size = 0;
|
||||
uw Largest_Src_Size = 0;
|
||||
|
||||
zpl_arena MemSpec;
|
||||
zpl_arena MemSrc;
|
||||
}
|
||||
using namespace StaticData;
|
||||
|
||||
|
||||
void prepare()
|
||||
{
|
||||
const sw num_srcs = zpl_array_count( Sources );
|
||||
|
||||
// Determine the largest content size.
|
||||
sw left = num_srcs;
|
||||
zpl_string* path = Sources;
|
||||
do
|
||||
{
|
||||
zpl_file src = {};
|
||||
zpl_file_error error = zpl_file_open( & src, *path );
|
||||
|
||||
if ( error != ZPL_FILE_ERROR_NONE )
|
||||
{
|
||||
fatal("IO::Prepare - Could not open source file: %s", *path );
|
||||
}
|
||||
|
||||
const sw fsize = zpl_file_size( & src );
|
||||
|
||||
if ( fsize > Largest_Src_Size )
|
||||
{
|
||||
Largest_Src_Size = fsize;
|
||||
}
|
||||
|
||||
zpl_file_close( & src );
|
||||
}
|
||||
while ( path++, left--, left > 1 );
|
||||
|
||||
uw persist_size = Largest_Src_Size * 2 + 8;
|
||||
|
||||
zpl_arena_init_from_allocator( & MemSrc, zpl_heap(), persist_size );
|
||||
}
|
||||
|
||||
void cleanup()
|
||||
{
|
||||
zpl_arena_free( & MemSpec );
|
||||
zpl_arena_free( & MemSrc );
|
||||
}
|
||||
|
||||
Array_Line get_specification()
|
||||
{
|
||||
zpl_file file {};
|
||||
zpl_file_error error = zpl_file_open( & file, Specification);
|
||||
|
||||
if ( error != ZPL_FILE_ERROR_NONE )
|
||||
{
|
||||
fatal("Could not open the specification file: %s", Specification);
|
||||
}
|
||||
|
||||
sw fsize = scast( sw, zpl_file_size( & file ) );
|
||||
|
||||
if ( fsize <= 0 )
|
||||
{
|
||||
fatal("No content in specificaiton to process");
|
||||
}
|
||||
|
||||
zpl_arena_init_from_allocator( & MemSpec, zpl_heap(), fsize * 3 + 8 );
|
||||
|
||||
char* content = rcast( char*, zpl_alloc( zpl_arena_allocator( & MemSpec), fsize + 1) );
|
||||
|
||||
zpl_file_read( & file, content, fsize);
|
||||
zpl_file_close( & file );
|
||||
|
||||
content[fsize] = 0;
|
||||
|
||||
Array_Line lines = zpl_str_split_lines( zpl_arena_allocator( & MemSpec ), content, false );
|
||||
return lines;
|
||||
}
|
||||
|
||||
char* get_next_source()
|
||||
{
|
||||
zpl_memset( MemSrc.physical_start, 0, MemSrc.total_allocated);
|
||||
zpl_free_all( zpl_arena_allocator( & MemSrc) );
|
||||
|
||||
Current++;
|
||||
|
||||
zpl_file file {};
|
||||
zpl_file_error error = zpl_file_open( & file, Sources[Current]);
|
||||
|
||||
if ( error != ZPL_FILE_ERROR_NONE )
|
||||
{
|
||||
fatal("IO::get_next_source - Could not open the source file: %s", Sources[Current]);
|
||||
}
|
||||
|
||||
auto size = zpl_file_size( & file );
|
||||
Current_Size = scast( sw, size );
|
||||
|
||||
if ( Current_Size <= 0 )
|
||||
return nullptr;
|
||||
|
||||
Current_Content = rcast( char* , zpl_alloc( zpl_arena_allocator( & MemSrc), Current_Size + 1) );
|
||||
|
||||
zpl_file_read( & file, Current_Content, Current_Size );
|
||||
zpl_file_close( & file );
|
||||
|
||||
Current_Content[Current_Size] = 0;
|
||||
Current_Size++;
|
||||
|
||||
return Current_Content;
|
||||
}
|
||||
|
||||
void write( zpl_string refacotred )
|
||||
{
|
||||
if ( refacotred == nullptr)
|
||||
return;
|
||||
|
||||
zpl_string dst = Destinations[Current];
|
||||
|
||||
zpl_file file_dest {};
|
||||
zpl_file_error error = zpl_file_create( & file_dest, dst );
|
||||
|
||||
if ( error != ZPL_FILE_ERROR_NONE )
|
||||
{
|
||||
fatal( "Unable to open destination file: %s\n", dst );
|
||||
}
|
||||
|
||||
zpl_file_write( & file_dest, refacotred, zpl_string_length(refacotred) );
|
||||
zpl_file_close( & file_dest );
|
||||
}
|
||||
}
|
25
project/IO.hpp
Normal file
25
project/IO.hpp
Normal file
@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
#include "Bloat.hpp"
|
||||
|
||||
|
||||
namespace IO
|
||||
{
|
||||
ct uw Path_Size_Largest = zpl_kilobytes(1);
|
||||
|
||||
// Preps the IO by loading all the files and checking to see what the largest size is.
|
||||
// The file with the largest size is used to determine the size of the persistent memory.
|
||||
void prepare();
|
||||
|
||||
// Frees the persistent and transient memory arenas.
|
||||
void cleanup();
|
||||
|
||||
// Provides the content of the specification.
|
||||
Array_Line get_specification();
|
||||
|
||||
// Provides the content of the next source, broken up as a series of lines.
|
||||
char* get_next_source();
|
||||
|
||||
// Writes the refactored content ot the current corresponding destination.
|
||||
void write( zpl_string refactored );
|
||||
}
|
41
project/Readme.md
Normal file
41
project/Readme.md
Normal file
@ -0,0 +1,41 @@
|
||||
# Documentation
|
||||
|
||||
The current implementation is divided into 4 parts:
|
||||
|
||||
* Bloat : General library provider.
|
||||
* IO : File I/O processing.
|
||||
* Spec : Specification parsing.
|
||||
* Refactor : Entrypoint, argument parsing, and refactoring process.
|
||||
|
||||
The files are setup to compile as one unit. As such the source files for Bloat, IO, and Spec are located within `refactor.cpp`.
|
||||
|
||||
Bloat contains some aliasing of some C++ keywords and does not use the standard library. Instead a library called ZPL is used (Single header replacement).
|
||||
|
||||
The program has pretty much no optimizations made to it, its just regular loops with no threading.
|
||||
Just tried to keep the memory at a reasonable size for what it does.
|
||||
|
||||
The program execution is pretty much outlined quite clearly in `int main()`.
|
||||
|
||||
1. Setup initial reserve of global memory in an arena.
|
||||
2. Parse the arguments provided.
|
||||
3. Prepare IO's memory for retreviing content.
|
||||
4. Reserve memory for the refactor buffer.
|
||||
5. Parse the specification file
|
||||
6. Iterate through all provided files to refactor and write the refactored content to the specificed destintation files.
|
||||
7. Cleanup all reserves of memory`*`
|
||||
|
||||
|
||||
`*` This technically can be skipped on windows, may be worth doing to reduce latency of process shutdown.
|
||||
|
||||
There are constraints for specific variables;
|
||||
|
||||
* `Path_Size_Largest` : Longest path size is set to 1 KB of characters.
|
||||
* `Token_Max_Length` : Set to 1 KB characters as well.
|
||||
* `Array_Reserve_Num` : Is set to 4 KB.
|
||||
* Initial Global arena size : Set to 2 megabytes.
|
||||
|
||||
The `Path_Size_Largest` and `Token_Max_Length` are compile-time constraints that the runtime will not have a fallback for, if 1 KB is not enough it will need to be changed for your use case.
|
||||
|
||||
`Array_Reserve_Num` is used to dictate the assumed amount of tokens will be held in total for any of spec's arrays holding ignores and refactor entries. If any of the array's exceed 4 KB they will grow triggering a resize which will bog down the speed of the refactor. Adjust if you think you can increase or lower for use case.
|
||||
|
||||
Initial Global arena size is a finicy thing, its most likely going to be custom allocator at one point so that it can handle growing properly, right now its just grows if the amount of memory file paths will need for sources is greater than 1 MB.
|
341
project/Spec.cpp
Normal file
341
project/Spec.cpp
Normal file
@ -0,0 +1,341 @@
|
||||
#include "Spec.hpp"
|
||||
|
||||
#include "IO.hpp"
|
||||
|
||||
|
||||
|
||||
namespace Spec
|
||||
{
|
||||
ct uw Array_Reserve_Num = zpl_kilobytes(4);
|
||||
ct uw Token_Max_Length = zpl_kilobytes(1);
|
||||
|
||||
namespace StaticData
|
||||
{
|
||||
// Custom comment signatures not supported yet (only C/C++ comments for now)
|
||||
bool Ignore_Comments = false;
|
||||
|
||||
Array_Entry Ignore_Includes;
|
||||
Array_Entry Ignore_Words;
|
||||
Array_Entry Ignore_Regexes;
|
||||
Array_Entry Ignore_Namespaces;
|
||||
|
||||
Array_Entry Includes;
|
||||
Array_Entry Words;
|
||||
Array_Entry Regexes;
|
||||
Array_Entry Namespaces;
|
||||
|
||||
u32 Sig_Smallest = Token_Max_Length;
|
||||
}
|
||||
using namespace StaticData;
|
||||
|
||||
void cleanup()
|
||||
{
|
||||
zpl_array_free( Ignore_Includes );
|
||||
zpl_array_free( Ignore_Words );
|
||||
zpl_array_free( Ignore_Namespaces );
|
||||
zpl_array_free( Includes );
|
||||
zpl_array_free( Words );
|
||||
zpl_array_free( Namespaces );
|
||||
}
|
||||
|
||||
|
||||
// Helper function for process().
|
||||
forceinline
|
||||
void find_next_token( Tok& type, zpl_string& token, char*& line, u32& length )
|
||||
{
|
||||
zpl_string_clear( token );
|
||||
length = 0;
|
||||
|
||||
#define current line[length]
|
||||
if (type == Tok::Include)
|
||||
{
|
||||
// Allows for '.'
|
||||
while ( zpl_char_is_alphanumeric( current )
|
||||
|| current == '_'
|
||||
|| current == '.'
|
||||
|| current == '/'
|
||||
|| current == '\\' )
|
||||
{
|
||||
length++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while ( zpl_char_is_alphanumeric( current ) || current == '_' )
|
||||
{
|
||||
length++;
|
||||
}
|
||||
}
|
||||
#undef current
|
||||
|
||||
if ( length == 0 )
|
||||
{
|
||||
fatal("Failed to find valid initial token");
|
||||
}
|
||||
|
||||
token = zpl_string_append_length( token, line, length );
|
||||
line += length;
|
||||
}
|
||||
|
||||
void parse()
|
||||
{
|
||||
static zpl_string token = zpl_string_make_reserve( g_allocator, zpl_kilobytes(1));
|
||||
|
||||
static bool Done = false;
|
||||
if (Done)
|
||||
{
|
||||
zpl_array_clear( Ignore_Includes );
|
||||
zpl_array_clear( Ignore_Words );
|
||||
zpl_array_clear( Ignore_Namespaces );
|
||||
zpl_array_clear( Includes );
|
||||
zpl_array_clear( Words );
|
||||
zpl_array_clear( Namespaces );
|
||||
}
|
||||
else
|
||||
{
|
||||
Done = true;
|
||||
|
||||
zpl_array_init_reserve( Ignore_Includes, zpl_heap(), Array_Reserve_Num );
|
||||
zpl_array_init_reserve( Ignore_Words, zpl_heap(), Array_Reserve_Num );
|
||||
zpl_array_init_reserve( Ignore_Namespaces, zpl_heap(), Array_Reserve_Num );
|
||||
zpl_array_init_reserve( Includes, zpl_heap(), Array_Reserve_Num );
|
||||
zpl_array_init_reserve( Words, zpl_heap(), Array_Reserve_Num );
|
||||
zpl_array_init_reserve( Namespaces, zpl_heap(), Array_Reserve_Num );
|
||||
}
|
||||
|
||||
Array_Line lines = IO::get_specification();
|
||||
|
||||
sw left = zpl_array_count( lines );
|
||||
|
||||
if ( left == 0 )
|
||||
{
|
||||
fatal("Spec::parse: lines array imporoperly setup");
|
||||
}
|
||||
|
||||
// Skip the first line as its the version number and we only support __VERSION 1.
|
||||
left--;
|
||||
lines++;
|
||||
|
||||
do
|
||||
{
|
||||
char* line = * lines;
|
||||
|
||||
// Ignore line if its a comment
|
||||
if ( line[0] == '/' && line[1] == '/')
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Remove indent
|
||||
{
|
||||
while ( zpl_char_is_space( line[0] ) )
|
||||
line++;
|
||||
|
||||
if ( line[0] == '\0' )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
u32 length = 0;
|
||||
Tok type = Tok::Num_Tok;
|
||||
bool ignore = false;
|
||||
Entry entry {};
|
||||
|
||||
log_fmt("\nIGNORE WORD COUNT: %d", zpl_array_count(Ignore_Words));
|
||||
|
||||
|
||||
// Find a valid token
|
||||
find_next_token( type, token, line, length );
|
||||
|
||||
// Will be reguarded as an ignore.
|
||||
if ( is_tok( Tok::Not, token, length ))
|
||||
{
|
||||
ignore = true;
|
||||
|
||||
while ( zpl_char_is_space( line[0] ) )
|
||||
line++;
|
||||
|
||||
if ( line[0] == '\0' )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Find the category token
|
||||
find_next_token( type, token, line, length );
|
||||
}
|
||||
|
||||
if ( is_tok( Tok::Comment, token, length ) )
|
||||
{
|
||||
// Custom comment signatures not supported yet (only C/C++ comments for now)
|
||||
Ignore_Comments = true;
|
||||
|
||||
continue;
|
||||
}
|
||||
else if ( is_tok( Tok::Word, token, length ) )
|
||||
{
|
||||
type = Tok::Word;
|
||||
}
|
||||
else if ( is_tok( Tok::Namespace, token, length ) )
|
||||
{
|
||||
type = Tok::Namespace;
|
||||
}
|
||||
else if ( is_tok( Tok::Include, token, length ))
|
||||
{
|
||||
type = Tok::Include;
|
||||
}
|
||||
else
|
||||
{
|
||||
log_fmt( "Sec::Parse - Unsupported keyword: %s on line: %d", token, zpl_array_count(lines) - left );
|
||||
continue;
|
||||
}
|
||||
|
||||
// Find the first argument
|
||||
while ( zpl_char_is_space( line[0] ) )
|
||||
line++;
|
||||
|
||||
if ( line[0] == '\0' )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
find_next_token( type, token, line, length );
|
||||
|
||||
// First argument is signature.
|
||||
entry.Sig = zpl_string_make_length( g_allocator, token, length );
|
||||
|
||||
if ( length < StaticData::Sig_Smallest )
|
||||
StaticData::Sig_Smallest = length;
|
||||
|
||||
if ( line[0] == '\0' || ignore )
|
||||
{
|
||||
switch ( type )
|
||||
{
|
||||
case Tok::Word:
|
||||
if ( ignore)
|
||||
zpl_array_append( Ignore_Words, entry );
|
||||
|
||||
else
|
||||
zpl_array_append( Words, entry );
|
||||
break;
|
||||
|
||||
case Tok::Namespace:
|
||||
if ( ignore)
|
||||
zpl_array_append( Ignore_Namespaces, entry );
|
||||
|
||||
else
|
||||
zpl_array_append( Namespaces, entry );
|
||||
break;
|
||||
|
||||
case Tok::Include:
|
||||
if ( ignore)
|
||||
zpl_array_append( Ignore_Includes, entry );
|
||||
|
||||
else
|
||||
zpl_array_append( Includes, entry );
|
||||
break;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// Look for second argument indicator
|
||||
{
|
||||
bool bSkip = false;
|
||||
|
||||
while ( line[0] != ',' )
|
||||
{
|
||||
if ( line[0] == '\0' )
|
||||
{
|
||||
switch ( type )
|
||||
{
|
||||
case Tok::Word:
|
||||
zpl_array_append( Words, entry );
|
||||
break;
|
||||
|
||||
case Tok::Namespace:
|
||||
zpl_array_append( Namespaces, entry );
|
||||
break;
|
||||
|
||||
case Tok::Include:
|
||||
zpl_array_append( Includes, entry );
|
||||
break;
|
||||
}
|
||||
|
||||
bSkip = true;
|
||||
break;
|
||||
}
|
||||
|
||||
line++;
|
||||
}
|
||||
|
||||
if ( bSkip )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Eat the argument delimiter.
|
||||
line++;
|
||||
|
||||
// Remove spacing
|
||||
{
|
||||
bool bSkip = true;
|
||||
|
||||
while ( zpl_char_is_space( line[0] ) )
|
||||
line++;
|
||||
|
||||
if ( line[0] == '\0' )
|
||||
{
|
||||
switch ( type )
|
||||
{
|
||||
case Tok::Word:
|
||||
zpl_array_append( Words, entry );
|
||||
break;
|
||||
|
||||
case Tok::Namespace:
|
||||
zpl_array_append( Namespaces, entry );
|
||||
break;
|
||||
|
||||
case Tok::Include:
|
||||
zpl_array_append( Includes, entry );
|
||||
break;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
find_next_token( type, token, line, length );
|
||||
|
||||
// Second argument is substitute.
|
||||
entry.Sub = zpl_string_make_length( g_allocator, token, length );
|
||||
|
||||
switch ( type )
|
||||
{
|
||||
case Tok::Word:
|
||||
zpl_array_append( Words, entry );
|
||||
continue;
|
||||
|
||||
case Tok::Namespace:
|
||||
zpl_array_append( Namespaces, entry );
|
||||
continue;
|
||||
|
||||
case Tok::Include:
|
||||
zpl_array_append( Includes, entry );
|
||||
continue;
|
||||
}
|
||||
}
|
||||
while ( lines++, left--, left > 0 );
|
||||
|
||||
Spec::Entry* ignore = Spec::Ignore_Words;
|
||||
sw ignores_left = zpl_array_count( Spec::Ignore_Words);
|
||||
|
||||
zpl_printf("\nIgnores: ");
|
||||
for ( ; ignores_left; ignores_left--, ignore++ )
|
||||
{
|
||||
zpl_printf("\n%s", ignore->Sig);
|
||||
}
|
||||
zpl_printf("\n");
|
||||
}
|
||||
}
|
76
project/Spec.hpp
Normal file
76
project/Spec.hpp
Normal file
@ -0,0 +1,76 @@
|
||||
#pragma once
|
||||
#include "Bloat.hpp"
|
||||
|
||||
|
||||
namespace Spec
|
||||
{
|
||||
enum Tok
|
||||
{
|
||||
Not,
|
||||
Comment,
|
||||
Include,
|
||||
Namespace,
|
||||
Word,
|
||||
|
||||
Num_Tok
|
||||
};
|
||||
|
||||
forceinline
|
||||
char const* str_tok( Tok tok )
|
||||
{
|
||||
static
|
||||
char const* tok_to_str[ Tok::Num_Tok ] =
|
||||
{
|
||||
"not",
|
||||
"comments",
|
||||
"include",
|
||||
"namespace",
|
||||
"word",
|
||||
};
|
||||
|
||||
return tok_to_str[ tok ];
|
||||
}
|
||||
|
||||
forceinline
|
||||
char strlen_tok( Tok tok )
|
||||
{
|
||||
static
|
||||
const u8 tok_to_len[ Tok::Num_Tok ] =
|
||||
{
|
||||
3,
|
||||
8,
|
||||
7,
|
||||
9,
|
||||
4,
|
||||
};
|
||||
|
||||
return tok_to_len[ tok ];
|
||||
}
|
||||
|
||||
forceinline
|
||||
bool is_tok( Tok tok, zpl_string str, u32 length )
|
||||
{
|
||||
char const* tok_str = str_tok(tok);
|
||||
const u8 tok_len = strlen_tok(tok);
|
||||
|
||||
if ( tok_len != length)
|
||||
return false;
|
||||
|
||||
s32 result = zpl_strncmp( tok_str, str, tok_len );
|
||||
|
||||
return result == 0;
|
||||
}
|
||||
|
||||
struct Entry
|
||||
{
|
||||
zpl_string Sig = nullptr; // Signature
|
||||
zpl_string Sub = nullptr; // Substitute
|
||||
};
|
||||
|
||||
using Array_Entry = zpl_array( Entry );
|
||||
|
||||
void cleanup();
|
||||
|
||||
// Extract the specificication from the provided file.
|
||||
void parse();
|
||||
}
|
@ -1,13 +1,13 @@
|
||||
/*
|
||||
BLOAT.
|
||||
|
||||
ZPL requires ZPL_IMPLEMENTATION whereever this library is included.
|
||||
|
||||
This file assumes it will be included in one compilation unit.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef BLOAT_IMPL
|
||||
# define ZPL_IMPLEMENTATION
|
||||
#endif
|
||||
|
||||
#if __clang__
|
||||
# pragma clang diagnostic ignored "-Wunused-const-variable"
|
||||
# pragma clang diagnostic ignored "-Wswitch"
|
||||
@ -33,14 +33,13 @@
|
||||
// # define ZPL_MODULE_REGEX
|
||||
// # define ZPL_MODULE_EVENT
|
||||
// # define ZPL_MODULE_DLL
|
||||
# define ZPL_MODULE_OPTS
|
||||
# define ZPL_MODULE_OPTS
|
||||
// # define ZPL_MODULE_PROCESS
|
||||
// # define ZPL_MODULE_MAT
|
||||
// # define ZPL_MODULE_THREADING
|
||||
// # define ZPL_MODULE_JOBS
|
||||
// # define ZPL_MODULE_PARSER
|
||||
#include "zpl.h"
|
||||
// }
|
||||
|
||||
#if __clang__
|
||||
# pragma clang diagnostic pop
|
||||
@ -59,18 +58,19 @@
|
||||
#define rcast( Type_, Value_ ) reinterpret_cast< Type_ >( Value_ )
|
||||
#define pcast( Type_, Value_ ) ( * (Type_*)( & Value_ ) )
|
||||
|
||||
#define do_once() \
|
||||
do \
|
||||
{ \
|
||||
static \
|
||||
bool Done = true; \
|
||||
if ( Done ) \
|
||||
return; \
|
||||
Done = false; \
|
||||
} \
|
||||
while(0) \
|
||||
#define do_once() \
|
||||
do \
|
||||
{ \
|
||||
static \
|
||||
bool Done = false; \
|
||||
if ( Done ) \
|
||||
return; \
|
||||
Done = true; \
|
||||
} \
|
||||
while(0) \
|
||||
|
||||
|
||||
using b32 = zpl_b32;
|
||||
using s8 = zpl_i8;
|
||||
using s32 = zpl_i32;
|
||||
using s64 = zpl_i64;
|
||||
@ -81,39 +81,39 @@ using f64 = zpl_f64;
|
||||
using uw = zpl_usize;
|
||||
using sw = zpl_isize;
|
||||
|
||||
using Line = char*;
|
||||
using Array_Line = zpl_array( Line );
|
||||
|
||||
|
||||
ct char const* Msg_Invalid_Value = "INVALID VALUE PROVIDED";
|
||||
|
||||
|
||||
namespace Memory
|
||||
{
|
||||
zpl_arena Global_Arena {};
|
||||
ct uw Initial_Reserve = zpl_megabytes(2);
|
||||
|
||||
extern zpl_arena Global_Arena;
|
||||
#define g_allocator zpl_arena_allocator( & Memory::Global_Arena)
|
||||
|
||||
void setup()
|
||||
{
|
||||
zpl_arena_init_from_allocator( & Global_Arena, zpl_heap(), zpl_megabytes(10) );
|
||||
|
||||
if ( Global_Arena.total_size == 0 )
|
||||
{
|
||||
zpl_assert_crash( "Failed to reserve memory for Tests:: Global_Arena" );
|
||||
}
|
||||
}
|
||||
|
||||
void cleanup()
|
||||
{
|
||||
zpl_arena_free( & Global_Arena);
|
||||
}
|
||||
void setup();
|
||||
void resize( uw new_size );
|
||||
void cleanup();
|
||||
}
|
||||
|
||||
sw log_fmt(char const *fmt, ...)
|
||||
{
|
||||
// Had to be made to support multiple sub-arguments per "opt" argument.
|
||||
b32 opts_custom_compile(zpl_opts *opts, int argc, char **argv);
|
||||
|
||||
inline
|
||||
sw log_fmt(char const *fmt, ...)
|
||||
{
|
||||
#if Build_Debug
|
||||
sw res;
|
||||
va_list va;
|
||||
|
||||
va_start(va, fmt);
|
||||
res = zpl_printf_va(fmt, va);
|
||||
va_end(va);
|
||||
|
||||
return res;
|
||||
|
||||
#else
|
||||
@ -121,6 +121,7 @@ namespace Memory
|
||||
#endif
|
||||
}
|
||||
|
||||
inline
|
||||
void fatal(char const *fmt, ...)
|
||||
{
|
||||
zpl_local_persist zpl_thread_local
|
||||
@ -139,6 +140,6 @@ void fatal(char const *fmt, ...)
|
||||
zpl_printf_err_va( fmt, va);
|
||||
va_end(va);
|
||||
|
||||
exit(1);
|
||||
zpl_exit(1);
|
||||
#endif
|
||||
}
|
||||
|
1005
project/refactor.cpp
1005
project/refactor.cpp
File diff suppressed because it is too large
Load Diff
63
refactor.10x
Normal file
63
refactor.10x
Normal file
@ -0,0 +1,63 @@
|
||||
<?xml version="1.0"?>
|
||||
<N10X>
|
||||
<Workspace>
|
||||
<IncludeFilter>*.*,</IncludeFilter>
|
||||
<ExcludeFilter>*.obj,*.lib,*.pch,*.dll,*.pdb,.vs,Debug,Release,x64,obj,*.user,Intermediate,.git,.idea,.vscode,</ExcludeFilter>
|
||||
<SyncFiles>true</SyncFiles>
|
||||
<Recursive>true</Recursive>
|
||||
<ShowEmptyFolders>true</ShowEmptyFolders>
|
||||
<IsVirtual>false</IsVirtual>
|
||||
<IsFolder>false</IsFolder>
|
||||
<BuildCommand></BuildCommand>
|
||||
<RebuildCommand></RebuildCommand>
|
||||
<BuildFileCommand></BuildFileCommand>
|
||||
<CleanCommand></CleanCommand>
|
||||
<BuildWorkingDirectory></BuildWorkingDirectory>
|
||||
<CancelBuild></CancelBuild>
|
||||
<RunCommand></RunCommand>
|
||||
<DebugCommand></DebugCommand>
|
||||
<ExePathCommand></ExePathCommand>
|
||||
<DebugSln></DebugSln>
|
||||
<UseVisualStudioEnvBat>false</UseVisualStudioEnvBat>
|
||||
<Configurations>
|
||||
<Configuration>Debug</Configuration>
|
||||
<Configuration>Release</Configuration>
|
||||
</Configurations>
|
||||
<Platforms>
|
||||
<Platform>x64</Platform>
|
||||
</Platforms>
|
||||
<AdditionalIncludePaths>
|
||||
<AdditionalIncludePath>C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.35.32215\include</AdditionalIncludePath>
|
||||
<AdditionalIncludePath>C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.35.32215\ATLMFC\include</AdditionalIncludePath>
|
||||
<AdditionalIncludePath>C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Auxiliary\VS\include</AdditionalIncludePath>
|
||||
<AdditionalIncludePath>C:\Program Files (x86)\Windows Kits\10\include\10.0.22621.0\ucrt</AdditionalIncludePath>
|
||||
<AdditionalIncludePath>C:\Program Files (x86)\Windows Kits\10\\include\10.0.22621.0\\um</AdditionalIncludePath>
|
||||
<AdditionalIncludePath>C:\Program Files (x86)\Windows Kits\10\\include\10.0.22621.0\\shared</AdditionalIncludePath>
|
||||
<AdditionalIncludePath>C:\Program Files (x86)\Windows Kits\10\\include\10.0.22621.0\\winrt</AdditionalIncludePath>
|
||||
<AdditionalIncludePath>C:\Program Files (x86)\Windows Kits\10\\include\10.0.22621.0\\cppwinrt</AdditionalIncludePath>
|
||||
<AdditionalIncludePath>C:\Program Files (x86)\Windows Kits\NETFXSDK\4.8\include\um</AdditionalIncludePath>
|
||||
</AdditionalIncludePaths>
|
||||
<Defines>
|
||||
<Define></Define>
|
||||
</Defines>
|
||||
<ConfigProperties>
|
||||
<ConfigAndPlatform>
|
||||
<Name>Debug:x64</Name>
|
||||
<Defines></Defines>
|
||||
<ForceIncludes>
|
||||
<ForceInclude>./project</ForceInclude>
|
||||
<ForceInclude>./thirdparty</ForceInclude>
|
||||
</ForceIncludes>
|
||||
</ConfigAndPlatform>
|
||||
<Config>
|
||||
<Name>Debug</Name>
|
||||
<Defines></Defines>
|
||||
</Config>
|
||||
<Platform>
|
||||
<Name>x64</Name>
|
||||
<Defines></Defines>
|
||||
</Platform>
|
||||
</ConfigProperties>
|
||||
<Children></Children>
|
||||
</Workspace>
|
||||
</N10X>
|
@ -42,46 +42,39 @@ if ( $type )
|
||||
|
||||
Start-Process meson $args_meson -NoNewWindow -Wait -WorkingDirectory $path_scripts
|
||||
}
|
||||
#endregion Regular Build
|
||||
|
||||
|
||||
#region Test Build
|
||||
write-host "`n`nBuilding Test`n"
|
||||
|
||||
if ( -not( Test-Path $path_build ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
$args_ninja = @()
|
||||
$args_ninja += "-C"
|
||||
$args_ninja += $path_build
|
||||
|
||||
Start-Process ninja $args_ninja -Wait -NoNewWindow -WorkingDirectory $path_root
|
||||
#endregion Regular Build
|
||||
|
||||
# Refactor thirdparty libraries
|
||||
& .\refactor_and_format.ps1
|
||||
|
||||
if ( $test -eq $false )
|
||||
if ( $test -eq $true )
|
||||
{
|
||||
return;
|
||||
#region Test Build
|
||||
write-host "`n`nBuilding Test`n"
|
||||
|
||||
# Refactor thirdparty libraries
|
||||
& .\refactor_and_format.ps1
|
||||
|
||||
$path_test = Join-Path $path_root test
|
||||
$path_test_build = Join-Path $path_test build
|
||||
|
||||
if ( -not( Test-Path $path_test_build ) )
|
||||
{
|
||||
$args_meson = @()
|
||||
$args_meson += "setup"
|
||||
$args_meson += $path_test_build
|
||||
|
||||
Start-Process meson $args_meson -NoNewWindow -Wait -WorkingDirectory $path_test
|
||||
}
|
||||
|
||||
$args_ninja = @()
|
||||
$args_ninja += "-C"
|
||||
$args_ninja += $path_test_build
|
||||
|
||||
Start-Process ninja $args_ninja -Wait -NoNewWindow -WorkingDirectory $path_test
|
||||
#endregion Test Build
|
||||
}
|
||||
|
||||
$path_test = Join-Path $path_root test
|
||||
$path_test_build = Join-Path $path_test build
|
||||
|
||||
if ( -not( Test-Path $path_test_build ) )
|
||||
{
|
||||
$args_meson = @()
|
||||
$args_meson += "setup"
|
||||
$args_meson += $path_test_build
|
||||
|
||||
Start-Process meson $args_meson -NoNewWindow -Wait -WorkingDirectory $path_scripts
|
||||
}
|
||||
|
||||
$args_ninja = @()
|
||||
$args_ninja += "-C"
|
||||
$args_ninja += $path_build
|
||||
|
||||
Start-Process ninja $args_ninja -Wait -NoNewWindow -WorkingDirectory $path_test
|
||||
#endregion Test Build
|
||||
|
@ -12,3 +12,10 @@ if ( Test-Path $path_test_build )
|
||||
{
|
||||
Remove-Item $path_test_build -Recurse
|
||||
}
|
||||
|
||||
[string[]] $include = '*.h', '*.hpp', '*.cpp'
|
||||
[string[]] $exclude =
|
||||
|
||||
$files = Get-ChildItem -Recurse -Path $path_test -Include $include -Exclude $exclude
|
||||
|
||||
Remove-Item $files
|
||||
|
@ -1,5 +1,5 @@
|
||||
[string[]] $include = '*.c', '*.cc', '*.cpp'
|
||||
# [stirng[]] $exclude =
|
||||
[string[]] $include = 'refactor.cpp' #'*.c', '*.cc', '*.cpp'
|
||||
# [string[]] $exclude =
|
||||
|
||||
$path_root = git rev-parse --show-toplevel
|
||||
$path_proj = Join-Path $path_root project
|
||||
|
@ -1,4 +1,4 @@
|
||||
project( 'refactor', 'c', 'cpp', default_options : ['buildtype=debug'] )
|
||||
project( 'refactor', 'c', 'cpp', default_options : ['buildtype=release'] )
|
||||
|
||||
# add_global_arguments('-E', language : 'cpp')
|
||||
|
||||
|
@ -1,9 +1,10 @@
|
||||
[string[]] $include = '*.h', '*.hh', '*.hpp', '*.c', '*.cc', '*.cpp'
|
||||
[string[]] $exclude = '*.g.*', '*.refactor', 'bloat.refactored.hpp', 'refactor.refactored.cpp'
|
||||
[string[]] $exclude = '*.g.*', '*.refactor'
|
||||
|
||||
|
||||
$path_root = git rev-parse --show-toplevel
|
||||
$path_build = Join-Path $path_root build
|
||||
$path_project = Join-Path $path_root project
|
||||
$path_test = Join-Path $path_root test
|
||||
$path_thirdparty = Join-Path $path_root thirdparty
|
||||
|
||||
@ -11,25 +12,48 @@ $file_spec = Join-Path $path_test zpl.refactor
|
||||
$refactor = Join-Path $path_build refactor.exe
|
||||
|
||||
# Gather the files to be formatted.
|
||||
$targetFiles = @(Get-ChildItem -Recurse -Path $path_thirdparty -Include $include -Exclude $exclude | Select-Object -ExpandProperty FullName)
|
||||
|
||||
|
||||
write-host "Beginning refactor...`n"
|
||||
|
||||
$refactors = @(@())
|
||||
$targetFiles = @(Get-ChildItem -Recurse -Path $path_thirdparty -Include $include -Exclude $exclude | Select-Object -ExpandProperty FullName)
|
||||
$refactoredFiles = @()
|
||||
|
||||
foreach ( $file in $targetFiles )
|
||||
{
|
||||
$destination = Join-Path $path_test (Split-Path $file -leaf)
|
||||
$destination = $destination.Replace( '.h', '.refactored.h' )
|
||||
|
||||
$destination = $destination.Replace( '.c', '.refactored.c' )
|
||||
|
||||
$refactoredFiles += $destination
|
||||
}
|
||||
|
||||
|
||||
write-host "Beginning thirdpary refactor...`n"
|
||||
|
||||
$refactors = @(@())
|
||||
|
||||
if ( $false ){
|
||||
foreach ( $file in $targetFiles )
|
||||
{
|
||||
$destination = Join-Path $path_test (Split-Path $file -leaf)
|
||||
$destination = $destination.Replace( '.h', '.refactored.h' )
|
||||
|
||||
$refactorParams = @(
|
||||
"-src=$($file)",
|
||||
"-dst=$($destination)"
|
||||
"-spec=$($file_spec)"
|
||||
)
|
||||
|
||||
$refactors += (Start-Process $refactor $refactorParams -NoNewWindow -PassThru)
|
||||
}
|
||||
}
|
||||
else {
|
||||
$refactorParams = @(
|
||||
"-src=$($file)",
|
||||
"-dst=$($destination)"
|
||||
"-debug",
|
||||
"-num=$($targetFiles.Count)"
|
||||
"-src=$($targetFiles)",
|
||||
"-dst=$($refactoredFiles)",
|
||||
"-spec=$($file_spec)"
|
||||
)
|
||||
|
||||
$refactors += (Start-Process $refactor $refactorParams -NoNewWindow -PassThru)
|
||||
Start-Process $refactor $refactorParams -NoNewWindow -PassThru -Wait
|
||||
}
|
||||
|
||||
foreach ( $process in $refactors )
|
||||
@ -42,10 +66,40 @@ foreach ( $process in $refactors )
|
||||
|
||||
Write-Host "`nRefactoring complete`n`n"
|
||||
|
||||
write-host "Beginning project refactor...`n"
|
||||
|
||||
# Gather the files to be formatted.
|
||||
$targetFiles = @(Get-ChildItem -Recurse -Path $path_project -Include $include -Exclude $exclude | Select-Object -ExpandProperty FullName)
|
||||
$refactoredFiles = @()
|
||||
|
||||
$file_spec = Join-Path $path_test project.refactor
|
||||
|
||||
write-host "FILE SPEC:" $file_spec
|
||||
|
||||
foreach ( $file in $targetFiles )
|
||||
{
|
||||
$destination = Join-Path $path_test (Split-Path $file -leaf)
|
||||
$destination = $destination.Replace( '.hpp', '.refactored.hpp' )
|
||||
$destination = $destination.Replace( '.cpp', '.refactored.cpp' )
|
||||
|
||||
$refactoredFiles += $destination
|
||||
}
|
||||
|
||||
$refactorParams = @(
|
||||
"-debug",
|
||||
"-num=$($targetFiles.Count)"
|
||||
"-src=$($targetFiles)",
|
||||
"-dst=$($refactoredFiles)",
|
||||
"-spec=$($file_spec)"
|
||||
)
|
||||
|
||||
Start-Process $refactor $refactorParams -NoNewWindow -PassThru -Wait
|
||||
|
||||
write-host "`nRefactoring complete`n`n"
|
||||
|
||||
|
||||
# Can't format zpl library... (It hangs clang format)
|
||||
if ( $false )
|
||||
{
|
||||
if ( $false ) {
|
||||
Write-Host "Beginning format...`n"
|
||||
|
||||
# Format the files.
|
||||
|
Loading…
Reference in New Issue
Block a user