У меня проблема с большой кодовой базой Delphi, где я работаю, где в качестве побочного эффекта переноса с Delphi 2007 на XE2 мы теперь сталкиваемся со следующими странными, связанными проблемами:
Вы не можете установить точки останова или пошаговый код даже в отладочной сборке, потому что нумерация строк испорчена, только в некоторых модулях.
Преднамеренное внесение синтаксической ошибки в строке 2010 приведет к тому, что курсор будет сфокусирован на строке 2020, дайте или возьмите 3 или 4 строки, что-то вроде этого:
.
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
Я надеюсь, что кто-то видел это раньше. Элементы проблемы могут включать в себя:
Код содержит много нечетных директив компилятора, таких как {$ REALCOMPATIBILITY ON} и {$H-}/{$H+}, тысячи директив {$H+}/{$H-} в коде.
Во-вторых, в коде используется много директив {$ я INCLUDE}, и я подозреваю, что включаемые файлы могут напрямую испортить нумерацию строк компилятора.
Я не могу сказать наверняка, но я подозреваю, что все эти старые "заставляют его работать как Turbo Pascal для DOS" переключатели компилятора являются причиной этого. Я хотел бы знать, знает ли кто-нибудь об этом наверняка. Это происходит только в некоторых местах кода, и с проектом, который имеет более 500 модулей, некоторые из которых достигают размера 10K/20KLOC, это определенно расстраивает. Что я могу сказать, так это то, что не только единицы, у которых есть директивы {$ я include.inc}, которые запутываются, и что много единиц, которые содержат много директив {$H-}/{$H+} или {$ REALCOMPATIBILITY} не имеют этой проблемы. Если бы я мог видеть, что общего у единиц, которые плохо себя ведут, я бы понял это.
Обновление: вопрос об окончании линии имеет смысл. Я запустил этот код, который обнаружил проблемы. Код исправления закомментирован, потому что если вы раскомментируете его и он удалит весь ваш исходный код, то это ваша проблема. Он загружает не-Unicode файл в Unicode TStringList и сохраняет его обратно. Это нормально в моем мире, потому что вся его версия контролируется и поддерживается. Ваш пробег может отличаться.
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.
Обновление 2. Если вам нужен сканер/исправитель для этой проблемы, вы можете загрузить мой (с исходным кодом) здесь. Ссылка - Google Drive. Вы можете просмотреть исходный код по ссылке, но нажмите раскрывающееся меню "Файл" (часть пользовательского веб-интерфейса Google Drive) и затем нажмите "Скачать", чтобы загрузить его.