स्रोत कोड फ़ाइलों की तुलना करें, स्वरूपण अंतर (जैसे व्हॉट्सएप, लाइनब्रेक,…) को अनदेखा करना


9

मैं एक ऐसे एप्लिकेशन की तलाश कर रहा हूं जो दो C ++ स्रोतों की तुलना कर सके और कोड-सार्थक अंतरों की खोज कर सके (उन संस्करणों की तुलना करने के लिए जिन्हें अलग-अलग तरीके से पुन: स्वरूपित किया जा सकता है)। बहुत कम से कम, कुछ जो सफेद रिक्त स्थान, टैब रिक्त स्थान और newlines में परिवर्तन की अनदेखी करने की क्षमता है जो स्रोत की कार्यक्षमता को प्रभावित नहीं करते हैं (ध्यान दें कि क्या एक नई पंक्ति को व्हाट्सएप माना जाता है भाषा-निर्भर है , और C और C ++ ऐसा करते हैं )। और, आदर्श रूप से, कुछ ऐसा है जो बिल्कुल सभी कोड-सार्थक अंतरों की पहचान कर सकता है। मैं उबंटू के अधीन हूं।

के अनुसार diff --help | grep ignore, मैंने यथोचित रूप से काम diff -bBwZकरने की उम्मीद की थी (मुझे बाद में निपटा जाने के लिए कुछ गलत नकारात्मक मिलने की उम्मीद थी)। फिर भी, यह नहीं है।

अगर मेरे पास स्निपेट्स के साथ निम्नलिखित फाइलें हैं

test_diff1.txt

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

और test_diff2.txt

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

फिर

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

खाली परिणामों के बजाय।

कोड इनपुट के रूप में दोनों इनपुटों पर "फिल्टर" के रूप में इन अंतरों को फ़िल्टर किया जा सकता है, लेकिन फिर परिणामी आउटपुट को वास्तविक टेक्स्ट और लाइन नंबरों को रखने के लिए मतभेदों की अंतिम रिपोर्टिंग के लिए मूल इनपुट्स से वापस बंधना होगा। तो उद्देश्य एक संकलक की आवश्यकता के बिना ठीक से प्राप्य है ... मुझे नहीं पता कि कुछ उपलब्ध है, हालांकि।

क्या उद्देश्य के साथ प्राप्त किया जा सकता है diff? अन्यथा, क्या कोई विकल्प है (अधिमानतः, कमांड लाइन के लिए)?

जवाबों:


6

आप उपयोग कर सकते हैं dwdiff। से man dwdiff:

dwdiff - एक सीमांकित शब्द भिन्न कार्यक्रम

कार्यक्रम बहुत चालाक है - देखें 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

इसके साथ परीक्षण करें:

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

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

फिर तुलना शुरू करें:

$ 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

कृपया 100% commonऊपर ध्यान दें ।


1

मुझे संदेह है कि यह कुछ ऐसा है जो अलग कर सकता है। यदि एक पंक्ति के भीतर स्थान परिवर्तन होते हैं, तो यह काम करेगा (या अन्य समान प्रोग्राम जैसे कोम्पर)। इससे भी बदतर, आप एक खोज-और-जगह और संक्षिप्त टैब वर्ण इत्यादि कर सकते हैं, लेकिन आप एक पंक्ति से परे व्हाट्सएप परिवर्तन के लिए क्या पूछ रहे हैं ...

आपको एक प्रोग्राम की आवश्यकता होगी जो C ++ भाषा को समझता हो। ध्यान दें कि सभी भाषाएं अलग हैं और पायथन, विशेष रूप से, कोड ब्लॉक को परिभाषित करने के लिए व्हाट्सएप का उपयोग करता है। जैसे, मुझे संदेह है कि कोई भी सामान्य अंतर-जैसे प्रोग्राम "किसी भी" (या विशिष्ट) प्रोग्रामिंग भाषा के साथ काम करेगा।

आप दो स्रोत फ़ाइलों के माध्यम से जाने के लिए किसी प्रकार के पार्सर पर विचार कर सकते हैं और फिर इस पार्सर के आउटपुट की तुलना कर सकते हैं।

यह मेरी पृष्ठभूमि से परे है, लेकिन मेरा सुझाव है कि आप लेक्स और याक को देखें । ये विकिपीडिया पृष्ठ हैं; आप इस पृष्ठ पर एक नज़र डालना चाहते हैं जो संक्षिप्त विवरण और एक उदाहरण देता है।


मुझे नहीं लगता कि मुझे कुछ ऐसी चीज़ों की ज़रूरत है जो विशेष रूप से C ++ को समझती हो (कम से कम नई कहानियों के कारण मतभेदों को अनदेखा करने के लिए), मुझे स्रोतों को संकलित करने की आवश्यकता नहीं है। इसे केवल भाषा की परवाह किए बिना उचित रूप से अलग करने की आवश्यकता है। वहाँ वास्तव में एक और जवाब है जो dwdiff का सुझाव देता है। अभी भी इसका परीक्षण करना है, लेकिन जो उदाहरण दिया गया है वह कायल है।
sancho.s ReinstateMonicaCellio

Lex / Yacc स्रोत कोड को संकलित नहीं करता है, प्रति से। यह इसे टोकन में अलग कर देता। उदाहरण के लिए, यदि आपके पास "int foo = 0" बनाम "int bar = 0" है, तो स्पष्ट रूप से foo और bar दो अलग-अलग शब्द हैं; लेकिन एक कार्यक्रम के संदर्भ में, वे वास्तव में समान हैं। यदि आप इस तरह की समानताओं को पकड़ना चाहते हैं, तो आपको किसी प्रकार के पार्सर की आवश्यकता हो सकती है। यदि आप नहीं करते हैं, तो वास्तव में, dwdiff सुझाव बहुत अच्छा लगता है। सौभाग्य!
रे

0

इसी तरह की स्थिति में, जब मुझे gitकोड-फॉर्मेटिंग एग्नोस्टिक तरीके से दो शाखाओं की तुलना करने की आवश्यकता हुई , तो मैंने ऐसा किया:

  1. बनाई गई अस्थायी शाखाएँ:

    $ git co feature-a
    $ git co -b 1
    $ git co feature-b
    $ git co -b 2
    
  2. दोनों शाखाओं का उपयोग करके स्वरूपित 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. वास्तविक तुलना की:

    $ git diff -w -b 1 2
    

    ( -w -bआपको अंतरिक्ष अंतर को अनदेखा करने की अनुमति देता है, बस मामले में)।

आप पसंद कर सकते हैं uncrustifyसे अधिक clang-format( uncrustifyके mod_full_brace_ifएकल लाइन के आसपास घुंघराले ब्रेसिज़ की प्रविष्टि / हटाने लागू करने के लिए इस्तेमाल किया जा सकता ifशरीर ')।

इसके अलावा, यदि जीएनयू parallelस्थापित नहीं है, तो उपयोग करें xargs- यह वही करता है, लेकिन थोड़ी देर।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.