From f707fe90e94513df4e46d43371273672cfbe9cda Mon Sep 17 00:00:00 2001 From: Basile Burg Date: Tue, 15 Sep 2015 01:36:55 +0200 Subject: [PATCH] initial work on #39, unified tool, using a shared library --- cedast/build/cedast.coedit | 18 +++++ cedast/src/ast.d | 21 ++++++ cedast/src/cedast.d | 146 +++++++++++++++++++++++++++++++++++++ cedast/src/common.d | 12 +++ lazproj/cedast_loader.lpi | 65 +++++++++++++++++ lazproj/cedast_loader.pas | 48 ++++++++++++ 6 files changed, 310 insertions(+) create mode 100644 cedast/build/cedast.coedit create mode 100644 cedast/src/ast.d create mode 100644 cedast/src/cedast.d create mode 100644 cedast/src/common.d create mode 100644 lazproj/cedast_loader.lpi create mode 100644 lazproj/cedast_loader.pas diff --git a/cedast/build/cedast.coedit b/cedast/build/cedast.coedit new file mode 100644 index 00000000..73ff8323 --- /dev/null +++ b/cedast/build/cedast.coedit @@ -0,0 +1,18 @@ +object CurrentProject: TCENativeProject + OptionsCollection = < + item + name = 'default' + messagesOptions.additionalWarnings = True + outputOptions.binaryKind = sharedlib + pathsOptions.outputFilename = '..\..\lazproj\cedast.dll' + end> + Sources.Strings = ( + '..\src\cedast.d' + '..\src\common.d' + '..\src\ast.d' + ) + ConfigurationIndex = 0 + LibraryAliases.Strings = ( + 'libdparse' + ) +end diff --git a/cedast/src/ast.d b/cedast/src/ast.d new file mode 100644 index 00000000..ca6f6885 --- /dev/null +++ b/cedast/src/ast.d @@ -0,0 +1,21 @@ +module ast; + +import std.d.lexer, std.d.parser, common; + +struct Ast +{ + this(string filename) + { + mixin(logcall); + } + + this(ubyte[] buffer) + { + mixin(logcall); + } + + void rescan() + { + mixin(logcall); + } +} diff --git a/cedast/src/cedast.d b/cedast/src/cedast.d new file mode 100644 index 00000000..f6ebaafb --- /dev/null +++ b/cedast/src/cedast.d @@ -0,0 +1,146 @@ +module cedast; + +import core.runtime, common, ast; + +__gshared Ast*[] modules; + +extern(C) export +AstToken scanFile(char* filename) +{ + AstToken result; + try + { + import std.string: fromStringz; + import std.algorithm: countUntil; + Ast* ast = new Ast(filename.fromStringz.idup); + result = countUntil(modules, null); + if (result == -1) + { + modules ~= ast; + result = modules.length; + } + else + { + modules[result] = ast; + ++result; + } + } + catch(Exception e) + { + if (result != 0) unleash(result); + result = invalidAstToken; + } + return result; +} + +extern(C) export +AstToken scanBuffer(ubyte* buffer, size_t len) +{ + AstToken result; + try + { + import std.algorithm: countUntil; + Ast* ast = new Ast(buffer[0 .. len]); + result = countUntil(modules, null); + if (result == -1) + { + modules ~= ast; + result = modules.length; + } + else + { + modules[result] = ast; + ++result; + } + } + catch(Exception e) + { + if (result != 0) unleash(result); + result = invalidAstToken; + } + return result; +} + +extern(C) export +void rescan(AstToken tok) +{ + if (tok < 1 || tok > modules.length) + return; + modules[tok - 1].rescan; +} + +extern(C) export +void unleash(AstToken tok) +{ + mixin(logcall); + if (tok < 1 || tok > modules.length) + return; + if (modules[tok - 1] == null) + return; + delete modules[tok - 1]; + modules[tok - 1] = null; + if (tok == modules.length) + modules.length -= 1; +} + +extern(C) export +char* moduleName(AstToken tok) +{ + char* result = null; + return result; +} + +extern(C) export +ubyte* symbolList(AstToken tok, ref size_t len, SerializationFormat fmt) +{ + ubyte* result = null; + return result; +} + +extern(C) export +ubyte* todoList(AstToken tok, ref size_t len, SerializationFormat fmt) +{ + ubyte* result = null; + return result; +} + +version(Windows) +{ + import core.sys.windows.windows; + import core.sys.windows.dll; + + __gshared HINSTANCE g_hInst; + + extern (Windows) + BOOL DllMain(HINSTANCE hInstance, ULONG ulReason, LPVOID pvReserved) + { + switch (ulReason) + { + case DLL_PROCESS_ATTACH: + Runtime.initialize; + g_hInst = hInstance; + dll_process_attach( hInstance, true ); + break; + + case DLL_PROCESS_DETACH: + Runtime.terminate; + dll_process_detach( hInstance, true ); + break; + + case DLL_THREAD_ATTACH: + dll_thread_attach( true, true ); + break; + + case DLL_THREAD_DETACH: + dll_thread_detach( true, true ); + break; + + default: + assert(0); + } + + return true; + } +} + + diff --git a/cedast/src/common.d b/cedast/src/common.d new file mode 100644 index 00000000..c4c2cfb8 --- /dev/null +++ b/cedast/src/common.d @@ -0,0 +1,12 @@ +module common; + +alias AstToken = ptrdiff_t; + +__gshared immutable AstToken invalidAstToken = 0; + +enum SerializationFormat {json, pascal} + +enum logcall = q{ + import std.file; + append("cedast_log.txt", cast(ubyte[])(__PRETTY_FUNCTION__ ~ "\r\n")); +}; diff --git a/lazproj/cedast_loader.lpi b/lazproj/cedast_loader.lpi new file mode 100644 index 00000000..7ea44914 --- /dev/null +++ b/lazproj/cedast_loader.lpi @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + <UseAppBundle Value="False"/> + <ResourceType Value="res"/> + </General> + <i18n> + <EnableI18N LFM="False"/> + </i18n> + <VersionInfo> + <StringTable ProductVersion=""/> + </VersionInfo> + <BuildModes Count="1"> + <Item1 Name="Default" Default="True"/> + </BuildModes> + <PublishOptions> + <Version Value="2"/> + </PublishOptions> + <RunParams> + <local> + <FormatVersion Value="1"/> + </local> + </RunParams> + <Units Count="1"> + <Unit0> + <Filename Value="cedast_loader.pas"/> + <IsPartOfProject Value="True"/> + </Unit0> + </Units> + </ProjectOptions> + <CompilerOptions> + <Version Value="11"/> + <PathDelim Value="\"/> + <Target> + <Filename Value="cedast_loader"/> + </Target> + <SearchPaths> + <IncludeFiles Value="$(ProjOutDir)"/> + <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> + </SearchPaths> + </CompilerOptions> + <Debugging> + <Exceptions Count="3"> + <Item1> + <Name Value="EAbort"/> + </Item1> + <Item2> + <Name Value="ECodetoolError"/> + </Item2> + <Item3> + <Name Value="EFOpenError"/> + </Item3> + </Exceptions> + </Debugging> +</CONFIG> diff --git a/lazproj/cedast_loader.pas b/lazproj/cedast_loader.pas new file mode 100644 index 00000000..9dc308d0 --- /dev/null +++ b/lazproj/cedast_loader.pas @@ -0,0 +1,48 @@ +program cedast_loader; + +uses dynlibs, classes, sysutils; + +type + + TAstToken = NativeInt; + + TScanFile = function(filename: PChar): TAstToken; cdecl; + TScanBuffer = function (buffer: PByte; len: NativeUint): TAstToken; cdecl; + TRescan = procedure (tok: TAstToken); cdecl; + TUnleash = procedure (tok: TAstToken); cdecl; + +var + dast: TLibHandle; + scanfile: TScanFile; + scanbuffer: TScanBuffer; + rescan: TRescan; + unleash: TUnleash; + tok: TAstToken; + + +begin + + dast := LoadLibrary('cedast.dll'); + if dast = NilHandle then + writeln('dast invalid handle') + else begin + scanfile := TScanFile(GetProcAddress(dast, 'scanFile')); + if scanFile = nil then writeln('invalid scanfile proc ptr') + else tok := scanfile(PChar('blah')); + + scanbuffer := TScanBuffer(GetProcAddress(dast, 'scanBuffer')); + if scanbuffer = nil then writeln('invalid scanBuffer proc ptr') + else scanbuffer(nil, 0); + + rescan := TRescan(GetProcAddress(dast, 'rescan')); + if rescan = nil then writeln('invalid rescan proc ptr') + else rescan(tok); + + unleash := TUnleash(GetProcAddress(dast, 'unleash')); + if unleash = nil then writeln('invalid unleash proc ptr') + else unleash(tok); + end; + + readln; +end. +