14

Delphi 2007 から XE2 への移植の副作用として、私が働いている大規模な Delphi コードベースで問題が発生しています。現在、次の奇妙な関連する問題が発生しています。

  • 一部のユニットでのみ行番号がすべて台無しになっているため、デバッグ ビルドでもブレークポイントを設定したり、コードを 1 ステップ実行したりすることはできません。

  • 意図的に 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-} ディレクティブなど、多くの奇妙なコンパイラ ディレクティブが含まれています。

第 2 に、コードは多くの {$I INCLUDE} ディレクティブを使用しており、インクルード ファイルがコンパイラの行番号付けを直接台無しにする可能性があると思われます。

確かなことは言えませんが、これらの古い「DOS のターボ パスカルのように動作させる」コンパイラ スイッチが原因であると思われます。誰かがこれについて確かなことを知っているかどうか知りたいです。これはコードの一部の場所でのみ発生し、500 ユニットを超えるプロジェクトでは、サイズが 10K/20KLOC に達するものもあり、間違いなくイライラします。私が言えることは、混乱するのは {$I include.inc} ディレクティブを持つユニットだけではなく、多くの {$H-}/{$H+} または {$REALCOMPATIBILITY} ディレクティブを含む多くのユニットが失敗するということです。この問題はありません。挙動不審なユニットの共通点がわかれば、それがわかる。

更新: 回線終端の問題は理にかなっています。問題を検出したこのコードを実行しました。修正コードがコメント アウトされているのは、コメントを外してすべてのソース コードが消去されてしまうと、それが問題になるからです。非ユニコード ファイルをユニコード 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ドライブです。リンクからソースコードを表示できますが、「ファイル」プルダウンメニュー(GoogleドライブのWebユーザーインターフェースの一部)をクリックし、「ダウンロード」をクリックしてダウンロードしてください。

4

3 に答える 3

23

私は以前にこのようなことを見たことがあります.IMEは通常、行番号をカウントする際のコンパイラのバグが原因です. いくつかのポイントで非標準の改行 (CRLF ではない) がある場合 (これが発生する可能性があります)、IDE は適切な改行を行いますが、コンパイラはそれらを新しい行としてカウントしないため、その後のすべてが 1 つ破棄されます。

このようなファイルに遭遇したときに私がすることは、それを EditPad で開き、すべての改行を他のスタイル (Unix または Mac スタイル) に変換してから、すべての改行を Windows スタイルに変換して保存することです。これにより、ファイル内のすべての行が CRLF で終わることが保証され、再構築後に青い点が正しく並んでいないという問題が解消されます。

于 2013-04-24T23:42:11.290 に答える
10

これは、行末文字の不一致が原因で発生する一般的な問題です。(行末の CR または LF が欠落しているコード。)また、エディターで開いているソース ファイルと一致しない .dcu があることが原因である可能性もあります。

最初の最も簡単な修正方法は、ソース ファイルを通常のテキスト エディタ (メモ帳など) で開くことです。小さな変更 (空白行を挿入してから削除) を行い、ファイルを保存します。メモ帳は行末を修正します。

これが問題でない場合は、IDE の検索パスでドライブにある可能性がある .dcu (または .pas) ファイルの余分なコピーを探します。コンパイラは、エディターで開いているものとは異なるバージョンを認識することがあります。

于 2013-04-24T23:42:50.223 に答える
0

It definitely is connected to line endings as explained in previous posts. It is extremely hard to try to edit it away, since the Embarcadero editor tries to do magic of its own and preserves the line endings of the current section (or so it seems),

Solution: Right click in the IDE editor window, select "Format Source" (Ctrl-D) and accept.

This will fix all line endings and removes the problem (for me any way). As a by-product you will get correctly formatted source code :-)

于 2019-04-02T10:48:23.620 に答える