Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

Part of the QA steps required for a project I am tangentially involved with require the person who is responsible to integrate new version of source file to first calculate how many lines have been added, removed and "changed". Changes may include physically move a whole function or procedure around the source file (without altering the content, just reorganization) and this is counted as "no change" while actually altering a line, say from

a=b;

to

a=b--;

Of course the matching should not include extra spaces or comments.

The question is: can you point to something (I suppose a Perl script would be enough as a starter) that given two version of a file can:

Remove comments Count added, removed and "modified" lines, giving the three results, and not counting whole functions/procedures which have been moved up or down in the file without altering the workings?

Language is C/C++.

At the moment this is done by diff-ing the two source files and manually counting the lines. The result needs not to be precise to the line - basically if you get over a certain quota of "significant changes" the source goes through a more complicated integration/testing phase, so as long as the results are close enough to actual changes it's ok, in case of "too many changes" it will be reviewed by a human anyway.

share|improve this question
1  
isn't a=b; and a=b--; if for instance - is overloaded. What i could imagine is in net this working by comparing if the 2 lines compile to the same clr –  Andrey Aug 20 '12 at 2:45
    
Language is "C/C++", not C#, therefore at best you have to take some guesses on a purely static basis –  p.marino Aug 20 '12 at 7:11
4  
Personally, I do not believe you the concept of an insignificant change helps, and all changes should be reviewed. So I'd suggest you fix the process not the tools ;) –  jk. Aug 20 '12 at 8:20
2  
The main reason why you'd want such a tool is when the review process has excessive overhead. You should be able to review three lines of code in less than a minute. Literally, 60 seconds. If you can't, fix the tooling instead of excluding code from review. That will benefit all reviews, not just the small ones. –  MSalters Aug 20 '12 at 9:56
    
If you are reviewing "3 lines of code in 60 seconds" - It's so superficial you might as well dump the review process altogether. –  mattnz Aug 24 '12 at 7:34
add comment

4 Answers

up vote 3 down vote accepted

Scooter Software do a great tool - Beyond Compare. that is language aware and can filter unimportant changes. However it is commercial and GUI - so may not be able to do what you ask. They have a full function eval period and it's not expensive if you want to check it out.

Beyond that, one of the rules of software development in an environment such as yours is (I will get slaughtered here for saying, but please here me out.) "If it ain't broke don't fix it". In your case, QA needs to carefully define "broken" for you work place. Why are people changing white space? Did that routine really need to be moved? Did the "a=a+1;" really need to be re-factored to "a++;" Software engineering (where you have a QA process) is no longer an individual choice.

As far as your QA rules go, I would suggest any change to source code is a change that needs measuring. You need to do measure "trivial", "meaningless" and "unimportant" changes - these are costing money - is it needlessly, as if so its wasted effort. If it's adding value, why is the tool not reporting it- either way it's a QA function to know this - the tool should report it. If you are ignoring these changes, you are not really doing QA.

You won't be able to automate it either - For instance, no tool can tell you if a comment change was needed or not - only a person can read a comment and check it's validity, what about code formatting, or variable naming (e.g. This change makes it more readable). Its all very subjective.......

share|improve this answer
    
I am not disagreeing, but please understand that what I am looking for is not a replacement for the rest of the current QA process (which is way stricter than what I described). I am just trying to partially automate something that is done manually and is not very precise anyway, at the moment. (i.e.: run "diff" and tell us if, in your opinion, there were more than X lines of meaningful changes). –  p.marino Aug 20 '12 at 9:08
    
+1 Beyond Compare is great. They lost the plot a bit with V3 though –  James Aug 20 '12 at 14:48
    
@p.mariio: In that case, take the time to investigate Beyond Compare (There are others that are probably just as good - it's just I know and use BCompare daily.). –  mattnz Aug 20 '12 at 21:35
add comment

If simple diff tools (and more advanced diff tools like Beyond Compare) won't meet your needs, then you can try a syntax/semantic-aware diff program like Semantic Designs' C++ Smart Differencer. It provides sample output such as the following (recognizing variable renames and recognizing moved code; the full example explains how it also automatically ignores changes to comments, formatting, and what format constants are given in):

Rename 68.42-104.10 to 62.42-98.10 with 'xtemp'->'x2'
Rename 161.1-194.1 to 155.1-188.1 with 'Vx'~>'U'
Delete 282.1-289.1 moving 282.1-289.1 to 429.1-436.1
<void DST(const ColumnVector& U, ColumnVector& V)
<{
<   // Discrete sine transform, type I
<   Tracer trace("DST");
<   REPORT
<   DST_inverse(U, V);
<   V *= (V.Nrows()-1)/2;
<}
Insert 429.1-436.1 moving 282.1-289.1 to 429.1-436.1
>void DST(const ColumnVector& U, ColumnVector& V)
>{
>   // Discrete sine transform, type I
>   Tracer trace("DST");
>   REPORT
>   DST_inverse(U, V);
>   V *= (V.Nrows()-1)/2;
>}
share|improve this answer
    
Thanks. I did check SmartDifferencer (while waiting for other answers to come in) and it would probably be the best choice in terms of functionality. Price is a bit steep and you would probably need two instances (one for C and one for C++) but it looks like the best fit, so far. –  p.marino Aug 20 '12 at 12:53
    
@p.marino - The semantic differences between C and C++ may be small enough (i.e., a lot of valid C code is also valid C++ code) that you could get by with only buying the C++ one. (I haven't used Smart Differencer myself, so I'm not certain.) –  Josh Kelley Aug 20 '12 at 13:00
add comment

Removing comments is not too difficult. Trivially, this can be done by running the program through the c preprocessor (though that brings everything else into the code).

A bit of code can be found for this in the perl FAQ (which just does not jump to where I want it to go to).

Identifying moved lines and recognizing if they should be a "no change" or a "change" is a very difficult problem, and even more so when one considers the structure of the lines that can be moved.

Consider

if(x == 2) { x = 3; }
if(x == 3) { x = 4; }

Swapping the location of the above two lines blocks within a method is a change and would need to be recognized as such.

While swapping the following two two methods might not (or might be depending on the specifics of the language) be a change

int foo() { doStuff(); return 42; }
int bar() { doStuff(); return 24; }

However (if you will pardon my java)

class Foo {
    int foo() { doStuff(); return 42; }
    int bar() { doStuff(); return 24; }
    private class Inner {
    }
}

changed to

class Foo {
    int foo() { doStuff(); return 42; }
    private class Inner {
        int bar() { doStuff(); return 24; }
    }
}

is a significant change and should be flagged as changed code.

The identification of the "not a change" part is very non-trivial and requires a deeper understanding of the code than any diff program I am aware of has.

share|improve this answer
    
Also, depending on language, reordering two identically named functions within the same scope is a significant change too. –  detly Aug 20 '12 at 3:25
    
I agree that the comment removing is trivial (I did something like this myself in PERL in the past). Regarding code swapping I intend a whole method/function/procedure being moved around. Of course reordering single lines has to be considered as a change. –  p.marino Aug 20 '12 at 7:16
    
-1 Rearranging foo() and bar() if they're virtual is a MASSIVE change –  James Aug 20 '12 at 14:49
    
@James I'm not that much of a C++ guy, I've changed the wording to 'might' with some qualifiers. –  MichaelT Aug 20 '12 at 16:56
add comment

Rather than using a fancy diff, use your approved linecounter tool, do before-and-after line counts, and punch keys on your calculator. Your configuration management system can supply the "before" code to do the "before" count. (If you aren't using a configuration management system to keep your source code under control, you have far bigger problems than getting line change counts for QA.)

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.