mirror of
https://github.com/Ed94/refactor.git
synced 2025-07-01 03:11:06 -07:00
Compare commits
18 Commits
add-licens
...
includes_n
Author | SHA1 | Date | |
---|---|---|---|
503df85733 | |||
c4f0b35a30 | |||
17458b4b4c | |||
1cd4287eb2 | |||
87c939e2b6 | |||
d0fad572bc | |||
97967e56d9 | |||
7e120ae5e9 | |||
231c893c6b | |||
d44f7ed6fa | |||
892d0cba64 | |||
aec095a9f0 | |||
9129b5a9fc | |||
d01625d464 | |||
71d9aa79eb | |||
d6345c58bf | |||
3e6ede0fbe | |||
6f76b43c12 |
11
.editorconfig
Normal file
11
.editorconfig
Normal file
@ -0,0 +1,11 @@
|
||||
[*.md]
|
||||
indent_style = tab
|
||||
indent_size = 4
|
||||
|
||||
[*.c]
|
||||
indent_style = tab
|
||||
indent_size = 4
|
||||
|
||||
[*.cpp]
|
||||
indent_style = tab
|
||||
indent_size = 4
|
7
.gitignore
vendored
Normal file
7
.gitignore
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
.idea
|
||||
|
||||
build/*
|
||||
|
||||
Test/*.h
|
||||
Test/*.hpp
|
||||
Test/*.cpp
|
35
.vscode/launch.json
vendored
35
.vscode/launch.json
vendored
@ -10,16 +10,37 @@
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build/refactor.exe",
|
||||
"args": [
|
||||
"-source=./thirdparty/zpl.h",
|
||||
"-destination=./Test/zpl.refactored.h",
|
||||
"-src=./thirdparty/zpl.h",
|
||||
"-dst=./Test/zpl.refactored.h",
|
||||
|
||||
"-specification=./Test/zpl.h.refactor"
|
||||
"-spec=./Test/zpl.refactor"
|
||||
],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "${workspaceRoot}",
|
||||
"environment": [],
|
||||
"console": "externalTerminal"
|
||||
}
|
||||
"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,12 +50,12 @@
|
||||
"-source=./refactor.cpp",
|
||||
"-destination=./Test/refactor.cpp",
|
||||
|
||||
"-specification=./Test/zpl.h.refactor"
|
||||
"-specification=./Test/zpl.refactor"
|
||||
],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "${workspaceRoot}",
|
||||
"environment": [],
|
||||
"console": "externalTerminal"
|
||||
"console": "integratedTerminal"
|
||||
}
|
||||
]
|
||||
}
|
42
Readme.md
42
Readme.md
@ -1,23 +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 :
|
||||
|
||||
* `-source`, `-src` : Source file to refactor
|
||||
* `-destination`, `-dst` : Destination file after the refactor (omit to use the same as source)
|
||||
* `-specification`, `-spec` : Specification containing rules to use for the refactor.
|
||||
* `-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 or what it does..)
|
||||
* 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.
|
||||
|
163
Test/.clang-format
Normal file
163
Test/.clang-format
Normal file
@ -0,0 +1,163 @@
|
||||
# Format Style Options - Created with Clang Power Tools
|
||||
---
|
||||
AccessModifierOffset: -4
|
||||
|
||||
AlignAfterOpenBracket: BlockIndent
|
||||
AlignArrayOfStructures: Right
|
||||
AlignConsecutiveAssignments:
|
||||
Enabled: true
|
||||
AcrossEmptyLines: false
|
||||
AcrossComments: true
|
||||
AlignCompound: true
|
||||
PadOperators: true
|
||||
AlignConsecutiveBitFields: AcrossComments
|
||||
AlignConsecutiveDeclarations: AcrossComments
|
||||
AlignConsecutiveMacros: AcrossComments
|
||||
AlignEscapedNewlines: Right
|
||||
AlignOperands: DontAlign
|
||||
|
||||
AlignTrailingComments: true
|
||||
|
||||
AllowAllArgumentsOnNextLine: false
|
||||
AllowAllConstructorInitializersOnNextLine: false
|
||||
AllowAllParametersOfDeclarationOnNextLine: false
|
||||
AllowShortBlocksOnASingleLine: Never
|
||||
AllowShortCaseLabelsOnASingleLine: false
|
||||
AllowShortLambdasOnASingleLine: None
|
||||
AllowShortEnumsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: None
|
||||
AllowShortIfStatementsOnASingleLine: Never
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
|
||||
AlwaysBreakAfterReturnType: None
|
||||
AlwaysBreakBeforeMultilineStrings: true
|
||||
AlwaysBreakTemplateDeclarations: Yes
|
||||
|
||||
BinPackArguments: false
|
||||
BinPackParameters: false
|
||||
|
||||
BitFieldColonSpacing: Both
|
||||
|
||||
BraceWrapping:
|
||||
AfterCaseLabel: false
|
||||
AfterClass: false
|
||||
AfterControlStatement: false
|
||||
AfterEnum: false
|
||||
AfterFunction: false
|
||||
AfterNamespace: false
|
||||
AfterObjCDeclaration: false
|
||||
AfterStruct: false
|
||||
AfterUnion: false
|
||||
AfterExternBlock: false
|
||||
BeforeCatch: false
|
||||
BeforeElse: false
|
||||
IndentBraces: false
|
||||
SplitEmptyFunction: false
|
||||
SplitEmptyRecord: false
|
||||
SplitEmptyNamespace: false
|
||||
BeforeLambdaBody: false
|
||||
BeforeWhile: false
|
||||
|
||||
# BreakAfterAttributes: Always
|
||||
# BreakArrays: false
|
||||
# BreakBeforeInlineASMColon: OnlyMultiline
|
||||
BreakBeforeBinaryOperators: NonAssignment
|
||||
BreakBeforeBraces: Allman
|
||||
BreakBeforeInheritanceComma: true
|
||||
BreakInheritanceList: BeforeComma
|
||||
BreakBeforeConceptDeclarations: true
|
||||
BreakBeforeTernaryOperators: true
|
||||
BreakConstructorInitializers: BeforeComma
|
||||
BreakStringLiterals: true
|
||||
|
||||
ColumnLimit: 180
|
||||
|
||||
CompactNamespaces: true
|
||||
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: true
|
||||
ConstructorInitializerIndentWidth : 4
|
||||
|
||||
ContinuationIndentWidth: 4
|
||||
|
||||
Cpp11BracedListStyle: false
|
||||
|
||||
DeriveLineEnding: true
|
||||
|
||||
ExperimentalAutoDetectBinPacking: false
|
||||
|
||||
FixNamespaceComments: true
|
||||
|
||||
IncludeBlocks: Preserve
|
||||
|
||||
|
||||
IndentCaseBlocks: true
|
||||
IndentCaseLabels: true
|
||||
IndentExternBlock: AfterExternBlock
|
||||
IndentGotoLabels: true
|
||||
IndentPPDirectives: AfterHash
|
||||
IndentRequires: true
|
||||
IndentWidth: 4
|
||||
IndentWrappedFunctionNames: false
|
||||
|
||||
# InsertNewlineAtEOF: true
|
||||
InsertTrailingCommas: Wrapped
|
||||
|
||||
LambdaBodyIndentation: OuterScope
|
||||
|
||||
Language: Cpp
|
||||
|
||||
MaxEmptyLinesToKeep: 4
|
||||
|
||||
NamespaceIndentation: All
|
||||
|
||||
PointerAlignment: Left
|
||||
|
||||
QualifierAlignment: Leave
|
||||
|
||||
ReferenceAlignment: Left
|
||||
|
||||
ReflowComments: true
|
||||
|
||||
# RequiresExpressionIndentation: OuterScope
|
||||
|
||||
SeparateDefinitionBlocks: Always
|
||||
|
||||
ShortNamespaceLines: 40
|
||||
|
||||
SortIncludes: true
|
||||
SortUsingDeclarations: true
|
||||
|
||||
SpaceAfterCStyleCast: false
|
||||
SpaceAfterLogicalNot: true
|
||||
SpaceAfterTemplateKeyword: false
|
||||
|
||||
SpaceAroundPointerQualifiers: Default
|
||||
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeCaseColon: true
|
||||
SpaceBeforeCpp11BracedList: true
|
||||
SpaceBeforeCtorInitializerColon: true
|
||||
SpaceBeforeInheritanceColon: true
|
||||
SpaceBeforeParens: ControlStatementsExceptControlMacros
|
||||
SpaceBeforeRangeBasedForLoopColon: true
|
||||
SpaceBeforeSquareBrackets: false
|
||||
SpacesBeforeTrailingComments: 4
|
||||
|
||||
SpaceInEmptyBlock: true
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesInAngles: true
|
||||
SpacesInCStyleCastParentheses: true
|
||||
SpacesInConditionalStatement: true
|
||||
SpacesInContainerLiterals: true
|
||||
SpacesInLineCommentPrefix:
|
||||
Minimum: 1
|
||||
Maximum: 20
|
||||
SpacesInParentheses: true
|
||||
SpacesInSquareBrackets: true
|
||||
|
||||
Standard: c++17
|
||||
|
||||
TabWidth: 4
|
||||
|
||||
UseTab: ForIndentation
|
||||
...
|
117
Test/bloat.hpp
117
Test/bloat.hpp
@ -1,117 +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_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) \
|
||||
|
||||
|
||||
using c8 = char;
|
||||
using u8 = zpl_u8;
|
||||
using u16 = zpl_u16;
|
||||
using u32 = zpl_u32;
|
||||
using u64 = zpl_u64;
|
||||
using s8 = zpl_i8;
|
||||
using s16 = zpl_i16;
|
||||
using s32 = zpl_i32;
|
||||
using s64 = zpl_i64;
|
||||
using uw = zpl_usize;
|
||||
using sw = zpl_isize;
|
||||
|
||||
|
||||
ct c8 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 )
|
||||
{
|
||||
assert_crash( "Failed to reserve memory for Tests:: Global_Arena" );
|
||||
}
|
||||
}
|
||||
|
||||
void cleanup()
|
||||
{
|
||||
arena_free( & Global_Arena);
|
||||
}
|
||||
}
|
||||
|
||||
void fatal()
|
||||
{
|
||||
Memory::cleanup();
|
||||
assert_crash("FATAL");
|
||||
}
|
@ -1,13 +1,11 @@
|
||||
|
||||
project( 'refactor', 'c', 'cpp', default_options : ['buildtype=debug'] )
|
||||
|
||||
# add_global_arguments('-E', language : 'cpp')
|
||||
|
||||
if get_option('buildtype').startswith('debug')
|
||||
|
||||
add_project_arguments('-DBuild_Debug', language : 'cpp')
|
||||
add_project_arguments('-DBuild_Debug', language : ['c', 'cpp'])
|
||||
|
||||
endif
|
||||
|
||||
executable( 'refactor', 'refactor.cpp' )
|
||||
|
||||
executable( 'refactor', 'refactor.refactored.cpp' )
|
||||
|
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,775 +0,0 @@
|
||||
#define ZPL_IMPLEMENTATION
|
||||
#include "bloat.hpp"
|
||||
|
||||
|
||||
namespace File
|
||||
{
|
||||
string Source = nullptr;
|
||||
string Destination = nullptr;
|
||||
|
||||
file_contents Content {};
|
||||
|
||||
zpl_arena Buffer;
|
||||
|
||||
void cleanup()
|
||||
{
|
||||
arena_free( & Buffer );
|
||||
}
|
||||
|
||||
void read()
|
||||
{
|
||||
zpl_file file_src = {};
|
||||
|
||||
Content.allocator = g_allocator;
|
||||
|
||||
file_error error_src = file_open( & file_src, Source );
|
||||
|
||||
if ( error_src == ZPL_FILE_ERROR_NONE )
|
||||
{
|
||||
zpl_isize fsize = zpl_cast(zpl_isize) file_size( & file_src);
|
||||
|
||||
if ( fsize > 0 )
|
||||
{
|
||||
arena_init_from_allocator( & Buffer, heap(), (fsize % 64) * 2 );
|
||||
|
||||
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 )
|
||||
{
|
||||
zpl_printf( "Unable to open source file: %s\n", Source );
|
||||
fatal();
|
||||
}
|
||||
}
|
||||
|
||||
void write(string refactored)
|
||||
{
|
||||
if ( refactored == nullptr)
|
||||
return;
|
||||
|
||||
zpl_file file_dest {};
|
||||
file_error error = file_create( & file_dest, Destination );
|
||||
|
||||
if ( error != ZPL_FILE_ERROR_NONE )
|
||||
{
|
||||
zpl_printf( "Unable to open destination file: %s\n", Destination );
|
||||
fatal();
|
||||
}
|
||||
|
||||
file_write( & file_dest, refactored, string_length(refactored) );
|
||||
}
|
||||
}
|
||||
|
||||
namespace Spec
|
||||
{
|
||||
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
|
||||
c8 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
|
||||
};
|
||||
|
||||
zpl_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 )
|
||||
{
|
||||
zpl_printf("Failed to find valid initial token");
|
||||
fatal();
|
||||
}
|
||||
|
||||
token = string_append_length( token, line, length );
|
||||
line += length;
|
||||
}
|
||||
|
||||
void process()
|
||||
{
|
||||
char* content;
|
||||
|
||||
zpl_array(char*) lines;
|
||||
|
||||
// Get the contents of the file.
|
||||
{
|
||||
zpl_file file {};
|
||||
file_error error = file_open( & file, File);
|
||||
|
||||
if ( error != ZPL_FILE_ERROR_NONE )
|
||||
{
|
||||
zpl_printf("Could not open the specification file: %s", File);
|
||||
fatal();
|
||||
}
|
||||
|
||||
sw fsize = scast( sw, file_size( & file ) );
|
||||
|
||||
if ( fsize <= 0 )
|
||||
{
|
||||
zpl_printf("No content in specificaiton to process");
|
||||
fatal();
|
||||
}
|
||||
|
||||
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 )
|
||||
{
|
||||
zpl_printf("Spec::process: lines array imporoperly setup");
|
||||
fatal();
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
zpl_printf("Specification Line: %d is missing valid keyword", array_count(lines) - left);
|
||||
lines++;
|
||||
}
|
||||
}
|
||||
|
||||
void cleanup()
|
||||
{
|
||||
arena_free( & Buffer );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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 );
|
||||
|
||||
// bool match = false;
|
||||
// if ( str_compare( "zpl_printf", current, sig_length ) == 0 )
|
||||
// {
|
||||
// match = true;
|
||||
// }
|
||||
|
||||
if ( string_are_equal( ignore->Sig, current ) )
|
||||
{
|
||||
char after = content[sig_length];
|
||||
|
||||
if ( char_is_alphanumeric( after ) || after == '_' )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
zpl_printf("\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 );
|
||||
zpl_printf("\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 after = content[sig_length];
|
||||
|
||||
if ( 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 );
|
||||
|
||||
zpl_printf("\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);
|
||||
zpl_printf("\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.
|
||||
zpl_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 )
|
||||
{
|
||||
zpl_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
|
||||
{
|
||||
zpl_printf( "-source not provided\n" );
|
||||
fatal();
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
zpl_printf( "Failed to parse arguments\n" );
|
||||
fatal();
|
||||
}
|
||||
|
||||
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,68 +0,0 @@
|
||||
__VERSION 1
|
||||
|
||||
// not : Ignore
|
||||
// word : Alphanumeric or underscore
|
||||
// regex : Unavailable in __VERSION 1.
|
||||
|
||||
// Precedence (highest to lowest):
|
||||
// word, namespace, regex
|
||||
|
||||
// Header files
|
||||
not word zpl_hedley
|
||||
|
||||
// Removes the namespace.
|
||||
namespace zpl_
|
||||
|
||||
// Don't expose internals
|
||||
not namespace zpl__
|
||||
|
||||
not word ZPL_IMPLEMENTATION
|
||||
|
||||
word cast, zpl_cast
|
||||
word zpl_strncmp, str_compare
|
||||
word zpl_strcmp, str_compare
|
||||
|
||||
// Undesired typedefs
|
||||
not word zpl_i8
|
||||
not word zpl_i16
|
||||
not word zpl_i32
|
||||
not word zpl_i64
|
||||
not word zpl_u8
|
||||
not word zpl_u16
|
||||
not word zpl_u32
|
||||
not word zpl_u64
|
||||
not word zpl_intptr
|
||||
not word zpl_uintptr
|
||||
not word zpl_usize
|
||||
not word zpl_isize
|
||||
|
||||
// Undesired exposures.
|
||||
not word zpl_allocator
|
||||
not word zpl_arena
|
||||
not word zpl_array
|
||||
not word zpl_file
|
||||
not word zpl_list
|
||||
not word zpl_pool
|
||||
not word zpl_opts
|
||||
|
||||
// Conflicts with refactor
|
||||
word alloc, allocator
|
||||
word file_size, fsize
|
||||
|
||||
// Conflicts with std.
|
||||
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_strlen
|
||||
not word zpl_strnlen
|
||||
not word zpl_exit
|
90
Test/zpl.refactor
Normal file
90
Test/zpl.refactor
Normal file
@ -0,0 +1,90 @@
|
||||
__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 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_
|
||||
|
||||
// Don't expose internals
|
||||
not namespace zpl__
|
||||
|
||||
// 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_uintptr, uptr
|
||||
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_file
|
||||
//not word zpl_list
|
||||
//not word zpl_pool
|
||||
//not word zpl_opts
|
||||
|
||||
// Conflicts with refactor
|
||||
word arena, a_arena
|
||||
word array, a_array
|
||||
word alloc, a_allocator
|
||||
word file, a_file
|
||||
word file_size, fsize
|
||||
word list, a_list
|
||||
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
|
18369
Test/zpl.refactored.h
18369
Test/zpl.refactored.h
File diff suppressed because it is too large
Load Diff
@ -1,8 +0,0 @@
|
||||
@echo off
|
||||
|
||||
if not exist build\nul (
|
||||
meson setup build
|
||||
)
|
||||
|
||||
echo:
|
||||
ninja -C build
|
15
meson.build
15
meson.build
@ -1,15 +0,0 @@
|
||||
|
||||
project( 'refactor', 'c', 'cpp', default_options : ['buildtype=debug'] )
|
||||
|
||||
include_thirdparty = include_directories( '../thirdparty' )
|
||||
|
||||
# add_global_arguments('-E', language : 'cpp')
|
||||
|
||||
if get_option('buildtype').startswith('debug')
|
||||
|
||||
add_project_arguments('-DBuild_Debug', language : 'cpp')
|
||||
|
||||
endif
|
||||
|
||||
executable( 'refactor', 'refactor.cpp', include_directories : include_thirdparty )
|
||||
|
@ -1,885 +0,0 @@
|
||||
#define ZPL_IMPLEMENTATION
|
||||
#include "bloat.hpp"
|
||||
|
||||
|
||||
namespace File
|
||||
{
|
||||
zpl_string Source = nullptr;
|
||||
zpl_string Destination = nullptr;
|
||||
|
||||
zpl_file_contents Content {};
|
||||
|
||||
zpl_arena Buffer;
|
||||
|
||||
void cleanup()
|
||||
{
|
||||
zpl_arena_free( & Buffer );
|
||||
}
|
||||
|
||||
void read()
|
||||
{
|
||||
zpl_file file_src = {};
|
||||
|
||||
Content.allocator = g_allocator;
|
||||
|
||||
zpl_file_error error_src = zpl_file_open( & file_src, Source );
|
||||
|
||||
if ( error_src == ZPL_FILE_ERROR_NONE )
|
||||
{
|
||||
zpl_isize file_size = cast(zpl_isize) zpl_file_size( & file_src);
|
||||
|
||||
if ( file_size > 0 )
|
||||
{
|
||||
zpl_arena_init_from_allocator( & Buffer, zpl_heap(), file_size + file_size % 64 );
|
||||
|
||||
Content.data = zpl_alloc( zpl_arena_allocator( & Buffer), file_size);
|
||||
Content.size = file_size;
|
||||
|
||||
zpl_file_read_at ( & file_src, Content.data, Content.size, 0);
|
||||
}
|
||||
|
||||
zpl_file_close( & file_src);
|
||||
}
|
||||
|
||||
if ( Content.data == nullptr )
|
||||
{
|
||||
zpl_printf( "Unable to open source file: %s\n", Source );
|
||||
fatal();
|
||||
}
|
||||
}
|
||||
|
||||
void write(zpl_string refactored)
|
||||
{
|
||||
if ( refactored == nullptr)
|
||||
return;
|
||||
|
||||
zpl_file file_dest {};
|
||||
zpl_file_error error = zpl_file_create( & file_dest, Destination );
|
||||
|
||||
if ( error != ZPL_FILE_ERROR_NONE )
|
||||
{
|
||||
zpl_printf( "Unable to open destination file: %s\n", Destination );
|
||||
fatal();
|
||||
}
|
||||
|
||||
zpl_file_write( & file_dest, refactored, zpl_string_length(refactored) );
|
||||
}
|
||||
}
|
||||
|
||||
namespace Spec
|
||||
{
|
||||
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
|
||||
c8 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, 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
|
||||
};
|
||||
|
||||
zpl_arena Buffer {};
|
||||
zpl_array(Entry) Word_Ignores;
|
||||
zpl_array(Entry) Namespace_Ignores;
|
||||
zpl_array(Entry) Words;
|
||||
zpl_array(Entry) Namespaces;
|
||||
|
||||
u32 Sig_Smallest = zpl_kilobytes(1);
|
||||
|
||||
forceinline
|
||||
void find_next_token( zpl_string& token, char*& line, u32& length )
|
||||
{
|
||||
zpl_string_clear( token );
|
||||
length = 0;
|
||||
while ( zpl_char_is_alphanumeric( line[length] ) || line[length] == '_' )
|
||||
{
|
||||
length++;
|
||||
}
|
||||
|
||||
if ( length == 0 )
|
||||
{
|
||||
zpl_printf("Failed to find valid initial token");
|
||||
fatal();
|
||||
}
|
||||
|
||||
token = zpl_string_append_length( token, line, length );
|
||||
line += length;
|
||||
}
|
||||
|
||||
void process()
|
||||
{
|
||||
char* content;
|
||||
|
||||
zpl_array(char*) lines;
|
||||
|
||||
// Get the contents of the file.
|
||||
{
|
||||
zpl_file file {};
|
||||
zpl_file_error error = zpl_file_open( & file, File);
|
||||
|
||||
if ( error != ZPL_FILE_ERROR_NONE )
|
||||
{
|
||||
zpl_printf("Could not open the specification file: %s", File);
|
||||
fatal();
|
||||
}
|
||||
|
||||
sw fsize = scast( sw, zpl_file_size( & file ) );
|
||||
|
||||
if ( fsize <= 0 )
|
||||
{
|
||||
zpl_printf("No content in specificaiton to process");
|
||||
fatal();
|
||||
}
|
||||
|
||||
zpl_arena_init_from_allocator( & Buffer, zpl_heap(), (fsize + fsize % 64) * 3 + zpl_kilobytes(1) );
|
||||
|
||||
char* content = rcast( char*, zpl_alloc( zpl_arena_allocator( & Buffer), fsize + 1) );
|
||||
|
||||
zpl_file_read( & file, content, fsize);
|
||||
|
||||
content[fsize] = 0;
|
||||
|
||||
lines = zpl_str_split_lines( zpl_arena_allocator( & Buffer ), content, false );
|
||||
|
||||
zpl_file_close( & file );
|
||||
}
|
||||
|
||||
sw left = zpl_array_count( lines );
|
||||
|
||||
if ( left == 0 )
|
||||
{
|
||||
zpl_printf("Spec::process: lines array imporoperly setup");
|
||||
fatal();
|
||||
}
|
||||
|
||||
// Skip the first line as its the version number and we only support __VERSION 1.
|
||||
left--;
|
||||
lines++;
|
||||
|
||||
zpl_array_init( Word_Ignores, zpl_arena_allocator( & Buffer));
|
||||
zpl_array_init( Namespace_Ignores, zpl_arena_allocator( & Buffer));
|
||||
zpl_array_init( Words, zpl_arena_allocator( & Buffer));
|
||||
zpl_array_init( Namespaces, zpl_arena_allocator( & Buffer));
|
||||
|
||||
// Limiting the maximum output of a token to 1 KB
|
||||
zpl_string token = zpl_string_make_reserve( zpl_arena_allocator( & Buffer), zpl_kilobytes(1));
|
||||
|
||||
while ( left-- )
|
||||
{
|
||||
char* line = * lines;
|
||||
|
||||
// Ignore line if its a comment
|
||||
if ( line[0] == '/' && line[1] == '/')
|
||||
{
|
||||
lines++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Remove indent
|
||||
{
|
||||
while ( zpl_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 ( zpl_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 ( zpl_char_is_space( line[0] ) )
|
||||
line++;
|
||||
|
||||
if ( line[0] == '\0' )
|
||||
{
|
||||
lines++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
find_next_token( token, line, length );
|
||||
|
||||
// First argument is signature.
|
||||
entry.Sig = zpl_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)
|
||||
zpl_array_append( Namespace_Ignores, entry );
|
||||
|
||||
else
|
||||
zpl_array_append( Namespaces, entry );
|
||||
break;
|
||||
|
||||
case Tok::Word:
|
||||
if ( ignore)
|
||||
zpl_array_append( Word_Ignores, entry );
|
||||
|
||||
else
|
||||
zpl_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:
|
||||
zpl_array_append( Namespaces, entry );
|
||||
break;
|
||||
|
||||
case Tok::Word:
|
||||
zpl_array_append( Words, entry );
|
||||
break;
|
||||
}
|
||||
|
||||
bSkip = true;
|
||||
break;
|
||||
}
|
||||
|
||||
line++;
|
||||
}
|
||||
|
||||
if ( bSkip )
|
||||
{
|
||||
lines++;
|
||||
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::Namespace:
|
||||
zpl_array_append( Namespaces, entry );
|
||||
break;
|
||||
|
||||
case Tok::Word:
|
||||
zpl_array_append( Words, entry );
|
||||
break;
|
||||
}
|
||||
|
||||
lines++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
find_next_token( token, line, length );
|
||||
|
||||
// Second argument is substitute.
|
||||
entry.Sub = zpl_string_make_length( g_allocator, token, length );
|
||||
|
||||
switch ( type )
|
||||
{
|
||||
case Tok::Namespace:
|
||||
zpl_array_append( Namespaces, entry );
|
||||
lines++;
|
||||
continue;
|
||||
|
||||
case Tok::Word:
|
||||
zpl_array_append( Words, entry );
|
||||
lines++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
zpl_printf("Specification Line: %d is missing valid keyword", zpl_array_count(lines) - left);
|
||||
lines++;
|
||||
}
|
||||
}
|
||||
|
||||
void cleanup()
|
||||
{
|
||||
zpl_arena_free( & Buffer );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
struct Token
|
||||
{
|
||||
u32 Start;
|
||||
u32 End;
|
||||
|
||||
zpl_string Sig;
|
||||
zpl_string Sub;
|
||||
};
|
||||
|
||||
zpl_string NSpace_Old = nullptr;
|
||||
zpl_string NSpace_New = nullptr;
|
||||
|
||||
void refactor()
|
||||
{
|
||||
sw buffer_size = File::Content.size;
|
||||
|
||||
zpl_array(Token) tokens;
|
||||
zpl_array_init( tokens, g_allocator);
|
||||
|
||||
char* content = rcast( char*, File::Content.data );
|
||||
|
||||
zpl_string current = zpl_string_make( g_allocator, "");
|
||||
zpl_string preview = zpl_string_make( g_allocator, "");
|
||||
|
||||
sw left = File::Content.size;
|
||||
|
||||
sw line = 0;
|
||||
|
||||
#if 1
|
||||
while ( left )
|
||||
{
|
||||
if ( content[0] == '\n' )
|
||||
line++;
|
||||
|
||||
// Word Ignores
|
||||
{
|
||||
Spec::Entry* ignore = Spec::Word_Ignores;
|
||||
|
||||
sw ignores_left = zpl_array_count( Spec::Word_Ignores);
|
||||
|
||||
do
|
||||
{
|
||||
if ( ignore->Sig[0] != content[0] )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
zpl_string_clear( current );
|
||||
|
||||
u32 sig_length = zpl_string_length( ignore->Sig );
|
||||
current = zpl_string_append_length( current, content, sig_length );
|
||||
|
||||
if ( zpl_string_are_equal( ignore->Sig, current ) && ! zpl_char_is_alphanumeric( content[sig_length] ) )
|
||||
{
|
||||
zpl_printf("\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 = zpl_array_count( Spec::Namespace_Ignores);
|
||||
|
||||
do
|
||||
{
|
||||
if ( ignore->Sig[0] != content[0] )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
zpl_string_clear( current );
|
||||
|
||||
u32 sig_length = zpl_string_length( ignore->Sig );
|
||||
current = zpl_string_append_length( current, content, sig_length );
|
||||
|
||||
if ( zpl_string_are_equal( ignore->Sig, current ) )
|
||||
{
|
||||
u32 length = sig_length;
|
||||
char* ns_content = content + sig_length;
|
||||
|
||||
while ( zpl_char_is_alphanumeric( ns_content[0] ) || ns_content[0] == '_' )
|
||||
{
|
||||
length++;
|
||||
ns_content++;
|
||||
}
|
||||
|
||||
zpl_string_clear( preview );
|
||||
preview = zpl_string_append_length( preview, content, length );
|
||||
zpl_printf("\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 = zpl_array_count ( Spec::Words);
|
||||
|
||||
do
|
||||
{
|
||||
if ( word->Sig[0] != content[0] )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
zpl_string_clear( current );
|
||||
|
||||
sw sig_length = zpl_string_length( word->Sig);
|
||||
current = zpl_string_append_length( current, content, sig_length );
|
||||
|
||||
if ( zpl_string_are_equal( word->Sig, current ) )
|
||||
{
|
||||
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 += zpl_string_length( entry.Sub) - sig_length;
|
||||
}
|
||||
|
||||
zpl_array_append( tokens, entry );
|
||||
|
||||
zpl_printf("\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 = zpl_array_count( Spec::Namespaces);
|
||||
|
||||
do
|
||||
{
|
||||
if ( nspace->Sig[0] != content[0] )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
zpl_string_clear( current );
|
||||
|
||||
u32 sig_length = zpl_string_length( nspace->Sig );
|
||||
current = zpl_string_append_length( current, content, sig_length );
|
||||
|
||||
if ( zpl_string_are_equal( nspace->Sig, current ) )
|
||||
{
|
||||
u32 length = sig_length;
|
||||
char* ns_content = content + sig_length;
|
||||
|
||||
while ( zpl_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 += zpl_string_length( entry.Sub ) - length;
|
||||
}
|
||||
|
||||
zpl_array_append( tokens, entry );
|
||||
|
||||
zpl_string_clear( preview );
|
||||
preview = zpl_string_append_length( preview, content, length);
|
||||
zpl_printf("\nFound %-40s %-40s line %d", preview, nspace->Sig, line);
|
||||
|
||||
content += length;
|
||||
left -= length;
|
||||
}
|
||||
}
|
||||
while ( nspace++, --nspaces_left );
|
||||
}
|
||||
|
||||
Skip:
|
||||
// content += Spec::Sig_Smallest;
|
||||
// left -= Spec::Sig_Smallest;
|
||||
content++;
|
||||
left--;
|
||||
// zpl_sleep_ms( 10 );
|
||||
continue;
|
||||
}
|
||||
|
||||
left = zpl_array_count( tokens);
|
||||
content = rcast( char*, File::Content.data);
|
||||
|
||||
// Generate the refactored file content.
|
||||
zpl_arena buffer;
|
||||
zpl_string refactored = nullptr;
|
||||
{
|
||||
Token* entry = tokens;
|
||||
|
||||
if ( entry == nullptr)
|
||||
return;
|
||||
|
||||
zpl_arena_init_from_allocator( & buffer, zpl_heap(), buffer_size * 2 );
|
||||
|
||||
zpl_string
|
||||
new_string = zpl_string_make_reserve( zpl_arena_allocator( & buffer), zpl_kilobytes(1) );
|
||||
refactored = zpl_string_make_reserve( zpl_arena_allocator( & buffer), buffer_size );
|
||||
|
||||
sw previous_end = 0;
|
||||
|
||||
while ( left-- )
|
||||
{
|
||||
sw segment_length = entry->Start - previous_end;
|
||||
|
||||
sw sig_length = zpl_string_length( entry->Sig );
|
||||
|
||||
// Append between tokens
|
||||
refactored = zpl_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 = zpl_string_append( refactored, entry->Sub );
|
||||
|
||||
refactored = zpl_string_append_length( refactored, content, segment_length );
|
||||
content += segment_length;
|
||||
|
||||
previous_end = entry->End;
|
||||
entry++;
|
||||
}
|
||||
|
||||
entry--;
|
||||
|
||||
if ( entry->End < File::Content.size )
|
||||
{
|
||||
refactored = zpl_string_append_length( refactored, content, File::Content.size - entry->End );
|
||||
}
|
||||
}
|
||||
|
||||
// Write refactored content to destination.
|
||||
File::write( refactored );
|
||||
|
||||
zpl_arena_free( & buffer );
|
||||
|
||||
#else
|
||||
u32 nspace_length = zpl_string_length( NSpace_Old );
|
||||
|
||||
// Gather all tokens.
|
||||
while ( (left - nspace_length) > 0 )
|
||||
{
|
||||
while ( left && * content != NSpace_Old[0] )
|
||||
{
|
||||
content++;
|
||||
left--;
|
||||
}
|
||||
|
||||
current = zpl_string_append_length( current, content, nspace_length );
|
||||
left -= nspace_length;
|
||||
content += nspace_length;
|
||||
|
||||
if ( zpl_string_are_equal( NSpace_Old, current ) )
|
||||
{
|
||||
u32 index = scast(u32, File::Content.size - left);
|
||||
|
||||
Token token =
|
||||
{
|
||||
index - nspace_length,
|
||||
index
|
||||
};
|
||||
|
||||
while ( left )
|
||||
{
|
||||
const char element = * content;
|
||||
|
||||
if ( element == '_' || zpl_char_is_alphanumeric( element ) )
|
||||
{
|
||||
token.End++;
|
||||
content++;
|
||||
left--;
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
buffer_size += token.End - token.Start + zpl_string_length( NSpace_New ) - nspace_length;
|
||||
|
||||
zpl_array_append( tokens, token );
|
||||
}
|
||||
|
||||
zpl_string_clear( current);
|
||||
}
|
||||
|
||||
left = zpl_array_count( tokens);
|
||||
content = rcast( char*, File::Content.data);
|
||||
|
||||
// Generate the refactored file content.
|
||||
zpl_arena buffer;
|
||||
zpl_string refactored = nullptr;
|
||||
{
|
||||
Token* token = tokens;
|
||||
|
||||
if ( token == nullptr)
|
||||
return;
|
||||
|
||||
zpl_arena_init_from_allocator( & buffer, zpl_heap(), buffer_size * 2 );
|
||||
|
||||
zpl_string
|
||||
new_string = zpl_string_make_reserve( zpl_arena_allocator( & buffer), 1024 );
|
||||
refactored = zpl_string_make_reserve( zpl_arena_allocator( & buffer), buffer_size );
|
||||
|
||||
u32 previous_end = 0;
|
||||
|
||||
while ( left-- )
|
||||
{
|
||||
u32 segment_length = token->Start - previous_end;
|
||||
|
||||
// Append between tokens
|
||||
refactored = zpl_string_append_length( refactored, content, segment_length );
|
||||
content += segment_length + nspace_length;
|
||||
|
||||
segment_length = token->End - token->Start - nspace_length;
|
||||
|
||||
// Append token
|
||||
refactored = zpl_string_append( refactored, NSpace_New );
|
||||
refactored = zpl_string_append_length( refactored, content, segment_length );
|
||||
content += segment_length;
|
||||
|
||||
previous_end = token->End;
|
||||
token++;
|
||||
}
|
||||
|
||||
token--;
|
||||
|
||||
if ( token->End < File::Content.size )
|
||||
{
|
||||
refactored = zpl_string_append_length( refactored, content, File::Content.size - token->End );
|
||||
}
|
||||
}
|
||||
|
||||
// Write refactored content to destination.
|
||||
File::write( refactored );
|
||||
|
||||
zpl_arena_free( & buffer );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
inline
|
||||
void parse_options( int num, char** arguments )
|
||||
{
|
||||
zpl_opts opts;
|
||||
zpl_opts_init( & opts, g_allocator, "refactor");
|
||||
zpl_opts_add( & opts, "source" , "src" , "File to refactor" , ZPL_OPTS_STRING);
|
||||
zpl_opts_add( & opts, "destination" , "dst" , "File post refactor" , ZPL_OPTS_STRING);
|
||||
zpl_opts_add( & opts, "specification", "spec", "Specification for refactoring", ZPL_OPTS_STRING);
|
||||
#if 0
|
||||
zpl_opts_add( & opts, "ns_old" , "old" , "Namespace to refactor" , ZPL_OPTS_STRING);
|
||||
zpl_opts_add( & opts, "ns_new" , "new" , "Namespace to refactor to" , ZPL_OPTS_STRING);
|
||||
#endif
|
||||
|
||||
if (zpl_opts_compile( & opts, num, arguments))
|
||||
{
|
||||
if ( zpl_opts_has_arg( & opts, "src" ) )
|
||||
{
|
||||
zpl_string opt = zpl_opts_string( & opts, "src", "INVALID PATH" );
|
||||
|
||||
File::Source = zpl_string_make( g_allocator, "" );
|
||||
File::Source = zpl_string_append( File::Source, opt );
|
||||
}
|
||||
else
|
||||
{
|
||||
zpl_printf( "-source not provided\n" );
|
||||
fatal();
|
||||
}
|
||||
|
||||
if ( zpl_opts_has_arg( & opts, "dst" ) )
|
||||
{
|
||||
zpl_string opt = zpl_opts_string( & opts, "dst", "INVALID PATH" );
|
||||
|
||||
File::Destination = zpl_string_make( g_allocator, "" );
|
||||
File::Destination = zpl_string_append( File::Destination, opt );
|
||||
}
|
||||
else if ( File::Source && File::Destination )
|
||||
{
|
||||
File::Destination = zpl_string_make( g_allocator, "" );
|
||||
File::Destination = zpl_string_append( File::Destination, File::Source );
|
||||
}
|
||||
|
||||
if ( zpl_opts_has_arg( & opts, "spec" ) )
|
||||
{
|
||||
zpl_string opt = zpl_opts_string( & opts, "spec", "INVALID PATH" );
|
||||
|
||||
Spec::File = zpl_string_make( g_allocator, "" );
|
||||
Spec::File = zpl_string_append( Spec::File, opt );
|
||||
}
|
||||
|
||||
#if 0
|
||||
if ( zpl_opts_has_arg( & opts, "old" ) )
|
||||
{
|
||||
zpl_string opt = zpl_opts_string( & opts, "old", "INVALID NAMESPACE" );
|
||||
|
||||
NSpace_Old = zpl_string_make( g_allocator, "" );
|
||||
NSpace_Old = zpl_string_append( NSpace_Old, opt );
|
||||
}
|
||||
if ( Spec::File == nullptr && NSpace_Old == nullptr )
|
||||
{
|
||||
zpl_printf( "Eitehr -ns_old or -specification must be provided\n" );
|
||||
fatal();
|
||||
}
|
||||
|
||||
NSpace_New = zpl_string_make( g_allocator, "" );
|
||||
if ( zpl_opts_has_arg( & opts, "new" ) )
|
||||
{
|
||||
zpl_string opt = zpl_opts_string( & opts, "new", "INVALID NAMESPACE" );
|
||||
|
||||
NSpace_New = zpl_string_append( NSpace_New , opt );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
zpl_printf( "Failed to parse arguments\n" );
|
||||
fatal();
|
||||
}
|
||||
|
||||
zpl_opts_free( & opts);
|
||||
}
|
||||
|
||||
int main( int num, char** arguments)
|
||||
{
|
||||
Memory::setup();
|
||||
|
||||
parse_options( num, arguments );
|
||||
|
||||
if ( Spec::File )
|
||||
Spec::process();
|
||||
|
||||
File::read();
|
||||
|
||||
refactor();
|
||||
|
||||
File:: cleanup();
|
||||
Memory::cleanup();
|
||||
}
|
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,15 +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_MATH
|
||||
// # define ZPL_MODULE_MAT
|
||||
// # define ZPL_MODULE_THREADING
|
||||
// # define ZPL_MODULE_JOBS
|
||||
// # define ZPL_MODULE_PARSER
|
||||
// extern "C" {
|
||||
#include "zpl.h"
|
||||
// }
|
||||
|
||||
#if __clang__
|
||||
# pragma clang diagnostic pop
|
||||
@ -60,19 +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 c8 = char;
|
||||
using b32 = zpl_b32;
|
||||
using s8 = zpl_i8;
|
||||
using s32 = zpl_i32;
|
||||
using s64 = zpl_i64;
|
||||
@ -83,33 +81,65 @@ using f64 = zpl_f64;
|
||||
using uw = zpl_usize;
|
||||
using sw = zpl_isize;
|
||||
|
||||
using Line = char*;
|
||||
using Array_Line = zpl_array( Line );
|
||||
|
||||
ct c8 const* Msg_Invalid_Value = "INVALID VALUE PROVIDED";
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
void fatal()
|
||||
// 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, ...)
|
||||
{
|
||||
Memory::cleanup();
|
||||
zpl_assert_crash("FATAL");
|
||||
#if Build_Debug
|
||||
sw res;
|
||||
va_list va;
|
||||
|
||||
va_start(va, fmt);
|
||||
res = zpl_printf_va(fmt, va);
|
||||
va_end(va);
|
||||
|
||||
return res;
|
||||
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline
|
||||
void fatal(char const *fmt, ...)
|
||||
{
|
||||
zpl_local_persist zpl_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
|
||||
}
|
685
project/refactor.cpp
Normal file
685
project/refactor.cpp
Normal file
@ -0,0 +1,685 @@
|
||||
#include "Bloat.cpp"
|
||||
#include "IO.cpp"
|
||||
#include "Spec.cpp"
|
||||
|
||||
|
||||
void parse_options( int num, char** arguments )
|
||||
{
|
||||
zpl_opts opts;
|
||||
zpl_opts_init( & opts, zpl_heap(), "refactor");
|
||||
zpl_opts_add( & opts, "num", "num" , "Number of files to refactor" , ZPL_OPTS_INT );
|
||||
zpl_opts_add( & opts, "src" , "src" , "File/s to refactor" , ZPL_OPTS_STRING);
|
||||
zpl_opts_add( & opts, "dst" , "dst" , "File/s post refactor" , ZPL_OPTS_STRING);
|
||||
zpl_opts_add( & opts, "spec", "spec", "Specification for refactoring", ZPL_OPTS_STRING);
|
||||
|
||||
#if Build_Debug
|
||||
zpl_opts_add( & opts, "debug", "debug", "Allows for wait to attach", ZPL_OPTS_FLAG);
|
||||
#endif
|
||||
|
||||
if (opts_custom_compile( & opts, num, arguments))
|
||||
{
|
||||
sw num = 0;
|
||||
|
||||
#if Build_Debug
|
||||
if ( zpl_opts_has_arg( & opts, "debug" ) )
|
||||
{
|
||||
zpl_printf("Will wait (pause available for attachment)");
|
||||
char pause = getchar();
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( zpl_opts_has_arg( & opts, "num" ) )
|
||||
{
|
||||
num = zpl_opts_integer( & opts, "num", -1 );
|
||||
uw global_reserve = num * sizeof(zpl_string) * IO::Path_Size_Largest * 2 + 8;
|
||||
|
||||
if ( global_reserve > zpl_megabytes(1) )
|
||||
{
|
||||
Memory::resize( global_reserve + zpl_megabytes(2) );
|
||||
}
|
||||
|
||||
zpl_array_init_reserve( IO::Sources, g_allocator, num );
|
||||
zpl_array_init_reserve( IO::Destinations, g_allocator, num );
|
||||
}
|
||||
else
|
||||
{
|
||||
num = 1;
|
||||
|
||||
zpl_array_init_reserve( IO::Sources, g_allocator, 1 );
|
||||
zpl_array_init_reserve( IO::Destinations, g_allocator, 1 );
|
||||
}
|
||||
|
||||
zpl_printf("NUM IS: %d", num);
|
||||
|
||||
if ( zpl_opts_has_arg( & opts, "src" ) )
|
||||
{
|
||||
zpl_string opt = zpl_opts_string( & opts, "src", "INVALID SRC ARGUMENT" );
|
||||
|
||||
if ( num == 1 )
|
||||
{
|
||||
zpl_string path = zpl_string_make_length( g_allocator, opt, zpl_string_length( opt ));
|
||||
zpl_array_append( IO::Sources, path );
|
||||
}
|
||||
else
|
||||
{
|
||||
char buffer[ IO::Path_Size_Largest ];
|
||||
|
||||
uw left = num;
|
||||
do
|
||||
{
|
||||
char* path = buffer;
|
||||
sw length = 0;
|
||||
|
||||
do
|
||||
{
|
||||
path[length] = *opt;
|
||||
}
|
||||
while ( length++, opt++, *opt != ' ' && *opt != '\0' );
|
||||
|
||||
zpl_string path_string = zpl_string_make_length( g_allocator, path, length );
|
||||
zpl_array_append( IO::Sources, path_string );
|
||||
|
||||
opt++;
|
||||
}
|
||||
while ( --left );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fatal( "-src not provided\n" );
|
||||
}
|
||||
|
||||
if ( zpl_opts_has_arg( & opts, "dst" ) )
|
||||
{
|
||||
zpl_string opt = zpl_opts_string( & opts, "dst", "INVALID DST ARGUMENT" );
|
||||
|
||||
if ( num == 1 )
|
||||
{
|
||||
zpl_string path = zpl_string_make_length( g_allocator, opt, zpl_string_length( opt) );
|
||||
zpl_array_append( IO::Destinations, path );
|
||||
}
|
||||
else
|
||||
{
|
||||
char buffer[ IO::Path_Size_Largest ];
|
||||
|
||||
uw left = num;
|
||||
do
|
||||
{
|
||||
char* path = buffer;
|
||||
sw length = 0;
|
||||
|
||||
do
|
||||
{
|
||||
path[length] = *opt;
|
||||
}
|
||||
while ( length++, opt++, *opt != ' ' && *opt != '\0' );
|
||||
|
||||
zpl_string path_string = zpl_string_make_length( g_allocator, path, length );
|
||||
zpl_array_append( IO::Destinations, path_string );
|
||||
|
||||
opt++;
|
||||
}
|
||||
while ( --left );
|
||||
|
||||
if ( zpl_array_count(IO::Destinations) != zpl_array_count( IO::Sources ) )
|
||||
{
|
||||
fatal("-dst count must match -src count");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
uw left = num;
|
||||
do
|
||||
{
|
||||
zpl_array_append( IO::Destinations, IO::Sources[num - left] );
|
||||
}
|
||||
while ( --left );
|
||||
}
|
||||
|
||||
if ( zpl_opts_has_arg( & opts, "spec" ) )
|
||||
{
|
||||
zpl_string opt = zpl_opts_string( & opts, "spec", "INVALID PATH" );
|
||||
|
||||
IO::Specification = zpl_string_make( g_allocator, "" );
|
||||
IO::Specification = zpl_string_append( IO::Specification, opt );
|
||||
}
|
||||
else
|
||||
{
|
||||
fatal( "-spec not provided\n" );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
zpl_printf("\nArguments: ");
|
||||
for ( int index = 0; index < num; index++)
|
||||
{
|
||||
zpl_printf("\nArg[%d]: %s", index, arguments[index]);
|
||||
}
|
||||
fatal( "Failed to parse arguments\n" );
|
||||
}
|
||||
|
||||
zpl_opts_free( & opts);
|
||||
}
|
||||
|
||||
|
||||
zpl_arena Refactor_Buffer;
|
||||
|
||||
void refactor()
|
||||
{
|
||||
ct static char const* include_sig = "include";
|
||||
|
||||
struct Token
|
||||
{
|
||||
u32 Start;
|
||||
u32 End;
|
||||
|
||||
zpl_string Sig;
|
||||
zpl_string Sub;
|
||||
};
|
||||
|
||||
static zpl_array(Token) tokens = nullptr;
|
||||
static zpl_string current = zpl_string_make( g_allocator, "");
|
||||
|
||||
#if Build_Debug
|
||||
static zpl_string preview = zpl_string_make( g_allocator, "");
|
||||
#endif
|
||||
|
||||
static bool Done = false;
|
||||
if (! Done)
|
||||
{
|
||||
zpl_array_init( tokens, g_allocator );
|
||||
Done = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
zpl_array_clear( tokens );
|
||||
}
|
||||
|
||||
// Prepare data and trackers.
|
||||
char const* src = IO::get_next_source();
|
||||
|
||||
if ( src == nullptr )
|
||||
return;
|
||||
|
||||
log_fmt("\n\nRefactoring: %s", IO::Sources[IO::Current]);
|
||||
|
||||
sw buffer_size = IO::Current_Size;
|
||||
|
||||
sw left = buffer_size;
|
||||
uw col = 0;
|
||||
uw line = 0;
|
||||
|
||||
#define pos (IO::Current_Size - left)
|
||||
|
||||
#define move_forward( Amount_ ) \
|
||||
if ( left - Amount_ <= 0 ) \
|
||||
goto End_Search; \
|
||||
\
|
||||
left -= Amount_; \
|
||||
col += Amount_; \
|
||||
src += Amount_ \
|
||||
|
||||
#define move_back( Amount_ ) \
|
||||
left += Amount_; \
|
||||
col -= Amount_; \
|
||||
src -= Amount_ \
|
||||
|
||||
do
|
||||
{
|
||||
if ( Spec::Ignore_Comments && src[0] == '/' && left - 2 > 0 )
|
||||
{
|
||||
if ( src[1] == '/' )
|
||||
{
|
||||
move_forward( 2 );
|
||||
|
||||
// Force end of line.
|
||||
while ( src[0] != '\n' )
|
||||
{
|
||||
move_forward( 1 );
|
||||
}
|
||||
|
||||
goto Skip;
|
||||
}
|
||||
else if ( src[1] == '*' )
|
||||
{
|
||||
do
|
||||
{
|
||||
move_forward( 1 );
|
||||
}
|
||||
while ( (left - 2) > 0 && !( src[0] == '*' && src[1] == '/' ) );
|
||||
|
||||
move_forward( 1 );
|
||||
|
||||
goto Skip;
|
||||
}
|
||||
}
|
||||
|
||||
// Includes to ignore
|
||||
do
|
||||
{
|
||||
Spec::Entry* ignore = Spec::Ignore_Includes;
|
||||
sw ignores_left = zpl_array_count( Spec::Ignore_Includes);
|
||||
sw rewind = 0;
|
||||
|
||||
if ( '#' != src[0] )
|
||||
break;
|
||||
|
||||
move_forward( 1 );
|
||||
rewind++;
|
||||
|
||||
// Ignore whitespace
|
||||
while ( zpl_char_is_space( src[0] ) )
|
||||
{
|
||||
move_forward( 1 );
|
||||
rewind++;
|
||||
}
|
||||
|
||||
if ( zpl_strncmp( include_sig, src, sizeof(include_sig) - 1 ) != 0 )
|
||||
{
|
||||
move_back( rewind );
|
||||
break;
|
||||
}
|
||||
|
||||
const u32 sig_size = sizeof(include_sig) - 1;
|
||||
|
||||
move_forward( sig_size );
|
||||
rewind += sig_size;
|
||||
|
||||
// Ignore whitespace
|
||||
while ( zpl_char_is_space( src[0] ) || src[0] == '\"' || src[0] == '<' )
|
||||
{
|
||||
move_forward(1);
|
||||
rewind++;
|
||||
}
|
||||
|
||||
for ( ; ignores_left; ignores_left--, ignore++ )
|
||||
{
|
||||
zpl_string_clear( current );
|
||||
|
||||
u32 sig_length = zpl_string_length( ignore->Sig );
|
||||
current = zpl_string_append_length( current, src, sig_length );
|
||||
|
||||
if ( zpl_string_are_equal( ignore->Sig, current ) )
|
||||
{
|
||||
log_fmt("\nIgnored %-81s line %d, col %d", current, line, col );
|
||||
|
||||
const sw length = zpl_string_length( current );
|
||||
|
||||
// The + 1 is for the closing " or > of the include
|
||||
move_forward( length + 1 );
|
||||
|
||||
// Force end of line.
|
||||
while ( src[0] != '\n' )
|
||||
{
|
||||
move_forward( 1 );
|
||||
}
|
||||
|
||||
goto Skip;
|
||||
}
|
||||
}
|
||||
|
||||
move_back( rewind );
|
||||
}
|
||||
while (false);
|
||||
|
||||
// Word Ignores
|
||||
{
|
||||
Spec::Entry* ignore = Spec::Ignore_Words;
|
||||
sw ignores_left = zpl_array_count( Spec::Ignore_Words);
|
||||
|
||||
for ( ; ignores_left; ignores_left--, ignore++ )
|
||||
{
|
||||
if ( ignore->Sig[0] != src[0] )
|
||||
continue;
|
||||
|
||||
zpl_string_clear( current );
|
||||
|
||||
u32 sig_length = zpl_string_length( ignore->Sig );
|
||||
current = zpl_string_append_length( current, src, sig_length );
|
||||
|
||||
if ( zpl_string_are_equal( ignore->Sig, current ) )
|
||||
{
|
||||
char before = src[-1];
|
||||
char after = src[sig_length];
|
||||
|
||||
if ( zpl_char_is_alphanumeric( before ) || before == '_'
|
||||
|| zpl_char_is_alphanumeric( after ) || after == '_' )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
log_fmt("\nIgnored %-81s line %d, col %d", current, line, col );
|
||||
|
||||
move_forward( sig_length );
|
||||
goto Skip;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Namespace Ignores
|
||||
{
|
||||
Spec::Entry* ignore = Spec::Ignore_Namespaces;
|
||||
sw ignores_left = zpl_array_count( Spec::Ignore_Namespaces);
|
||||
|
||||
for ( ; ignores_left; ignores_left--, ignore++ )
|
||||
{
|
||||
if ( ignore->Sig[0] != src[0] )
|
||||
{
|
||||
ignore++;
|
||||
continue;
|
||||
}
|
||||
|
||||
zpl_string_clear( current );
|
||||
|
||||
u32 sig_length = zpl_string_length( ignore->Sig );
|
||||
current = zpl_string_append_length( current, src, sig_length );
|
||||
|
||||
if ( zpl_string_are_equal( ignore->Sig, current ) )
|
||||
{
|
||||
u32 length = sig_length;
|
||||
char const* ns_content = src + sig_length;
|
||||
|
||||
while ( zpl_char_is_alphanumeric( ns_content[0] ) || ns_content[0] == '_' )
|
||||
{
|
||||
length++;
|
||||
ns_content++;
|
||||
}
|
||||
|
||||
#if Build_Debug
|
||||
zpl_string_clear( preview );
|
||||
preview = zpl_string_append_length( preview, src, length );
|
||||
log_fmt("\nIgnored %-40s %-40s line %d, column %d", preview, ignore->Sig, line, col );
|
||||
#endif
|
||||
|
||||
move_forward( length );
|
||||
goto Skip;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Includes to match
|
||||
do
|
||||
{
|
||||
Spec::Entry* include = Spec::Includes;
|
||||
sw includes_left = zpl_array_count ( Spec::Includes);
|
||||
sw rewind = 0;
|
||||
|
||||
if ( '#' != src[0] )
|
||||
break;
|
||||
|
||||
move_forward( 1 );
|
||||
rewind++;
|
||||
|
||||
// Ignore whitespace
|
||||
while ( zpl_char_is_space( src[0] ) )
|
||||
{
|
||||
move_forward( 1 );
|
||||
rewind++;
|
||||
}
|
||||
|
||||
if ( zpl_strncmp( include_sig, src, sizeof(include_sig) - 1 ) != 0 )
|
||||
{
|
||||
move_back( rewind );
|
||||
break;
|
||||
}
|
||||
|
||||
const u32 sig_size = sizeof(include_sig) - 1;
|
||||
|
||||
move_forward( sig_size );
|
||||
rewind += sig_size;
|
||||
|
||||
// Ignore whitespace
|
||||
while ( zpl_char_is_space( src[0] ) || src[0] == '\"' || src[0] == '<' )
|
||||
{
|
||||
move_forward( 1 );
|
||||
rewind++;
|
||||
}
|
||||
|
||||
for ( ; includes_left; includes_left--, include++ )
|
||||
{
|
||||
zpl_string_clear( current );
|
||||
|
||||
u32 sig_length = zpl_string_length( include->Sig );
|
||||
current = zpl_string_append_length( current, src, sig_length );
|
||||
|
||||
if ( zpl_string_are_equal( include->Sig, current ) )
|
||||
{
|
||||
Token entry {};
|
||||
|
||||
entry.Start = pos;
|
||||
entry.End = pos + sig_length;
|
||||
entry.Sig = include->Sig;
|
||||
|
||||
if ( include->Sub != nullptr )
|
||||
{
|
||||
entry.Sub = include->Sub;
|
||||
buffer_size += zpl_string_length( entry.Sub) - sig_length;
|
||||
}
|
||||
|
||||
zpl_array_append( tokens, entry );
|
||||
|
||||
log_fmt("\nFound %-81s line %d, column %d", current, line, col );
|
||||
|
||||
// The + 1 is for the closing " or > of the include
|
||||
move_forward( sig_length + 1 );
|
||||
|
||||
// Force end of line.
|
||||
while ( src[0] != '\n' )
|
||||
{
|
||||
move_forward( 1 );
|
||||
}
|
||||
|
||||
goto Skip;
|
||||
}
|
||||
}
|
||||
|
||||
move_back( rewind );
|
||||
}
|
||||
while (false);
|
||||
|
||||
// Words to match
|
||||
{
|
||||
Spec::Entry* word = Spec::Words;
|
||||
sw words_left = zpl_array_count ( Spec::Words);
|
||||
|
||||
for ( ; words_left; words_left--, word++ )
|
||||
{
|
||||
if ( word->Sig[0] != src[0] )
|
||||
continue;
|
||||
|
||||
zpl_string_clear( current );
|
||||
|
||||
sw sig_length = zpl_string_length( word->Sig);
|
||||
current = zpl_string_append_length( current, src, sig_length );
|
||||
|
||||
if ( zpl_string_are_equal( word->Sig, current ) )
|
||||
{
|
||||
char before = src[-1];
|
||||
char after = src[sig_length];
|
||||
|
||||
if ( zpl_char_is_alphanumeric( before ) || before == '_'
|
||||
|| zpl_char_is_alphanumeric( after ) || after == '_' )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Token entry {};
|
||||
|
||||
entry.Start = pos;
|
||||
entry.End = pos + sig_length;
|
||||
entry.Sig = word->Sig;
|
||||
|
||||
if ( word->Sub != nullptr )
|
||||
{
|
||||
entry.Sub = word->Sub;
|
||||
buffer_size += zpl_string_length( entry.Sub) - sig_length;
|
||||
}
|
||||
|
||||
zpl_array_append( tokens, entry );
|
||||
|
||||
log_fmt("\nFound %-81s line %d, column %d", current, line, col );
|
||||
|
||||
move_forward( sig_length );
|
||||
goto Skip;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Namespaces to match
|
||||
{
|
||||
Spec::Entry* nspace = Spec::Namespaces;
|
||||
|
||||
sw nspaces_left = zpl_array_count( Spec::Namespaces);
|
||||
|
||||
for ( ; nspaces_left; nspaces_left--, nspace++ )
|
||||
{
|
||||
if ( nspace->Sig[0] != src[0] )
|
||||
continue;
|
||||
|
||||
zpl_string_clear( current );
|
||||
|
||||
u32 sig_length = zpl_string_length( nspace->Sig );
|
||||
current = zpl_string_append_length( current, src, sig_length );
|
||||
|
||||
if ( zpl_string_are_equal( nspace->Sig, current ) )
|
||||
{
|
||||
u32 length = sig_length;
|
||||
char const* ns_content = src + sig_length;
|
||||
|
||||
while ( zpl_char_is_alphanumeric( ns_content[0] ) || ns_content[0] == '_' )
|
||||
{
|
||||
length++;
|
||||
ns_content++;
|
||||
}
|
||||
|
||||
Token entry {};
|
||||
|
||||
entry.Start = pos;
|
||||
entry.End = pos + length;
|
||||
entry.Sig = nspace->Sig;
|
||||
|
||||
buffer_size += sig_length;
|
||||
|
||||
if ( nspace->Sub != nullptr )
|
||||
{
|
||||
entry.Sub = nspace->Sub;
|
||||
buffer_size += zpl_string_length( entry.Sub ) - length;
|
||||
}
|
||||
|
||||
zpl_array_append( tokens, entry );
|
||||
|
||||
#if Build_Debug
|
||||
zpl_string_clear( preview );
|
||||
preview = zpl_string_append_length( preview, src, length);
|
||||
log_fmt("\nFound %-40s %-40s line %d, column %d", preview, nspace->Sig, line, col );
|
||||
#endif
|
||||
|
||||
move_forward( length );
|
||||
goto Skip;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Skip:
|
||||
if ( src[0] == '\n' )
|
||||
{
|
||||
line++;
|
||||
col = 0;
|
||||
}
|
||||
|
||||
move_forward( 1 );
|
||||
|
||||
// zpl_string_clear( preview );
|
||||
// preview = zpl_string_append_length( preview, src, 100);
|
||||
// log_fmt( "__PREVIEW: %d \nn%s\n\n__PREVIEW_END", left, preview );
|
||||
}
|
||||
while ( left );
|
||||
End_Search:
|
||||
|
||||
if (zpl_array_count( tokens ) == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Prep data for building the content
|
||||
left = zpl_array_count( tokens);
|
||||
|
||||
char* content = IO::Current_Content;
|
||||
|
||||
zpl_string refactored = zpl_string_make_reserve( zpl_arena_allocator( & Refactor_Buffer ), buffer_size );
|
||||
|
||||
// Generate the refactored file content.
|
||||
{
|
||||
Token* entry = tokens;
|
||||
sw previous_end = 0;
|
||||
|
||||
do
|
||||
{
|
||||
sw segment_length = entry->Start - previous_end;
|
||||
sw sig_length = zpl_string_length( entry->Sig );
|
||||
|
||||
// Append between tokens
|
||||
refactored = zpl_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 = zpl_string_append( refactored, entry->Sub );
|
||||
}
|
||||
|
||||
refactored = zpl_string_append_length( refactored, content, segment_length );
|
||||
content += segment_length;
|
||||
|
||||
previous_end = entry->End;
|
||||
entry++;
|
||||
}
|
||||
while ( --left > 0 );
|
||||
|
||||
entry--;
|
||||
|
||||
if ( entry->End < IO::Current_Size )
|
||||
{
|
||||
refactored = zpl_string_append_length( refactored, content, IO::Current_Size - 1 - entry->End );
|
||||
}
|
||||
}
|
||||
|
||||
IO::write( refactored );
|
||||
|
||||
zpl_free_all( zpl_arena_allocator( & Refactor_Buffer ));
|
||||
|
||||
#undef pos
|
||||
#undef move_forward
|
||||
}
|
||||
|
||||
int main( int num, char** arguments )
|
||||
{
|
||||
Memory::setup();
|
||||
|
||||
parse_options( num, arguments);
|
||||
|
||||
IO::prepare();
|
||||
|
||||
// Just reserving more than we'll ever problably need.
|
||||
zpl_arena_init_from_allocator( & Refactor_Buffer, zpl_heap(), IO::Largest_Src_Size * 4 + 8);
|
||||
|
||||
Spec::parse();
|
||||
|
||||
sw left = zpl_array_count( IO::Sources );
|
||||
do
|
||||
{
|
||||
refactor();
|
||||
|
||||
zpl_printf("\nRefactored: %s", IO::Sources[IO::Current]);
|
||||
}
|
||||
while ( --left );
|
||||
|
||||
zpl_arena_free( & Refactor_Buffer );
|
||||
|
||||
Spec:: cleanup();
|
||||
IO:: cleanup();
|
||||
Memory::cleanup();
|
||||
}
|
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>
|
779
refactor.cpp
779
refactor.cpp
@ -1,779 +0,0 @@
|
||||
#define ZPL_IMPLEMENTATION
|
||||
#include "bloat.hpp"
|
||||
|
||||
|
||||
namespace File
|
||||
{
|
||||
zpl_string Source = nullptr;
|
||||
zpl_string Destination = nullptr;
|
||||
|
||||
zpl_file_contents Content {};
|
||||
|
||||
zpl_arena Buffer;
|
||||
|
||||
void cleanup()
|
||||
{
|
||||
zpl_arena_free( & Buffer );
|
||||
}
|
||||
|
||||
void read()
|
||||
{
|
||||
zpl_file file_src = {};
|
||||
|
||||
Content.allocator = g_allocator;
|
||||
|
||||
zpl_file_error error_src = zpl_file_open( & file_src, Source );
|
||||
|
||||
if ( error_src == ZPL_FILE_ERROR_NONE )
|
||||
{
|
||||
zpl_isize fsize = cast(zpl_isize) zpl_file_size( & file_src);
|
||||
|
||||
if ( fsize > 0 )
|
||||
{
|
||||
zpl_arena_init_from_allocator( & Buffer, zpl_heap(), (fsize + fsize % 64) * 4 );
|
||||
|
||||
Content.data = zpl_alloc( zpl_arena_allocator( & Buffer), fsize);
|
||||
Content.size = fsize;
|
||||
|
||||
zpl_file_read_at ( & file_src, Content.data, Content.size, 0);
|
||||
}
|
||||
|
||||
zpl_file_close( & file_src);
|
||||
}
|
||||
|
||||
if ( Content.data == nullptr )
|
||||
{
|
||||
zpl_printf( "Unable to open source file: %s\n", Source );
|
||||
fatal();
|
||||
}
|
||||
}
|
||||
|
||||
void write(zpl_string refactored)
|
||||
{
|
||||
if ( refactored == nullptr)
|
||||
return;
|
||||
|
||||
zpl_file file_dest {};
|
||||
zpl_file_error error = zpl_file_create( & file_dest, Destination );
|
||||
|
||||
if ( error != ZPL_FILE_ERROR_NONE )
|
||||
{
|
||||
zpl_printf( "Unable to open destination file: %s\n", Destination );
|
||||
fatal();
|
||||
}
|
||||
|
||||
zpl_file_write( & file_dest, refactored, zpl_string_length(refactored) );
|
||||
}
|
||||
}
|
||||
|
||||
namespace Spec
|
||||
{
|
||||
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
|
||||
c8 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, 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
|
||||
};
|
||||
|
||||
zpl_arena Buffer {};
|
||||
zpl_array(Entry) Word_Ignores;
|
||||
zpl_array(Entry) Namespace_Ignores;
|
||||
zpl_array(Entry) Words;
|
||||
zpl_array(Entry) Namespaces;
|
||||
|
||||
u32 Sig_Smallest = zpl_kilobytes(1);
|
||||
|
||||
forceinline
|
||||
void find_next_token( zpl_string& token, char*& line, u32& length )
|
||||
{
|
||||
zpl_string_clear( token );
|
||||
length = 0;
|
||||
while ( zpl_char_is_alphanumeric( line[length] ) || line[length] == '_' )
|
||||
{
|
||||
length++;
|
||||
}
|
||||
|
||||
if ( length == 0 )
|
||||
{
|
||||
zpl_printf("Failed to find valid initial token");
|
||||
fatal();
|
||||
}
|
||||
|
||||
token = zpl_string_append_length( token, line, length );
|
||||
line += length;
|
||||
}
|
||||
|
||||
void process()
|
||||
{
|
||||
char* content;
|
||||
|
||||
zpl_array(char*) lines;
|
||||
|
||||
// Get the contents of the file.
|
||||
{
|
||||
zpl_file file {};
|
||||
zpl_file_error error = zpl_file_open( & file, File);
|
||||
|
||||
if ( error != ZPL_FILE_ERROR_NONE )
|
||||
{
|
||||
zpl_printf("Could not open the specification file: %s", File);
|
||||
fatal();
|
||||
}
|
||||
|
||||
sw fsize = scast( sw, zpl_file_size( & file ) );
|
||||
|
||||
if ( fsize <= 0 )
|
||||
{
|
||||
zpl_printf("No content in specificaiton to process");
|
||||
fatal();
|
||||
}
|
||||
|
||||
zpl_arena_init_from_allocator( & Buffer, zpl_heap(), (fsize + fsize % 64) * 10 + zpl_kilobytes(1) );
|
||||
|
||||
char* content = rcast( char*, zpl_alloc( zpl_arena_allocator( & Buffer), fsize + 1) );
|
||||
|
||||
zpl_file_read( & file, content, fsize);
|
||||
|
||||
content[fsize] = 0;
|
||||
|
||||
lines = zpl_str_split_lines( zpl_arena_allocator( & Buffer ), content, false );
|
||||
|
||||
zpl_file_close( & file );
|
||||
}
|
||||
|
||||
sw left = zpl_array_count( lines );
|
||||
|
||||
if ( left == 0 )
|
||||
{
|
||||
zpl_printf("Spec::process: lines array imporoperly setup");
|
||||
fatal();
|
||||
}
|
||||
|
||||
// Skip the first line as its the version number and we only support __VERSION 1.
|
||||
left--;
|
||||
lines++;
|
||||
|
||||
zpl_array_init( Word_Ignores, zpl_arena_allocator( & Buffer));
|
||||
zpl_array_init( Namespace_Ignores, zpl_arena_allocator( & Buffer));
|
||||
zpl_array_init( Words, zpl_arena_allocator( & Buffer));
|
||||
zpl_array_init( Namespaces, zpl_arena_allocator( & Buffer));
|
||||
|
||||
// Limiting the maximum output of a token to 1 KB
|
||||
zpl_string token = zpl_string_make_reserve( zpl_arena_allocator( & Buffer), zpl_kilobytes(1));
|
||||
|
||||
while ( left-- )
|
||||
{
|
||||
char* line = * lines;
|
||||
|
||||
// Ignore line if its a comment
|
||||
if ( line[0] == '/' && line[1] == '/')
|
||||
{
|
||||
lines++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Remove indent
|
||||
{
|
||||
while ( zpl_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 ( zpl_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 ( zpl_char_is_space( line[0] ) )
|
||||
line++;
|
||||
|
||||
if ( line[0] == '\0' )
|
||||
{
|
||||
lines++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
find_next_token( token, line, length );
|
||||
|
||||
// First argument is signature.
|
||||
entry.Sig = zpl_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)
|
||||
zpl_array_append( Namespace_Ignores, entry );
|
||||
|
||||
else
|
||||
zpl_array_append( Namespaces, entry );
|
||||
break;
|
||||
|
||||
case Tok::Word:
|
||||
if ( ignore)
|
||||
{
|
||||
zpl_array_append( Word_Ignores, entry );
|
||||
u32 test = zpl_array_count( Word_Ignores );
|
||||
}
|
||||
|
||||
|
||||
else
|
||||
zpl_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:
|
||||
zpl_array_append( Namespaces, entry );
|
||||
break;
|
||||
|
||||
case Tok::Word:
|
||||
zpl_array_append( Words, entry );
|
||||
break;
|
||||
}
|
||||
|
||||
bSkip = true;
|
||||
break;
|
||||
}
|
||||
|
||||
line++;
|
||||
}
|
||||
|
||||
if ( bSkip )
|
||||
{
|
||||
lines++;
|
||||
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::Namespace:
|
||||
zpl_array_append( Namespaces, entry );
|
||||
break;
|
||||
|
||||
case Tok::Word:
|
||||
zpl_array_append( Words, entry );
|
||||
break;
|
||||
}
|
||||
|
||||
lines++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
find_next_token( token, line, length );
|
||||
|
||||
// Second argument is substitute.
|
||||
entry.Sub = zpl_string_make_length( g_allocator, token, length );
|
||||
|
||||
switch ( type )
|
||||
{
|
||||
case Tok::Namespace:
|
||||
zpl_array_append( Namespaces, entry );
|
||||
lines++;
|
||||
continue;
|
||||
|
||||
case Tok::Word:
|
||||
zpl_array_append( Words, entry );
|
||||
lines++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
zpl_printf("Specification Line: %d is missing valid keyword", zpl_array_count(lines) - left);
|
||||
lines++;
|
||||
}
|
||||
}
|
||||
|
||||
void cleanup()
|
||||
{
|
||||
zpl_arena_free( & Buffer );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
struct Token
|
||||
{
|
||||
u32 Start;
|
||||
u32 End;
|
||||
|
||||
zpl_string Sig;
|
||||
zpl_string Sub;
|
||||
};
|
||||
|
||||
void refactor()
|
||||
{
|
||||
sw buffer_size = File::Content.size;
|
||||
|
||||
zpl_array(Token) tokens;
|
||||
zpl_array_init( tokens, g_allocator);
|
||||
|
||||
char* content = rcast( char*, File::Content.data );
|
||||
|
||||
zpl_string current = zpl_string_make( g_allocator, "");
|
||||
zpl_string preview = zpl_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 = zpl_array_count( Spec::Word_Ignores);
|
||||
|
||||
do
|
||||
{
|
||||
if ( ignore->Sig[0] != content[0] )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
zpl_string_clear( current );
|
||||
|
||||
u32 sig_length = zpl_string_length( ignore->Sig );
|
||||
current = zpl_string_append_length( current, content, sig_length );
|
||||
|
||||
// bool match = false;
|
||||
// if ( zpl_strncmp( "zpl_printf", current, sig_length ) == 0 )
|
||||
// {
|
||||
// match = true;
|
||||
// }
|
||||
|
||||
if ( zpl_string_are_equal( ignore->Sig, current ) )
|
||||
{
|
||||
char before = content[-1];
|
||||
char after = content[sig_length];
|
||||
|
||||
if ( zpl_char_is_alphanumeric( before ) || before == '_'
|
||||
|| zpl_char_is_alphanumeric( after ) || after == '_' )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
zpl_printf("\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 = zpl_array_count( Spec::Namespace_Ignores);
|
||||
|
||||
do
|
||||
{
|
||||
if ( ignore->Sig[0] != content[0] )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
zpl_string_clear( current );
|
||||
|
||||
u32 sig_length = zpl_string_length( ignore->Sig );
|
||||
current = zpl_string_append_length( current, content, sig_length );
|
||||
|
||||
if ( zpl_string_are_equal( ignore->Sig, current ) )
|
||||
{
|
||||
u32 length = sig_length;
|
||||
char* ns_content = content + sig_length;
|
||||
|
||||
while ( zpl_char_is_alphanumeric( ns_content[0] ) || ns_content[0] == '_' )
|
||||
{
|
||||
length++;
|
||||
ns_content++;
|
||||
}
|
||||
|
||||
zpl_string_clear( preview );
|
||||
preview = zpl_string_append_length( preview, content, length );
|
||||
zpl_printf("\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 = zpl_array_count ( Spec::Words);
|
||||
|
||||
do
|
||||
{
|
||||
if ( word->Sig[0] != content[0] )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
zpl_string_clear( current );
|
||||
|
||||
sw sig_length = zpl_string_length( word->Sig);
|
||||
current = zpl_string_append_length( current, content, sig_length );
|
||||
|
||||
if ( zpl_string_are_equal( word->Sig, current ) )
|
||||
{
|
||||
char before = content[-1];
|
||||
char after = content[sig_length];
|
||||
|
||||
if ( zpl_char_is_alphanumeric( before ) || before == '_'
|
||||
|| zpl_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 += zpl_string_length( entry.Sub) - sig_length;
|
||||
}
|
||||
|
||||
zpl_array_append( tokens, entry );
|
||||
|
||||
zpl_printf("\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 = zpl_array_count( Spec::Namespaces);
|
||||
|
||||
do
|
||||
{
|
||||
if ( nspace->Sig[0] != content[0] )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
zpl_string_clear( current );
|
||||
|
||||
u32 sig_length = zpl_string_length( nspace->Sig );
|
||||
current = zpl_string_append_length( current, content, sig_length );
|
||||
|
||||
if ( zpl_string_are_equal( nspace->Sig, current ) )
|
||||
{
|
||||
u32 length = sig_length;
|
||||
char* ns_content = content + sig_length;
|
||||
|
||||
while ( zpl_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 += zpl_string_length( entry.Sub ) - length;
|
||||
}
|
||||
|
||||
zpl_array_append( tokens, entry );
|
||||
|
||||
zpl_string_clear( preview );
|
||||
preview = zpl_string_append_length( preview, content, length);
|
||||
zpl_printf("\nFound %-40s %-40s line %d", preview, nspace->Sig, line);
|
||||
|
||||
content += length;
|
||||
left -= length;
|
||||
}
|
||||
}
|
||||
while ( nspace++, --nspaces_left );
|
||||
}
|
||||
|
||||
content++;
|
||||
left--;
|
||||
Skip:
|
||||
continue;
|
||||
}
|
||||
|
||||
left = zpl_array_count( tokens);
|
||||
content = rcast( char*, File::Content.data);
|
||||
|
||||
// Generate the refactored file content.
|
||||
zpl_arena buffer;
|
||||
zpl_string refactored = nullptr;
|
||||
{
|
||||
Token* entry = tokens;
|
||||
|
||||
if ( entry == nullptr)
|
||||
return;
|
||||
|
||||
zpl_arena_init_from_allocator( & buffer, zpl_heap(), buffer_size * 2 );
|
||||
|
||||
zpl_string
|
||||
new_string = zpl_string_make_reserve( zpl_arena_allocator( & buffer), zpl_kilobytes(1) );
|
||||
refactored = zpl_string_make_reserve( zpl_arena_allocator( & buffer), buffer_size );
|
||||
|
||||
sw previous_end = 0;
|
||||
|
||||
while ( left-- )
|
||||
{
|
||||
sw segment_length = entry->Start - previous_end;
|
||||
|
||||
sw sig_length = zpl_string_length( entry->Sig );
|
||||
|
||||
// Append between tokens
|
||||
refactored = zpl_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 = zpl_string_append( refactored, entry->Sub );
|
||||
|
||||
refactored = zpl_string_append_length( refactored, content, segment_length );
|
||||
content += segment_length;
|
||||
|
||||
previous_end = entry->End;
|
||||
entry++;
|
||||
}
|
||||
|
||||
entry--;
|
||||
|
||||
if ( entry->End < File::Content.size )
|
||||
{
|
||||
refactored = zpl_string_append_length( refactored, content, File::Content.size - entry->End );
|
||||
}
|
||||
}
|
||||
|
||||
// Write refactored content to destination.
|
||||
File::write( refactored );
|
||||
|
||||
zpl_arena_free( & buffer );
|
||||
}
|
||||
|
||||
|
||||
inline
|
||||
void parse_options( int num, char** arguments )
|
||||
{
|
||||
zpl_opts opts;
|
||||
zpl_opts_init( & opts, g_allocator, "refactor");
|
||||
zpl_opts_add( & opts, "source" , "src" , "File to refactor" , ZPL_OPTS_STRING);
|
||||
zpl_opts_add( & opts, "destination" , "dst" , "File post refactor" , ZPL_OPTS_STRING);
|
||||
zpl_opts_add( & opts, "specification", "spec", "Specification for refactoring", ZPL_OPTS_STRING);
|
||||
|
||||
if (zpl_opts_compile( & opts, num, arguments))
|
||||
{
|
||||
if ( zpl_opts_has_arg( & opts, "src" ) )
|
||||
{
|
||||
zpl_string opt = zpl_opts_string( & opts, "src", "INVALID PATH" );
|
||||
|
||||
File::Source = zpl_string_make( g_allocator, "" );
|
||||
File::Source = zpl_string_append( File::Source, opt );
|
||||
}
|
||||
else
|
||||
{
|
||||
zpl_printf( "-source not provided\n" );
|
||||
fatal();
|
||||
}
|
||||
|
||||
if ( zpl_opts_has_arg( & opts, "dst" ) )
|
||||
{
|
||||
zpl_string opt = zpl_opts_string( & opts, "dst", "INVALID PATH" );
|
||||
|
||||
File::Destination = zpl_string_make( g_allocator, "" );
|
||||
File::Destination = zpl_string_append( File::Destination, opt );
|
||||
}
|
||||
else if ( File::Source )
|
||||
{
|
||||
File::Destination = zpl_string_make( g_allocator, "" );
|
||||
File::Destination = zpl_string_append( File::Destination, File::Source );
|
||||
}
|
||||
|
||||
if ( zpl_opts_has_arg( & opts, "spec" ) )
|
||||
{
|
||||
zpl_string opt = zpl_opts_string( & opts, "spec", "INVALID PATH" );
|
||||
|
||||
Spec::File = zpl_string_make( g_allocator, "" );
|
||||
Spec::File = zpl_string_append( Spec::File, opt );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
zpl_printf( "Failed to parse arguments\n" );
|
||||
fatal();
|
||||
}
|
||||
|
||||
zpl_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();
|
||||
}
|
80
scripts/build.ps1
Normal file
80
scripts/build.ps1
Normal file
@ -0,0 +1,80 @@
|
||||
cls
|
||||
|
||||
[string] $type = $null
|
||||
[string] $test = $false
|
||||
|
||||
foreach ( $arg in $args )
|
||||
{
|
||||
if ( $arg -eq "test" )
|
||||
{
|
||||
$test = $true
|
||||
}
|
||||
else
|
||||
{
|
||||
$type = $arg
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#region Regular Build
|
||||
write-host "Building project`n"
|
||||
|
||||
$path_root = git rev-parse --show-toplevel
|
||||
$path_build = Join-Path $path_root build
|
||||
$path_scripts = Join-Path $path_root scripts
|
||||
|
||||
|
||||
if ( -not( Test-Path $path_build ) )
|
||||
{
|
||||
$args_meson = @()
|
||||
$args_meson += "setup"
|
||||
$args_meson += $path_build
|
||||
|
||||
Start-Process meson $args_meson -NoNewWindow -Wait -WorkingDirectory $path_scripts
|
||||
}
|
||||
|
||||
if ( $type )
|
||||
{
|
||||
$args_meson = @()
|
||||
$args_meson += "configure"
|
||||
$args_meson += $path_build
|
||||
$args_meson += "--buildtype $($type)"
|
||||
|
||||
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_root
|
||||
#endregion Regular Build
|
||||
|
||||
|
||||
if ( $test -eq $true )
|
||||
{
|
||||
#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
|
||||
}
|
21
scripts/clean.ps1
Normal file
21
scripts/clean.ps1
Normal file
@ -0,0 +1,21 @@
|
||||
$path_root = git rev-parse --show-toplevel
|
||||
$path_build = Join-Path $path_root build
|
||||
$path_test = Join-Path $path_root test
|
||||
$path_test_build = Join-Path $path_test build
|
||||
|
||||
if ( Test-Path $path_build )
|
||||
{
|
||||
Remove-Item $path_build -Recurse
|
||||
}
|
||||
|
||||
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
|
12
scripts/get_sources.ps1
Normal file
12
scripts/get_sources.ps1
Normal file
@ -0,0 +1,12 @@
|
||||
[string[]] $include = 'refactor.cpp' #'*.c', '*.cc', '*.cpp'
|
||||
# [string[]] $exclude =
|
||||
|
||||
$path_root = git rev-parse --show-toplevel
|
||||
$path_proj = Join-Path $path_root project
|
||||
|
||||
$files = Get-ChildItem -Recurse -Path $path_proj -Include $include -Exclude $exclude
|
||||
|
||||
$sources = $files | Select-Object -ExpandProperty FullName | Resolve-Path -Relative
|
||||
$sources = $sources.Replace( '\', '/' )
|
||||
|
||||
return $sources
|
19
scripts/meson.build
Normal file
19
scripts/meson.build
Normal file
@ -0,0 +1,19 @@
|
||||
project( 'refactor', 'c', 'cpp', default_options : ['buildtype=release'] )
|
||||
|
||||
# add_global_arguments('-E', language : 'cpp')
|
||||
|
||||
includes = include_directories(
|
||||
[ '../project'
|
||||
, '../thirdparty'
|
||||
])
|
||||
|
||||
get_sources = files('./get_sources.ps1')
|
||||
sources = files(run_command('powershell', get_sources, check: true).stdout().strip().split('\n'))
|
||||
|
||||
if get_option('buildtype').startswith('debug')
|
||||
|
||||
add_project_arguments('-DBuild_Debug', language : ['c', 'cpp'])
|
||||
|
||||
endif
|
||||
|
||||
executable( 'refactor', sources, include_directories : includes )
|
117
scripts/refactor_and_format.ps1
Normal file
117
scripts/refactor_and_format.ps1
Normal file
@ -0,0 +1,117 @@
|
||||
[string[]] $include = '*.h', '*.hh', '*.hpp', '*.c', '*.cc', '*.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
|
||||
|
||||
$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)
|
||||
$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 = @(
|
||||
"-debug",
|
||||
"-num=$($targetFiles.Count)"
|
||||
"-src=$($targetFiles)",
|
||||
"-dst=$($refactoredFiles)",
|
||||
"-spec=$($file_spec)"
|
||||
)
|
||||
|
||||
Start-Process $refactor $refactorParams -NoNewWindow -PassThru -Wait
|
||||
}
|
||||
|
||||
foreach ( $process in $refactors )
|
||||
{
|
||||
if ( $process )
|
||||
{
|
||||
$process.WaitForExit()
|
||||
}
|
||||
}
|
||||
|
||||
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 ) {
|
||||
Write-Host "Beginning format...`n"
|
||||
|
||||
# Format the files.
|
||||
$formatParams = @(
|
||||
'-i' # In-place
|
||||
'-style=file' # Search for a .clang-format file in the parent directory of the source file.
|
||||
'-verbose'
|
||||
)
|
||||
|
||||
$targetFiles = @(Get-ChildItem -Recurse -Path $path_test -Include $include -Exclude $exclude | Select-Object -ExpandProperty FullName)
|
||||
|
||||
clang-format $formatParams $targetFiles
|
||||
|
||||
Write-Host "`nFormatting complete"
|
||||
}
|
255
thirdparty/zpl.h
vendored
255
thirdparty/zpl.h
vendored
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user