Delphi XE2: Wyłączone przez 7-20 linii w numerach linii błędów debugera i kompilatora również wyłączone o tę samą wartość
Mam problem z dużą bazą kodu Delphi, w której pracuję, gdzie jako efekt uboczny przenoszenia z Delphi 2007 do XE2, napotykamy następujące dziwne, powiązane problemy:
Nie można ustawić punktów przerwania ani pojedynczego kroku, nawet w kompilacji debugowania, ponieważ numeracja linii jest pomieszana tylko w niektórych jednostkach.
Wprowadzenie celowego błędu składniowego w linii 2010 spowoduje, że kursor skupi się na linii 2020, podając lub przyjmując 3 lub 4 linie, coś takiego:
.
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
Mam nadzieję, że ktoś już to widział. Elementy problemu mogą obejmować:
Kod zawiera wiele dziwnych dyrektyw kompilatora, takich jak dyrektywy {$ REALCOMPATIBILITY ON} i {$ H -} / {$ H +}, tysiące dyrektyw {$ H +} / {$ H-} w kodzie.
Po drugie, kod korzysta z wielu dyrektyw {$ I INCLUDE} i podejrzewam, że pliki dołączane mogą bezpośrednio zepsuć numerację linii kompilatora.
Nie jestem w stanie powiedzieć tego na pewno, ale podejrzewam, że powodem tego są wszystkie stare przełączniki kompilatora turbo pascal dla DOS. Chciałbym wiedzieć, czy ktoś na pewno coś o tym wie. Zdarza się to tylko w niektórych miejscach kodu i dzięki projektowi, który ma ponad 500 jednostek, z których niektóre osiągają rozmiar 10K / 20KLOC, jest to zdecydowanie frustrujące. Mogę powiedzieć, że nie tylko jednostki posiadające dyrektywy {$ I include.inc} zepsuły się, a wiele jednostek zawierających wiele dyrektyw {$ H -} / {$ H +} lub {$ REALCOMPATIBILITY} robi nie mam tego problemu. Gdybym mógł zobaczyć, co wspólnego mają jednostki, które się źle zachowują, mógłbym to rozgryźć.
Aktualizacja: problem zakończenia linii ma sens. Uruchomiłem ten kod, który wykrył problemy. Kod poprawki jest skomentowany, ponieważ jeśli go odkomentujesz i usuniesz cały kod źródłowy, to twój problem. Ładuje plik nie unicode do unicode TStringList i zapisuje go z powrotem. W moim świecie jest to w porządku, ponieważ wszystkie wersje są kontrolowane i archiwizowane. Twój przebieg może się różnić.
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.
Aktualizacja 2: Jeśli chcesz skaner / fixer do tego problemu, możesz pobrać mój (ze źródłem) tutaj. Link to Dysk Google. Możesz wyświetlić kod źródłowy z linku, ale kliknij menu rozwijane „Plik” (część interfejsu użytkownika dysku internetowego google), a następnie kliknij „Pobierz”, aby go pobrać.