Delphi XE2:由7-20行的调试器和编译器错误行号也关闭相同的数量 [英] Delphi XE2 : Off by 7-20 lines in debugger and compiler error line numbers also off by the same amount

查看:144
本文介绍了Delphi XE2:由7-20行的调试器和编译器错误行号也关闭相同的数量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到一个大型的Delphi代码库问题,在那里我作为从Delphi 2007移植到XE2的副作用,我们现在遇到以下奇怪的相关问题:




  • 即使在调试版本中,也不能设置断点或单步执行代码,因为只能在某些单元中排列行编号。

    / li>
  • 故意在2010年线上引入语法错误将导致游标在2020行焦点,给或采取3或4行,如下所示:




 程序正确; 
begin
DoSomething; //这里报告的语法错误,但真正的错误在下面。
//更多的东西在这里。
结束

程序OllKorrect;
begin
ThisLineIsFine();
__VARIABLE_NOT_DEFINED__:= 1; //故意错误
结束

我希望有人以前见过这个。问题的要素可能包括:



该代码包含许多奇怪的编译器指令,如{$ REALCOMPATIBILITY ON}和{$ H - } / {$ H +}指令,数千个{$ H +} / {$ H-}指令中的代码。



其次,该代码使用了很多{$ I INCLUDE}指令,我怀疑include文件可能会直接导致编译器的行编号。



我无法肯定地说,但我怀疑所有这些旧的使它像turbo pascal一样工作DOS编译器开关是背后的原因。我想知道有没有人知道这一点。它只发生在代码的某些地方,一个项目有500多个单位,其中一些达到10K / 20KLOC的大小,这绝对令人沮丧。我可以说的是,它不仅具有{$ I include.inc}指令的单位,而且包含很多{$ H - } / {$ H +}或{$ REALCOMPATIBILITY}指令的单位没有这个问题。如果我可以看到不正之风的单位有什么共同之处,我可以弄清楚这一点。



更新:线路终止问题是有道理的。我运行这个代码检测到问题。修复代码被注释掉,因为如果您取消注释并清除所有源代码,那就是您的问题。
将unicode文件加载到unicode TStringList并将其保存回来。这在我的世界是没问题的,因为它的所有版本都受到控制和备份。您的里程可能会有所不同。

  program linefeedsProject1; 

{$ APPTYPE CONSOLE}

使用
IOUtils,
类,
类型,
SysUtils;


var
broken,notBroken:Integer;

函数fix(filename:String):Boolean;
var
sl:TStringList;
begin
sl:= TStringList.Create;
try
sl.LoadFromFile(filename);
// TODO:更改文件扩展名。
sl.SaveToFile(filename);
finally
sl.Free;
结束
结束

函数scan(filename:String):Boolean;
var
crFlag:Boolean;
lfFlag:Boolean;
missingCr:Integer;
missingLf:整数;
f:TFileStream;
buf:AnsiChar的Array [0..1024];
n:整数;
程序scanChars;
var
i:整数;
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
如果不是crFlag然后
inc(missingCr);
lfFlag:= true;
crFlag:= false;
end
else begin
if(crFlag)then
inc(missingLf);
crFlag:= false;
lfFlag:= false;
结束
结束
结束
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;
结束

if(missingCr> 0)或(missingLf> 0)然后
begin
WriteLn('',filename);
Inc(破);
result:= true;
end
else
begin
Inc(notBroken);
end
finally
f.Free;
结束

end;
var
文件:TStringDynArray;
afile:String;
begin
try
broken:= 0;
notBroken:= 0;
文件:= TDirectory.GetFiles('C:\dev\abackupcopyofyoursourcecode','* .pas',
TSearchOption.soTopDirectoryOnly);
//尝试TSearchOption.soAllDirectories它爆炸了。不建议。

在文件中为$ f
begin
如果scan(afile)然后
begin
// fix(afile); //取消注释你自己的风险,只有你的代码的备份副本。
结束

end;


WriteLn('Broken',broken);
写入('not broken',notBroken);

// readln;

除了
对于E:异常do
Writeln(E.ClassName,':',E.Message);
结束
结束。

更新2:如果你想要一个扫描仪/修复程序出现这个问题,可以在这里下载我的(源代码)。链接是Google Drive。您可以从链接查看源代码,但点击文件下拉菜单(部分谷歌驱动器Web用户界面),然后单击下载下载。

解决方案

我以前看过这样的东西,IME通常是由于计算行号的编译器错误。如果在某些点(如果可能发生)中有非标准换行符(不是CRLF),则IDE将进行适当的换行符,但是编译器不会将其视为新行,因此所有事情都将被抛出一个。 p>

当我遇到像这样的文件时,我打开它,将所有换行符转换为其他样式(Unix或Mac风格),然后将所有换行符转换为Windows样式并保存。这确保文件中的每一行都以CRLF结尾,重建后,蓝点不排队的问题就会消失。


I am having a problem with a large Delphi codebase where I work where as a side effect of porting from Delphi 2007 to XE2, we now encounter the following strange, related issues:

  • You can not set breakpoints or single step through code even in the debug build because the line numbering is all messed up, only in some of the units.

  • Introducing a syntax error deliberately at line 2010 will cause the cursor to focus at line 2020, give or take 3 or 4 lines, something like this:

.

 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

I am hoping someone has seen this before. Elements of the issue may include:

The code contains many odd compiler directives like {$REALCOMPATIBILITY ON} and {$H-}/{$H+} directives, thousands of {$H+}/{$H-} directives in the code.

Secondly, the code uses a lot of {$I INCLUDE} directives, and I suspect that include files might directly mess up the line-numbering of the compiler.

I am unable to say for sure, but I suspect all these old "make it work like turbo pascal for DOS" compiler switches are the reason behind it. I'd like to know if anyone knows something about this for sure. It only happens in some places in the code, and with a project that has over 500 units, some of which reach 10K/20KLOC in size, it is definitely frustrating. What I can say is that it not only units that have {$I include.inc} directives that mess up, and that many units that contain a lot of {$H-}/{$H+} or {$REALCOMPATIBILITY} directives do not have this problem. If I could see what the units that misbehave have in common I could figure this out.

Update: The line termination issue makes sense. I ran this code which detected problems. The fix code is commented out because if you uncomment it and it erases all your source code, that's your problem. It is loading a non-unicode file into a unicode TStringList and saving it back out. That's okay in my world because its all version controlled and backed up. Your mileage may vary.

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: If you want a scanner/fixer for this issue you can download mine (with source) here. Link is Google Drive. You can view the source code from the link, but click the "File" pull down menu (part of the google drive web user interface) and then click "Download" to download it.

解决方案

I've seen things like this before, and IME it's generally due to an compiler bug in counting line numbers. If you have nonstandard line breaks (not CRLF) at some points--which can happen--the IDE will do proper line breaks but the compiler doesn't count them as new lines, so everything afterwards gets thrown off by one.

What I do when I encounter a file like this is open it in EditPad, convert all linebreaks to some other style (Unix or Mac style) and then convert all linebreaks to Windows style and save it. This ensures that every line in the file ends with CRLF, and after a rebuild the issue with the blue dots not lining up right goes away.

这篇关于Delphi XE2:由7-20行的调试器和编译器错误行号也关闭相同的数量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆