mirror of
https://github.com/Ed94/refactor.git
synced 2025-07-01 03:11:06 -07:00
Compare commits
62 Commits
add-licens
...
bloat
Author | SHA1 | Date | |
---|---|---|---|
5efd14322e | |||
c4efd1890d | |||
063a3a972c | |||
e301b400ba | |||
6bc4346652 | |||
6e91555a20 | |||
1b0c5d176c | |||
ea09b27b3b | |||
d344043c44 | |||
bdc272cc2b | |||
8d5cdec586 | |||
1d807eaf0a | |||
2fe7ded7ec | |||
1f2d3cdd42 | |||
03f5441b25 | |||
b05ee03609 | |||
e30539fe32 | |||
935bfe63ad | |||
d95d4a8d06 | |||
7d7c34d157 | |||
25df998dc2 | |||
9479a28282 | |||
0246b8419a | |||
0da1505190 | |||
d73d22282b | |||
78cdfcd7b3 | |||
018286be6f | |||
a0a3e42e6a | |||
f9b8f02351 | |||
5bfa8395db | |||
048fcac1bf | |||
eccbdac3b2 | |||
2933393f55 | |||
61880e8dee | |||
9bf6af8ce5 | |||
20dd92a684 | |||
be6b37ae00 | |||
e867768862 | |||
b08ff787a8 | |||
263fa66f7f | |||
6e9d35cb37 | |||
2176314adf | |||
484c2ac35c | |||
2419f407a8 | |||
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
|
110
.github/workflows/main.yml
vendored
Normal file
110
.github/workflows/main.yml
vendored
Normal file
@ -0,0 +1,110 @@
|
||||
# Name of the workflow
|
||||
name: Build
|
||||
|
||||
# Events used by github actions to know when to execute this workflow
|
||||
on:
|
||||
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
type:
|
||||
description: 'Meson buildtype (release, debug, etc.)'
|
||||
default: release
|
||||
required: false
|
||||
|
||||
test:
|
||||
description: 'Run tests (test)'
|
||||
default: test
|
||||
required: true
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on:
|
||||
windows-latest
|
||||
|
||||
steps:
|
||||
- name: Check out repository
|
||||
uses: actions/checkout@v2
|
||||
|
||||
|
||||
- name: Install Meson, Ninja, and Clang with Chocolatey and pip
|
||||
shell: pwsh
|
||||
|
||||
run: |
|
||||
$ErrorActionPreference = "Stop"
|
||||
if (-not (Get-Command choco -ErrorAction SilentlyContinue))
|
||||
{
|
||||
Set-ExecutionPolicy Bypass -Scope Process -Force
|
||||
iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
|
||||
}
|
||||
|
||||
if (-not (choco list --local-only | Select-String "python"))
|
||||
{
|
||||
choco install -y python
|
||||
}
|
||||
|
||||
if (-not (choco list --local-only | Select-String "ninja"))
|
||||
{
|
||||
choco install -y ninja
|
||||
}
|
||||
|
||||
if (-not (choco list --local-only | Select-String "llvm"))
|
||||
{
|
||||
choco install -y llvm
|
||||
}
|
||||
|
||||
python -m pip install meson
|
||||
|
||||
|
||||
- name: Run PowerShell build script
|
||||
|
||||
shell: pwsh
|
||||
|
||||
env:
|
||||
CC: clang
|
||||
CXX: clang++
|
||||
BUILD_TYPE: ${{ github.event.inputs.type }}
|
||||
RUN_TESTS: ${{ github.event.inputs.test }}
|
||||
|
||||
run: |
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
$type = $env:BUILD_TYPE
|
||||
$test = $env:RUN_TESTS
|
||||
|
||||
$args = @()
|
||||
if (-not [string]::IsNullOrEmpty($type)) { $args += $type }
|
||||
if (-not [string]::IsNullOrEmpty($test)) { $args += $test }
|
||||
|
||||
Invoke-Expression "& .\scripts\build.ci.ps1 $args"
|
||||
|
||||
- name: Get Short Commit SHA
|
||||
shell: pwsh
|
||||
run: |
|
||||
$shortSHA = $env:github_sha.Substring(0, 7)
|
||||
echo "Short SHA: $shortSHA"
|
||||
echo "SHORT_SHA=$shortSHA" | Out-File -FilePath $env:GITHUB_ENV -Append
|
||||
|
||||
- name: Create Package
|
||||
shell: pwsh
|
||||
run: |
|
||||
New-Item -ItemType Directory -Path "./artifact"
|
||||
Copy-Item "./build/refactor.exe" -Destination "./artifact/refactor.exe"
|
||||
|
||||
Compress-Archive -Path "./artifact/*" -DestinationPath "./artifact/refactor-$($env:SHORT_SHA).zip"
|
||||
|
||||
- name: Upload Release
|
||||
uses: ncipollo/release-action@v1
|
||||
with:
|
||||
tag: Release
|
||||
artifacts: ./artifact/refactor-${{ env.SHORT_SHA }}.zip
|
||||
omitBody: true
|
||||
# bodyFile: "body.md"
|
||||
allowUpdates: true
|
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"
|
||||
}
|
||||
]
|
||||
}
|
90
Readme.md
90
Readme.md
@ -1,23 +1,91 @@
|
||||
# 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 if on debug build and desire to attach to process, or to get a more verbose log.
|
||||
|
||||
Syntax :
|
||||
## Syntax
|
||||
|
||||
* `not` Omit word or namespace.
|
||||
* `not` Omit an a signature. (Modifies include, word, namespace, etc)
|
||||
* `include` Preprocessor include `<file path>` 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.
|
||||
|
||||
TODO:
|
||||
* Possibly come up with a better name.
|
||||
* Cleanup memory usage (it hogs quite a bit or what it does..)
|
||||
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 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.
|
||||
|
||||
### Example scripts
|
||||
|
||||
See `scripts/template_reafactor.ps1` and the `test/*.refactor` related scripts on intended usage.
|
||||
|
||||
This app is not very nice to use directly from CLI. Instead run from a script after gathering the arguments.
|
||||
|
||||
There is a desire also to get this setup as a single-header library and also alternative with a minimalist GUI for simple refactors.
|
||||
|
||||
### Notes
|
||||
|
||||
* 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.
|
||||
* 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.
|
||||
|
||||
## Building
|
||||
|
||||
The project has all build configuration in the `scripts` directory.
|
||||
|
||||
* `build.ci.ps1` is intended for a continuous intergration setup (GH-worfklow for now).
|
||||
* `build.ps1` is just a wrap of build.ci that just calls cls.
|
||||
* `clean.ps1` will clean the workspace of all generated files.
|
||||
* `get_sources.ps1` is used to gather sources since meson devs refuse to add dynamic retrival of sources for a build.
|
||||
|
||||
The project uses [meson](https://github.com/mesonbuild/meson) as the build tool.
|
||||
Compiler : clang
|
||||
OS: Windows 11 (windows-latest for github actions)
|
||||
|
||||
There should theoretically not be anything stopping it from building on other plaforms.
|
||||
The library's main dependency is [zpl](https://github.com/zpl-c) which seems to support all major platforms.
|
||||
|
||||
## Testing
|
||||
|
||||
If the `test` parameter is provided to the build scripts, the project and thirdparty code will be refactored based on the specificiation files `*.refactor` residing in `test`.
|
||||
|
||||
With the refactors applied a meson configuraiton is setup (`meson.build` in test) and run to build. So long as it compiles, the feature set of the current version should work fine.
|
||||
|
||||
* There is an extra file `stb_image` that is parsed but unused during compilation.
|
||||
* Planned for use in the namespace addition todo.
|
||||
|
||||
## TODO:
|
||||
|
||||
* Provide binaries in the release page for github. (debug and release builds)
|
||||
* Ability to run and not emit any changes to files unless all files sucessfully are refactored.
|
||||
* Would fix issue where a refactor overwrites files but failed to complete
|
||||
* Can have a heavy memory cost, so most likely do not want on by default.
|
||||
* Make comments ignored by default, and just have ability to specify custom comments.
|
||||
* Would need a directive to add refactors to comments.
|
||||
* Directive to add cpp namespaces on specific lines of a file, or near specific signatures.
|
||||
* This can honestly be done also with placing words on specific lines..
|
||||
* Provide a GUI build.
|
||||
* Provide as a single-header library.
|
||||
* Could add a test case where this library is refactored into pure C (most likely c99 or c11).
|
||||
* Better tests:
|
||||
* Automatically pull the zpl repo, refactor and format the library, and package the single header before using it in testing.
|
||||
* Use gencpp editor/scanner functionality to give it more rich context refactors.
|
||||
* Port to other platforms.
|
||||
* Ability to change the naming convention of a signature (snake_case to PascalCase, etc)
|
||||
|
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' )
|
||||
|
204
Test/project.refactor
Normal file
204
Test/project.refactor
Normal file
@ -0,0 +1,204 @@
|
||||
__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
|
||||
|
||||
// Removes the namespace.
|
||||
namespace zpl_
|
||||
namespace zpl_re_, regex_
|
||||
namespace zpl_random_, rng_
|
||||
namespace zpl_pr, process_
|
||||
namespace zpl__, __
|
||||
namespace ZPL_ADT_, EADT
|
||||
namespace ZPL_ALLOCATION_, EAllocation
|
||||
namespace ZPL_CSV_ERROR, ECSV_Error
|
||||
namespace ZPL_FILE_MODE_, EFileMode_
|
||||
namespace ZPL_FILE_ERROR_, EFileError_
|
||||
namespace ZPL_SEEK_WHENCE_, ESeekWhence_
|
||||
namespace ZPL_FILE_STANDARD_, EFileStandard_
|
||||
namespace ZPL_FILE_STREAM_, EFileStream_
|
||||
namespace ZPL_JSON_ERROR_, EJSON_Error_
|
||||
namespace ZPL_RE_ERROR_, ERegexError_
|
||||
namespace ZPL_OPTS_, EOpts_
|
||||
namespace ZPL_OPTS_ERR, EOptsError_
|
||||
namespace ZPL_PR_OPTS_, EProcessOpts_
|
||||
|
||||
// Macro exposure
|
||||
//namespace ZPL_
|
||||
//not word ZPL_IMPLEMENTATION
|
||||
|
||||
// Type Renames
|
||||
word zpl_aabb2, AABB2
|
||||
word zpl_aabb3, AABB3
|
||||
word zpl_adt_assign_style, ADT_AssignStyle
|
||||
word zpl_adt_delim_style, ADT_DelimStyle
|
||||
word zpl_adt_error, ADT_Error
|
||||
word zpl_adt_naming_style, ADT_NamingStyle
|
||||
word zpl_adt_node, ADT_Node
|
||||
word zpl_adt_props, ADT_Props
|
||||
word zpl_adt_type, ADT_Type
|
||||
word zpl_affinity, Affinity
|
||||
word zpl_allocation_header_event, AllocationHeaderEvent
|
||||
word zpl_allocator, AllocatorInfo
|
||||
word zpl_allocator_proc, AllocatorProc
|
||||
word zpl_alloc_flags, AllocFlags
|
||||
word zpl_alloc_type, AllocType
|
||||
word zpl_arena, Arena
|
||||
word zpl_arena_snapshot, ArenaSnapshot
|
||||
word zpl_array, Array
|
||||
word zpl_array_header, ArrayHeader
|
||||
word zpl_buffer, Buffer
|
||||
word zpl_buffer_header, BufferHeader
|
||||
word zpl_compare_proc, CompareProc
|
||||
word zpl_csv_error, CSV_Error
|
||||
word zpl_csv_object, CSV_Object
|
||||
word zpl_dll_handle, DLLHandle
|
||||
word zpl_dll_proc, DLLProc
|
||||
word zpl_dir_type, DirType
|
||||
word zpl_dir_entry, DirEntry
|
||||
word zpl_dir_info, DirInfo
|
||||
word zpl_file_contents, FileContents
|
||||
word zpl_file_descriptor, FileDescriptor
|
||||
word zpl_file_error, FileError
|
||||
word zpl_file, FileInfo
|
||||
word zpl_file_mode, FileMode
|
||||
word zpl_file_mode_flag, FileModeFlag
|
||||
word zpl_file_operations, FileOperations
|
||||
word zpl_file_close_proc, FileCloseProc
|
||||
word zpl_file_read_proc, FileReadProc
|
||||
word zpl_file_seek_proc, FileSeekProc
|
||||
word zpl_file_write_proc, FileWriteProc
|
||||
word zpl_file_standard_type, FileStandardType
|
||||
word zpl_file_stream_flags, FileStreamFlags
|
||||
word zpl_float2, Float2
|
||||
word zpl_float3, Float3
|
||||
word zpl_float4, Float4
|
||||
word zpl_frustum, Frustum
|
||||
word zpl_half, Half
|
||||
word zpl_jobs_priority, JobsPriority
|
||||
word zpl_jobs_status, JobsStatus
|
||||
word zpl_jobs_system, JobsSystem
|
||||
word zpl_json_error, JSON_Error
|
||||
word zpl_json_object, JSON_Object
|
||||
word zpl_list, List
|
||||
word zpl_mat2, Mat2
|
||||
word zpl_mat3, Mat3
|
||||
word zpl_mat4, Mat4
|
||||
word zpl_mutex, Mutex
|
||||
word zpl_plane, Plane
|
||||
word zpl_pool, Pool
|
||||
word zpl_pr, Process
|
||||
word zpl_pr_si, ProcessStartupInfo
|
||||
word zpl_quat, Quat
|
||||
word zpl_rect2, Rect2
|
||||
word zpl_rect3, Rect3
|
||||
word zpl_re, Regex
|
||||
word zpl_re_capture, RegexCapture
|
||||
word zpl_regex_error, RegexError
|
||||
wrod zpl_random, RNG
|
||||
word zpl_rune, Rune
|
||||
word zpl_scratch_memory, ScratchMemory
|
||||
word zpl_seek_whence_type, SeekWhenceType
|
||||
word zpl_semaphore, Semaphore
|
||||
word zpl_string, String
|
||||
word zpl_string_header, StringHeader
|
||||
word zpl_sync, Sync
|
||||
word zpl_opts, Opts
|
||||
word zpl_opts_entry, OptsEntry
|
||||
word zpl_opts_err, OptsError
|
||||
word zpl_opts_err_type, OptsErrorType
|
||||
word zpl_opts_types, OptsTypes
|
||||
word zpl_tar_errors, TarErrors
|
||||
word zpl_tar_file_type, TarFileType
|
||||
word zpl_tar_record, TarRecord
|
||||
word zpl_tar_unpack_proc, TarUnpackProc
|
||||
word zpl_thread, Thread
|
||||
word zpl_thread_job, ThreadJob
|
||||
word zpl_thread_proc, ThreadProc
|
||||
word zpl_thread_queue, ThreadQueue
|
||||
word zpl_thread_worker, ThreadWorker
|
||||
word zpl_vec2, Vec2
|
||||
word zpl_vec3, Vec3
|
||||
word zpl_vec4, Vec4
|
||||
word zpl_virtual_memory, VirtualMemory
|
||||
|
||||
// Function Renames
|
||||
word zpl_lfence, fence_load
|
||||
word zpl_mfence, fence_memory
|
||||
word zpl_sfence, fence_store
|
||||
word zpl_memchr, mem_find
|
||||
word zpl_memcopy, mem_copy
|
||||
word zpl_memmove, mem_move
|
||||
word zpl_memset, mem_set
|
||||
word zpl_memswap, mem_swap
|
||||
word zpl_exit, process_exit
|
||||
word zpl_rdtsc, read_cpu_time_stamp_counter
|
||||
word zpl_strcmp, str_compare
|
||||
word zpl_strncmp, str_compare
|
||||
word zpl_strcat, str_concat
|
||||
word zpl_strcpy, str_copy
|
||||
word zpl_strncpy, str_copy
|
||||
word zpl_strlcpy, str_copy_nulpad
|
||||
word zpl_strdup, str_dup
|
||||
word zpl_strchr, str_find
|
||||
word zpl_strrchr, str_find_last
|
||||
word zpl_strstr, str_find_substr
|
||||
word zpl_snprintf, str_fmt
|
||||
word zpl_snprintf_va, str_fmt_va
|
||||
word zpl_asprintf, str_fmt_alloc
|
||||
word zpl_asprintf_va, str_fmt_alloc_va
|
||||
word zpl_bprintf, str_fmt_buf
|
||||
word zpl_bprintf_va, str_fmt_buf_va
|
||||
word zpl_printf, str_fmt_out
|
||||
word zpl_printf_va, str_fmt_out_va
|
||||
word zpl_printf_err, str_fmt_out_err
|
||||
word zpl_printf_err_va, str_fmt_out_err_va
|
||||
word zpl_fprintf, str_fmt_file
|
||||
word zpl_fprintf_va, str_fmt_file_va
|
||||
word zpl_strlen, str_len
|
||||
word zpl_strnlen, str_len
|
||||
word zpl_strrev, str_reverse
|
||||
word zpl_strtok, str_tok
|
||||
word zpl_strtok_r, str_tok_reentrant
|
||||
word zpl_sleep, thread_sleep
|
||||
word zpl_sleep_ms, thread_sleep_ms
|
||||
word zpl_yield_thread, thread_yield
|
||||
word zpl_utf8_strlen, utf8_len
|
||||
word zpl_utf8_strnlen, utf8_len
|
||||
|
||||
// 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.
|
||||
word cast, zpl_cast
|
||||
|
||||
not word zpl_thread_local
|
@ -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();
|
||||
}
|
6
Test/stb_image.refactor
Normal file
6
Test/stb_image.refactor
Normal file
@ -0,0 +1,6 @@
|
||||
__VERSION 1
|
||||
|
||||
not comments
|
||||
|
||||
namespace stbi_
|
||||
not namepsace stbi__
|
@ -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
|
214
Test/zpl.refactor
Normal file
214
Test/zpl.refactor
Normal file
@ -0,0 +1,214 @@
|
||||
__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
|
||||
|
||||
// This is a cpp refactor specification for zpl.h
|
||||
// Its intended that the content will be within a cpp namesapce
|
||||
|
||||
// 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 header/regex.h
|
||||
not include source/core/file.c
|
||||
not include source/opts.c
|
||||
|
||||
// Removes the namespace.
|
||||
namespace zpl_
|
||||
namespace zpl_re_, regex_
|
||||
namespace zpl_random_, rng_
|
||||
namespace zpl_pr, process_
|
||||
namespace zpl__, __
|
||||
namespace ZPL_ADT_, EADT
|
||||
namespace ZPL_ALLOCATION_, EAllocation
|
||||
namespace ZPL_CSV_ERROR, ECSV_Error
|
||||
namespace ZPL_FILE_MODE_, EFileMode_
|
||||
namespace ZPL_FILE_ERROR_, EFileError_
|
||||
namespace ZPL_SEEK_WHENCE_, ESeekWhence_
|
||||
namespace ZPL_FILE_STANDARD_, EFileStandard_
|
||||
namespace ZPL_FILE_STREAM_, EFileStream_
|
||||
namespace ZPL_JSON_ERROR_, EJSON_Error_
|
||||
namespace ZPL_RE_ERROR_, ERegexError_
|
||||
namespace ZPL_OPTS_, EOpts_
|
||||
namespace ZPL_OPTS_ERR, EOptsError_
|
||||
namespace ZPL_PR_OPTS_, EProcessOpts_
|
||||
|
||||
// Macro exposure
|
||||
//namespace ZPL_
|
||||
//not word ZPL_IMPLEMENTATION
|
||||
|
||||
// Type Renames
|
||||
word zpl_aabb2, AABB2
|
||||
word zpl_aabb3, AABB3
|
||||
word zpl_adt_assign_style, ADT_AssignStyle
|
||||
word zpl_adt_delim_style, ADT_DelimStyle
|
||||
word zpl_adt_error, ADT_Error
|
||||
word zpl_adt_naming_style, ADT_NamingStyle
|
||||
word zpl_adt_node, ADT_Node
|
||||
word zpl_adt_props, ADT_Props
|
||||
word zpl_adt_type, ADT_Type
|
||||
word zpl_affinity, Affinity
|
||||
word zpl_allocation_header_event, AllocationHeaderEvent
|
||||
word zpl_allocator, AllocatorInfo
|
||||
word zpl_allocator_proc, AllocatorProc
|
||||
word zpl_alloc_flags, AllocFlags
|
||||
word zpl_alloc_type, AllocType
|
||||
word zpl_arena, Arena
|
||||
word zpl_arena_snapshot, ArenaSnapshot
|
||||
word zpl_array, Array
|
||||
word zpl_array_header, ArrayHeader
|
||||
word zpl_buffer, Buffer
|
||||
word zpl_buffer_header, BufferHeader
|
||||
word zpl_compare_proc, CompareProc
|
||||
word zpl_csv_error, CSV_Error
|
||||
word zpl_csv_object, CSV_Object
|
||||
word zpl_dll_handle, DLLHandle
|
||||
word zpl_dll_proc, DLLProc
|
||||
word zpl_dir_type, DirType
|
||||
word zpl_dir_entry, DirEntry
|
||||
word zpl_dir_info, DirInfo
|
||||
word zpl_file_contents, FileContents
|
||||
word zpl_file_descriptor, FileDescriptor
|
||||
word zpl_file_error, FileError
|
||||
word zpl_file, FileInfo
|
||||
word zpl_file_mode, FileMode
|
||||
word zpl_file_mode_flag, FileModeFlag
|
||||
word zpl_file_operations, FileOperations
|
||||
word zpl_file_close_proc, FileCloseProc
|
||||
word zpl_file_read_proc, FileReadProc
|
||||
word zpl_file_seek_proc, FileSeekProc
|
||||
word zpl_file_write_proc, FileWriteProc
|
||||
word zpl_file_standard_type, FileStandardType
|
||||
word zpl_file_stream_flags, FileStreamFlags
|
||||
word zpl_float2, Float2
|
||||
word zpl_float3, Float3
|
||||
word zpl_float4, Float4
|
||||
word zpl_frustum, Frustum
|
||||
word zpl_half, Half
|
||||
word zpl_jobs_priority, JobsPriority
|
||||
word zpl_jobs_status, JobsStatus
|
||||
word zpl_jobs_system, JobsSystem
|
||||
word zpl_json_error, JSON_Error
|
||||
word zpl_json_object, JSON_Object
|
||||
word zpl_list, List
|
||||
word zpl_mat2, Mat2
|
||||
word zpl_mat3, Mat3
|
||||
word zpl_mat4, Mat4
|
||||
word zpl_mutex, Mutex
|
||||
word zpl_plane, Plane
|
||||
word zpl_pool, Pool
|
||||
word zpl_pr, Process
|
||||
word zpl_pr_si, ProcessStartupInfo
|
||||
word zpl_quat, Quat
|
||||
word zpl_rect2, Rect2
|
||||
word zpl_rect3, Rect3
|
||||
word zpl_re, Regex
|
||||
word zpl_re_capture, RegexCapture
|
||||
word zpl_regex_error, RegexError
|
||||
wrod zpl_random, RNG
|
||||
word zpl_rune, Rune
|
||||
word zpl_scratch_memory, ScratchMemory
|
||||
word zpl_seek_whence_type, SeekWhenceType
|
||||
word zpl_semaphore, Semaphore
|
||||
word zpl_string, String
|
||||
word zpl_string_header, StringHeader
|
||||
word zpl_sync, Sync
|
||||
word zpl_opts, Opts
|
||||
word zpl_opts_entry, OptsEntry
|
||||
word zpl_opts_err, OptsError
|
||||
word zpl_opts_err_type, OptsErrorType
|
||||
word zpl_opts_types, OptsTypes
|
||||
word zpl_tar_errors, TarErrors
|
||||
word zpl_tar_file_type, TarFileType
|
||||
word zpl_tar_record, TarRecord
|
||||
word zpl_tar_unpack_proc, TarUnpackProc
|
||||
word zpl_thread, Thread
|
||||
word zpl_thread_job, ThreadJob
|
||||
word zpl_thread_proc, ThreadProc
|
||||
word zpl_thread_queue, ThreadQueue
|
||||
word zpl_thread_worker, ThreadWorker
|
||||
word zpl_vec2, Vec2
|
||||
word zpl_vec3, Vec3
|
||||
word zpl_vec4, Vec4
|
||||
word zpl_virtual_memory, VirtualMemory
|
||||
|
||||
// Function Renames
|
||||
word zpl_lfence, fence_load
|
||||
word zpl_mfence, fence_memory
|
||||
word zpl_sfence, fence_store
|
||||
word zpl_memchr, mem_find
|
||||
word zpl_memcopy, mem_copy
|
||||
word zpl_memmove, mem_move
|
||||
word zpl_memset, mem_set
|
||||
word zpl_memswap, mem_swap
|
||||
word zpl_exit, process_exit
|
||||
word zpl_rdtsc, read_cpu_time_stamp_counter
|
||||
word zpl_strcmp, str_compare
|
||||
word zpl_strncmp, str_compare
|
||||
word zpl_strcat, str_concat
|
||||
word zpl_strcpy, str_copy
|
||||
word zpl_strncpy, str_copy
|
||||
word zpl_strlcpy, str_copy_nulpad
|
||||
word zpl_strdup, str_dup
|
||||
word zpl_strchr, str_find
|
||||
word zpl_strrchr, str_find_last
|
||||
word zpl_strstr, str_find_substr
|
||||
word zpl_snprintf, str_fmt
|
||||
word zpl_snprintf_va, str_fmt_va
|
||||
word zpl_asprintf, str_fmt_alloc
|
||||
word zpl_asprintf_va, str_fmt_alloc_va
|
||||
word zpl_bprintf, str_fmt_buf
|
||||
word zpl_bprintf_va, str_fmt_buf_va
|
||||
word zpl_printf, str_fmt_out
|
||||
word zpl_printf_va, str_fmt_out_va
|
||||
word zpl_printf_err, str_fmt_out_err
|
||||
word zpl_printf_err_va, str_fmt_out_err_va
|
||||
word zpl_fprintf, str_fmt_file
|
||||
word zpl_fprintf_va, str_fmt_file_va
|
||||
word zpl_strlen, str_len
|
||||
word zpl_strnlen, str_len
|
||||
word zpl_strrev, str_reverse
|
||||
word zpl_strtok, str_tok
|
||||
word zpl_strtok_r, str_tok_reentrant
|
||||
word zpl_sleep, thread_sleep
|
||||
word zpl_sleep_ms, thread_sleep_ms
|
||||
word zpl_yield_thread, thread_yield
|
||||
word zpl_utf8_strlen, utf8_len
|
||||
word zpl_utf8_strnlen, utf8_len
|
||||
|
||||
// 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.
|
||||
word cast, zpl_cast
|
||||
|
||||
not word zpl_thread_local
|
||||
|
||||
// Name Conflicts
|
||||
word file_size, fsize
|
||||
word alloc, allocator
|
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();
|
||||
}
|
170
project/Bloat.cpp
Normal file
170
project/Bloat.cpp
Normal file
@ -0,0 +1,170 @@
|
||||
#define BLOAT_IMPL
|
||||
#include "Bloat.hpp"
|
||||
|
||||
namespace Global
|
||||
{
|
||||
bool ShouldShowDebug = false;
|
||||
}
|
||||
|
||||
namespace Memory
|
||||
{
|
||||
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;
|
||||
}
|
@ -1,21 +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
|
||||
|
||||
#if __clang__
|
||||
# pragma clang diagnostic ignored "-Wunused-const-variable"
|
||||
# pragma clang diagnostic ignored "-Wswitch"
|
||||
# pragma clang diagnostic ignored "-Wunused-variable"
|
||||
#ifdef BLOAT_IMPL
|
||||
# define ZPL_IMPLEMENTATION
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#pragma region ZPL INCLUDE
|
||||
#if __clang__
|
||||
# pragma clang diagnostic push
|
||||
@ -35,13 +27,11 @@
|
||||
// # define ZPL_MODULE_DLL
|
||||
# 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
|
||||
@ -50,6 +40,15 @@
|
||||
|
||||
|
||||
|
||||
#if __clang__
|
||||
# pragma clang diagnostic ignored "-Wunused-const-variable"
|
||||
# pragma clang diagnostic ignored "-Wswitch"
|
||||
# pragma clang diagnostic ignored "-Wunused-variable"
|
||||
# pragma clang diagnostic ignored "-Wunknown-pragmas"
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#define bit( Value_ ) ( 1 << Value_ )
|
||||
#define bitfield_is_equal( Field_, Mask_ ) ( ( Mask_ & Field_ ) == Mask_ )
|
||||
#define ct constexpr
|
||||
@ -64,15 +63,15 @@
|
||||
do \
|
||||
{ \
|
||||
static \
|
||||
bool Done = true; \
|
||||
bool Done = false; \
|
||||
if ( Done ) \
|
||||
return; \
|
||||
Done = false; \
|
||||
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 +82,69 @@ 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 Global
|
||||
{
|
||||
extern bool ShouldShowDebug;
|
||||
}
|
||||
|
||||
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 setup();
|
||||
void resize( uw new_size );
|
||||
void cleanup();
|
||||
}
|
||||
|
||||
void cleanup()
|
||||
// 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, ...)
|
||||
{
|
||||
zpl_arena_free( & Global_Arena);
|
||||
}
|
||||
if ( Global::ShouldShowDebug == false )
|
||||
return 0;
|
||||
|
||||
sw res;
|
||||
va_list va;
|
||||
|
||||
va_start(va, fmt);
|
||||
res = zpl_printf_va(fmt, va);
|
||||
va_end(va);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void fatal()
|
||||
inline
|
||||
void fatal(char const *fmt, ...)
|
||||
{
|
||||
Memory::cleanup();
|
||||
zpl_assert_crash("FATAL");
|
||||
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
|
||||
}
|
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 > 0 );
|
||||
|
||||
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 128 KB.
|
||||
* `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 current size 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.
|
328
project/Spec.cpp
Normal file
328
project/Spec.cpp
Normal file
@ -0,0 +1,328 @@
|
||||
#include "Spec.hpp"
|
||||
|
||||
#include "IO.hpp"
|
||||
|
||||
|
||||
|
||||
namespace Spec
|
||||
{
|
||||
ct uw Array_Reserve_Num = zpl_kilobytes(4);
|
||||
ct uw Token_Max_Length = 128;
|
||||
|
||||
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 {};
|
||||
|
||||
// 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 );
|
||||
}
|
||||
}
|
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();
|
||||
}
|
687
project/refactor.cpp
Normal file
687
project/refactor.cpp
Normal file
@ -0,0 +1,687 @@
|
||||
#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);
|
||||
|
||||
zpl_opts_add( & opts, "debug", "debug", "Allows for wait to attach", ZPL_OPTS_FLAG);
|
||||
|
||||
if (opts_custom_compile( & opts, num, arguments))
|
||||
{
|
||||
sw num = 0;
|
||||
|
||||
if ( zpl_opts_has_arg( & opts, "debug" ) )
|
||||
{
|
||||
#if Build_Debug
|
||||
zpl_printf("Will wait (pause available for attachment)");
|
||||
char pause = getchar();
|
||||
#endif
|
||||
|
||||
Global::ShouldShowDebug = true;
|
||||
}
|
||||
|
||||
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 );
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Refactor will problably have the execution and arg parsing (main and opts)
|
||||
moved to a separate file.
|
||||
*/
|
||||
|
||||
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)
|
||||
|
||||
struct Snapshot
|
||||
{
|
||||
char const* Src;
|
||||
sw Left;
|
||||
uw Col;
|
||||
uw Line;
|
||||
};
|
||||
|
||||
#define move_forward( Amount_ ) \
|
||||
do { \
|
||||
if ( left - Amount_ <= 0 ) \
|
||||
goto End_Search; \
|
||||
\
|
||||
const sw end = Amount_ - 1; \
|
||||
\
|
||||
line += src[end] == '\n'; \
|
||||
left -= Amount_; \
|
||||
col = (col + Amount_) * src[end] != '\n'; \
|
||||
src += Amount_; \
|
||||
} \
|
||||
while (0) \
|
||||
|
||||
#define restore( Snapshot_ ) \
|
||||
src = Snapshot_.Src; \
|
||||
left = Snapshot_.Left; \
|
||||
col = Snapshot_.Col; \
|
||||
line = Snapshot_.Line \
|
||||
|
||||
do
|
||||
{
|
||||
// Check for comments if ignoring.
|
||||
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);
|
||||
Snapshot backup = { src, left, col, line };
|
||||
|
||||
if ( '#' != src[0] )
|
||||
break;
|
||||
|
||||
move_forward( 1 );
|
||||
|
||||
// Ignore whitespace
|
||||
while ( zpl_char_is_space( src[0] ) )
|
||||
{
|
||||
move_forward( 1 );
|
||||
}
|
||||
|
||||
if ( zpl_strncmp( include_sig, src, sizeof(include_sig) - 1 ) != 0 )
|
||||
{
|
||||
restore( backup );
|
||||
break;
|
||||
}
|
||||
|
||||
const u32 sig_size = sizeof(include_sig) - 1;
|
||||
|
||||
move_forward( sig_size );
|
||||
|
||||
// Ignore whitespace
|
||||
while ( zpl_char_is_space( src[0] ) || src[0] == '\"' || src[0] == '<' )
|
||||
{
|
||||
move_forward(1);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
restore( backup );
|
||||
}
|
||||
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);
|
||||
Snapshot backup = { src, left, col, line };
|
||||
|
||||
if ( '#' != src[0] )
|
||||
break;
|
||||
|
||||
move_forward( 1 );
|
||||
|
||||
// Ignore whitespace
|
||||
while ( zpl_char_is_space( src[0] ) )
|
||||
{
|
||||
move_forward( 1 );
|
||||
}
|
||||
|
||||
if ( zpl_strncmp( include_sig, src, sizeof(include_sig) - 1 ) != 0 )
|
||||
{
|
||||
restore( backup );
|
||||
break;
|
||||
}
|
||||
|
||||
const u32 sig_size = sizeof(include_sig) - 1;
|
||||
|
||||
move_forward( sig_size );
|
||||
|
||||
// Ignore whitespace
|
||||
while ( zpl_char_is_space( src[0] ) || src[0] == '\"' || src[0] == '<' )
|
||||
{
|
||||
move_forward( 1 );
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
restore( backup );
|
||||
}
|
||||
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:
|
||||
move_forward( 1 );
|
||||
}
|
||||
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();
|
||||
}
|
92
scripts/build.ci.ps1
Normal file
92
scripts/build.ci.ps1
Normal file
@ -0,0 +1,92 @@
|
||||
[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
|
||||
Push-Location $path_scripts
|
||||
Invoke-Expression "& meson $args_meson"
|
||||
Pop-Location
|
||||
}
|
||||
|
||||
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
|
||||
Push-Location $path_scripts
|
||||
Invoke-Expression "& meson $args_meson"
|
||||
Pop-Location
|
||||
}
|
||||
|
||||
$args_ninja = @()
|
||||
$args_ninja += "-C"
|
||||
$args_ninja += $path_build
|
||||
|
||||
Push-Location $path_root
|
||||
ninja $args_ninja
|
||||
Pop-Location
|
||||
#endregion Regular Build
|
||||
|
||||
|
||||
if ( $test -eq $true )
|
||||
{
|
||||
#region Test Build
|
||||
write-host "`n`nBuilding Test`n"
|
||||
|
||||
# Refactor thirdparty libraries
|
||||
Invoke-Expression "& $(Join-Path $PSScriptRoot 'refactor_and_format.ps1') $args"
|
||||
|
||||
|
||||
$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
|
||||
|
||||
Push-Location $path_test
|
||||
& meson $args_meson
|
||||
Pop-Location
|
||||
}
|
||||
|
||||
$args_ninja = @()
|
||||
$args_ninja += "-C"
|
||||
$args_ninja += $path_test_build
|
||||
|
||||
Push-Location $path_root
|
||||
ninja $args_ninja
|
||||
Pop-Location
|
||||
#endregion Test Build
|
||||
}
|
2
scripts/build.ps1
Normal file
2
scripts/build.ps1
Normal file
@ -0,0 +1,2 @@
|
||||
cls
|
||||
Invoke-Expression "& $(Join-Path $PSScriptRoot 'build.ci.ps1') $args"
|
24
scripts/clean.ps1
Normal file
24
scripts/clean.ps1
Normal file
@ -0,0 +1,24 @@
|
||||
$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
|
||||
|
||||
if ( $files )
|
||||
{
|
||||
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 )
|
115
scripts/refactor_and_format.ps1
Normal file
115
scripts/refactor_and_format.ps1
Normal file
@ -0,0 +1,115 @@
|
||||
[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
|
||||
|
||||
$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..."
|
||||
|
||||
$file_spec = Join-Path $path_test zpl.refactor
|
||||
|
||||
$refactorParams = @(
|
||||
"-src=$(Join-Path $path_thirdparty "zpl.h")",
|
||||
"-dst=$(Join-Path $path_test "zpl.refactored.h")",
|
||||
"-spec=$($file_spec)"
|
||||
)
|
||||
|
||||
if ( $args.Contains( "debug" ) )
|
||||
{
|
||||
$refactorParams += "-debug"
|
||||
}
|
||||
|
||||
write-host "`zpl refactor: " $refactorParams
|
||||
& $refactor $refactorParams
|
||||
|
||||
$file_spec = Join-Path $path_test "stb_image.refactor"
|
||||
|
||||
$refactorParams = @(
|
||||
"-src=$(Join-Path $path_thirdparty "stb_image.h")",
|
||||
"-dst=$(Join-Path $path_test "stb_image.refactored.h")",
|
||||
"-spec=$($file_spec)"
|
||||
)
|
||||
|
||||
if ( $args.Contains( "debug" ) )
|
||||
{
|
||||
$refactorParams += "-debug"
|
||||
}
|
||||
|
||||
write-host "`n`nstb_image refactor: " $refactorParams
|
||||
& $refactor $refactorParams
|
||||
|
||||
Write-Host "`nRefactoring complete`n"
|
||||
|
||||
|
||||
write-host "Beginning project refactor..."
|
||||
|
||||
# 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
|
||||
|
||||
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 = @(
|
||||
"-num=$($targetFiles.Count)"
|
||||
"-src=$($targetFiles)",
|
||||
"-dst=$($refactoredFiles)",
|
||||
"-spec=$($file_spec)"
|
||||
)
|
||||
|
||||
if ( $args.Contains( "debug" ) )
|
||||
{
|
||||
$refactorParams += "-debug"
|
||||
}
|
||||
|
||||
& $refactor $refactorParams
|
||||
|
||||
write-host "`nRefactoring complete`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"
|
||||
}
|
||||
|
38
scripts/template_reafactor.ps1
Normal file
38
scripts/template_reafactor.ps1
Normal file
@ -0,0 +1,38 @@
|
||||
[string[]] $include = '*.h', '*.hh', '*.hpp', '*.c', '*.cc', '*.cpp'
|
||||
[string[]] $exclude = '*.g.*', '*.refactor'
|
||||
|
||||
# Change this to your root directory if needed.
|
||||
$path_root = $PSScriptRoot
|
||||
|
||||
# Change this to your desired destination
|
||||
$path_dest = $path_root
|
||||
|
||||
# Gather the files to be formatted.
|
||||
$targetFiles = @(Get-ChildItem -Recurse -Path $path_root -Include $include -Exclude $exclude | Select-Object -ExpandProperty FullName)
|
||||
$refactoredFiles = @()
|
||||
|
||||
foreach ( $file in $targetFiles )
|
||||
{
|
||||
$destination = Join-Path $path_dest (Split-Path $file -leaf)
|
||||
$destination = $destination.Replace( '.h', '.refactored.h' )
|
||||
$destination = $destination.Replace( '.c', '.refactored.c' )
|
||||
|
||||
$refactoredFiles += $destination
|
||||
}
|
||||
|
||||
|
||||
write-host "Beginning refactor...`n"
|
||||
|
||||
$refactors = @(@())
|
||||
|
||||
$refactorParams = @(
|
||||
# "-debug",
|
||||
"-num=$($targetFiles.Count)"
|
||||
"-src=$($targetFiles)",
|
||||
"-dst=$($refactoredFiles)",
|
||||
"-spec=$($file_spec)"
|
||||
)
|
||||
|
||||
& $refactor $refactorParams
|
||||
|
||||
Write-Host "`nRefactoring complete`n`n"
|
7987
thirdparty/stb_image.h
vendored
Normal file
7987
thirdparty/stb_image.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
500
thirdparty/zpl.h
vendored
500
thirdparty/zpl.h
vendored
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user