mirror of https://gitlab.com/basile.b/dexed.git
add read only support for dub SDL projects, close #96
This commit is contained in:
parent
dfd7bbf633
commit
1cf1c8b287
|
@ -13,14 +13,19 @@ enum ErrorType: ubyte
|
||||||
error
|
error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Stores a dparse AST error
|
||||||
@NoInit @NoGc struct AstError
|
@NoInit @NoGc struct AstError
|
||||||
{
|
{
|
||||||
|
///
|
||||||
ErrorType type;
|
ErrorType type;
|
||||||
|
///
|
||||||
@NoGc string message;
|
@NoGc string message;
|
||||||
|
///
|
||||||
size_t line, column;
|
size_t line, column;
|
||||||
|
|
||||||
@disable this();
|
@disable this();
|
||||||
|
|
||||||
|
///
|
||||||
this(ErrorType type, string message, size_t line, size_t column) @nogc @safe
|
this(ErrorType type, string message, size_t line, size_t column) @nogc @safe
|
||||||
{
|
{
|
||||||
this.type = type;
|
this.type = type;
|
||||||
|
@ -43,6 +48,7 @@ alias AstErrors = AstError*[];
|
||||||
destruct(err);
|
destruct(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Write function call when compiled with version "devel"
|
||||||
enum logCall =
|
enum logCall =
|
||||||
q{
|
q{
|
||||||
import std.experimental.logger: log;
|
import std.experimental.logger: log;
|
||||||
|
@ -162,13 +168,12 @@ private static immutable predefinedVersions = [
|
||||||
"X86_64"
|
"X86_64"
|
||||||
];
|
];
|
||||||
|
|
||||||
private void fillBadVersions()
|
private void fillBadVrsions()
|
||||||
{
|
{
|
||||||
// note: compiler switch -m32/64 can lead to wrong results
|
// note: compiler switch -m32/64 can lead to wrong results
|
||||||
string addVersionidentifier(string ver)()
|
|
||||||
{
|
alias addVerId = (ver) => `version(` ~ ver ~ `){}
|
||||||
return `version(` ~ ver ~ `){} else _badVersions["` ~ ver ~ "\"] = true;\n";
|
else _badVersions["` ~ ver ~ "\"] = true;\n";
|
||||||
}
|
|
||||||
|
|
||||||
string addVerionIdentifiers()
|
string addVerionIdentifiers()
|
||||||
{
|
{
|
||||||
|
@ -177,7 +182,7 @@ private void fillBadVersions()
|
||||||
string result;
|
string result;
|
||||||
foreach(i; aliasSeqOf!(iota(0, predefinedVersions.length)))
|
foreach(i; aliasSeqOf!(iota(0, predefinedVersions.length)))
|
||||||
{
|
{
|
||||||
result ~= addVersionidentifier!(predefinedVersions[i]);
|
result ~= addVerId(predefinedVersions[i]);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -358,8 +363,7 @@ T parseAndVisit(T : ASTVisitor)(const(char)[] source)
|
||||||
* By default libdparse outputs errors and warnings to the standard streams.
|
* By default libdparse outputs errors and warnings to the standard streams.
|
||||||
* This function prevents that.
|
* This function prevents that.
|
||||||
*/
|
*/
|
||||||
void ignoreErrors(string fname, size_t line, size_t col, string message,
|
void ignoreErrors(string, size_t, size_t, string, bool)
|
||||||
bool err)
|
|
||||||
{
|
{
|
||||||
// dont pollute output
|
// dont pollute output
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,6 +54,7 @@ type
|
||||||
|
|
||||||
TCEDubProject = class(TComponent, ICECommonProject)
|
TCEDubProject = class(TComponent, ICECommonProject)
|
||||||
private
|
private
|
||||||
|
fIsSdl: boolean;
|
||||||
fInGroup: boolean;
|
fInGroup: boolean;
|
||||||
fDubProc: TCEProcess;
|
fDubProc: TCEProcess;
|
||||||
fPreCompilePath: string;
|
fPreCompilePath: string;
|
||||||
|
@ -130,6 +131,7 @@ type
|
||||||
//
|
//
|
||||||
property json: TJSONObject read fJSON;
|
property json: TJSONObject read fJSON;
|
||||||
property packageName: string read fPackageName;
|
property packageName: string read fPackageName;
|
||||||
|
property isSDL: boolean read fIsSdl;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
// these 9 built types always exist
|
// these 9 built types always exist
|
||||||
|
@ -138,6 +140,9 @@ type
|
||||||
// returns true if filename is a valid dub project. Only json format is supported.
|
// returns true if filename is a valid dub project. Only json format is supported.
|
||||||
function isValidDubProject(const filename: string): boolean;
|
function isValidDubProject(const filename: string): boolean;
|
||||||
|
|
||||||
|
// converts a sdl description to json, returns the json
|
||||||
|
function sdl2json(const filename: string): TJSONObject;
|
||||||
|
|
||||||
function getDubCompiler: TCECompiler;
|
function getDubCompiler: TCECompiler;
|
||||||
procedure setDubCompiler(value: TCECompiler);
|
procedure setDubCompiler(value: TCECompiler);
|
||||||
|
|
||||||
|
@ -145,6 +150,9 @@ var
|
||||||
DubCompiler: TCECompiler = dmd;
|
DubCompiler: TCECompiler = dmd;
|
||||||
DubCompilerFilename: string = 'dmd';
|
DubCompilerFilename: string = 'dmd';
|
||||||
|
|
||||||
|
const
|
||||||
|
DubSdlWarning = 'this feature is not available for a DUB project with the SDL format';
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
var
|
var
|
||||||
|
@ -330,66 +338,83 @@ procedure TCEDubProject.loadFromFile(const fname: string);
|
||||||
var
|
var
|
||||||
loader: TMemoryStream;
|
loader: TMemoryStream;
|
||||||
parser : TJSONParser;
|
parser : TJSONParser;
|
||||||
|
ext: string;
|
||||||
bom: dword = 0;
|
bom: dword = 0;
|
||||||
begin
|
begin
|
||||||
loader := TMemoryStream.Create;
|
ext := fname.extractFileExt.upperCase;
|
||||||
try
|
fBasePath := fname.extractFilePath;
|
||||||
fBasePath := fname.extractFilePath;
|
fFilename := fname;
|
||||||
fFilename := fname;
|
fSaveAsUtf8 := false;
|
||||||
loader.LoadFromFile(fFilename);
|
fIsSdl := false;
|
||||||
fSaveAsUtf8 := false;
|
if ext = '.JSON' then
|
||||||
// skip BOM, this crashes the parser
|
begin
|
||||||
loader.Read(bom, 4);
|
loader := TMemoryStream.Create;
|
||||||
if (bom and $BFBBEF) = $BFBBEF then
|
|
||||||
begin
|
|
||||||
loader.Position:= 3;
|
|
||||||
fSaveAsUtf8 := true;
|
|
||||||
end
|
|
||||||
else if (bom = $FFFE0000) or (bom = $FEFF) then
|
|
||||||
begin
|
|
||||||
// UCS-4 LE/BE not handled by DUB
|
|
||||||
loader.clear;
|
|
||||||
loader.WriteByte(byte('{'));
|
|
||||||
loader.WriteByte(byte('}'));
|
|
||||||
loader.Position:= 0;
|
|
||||||
fFilename := '';
|
|
||||||
end
|
|
||||||
else if ((bom and $FEFF) = $FEFF) or ((bom and $FFFE) = $FFFE) then
|
|
||||||
begin
|
|
||||||
// UCS-2 LE/BE not handled by DUB
|
|
||||||
loader.clear;
|
|
||||||
loader.WriteByte(byte('{'));
|
|
||||||
loader.WriteByte(byte('}'));
|
|
||||||
loader.Position:= 0;
|
|
||||||
fFilename := '';
|
|
||||||
end
|
|
||||||
else
|
|
||||||
loader.Position:= 0;
|
|
||||||
//
|
|
||||||
FreeAndNil(fJSON);
|
|
||||||
parser := TJSONParser.Create(loader, [joIgnoreTrailingComma, joUTF8]);
|
|
||||||
//TODO-cfcl-json: remove etc/fcl-json the day they'll merge and rlz the version with 'Options'
|
|
||||||
//TODO-cfcl-json: track possible changes and fixes at http://svn.freepascal.org/cgi-bin/viewvc.cgi/trunk/packages/fcl-json/
|
|
||||||
//latest in etc = rev 34196.
|
|
||||||
try
|
try
|
||||||
try
|
loader.LoadFromFile(fFilename);
|
||||||
fJSON := parser.Parse as TJSONObject;
|
// skip BOMs, they crash the parser
|
||||||
except
|
loader.Read(bom, 4);
|
||||||
if assigned(fJSON) then
|
if (bom and $BFBBEF) = $BFBBEF then
|
||||||
FreeAndNil(fJSON);
|
begin
|
||||||
|
loader.Position:= 3;
|
||||||
|
fSaveAsUtf8 := true;
|
||||||
|
end
|
||||||
|
else if (bom = $FFFE0000) or (bom = $FEFF) then
|
||||||
|
begin
|
||||||
|
// UCS-4 LE/BE not handled by DUB
|
||||||
|
loader.clear;
|
||||||
|
loader.WriteByte(byte('{'));
|
||||||
|
loader.WriteByte(byte('}'));
|
||||||
|
loader.Position:= 0;
|
||||||
fFilename := '';
|
fFilename := '';
|
||||||
|
end
|
||||||
|
else if ((bom and $FEFF) = $FEFF) or ((bom and $FFFE) = $FFFE) then
|
||||||
|
begin
|
||||||
|
// UCS-2 LE/BE not handled by DUB
|
||||||
|
loader.clear;
|
||||||
|
loader.WriteByte(byte('{'));
|
||||||
|
loader.WriteByte(byte('}'));
|
||||||
|
loader.Position:= 0;
|
||||||
|
fFilename := '';
|
||||||
|
end
|
||||||
|
else
|
||||||
|
loader.Position:= 0;
|
||||||
|
//
|
||||||
|
FreeAndNil(fJSON);
|
||||||
|
parser := TJSONParser.Create(loader, [joIgnoreTrailingComma, joUTF8]);
|
||||||
|
//TODO-cfcl-json: remove etc/fcl-json the day they'll merge and rlz the version with 'Options'
|
||||||
|
//TODO-cfcl-json: track possible changes and fixes at http://svn.freepascal.org/cgi-bin/viewvc.cgi/trunk/packages/fcl-json/
|
||||||
|
//latest in etc = rev 34196.
|
||||||
|
try
|
||||||
|
try
|
||||||
|
fJSON := parser.Parse as TJSONObject;
|
||||||
|
except
|
||||||
|
if assigned(fJSON) then
|
||||||
|
FreeAndNil(fJSON);
|
||||||
|
fFilename := '';
|
||||||
|
end;
|
||||||
|
finally
|
||||||
|
parser.Free;
|
||||||
end;
|
end;
|
||||||
finally
|
finally
|
||||||
parser.Free;
|
loader.Free;
|
||||||
end;
|
end;
|
||||||
finally
|
end
|
||||||
loader.Free;
|
else if ext = '.SDL' then
|
||||||
if not assigned(fJSON) then
|
begin
|
||||||
fJson := TJSONObject.Create(['name','invalid json']);
|
FreeAndNil(fJSON);
|
||||||
updateFields;
|
fJSON := sdl2json(fFilename);
|
||||||
subjProjChanged(fProjectSubject, self);
|
if fJSON.isNil then
|
||||||
fModified := false;
|
fFilename := ''
|
||||||
|
else
|
||||||
|
fIsSdl := true;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
if not assigned(fJSON) then
|
||||||
|
fJson := TJSONObject.Create(['name','invalid json']);
|
||||||
|
|
||||||
|
updateFields;
|
||||||
|
subjProjChanged(fProjectSubject, self);
|
||||||
|
fModified := false;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCEDubProject.saveToFile(const fname: string);
|
procedure TCEDubProject.saveToFile(const fname: string);
|
||||||
|
@ -1073,11 +1098,58 @@ end;
|
||||||
{$ENDREGION --------------------------------------------------------------------}
|
{$ENDREGION --------------------------------------------------------------------}
|
||||||
|
|
||||||
{$REGION Miscellaneous DUB free functions --------------------------------------}
|
{$REGION Miscellaneous DUB free functions --------------------------------------}
|
||||||
|
function sdl2json(const filename: string): TJSONObject;
|
||||||
|
var
|
||||||
|
dub: TProcess;
|
||||||
|
str: TStringList;
|
||||||
|
jsn: TJSONData;
|
||||||
|
prs: TJSONParser;
|
||||||
|
old: string;
|
||||||
|
begin
|
||||||
|
result := nil;
|
||||||
|
dub := TProcess.Create(nil);
|
||||||
|
str := TStringList.Create;
|
||||||
|
old := GetCurrentDirUTF8;
|
||||||
|
try
|
||||||
|
SetCurrentDirUTF8(filename.extractFilePath);
|
||||||
|
dub.Executable := 'dub' + exeExt;
|
||||||
|
dub.Options := [poUsePipes{$IFDEF WINDOWS}, poNewConsole{$ENDIF}];
|
||||||
|
dub.ShowWindow := swoHIDE;
|
||||||
|
dub.CurrentDirectory:= filename.extractFilePath;
|
||||||
|
dub.Parameters.Add('describe');
|
||||||
|
dub.Execute;
|
||||||
|
processOutputToStrings(dub, str);
|
||||||
|
while dub.Running do;
|
||||||
|
prs := TJSONParser.Create(str.Text, [joIgnoreTrailingComma, joUTF8]);
|
||||||
|
try
|
||||||
|
jsn := prs.Parse;
|
||||||
|
try
|
||||||
|
if jsn.isNotNil and (jsn.JSONType = jtObject)
|
||||||
|
and TJSONObject(jsn).Find('packages').isNotNil
|
||||||
|
and (TJSONObject(jsn).Find('packages').JSONType = jtArray)
|
||||||
|
and (TJSONArray(TJSONObject(jsn).Find('packages')).Count > 0)
|
||||||
|
and (TJSONArray(TJSONObject(jsn).Find('packages')).Items[0].JSONType = jtObject) then
|
||||||
|
result := TJSONObject(TJSONArray(TJSONObject(jsn).Find('packages')).Items[0].Clone);
|
||||||
|
finally
|
||||||
|
jsn.free;
|
||||||
|
end;
|
||||||
|
finally
|
||||||
|
prs.Free
|
||||||
|
end;
|
||||||
|
finally
|
||||||
|
SetCurrentDirUTF8(old);
|
||||||
|
dub.free;
|
||||||
|
str.Free;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
function isValidDubProject(const filename: string): boolean;
|
function isValidDubProject(const filename: string): boolean;
|
||||||
var
|
var
|
||||||
maybe: TCEDubProject;
|
maybe: TCEDubProject;
|
||||||
|
ext: string;
|
||||||
begin
|
begin
|
||||||
if (filename.extractFileExt.upperCase <> '.JSON') then
|
ext := filename.extractFileExt.upperCase;
|
||||||
|
if (ext <> '.JSON') and (ext <> '.SDL') then
|
||||||
exit(false);
|
exit(false);
|
||||||
result := true;
|
result := true;
|
||||||
// avoid the project to notify the observers, current project is not replaced
|
// avoid the project to notify the observers, current project is not replaced
|
||||||
|
|
|
@ -21,10 +21,10 @@ inherited CEDubProjectEditorWidget: TCEDubProjectEditorWidget
|
||||||
Height = 380
|
Height = 380
|
||||||
Top = 4
|
Top = 4
|
||||||
Width = 403
|
Width = 403
|
||||||
ActivePage = TabSheet2
|
ActivePage = TabSheet1
|
||||||
Align = alClient
|
Align = alClient
|
||||||
BorderSpacing.Around = 4
|
BorderSpacing.Around = 4
|
||||||
TabIndex = 1
|
TabIndex = 0
|
||||||
TabOrder = 0
|
TabOrder = 0
|
||||||
object TabSheet1: TTabSheet
|
object TabSheet1: TTabSheet
|
||||||
Caption = 'Inspector'
|
Caption = 'Inspector'
|
||||||
|
|
|
@ -287,7 +287,7 @@ begin
|
||||||
if project.getProject <> fProj then
|
if project.getProject <> fProj then
|
||||||
exit;
|
exit;
|
||||||
fProj := nil;
|
fProj := nil;
|
||||||
//
|
|
||||||
updateEditor;
|
updateEditor;
|
||||||
updateInspector;
|
updateInspector;
|
||||||
enabled := false;
|
enabled := false;
|
||||||
|
@ -308,6 +308,12 @@ begin
|
||||||
if not Visible then
|
if not Visible then
|
||||||
exit;
|
exit;
|
||||||
|
|
||||||
|
if fProj.isSDL then
|
||||||
|
begin
|
||||||
|
edProp.Enabled:= false;
|
||||||
|
btnAcceptProp.Enabled:=false;
|
||||||
|
end;
|
||||||
|
|
||||||
updateEditor;
|
updateEditor;
|
||||||
updateInspector;
|
updateInspector;
|
||||||
end;
|
end;
|
||||||
|
|
|
@ -3227,10 +3227,13 @@ begin
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCEMainForm.openProj(const fname: string);
|
procedure TCEMainForm.openProj(const fname: string);
|
||||||
|
var
|
||||||
|
ext: string;
|
||||||
begin
|
begin
|
||||||
if not closeProj then
|
if not closeProj then
|
||||||
exit;
|
exit;
|
||||||
if fname.extractFileExt.upperCase = '.JSON' then
|
ext := fname.extractFileExt.upperCase;
|
||||||
|
if (ext = '.JSON') or (ext = '.SDL') then
|
||||||
newDubProj
|
newDubProj
|
||||||
else
|
else
|
||||||
newNativeProj;
|
newNativeProj;
|
||||||
|
@ -3260,6 +3263,11 @@ procedure TCEMainForm.actProjSaveAsExecute(Sender: TObject);
|
||||||
begin
|
begin
|
||||||
if checkProjectLock then
|
if checkProjectLock then
|
||||||
exit;
|
exit;
|
||||||
|
if (fProject.getFormat = pfDub) and TCEDubProject(fProject.getProject).isSDL then
|
||||||
|
begin
|
||||||
|
fMsgs.message(DubSdlWarning, fProject, amcProj, amkWarn);
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
with TSaveDialog.Create(nil) do
|
with TSaveDialog.Create(nil) do
|
||||||
try
|
try
|
||||||
if execute then saveProjAs(filename);
|
if execute then saveProjAs(filename);
|
||||||
|
@ -3271,6 +3279,11 @@ end;
|
||||||
procedure TCEMainForm.actProjSaveExecute(Sender: TObject);
|
procedure TCEMainForm.actProjSaveExecute(Sender: TObject);
|
||||||
begin
|
begin
|
||||||
if fProject = nil then exit;
|
if fProject = nil then exit;
|
||||||
|
if (fProject.getFormat = pfDub) and TCEDubProject(fProject.getProject).isSDL then
|
||||||
|
begin
|
||||||
|
fMsgs.message(DubSdlWarning, fProject, amcProj, amkWarn);
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
if checkProjectLock then
|
if checkProjectLock then
|
||||||
exit;
|
exit;
|
||||||
if fProject.filename.isNotEmpty then saveProj
|
if fProject.filename.isNotEmpty then saveProj
|
||||||
|
@ -3311,6 +3324,11 @@ procedure TCEMainForm.actProjSourceExecute(Sender: TObject);
|
||||||
begin
|
begin
|
||||||
if fProject = nil then exit;
|
if fProject = nil then exit;
|
||||||
if not fProject.filename.fileExists then exit;
|
if not fProject.filename.fileExists then exit;
|
||||||
|
if (fProject.getFormat = pfDub) and TCEDubProject(fProject.getProject).isSDL then
|
||||||
|
begin
|
||||||
|
fMsgs.message(DubSdlWarning, fProject, amcProj, amkWarn);
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
//
|
//
|
||||||
openFile(fProject.filename);
|
openFile(fProject.filename);
|
||||||
fDoc.isProjectDescription := true;
|
fDoc.isProjectDescription := true;
|
||||||
|
|
|
@ -36,17 +36,23 @@ procedure saveModifiedProjectFiles(project: ICECommonProject);
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
function isProject(const filename: string): boolean;
|
function isProject(const filename: string): boolean;
|
||||||
|
var
|
||||||
|
ext: string;
|
||||||
begin
|
begin
|
||||||
if filename.extractFileExt = '.json' then
|
ext := filename.extractFileExt.upperCase;
|
||||||
|
if (ext = '.JSON') or (ext = '.SDL') then
|
||||||
result := isValidDubProject(filename)
|
result := isValidDubProject(filename)
|
||||||
else
|
else
|
||||||
result := isValidNativeProject(filename);
|
result := isValidNativeProject(filename);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function projectFormat(const filename: string): TCEProjectFileFormat;
|
function projectFormat(const filename: string): TCEProjectFileFormat;
|
||||||
|
var
|
||||||
|
ext: string;
|
||||||
begin
|
begin
|
||||||
result := pffNone;
|
result := pffNone;
|
||||||
if filename.extractFileExt = '.json' then
|
ext := filename.extractFileExt.upperCase;
|
||||||
|
if (ext = '.JSON') or (ext = '.SDL') then
|
||||||
begin
|
begin
|
||||||
if isValidDubProject(filename) then
|
if isValidDubProject(filename) then
|
||||||
result := pffDub;
|
result := pffDub;
|
||||||
|
|
Loading…
Reference in New Issue