Biçimlendirme farklılıklarını yok sayarak, kaynak kodu dosyalarını karşılaştırın (boşluk, çizgi gibi…)


9

İki farklı C ++ kaynağı karşılaştırmak ve kod anlamlı farklılıkları (farklı biçimlendirilmiş sürümleri karşılaştırmak için) bulmak bir uygulama arıyorum. En azından, kaynağın işlevselliğini etkilemeyen beyaz boşluklar, sekme boşlukları ve yeni satırlardaki değişiklikleri göz ardı etme yeteneğine sahip bir şey (bir satırsonunun boşluk boşluğunun dile bağlı olup olmadığı ve C ve C ++ bunu yaptığına dikkat edin) ). Ve ideal olarak, tüm kod-anlamlı farklılıkları tam olarak tanımlayabilen bir şey. Ubuntu'dayım.

Buna göre diff --help | grep ignore, makul bir şekilde iş diff -bBwZyapmayı bekledim (daha sonra ele alınacak yanlış negatifler almayı bekledim). Yine de öyle değil.

parçacıkları olan aşağıdaki dosyalara sahipsem

test_diff1.txt

    else if (prop == "P1") { return 0; }

ve test_diff2.txt

    else if (prop == "P1") {
        return 0;
    }

sonra

$ diff -bBwZ test_diff1.txt test_diff2.txt
1c1,3
<     else if (prop == "P1") { return 0; }
---
>     else if (prop == "P1") {
>         return 0;
>     }

boş sonuçlar yerine.

Her iki girişte de bir kod biçimlendiricisinin "filtre" olarak kullanılması bu farklılıkları filtreleyebilir, ancak daha sonra elde edilen çıktının, gerçek metin ve satır numaralarını tutmak için farklılıkların son raporlaması için orijinal girdilere bağlanması gerekir. Yani amaca uygun bir derleyiciye ihtiyaç duyulmadan ulaşılabilir ... Yine de bir şey olup olmadığını bilmiyorum.

Hedefe ulaşılabilir diffmi? Aksi takdirde, bir alternatif var mı (tercihen komut satırı için)?

Yanıtlar:


6

Kullanabilirsiniz dwdiff. Gönderen man dwdiff:

dwdiff - sınırlandırılmış bir kelime farkı programı

Program çok zekidir - bakınız dwdiff --help:

$ dwdiff --help
Usage: dwdiff [OPTIONS] <OLD FILE> <NEW FILE>
-h, --help                             Print this help message
-v, --version                          Print version and copyright information
-d <delim>, --delimiters=<delim>       Specify delimiters
-P, --punctuation                      Use punctuation characters as delimiters
-W <ws>, --white-space=<ws>            Specify whitespace characters
-u, --diff-input                       Read the input as the output from diff
-S[<marker>], --paragraph-separator[=<marker>]  Show inserted or deleted blocks
                               of empty lines, optionally overriding the marker
-1, --no-deleted                       Do not print deleted words
-2, --no-inserted                      Do not print inserted words
-3, --no-common                        Do not print common words
-L[<width>], --line-numbers[<width>]   Prepend line numbers
-C<num>, --context=<num>               Show <num> lines of context
-s, --statistics                       Print statistics when done
--wdiff-output                         Produce wdiff compatible output
-i, --ignore-case                      Ignore differences in case
-I, --ignore-formatting                Ignore formatting differences
-m <num>, --match-context=<num>        Use <num> words of context for matching
--aggregate-changes                    Allow close changes to aggregate
-A <alg>, --algorithm=<alg>            Choose algorithm: best, normal, fast
-c[<spec>], --color[=<spec>]           Color mode
-l, --less-mode                        As -p but also overstrike whitespace
-p, --printer                          Use overstriking and bold text
-w <string>, --start-delete=<string>   String to mark begin of deleted text
-x <string>, --stop-delete=<string>    String to mark end of deleted text
-y <string>, --start-insert=<string>   String to mark begin of inserted text
-z <string>, --stop-insert=<string>    String to mark end of inserted text
-R, --repeat-markers                   Repeat markers at newlines
--profile=<name>                       Use profile <name>
--no-profile                           Disable profile reading

Şunlarla test edin:

cat << EOF > test_diff1.txt
    else if (prop == "P1") { return 0; }
EOF

cat << EOF > test_diff2.txt
    else if (prop == "P1") {
        return 0;
    }
EOF

Ardından karşılaştırmayı başlatın:

$ dwdiff test_diff1.txt test_diff2.txt --statistics
    else if (prop == "P1") {
        return 0;
    }
old: 9 words  9 100% common  0 0% deleted  0 0% changed
new: 9 words  9 100% common  0 0% inserted  0 0% changed

Lütfen 100% commonyukarıda not edin .


1

Bunun diff'in yapabileceği bir şey olduğundan şüpheliyim. Bir satırda alan değişiklikleri varsa, o zaman çalışır (veya kompare gibi diğer benzer programlar). Daha da kötüsü, sekme karakterleri vb. Arama ve değiştirme ve daraltma işlemleri yapabilirsiniz. Ancak bir satırın ötesinde boşluk değişikliği istedikleriniz ...

C ++ dilini anlayan bir programa ihtiyacınız olacaktır. Tüm diller farklıdır ve özellikle Python'un kod bloklarını tanımlamak için boşluk kullandığını unutmayın. Bu nedenle, herhangi bir genel diff benzeri programın "herhangi" (veya belirli) bir programlama dili ile çalışacağından şüpheliyim.

Bir tür ayrıştırıcının iki kaynak dosyadan geçip bu ayrıştırıcının çıktılarını karşılaştırmasını düşünebilirsiniz.

Bu benim arka planımın ötesinde, ama Lex ve Yacc'a bakmanızı öneririm . Bunlar Wikipedia sayfaları; kısa bir açıklama ve örnek veren bu sayfaya bir göz atmak isteyebilirsiniz .


Özellikle C ++ anlayan bir şeye ihtiyacım olduğunu sanmıyorum (en azından satırsonu nedeniyle farklılıkları görmezden gelmek için), kaynakları derlememe gerek yok. Dilden bağımsız olarak sadece uygun şekilde farklı olması gerekir. Aslında dwdiff'i gösteren başka bir cevap daha var. Hala test etmek zorunda, ancak sağlanan örnek ikna edici görünüyor.
sancho.s ReinstateMonicaCellio

Lex / Yacc kendi başına kaynak kodunu derlemez. Onu jetonlara ayıracaktı. Örneğin, "int foo = 0" ve "int bar = 0" varsa, açıkça foo ve bar iki farklı kelimedir; ancak bir program bağlamında, aslında aynıdırlar. Bunun gibi benzerlikleri yakalamak istiyorsanız, bir tür ayrıştırıcıya ihtiyacınız olabilir. Eğer yapmazsanız, gerçekten, dwdiff önerisi çok iyi bir öneri gibi görünüyor. İyi şanslar!
Ray

0

Benzer durumda, gitkod biçimlendirme agnostik şekilde iki dalı karşılaştırmak gerektiğinde , bunu yaptım:

  1. oluşturulan geçici şubeler:

    $ git co feature-a
    $ git co -b 1
    $ git co feature-b
    $ git co -b 2
    
  2. her iki dalı şu şekilde biçimlendirmiştir clang-format:

    $ git co 1
    $ find . -name '*.cpp' -print0 | parallel -0 -n 1 clang-format -i -style=google
    $ git ci -a -m1 --no-verify
    $ git co 2
    $ find . -name '*.cpp' -print0 | parallel -0 -n 1 clang-format -i -style=google
    $ git ci -a -m2 --no-verify
    
  3. gerçek karşılaştırma yaptı:

    $ git diff -w -b 1 2
    

    ( -w -bher ihtimale karşı boşluk farkını görmezden gelmenizi sağlar).

Sen tercih edebilir uncrustifyüzerinde clang-format( uncrustify'ın mod_full_brace_iftek hat etrafında küme parantezleri ekleme / kaldırma zorlamak için kullanılabilir ifvücut').

Ayrıca, GNU parallelyüklü değilse, kullanın xargs- aynı şeyi yapar, ancak biraz daha uzun.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.