Delphi XE2: Aus um 7-20 Zeilen in Debugger- und Compilerfehlerzeilennummern ebenfalls um den gleichen Betrag
Ich habe ein Problem mit einer großen Delphi-Codebasis, in der ich arbeite. Als Nebeneffekt der Portierung von Delphi 2007 auf XE2 treten jetzt die folgenden seltsamen, verwandten Probleme auf:
Sie können auch im Debug-Build keine Haltepunkte oder Code-Einzelschritte festlegen, da die Zeilennummerierung nur in einigen Einheiten fehlerhaft ist.
Das absichtliche Einfügen eines Syntaxfehlers in Zeile 2010 bewirkt, dass sich der Cursor auf Zeile 2020 fokussiert, 3 oder 4 Zeilen gibt oder nimmt.
.
procedure Correct;
begin
DoSomething; // syntax error reported HERE but the real error is below.
// more stuff here.
end;
procedure OllKorrect;
begin
ThisLineIsFine();
__VARIABLE_NOT_DEFINED__ := 1; // intentional error
end
Ich hoffe jemand hat das schon mal gesehen. Zu den Elementen des Problems können gehören:
Der Code enthält viele ungerade Compiler-Direktiven wie {$ REALCOMPATIBILITY ON} und {$ H -} / {$ H +} Direktiven, Tausende von {$ H +} / {$ H-} Direktiven im Code.
Zweitens verwendet der Code viele Anweisungen {$ I INCLUDE}, und ich vermute, dass Include-Dateien die Zeilennummerierung des Compilers direkt durcheinander bringen könnten.
Ich kann es nicht mit Sicherheit sagen, aber ich vermute, dass all diese alten Compiler-Schalter der Grund dafür sind, dass "es wie Turbo Pascal für DOS funktioniert". Ich würde gerne wissen, ob jemand etwas darüber sicher weiß. Es kommt nur an einigen Stellen im Code vor und bei einem Projekt mit über 500 Einheiten, von denen einige eine Größe von 10 K / 20 K LOC erreichen, ist es definitiv frustrierend. Was ich sagen kann ist, dass es nicht nur Einheiten gibt, die Direktiven {$ I include.inc} haben, die durcheinander bringen, und dass viele Einheiten, die viele Direktiven {$ H -} / {$ H +} oder {$ REALCOMPATIBILITY} enthalten, dies tun habe dieses problem nicht. Wenn ich sehen könnte, was die Einheiten, die sich schlecht benehmen, gemeinsam haben, könnte ich das herausfinden.
Update: Das Problem mit der Leitungsbeendigung ist sinnvoll. Ich habe diesen Code ausgeführt, der Probleme festgestellt hat. Der Fixcode ist auskommentiert, da dies Ihr Problem ist, wenn Sie ihn auskommentieren und Ihren gesamten Quellcode löschen. Es lädt eine Nicht-Unicode-Datei in eine Unicode-TStringList und speichert sie wieder ab. In meiner Welt ist das in Ordnung, da alle Versionen kontrolliert und gesichert werden. Ihr Kilometerstand kann variieren.
program linefeedsProject1;
{$APPTYPE CONSOLE}
uses
IOUtils,
Classes,
Types,
SysUtils;
var
broken,notBroken:Integer;
function fix(filename:String):Boolean;
var
sl:TStringList;
begin
sl := TStringList.Create;
try
sl.LoadFromFile(filename);
//TODO:Change file extensions.
sl.SaveToFile(filename);
finally
sl.Free;
end;
end;
function scan(filename:String):Boolean;
var
crFlag:Boolean;
lfFlag:Boolean;
missingCr:Integer;
missingLf:Integer;
f:TFileStream;
buf:Array[0..1024] of AnsiChar;
n:Integer;
procedure scanChars;
var
i:Integer;
begin
for i := 0 to n-1 do
begin
if buf[i]=#13 then
begin
crFlag := true;
lfFlag := false;
end
else if buf[i]=#10 then
begin
if not crFlag then
inc(missingCr);
lfFlag := true;
crFlag := false;
end
else begin
if (crFlag) then
inc(missingLf);
crFlag := false;
lfFlag := false;
end;
end;
end;
begin
result := false;
crFlag := false;
lfFlag := false;
missingCr := 0;
missingLf := 0;
f := TFileStream.Create(filename, fmOpenRead);
try
while f.Position< f.Size do
begin
n := f.Read(buf[0],1024);
scanChars;
end;
if (missingCr>0) or (missingLf>0) then
begin
WriteLn(' ', filename);
Inc(broken);
result := true;
end
else
begin
Inc(notBroken);
end
finally
f.Free;
end;
end;
var
files:TStringDynArray;
afile:String;
begin
try
broken := 0;
notBroken := 0;
files := TDirectory.GetFiles('C:\dev\abackupcopyofyoursourcecode', '*.pas',
TSearchOption.soTopDirectoryOnly );
// tried TSearchOption.soAllDirectories and it exploded. not recommended.
for afile in files do
begin
if scan(afile) then
begin
// fix(afile); // uncomment at your own risk and only on a backup copy of your code.
end;
end;
WriteLn('Broken ', broken);
WriteLn('not broken ',notBroken);
// readln;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.
Update 2: Wenn Sie einen Scanner / Fixer für dieses Problem benötigen, können Sie meinen (mit Quelle) hier herunterladen. Link ist Google Drive. Sie können den Quellcode über den Link anzeigen, aber auf das Pulldown-Menü "Datei" (Teil der Google Drive-Webbenutzeroberfläche) klicken und dann auf "Herunterladen" klicken, um ihn herunterzuladen.