2013-04-24 17 views
10

Delphi 2007'den XE2'ye geçişin bir yan etkisi olarak çalıştığım büyük bir Delphi kod tabanı ile ilgili bir sorun yaşıyorum biz şimdi aşağıdaki garip, ilgili sorunlarla karşılaşabilirsiniz: satır numaralandırma sadece bazı birimlerde, darmadağandı çünküDelphi XE2: Hata ayıklayıcı ve derleyici hata satır numaralarında 7-20 satırında kapalı da aynı miktarda

  • hatta ayıklama derlemesi kod aracılığıyla kesme noktaları veya tek adım ayarlanamaz. hat 2010'da kasten bir sözdizimi hatası Tanıtımı

  • imleç, çizgi 2020 odaklanmak vermek ya böyle 3 veya 4 satır, bir şey almak neden olur:

.

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 

Birinin bunu daha önce görmüş olmasını umuyorum. Sorunun öğeleri şunları içerebilir:

Bu kodda, {$ REALCOMPATIBILITY ON} ve {$ H -}/{$ H +} yönergeleri, binlerce {$ H +}/{$ H-} yönergesi gibi pek çok derleyici yönergesi yer almaktadır. kodda. İkinci olarak, kod çok sayıda {$ I INCLUDE} direktif kullanır ve dosyaların dahil edilmesinin derleyicinin satır numaralandırmasını doğrudan bozabileceğinden şüpheleniyorum.

Kesin olarak söyleyemiyorum, ama bütün bunların eskiden "DOS için turbo pascal gibi çalışmasını sağlayın" der. Bu konuda emin bir şey bilen var mı bilmek isterim. Sadece kodun bazı yerlerinde ve bazılarının 10K/20KLOC boyutuna ulaşan 500 üniteden fazla bir projeyle gerçekleşmesi, kesinlikle sinir bozucu. Söyleyebileceğim tek şey, yalnızca {$ I include.inc} yönergesi olan birimlerin değil, ve çok sayıda {$ H -}/{$ H +} veya {$ REALCOMPATIBILITY} yönergesi içeren birçok birim de bu problemi yok. Yanlış davranan birimlerin ortak yanlarını görebilseydim bunu anlayabilirdim.

Güncelleme: Hat sonlandırma sorunu anlamlıdır. Sorun tespit edilen bu kodu çalıştırdım. Düzeltme kodu yorumlanır, çünkü eğer siz onu rahatsız ediyorsanız ve tüm kaynak kodunuzu silerseniz, bu sizin probleminizdir. Unicode olmayan bir dosyayı bir unicode TStringList içine yükleyerek ve geri kaydederek. Bu benim dünyamda tamam, çünkü tüm versiyonu kontrol ediliyor ve destekleniyor. Yolculuğunuz değişebilir. Bağlantı

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. Bağlantı Google Drive. Kaynak kodunu bağlantıdan görüntüleyebilirsiniz, ancak "Dosya" açılır menüsünü (google sürücü web kullanıcı arayüzünün bir parçası) tıklayın ve daha sonra indirmek için "İndir" seçeneğini tıklayın.

+0

+1, Aynı davranışı {$ I INCLUDE} yönergesini kullanarak yaşadım. – RRUZ

+0

Hat içi sonlandırma karakterleri .inc dosyasının ana dosya yerine dosyaları içerdiğini merak ediyorum, bu da beni rahatsız ediyor. –

+1

Kod satırlarını eklediyseniz (veya çıkardıysanız) ve F9 tuşuna basarsanız, ikilide kullanılmakta olan DCU'lar (ve bu nedenle hata ayıklayıcının belirteçleri) yeniden oluşturulamıyor olabilir (bu sorunu birçok kez yaşadım) . Bu gibi durumlarda, sadece bir "Temiz" yapıyorum, sonra "Oluştur" ve sorun gider. Bunu denedin mi? – LaKraven

cevap

21

Daha önce böyle şeyler gördüm ve IME genellikle satır numaralarını sayma derleyici bir hata nedeniyle. Eğer bazı noktalarda standart olmayan satır sonları (CRLF değil) varsa - bu gerçekleşebilir - IDE doğru satır sonları yapar ancak derleyici bunları yeni satırlar olarak saymaz, bundan sonra her şey birer birer atılır. Böyle bir dosya EditPad o açıktır karşılaştığınızda Ne yapmam

, diğer bazı stili (Unix veya Mac tarzı) tüm linebreaks dönüştürmek ve ardından Windows stiline tüm linebreaks dönüştürmek ve kaydedin. Bu, dosyadaki her satırın CRLF ile bittiğini ve sorunu yeniden oluşturmayacak şekilde mavi noktalarla yeniden oluşturmayı sağlar.

+0

Bu, Visual Studio'da da olur. Orada karışık satır sonları olan ve onları bir stile dönüştürme seçeneği olan herhangi bir dosya için beni uyarır 'CodeRush' kullanın. –

+0

Yardım etmek ve yukarıdaki cevaba eklemek için biraz yardımcı program yazdım. Eğer insanlar için yararlıysa, daha az aceleyle bir şey yazacağım ve onu açık kaynak haline getireceğim. –

+0

Onaylandı. Yukarıdaki cevabı verdiğim kodu çalıştırdıktan sonra, artık bu sorunları yeniden üretemiyorum. İyi arama. İkinize de cevap verecek zaman ayırdığınız için teşekkürler. –

9

Bu, eşleşmeyen satır sonlandırma karakterlerinden kaynaklanan yaygın bir sorundur. (Çizginin bitiminde eksik bir CR veya LF ile kodlayın.) Buna sahip olmak da olabilir.dcu, editörde açık olan kaynak dosyayla eşleşmiyor.

İlk olarak, en kolay düzeltme, kaynak dosyayı normal bir metin düzenleyicisinde (Not Defteri gibi) açmaktır. Küçük bir değişiklik yapın (boş bir satır ekleyin ve sonra silin) ​​ve dosyayı kaydedin. Not defteri satır sonlarını düzeltir. Sorun bu değilse, IDE'nin arama yolunda sürücünüzde bulunan .dcu (veya .pas) dosyasının fazladan kopyalarını arayın. Bazen derleyici editörde açık olandan farklı bir versiyon görür.

+0

Büyük bir kod tabanında otomatik olarak satır sonlandırmayı düzeltmek için bir araç var mı? Sorun buysa, onunla tamamen ilgilenmeyi tercih ederim. Orada bir tane bulamazsam böyle bir araç yazabilirim. –

+0

Gördüğümden değil. Bir keresinde bir tane yazdım (bir klasörde her bir .pas dosyasını yineleyen bir Delphi uygulaması, dosyayı bir TStringList'e yükledikten sonra bir "SaveToFile" yaptı). (Bu, D2005'ten beri, mevcut editör kod tabanı başlatıldığında, IDE'de bilinen bir sorun olmuştur. Neden henüz çözülmediğini bilmiyorum; muhtemelen xPlatform desteğiyle karşılaştırıldığında düşük öncelikli bir sorun.) –

+0

bunu sanırım. Geçersiz satır sonlandırma karakterlerini satırlardan birinde bir orta nokta olarak tutmazsa. –

İlgili konular