0

Is there a quick and easy way to comment out multi lined print statements? Something like this? I have a ton of printf statements that I use for debugging that are spread out across my program. I would like to comment out every printf() except the ones that contain "ACCEPT" or "Reject". I have several hundred of them but they are scattered between important code so I can't use block comments.

                   lower_bound_of_big_boy_counter++;
                    printf("3387 strings_line_tokens[lower_bound_of_big_boy_counter] %s \n", 
                    strings_line_tokens[lower_bound_of_big_boy_counter]);
                    printf("3389 lower_bound_of_big_boy_counter %d \n", lower_bound_of_big_boy_counter);
                }
                strcpy(array_id1, strings_line_tokens[lower_bound_of_big_boy_counter]);
                integer_match_flag = 0; 
                float_match_flag = 0;
            }
        }
        if(keywords_match_flag1 != 1)
        {
            lower_bound_of_big_boy_counter++;
        }
        cmp_str9 = strcmp("return", strings_line_tokens[lower_bound_of_big_boy_counter ]);
        printf("4006 lower_bound_of_big_boy_counter %d \n", lower_bound_of_big_boy_counter);
        printf("4007 strings_line_tokens[lower_bound_of_big_boy_counter] %s \n", 
        strings_line_tokens[lower_bound_of_big_boy_counter]);
        //int
        if(cmp_str9 == 0)
        {
            printf("3402 checking return stuff \n");
            return_match_flag = 1;
            lower_bound_of_big_boy_counter++;
            get_function_type_for_proper_return(symbol_table_functions, type,id, 
                                     scope_char, symbol_table_functions_counter, function_type_for_proper_return);
            printf("3407 lower_bound_of_big_boy_counter %d \n", lower_bound_of_big_boy_counter);
            printf("3408 strings_line_tokens[lower_bound_of_big_boy_counter] %s \n", 
            strings_line_tokens[lower_bound_of_big_boy_counter]);
            printf("3410 function_type_for_proper_return %s \n", function_type_for_proper_return);
rockstar797
  • 137
  • 1
  • 2
  • 11
  • 3
    Maybe you should use a different function name (or a macro name) in future — so that you have `#define DEBUG_PRINT(...) printf(__VA_ARGS__)` etc. See [C `#define` macro for debug printing](https://stackoverflow.com/questions/1644868/c-define-macro-for-debug-printing/1644898#1644898) and related posts for more complex ways to do that. Which editor do you use? How many files like this do you have to process? – Jonathan Leffler Apr 10 '16 at 03:29
  • You really need to show some example `printf()` statements that should be retained. AFAICS, all the examples in your code fragment should be commented out. But it would help to have some examples that should be kept too — it is easy enough to comment out every `printf()` statement (a little bit of not-quite-elementary `sed` will do that: `sed -e '/printf(.*);/ { s%^%//%; n; }' -e '/printf(/,/);/ s%^%//%' `). But preserving the 'ACCEPT' and 'Reject' lines makes it harder. – Jonathan Leffler Apr 10 '16 at 03:36
  • @JonathanLeffler I have one file with 5k lines of code. I have lots of functions not crazy enough to do everything in main. I use notepad ++ in windows and vim in linux/unix. Do you have any favorite text editors? Ok I can always uncomment them. I have like 10 lines i want to keep and hundreds of lines I want to comment out. – rockstar797 Apr 10 '16 at 04:12
  • 1
    I use `vim`, usually even when I work on Windows (which is rather seldom). The `sed` script I showed will do a decent job on commenting all the `printf()` lines — even multi-line ones — out. It can be confused, but you probably won't confuse it. If you had `);` inside a string on the second or subsequent line of a `printf()`, but that wasn't the last line, the script would stop commenting lines too soon. But that's pretty implausible. – Jonathan Leffler Apr 10 '16 at 04:15

4 Answers4

2

Since your base code is C and the printf statements are [obviously] for debug, please allow me to suggest an alternative approach.

Change the printf used for debug into (e.g.) DEBUGPRINTF. This is a CPP macro that can be compiled to something with a compiler command line option like -DDEBUG. See my recent answer here: Why doesn't my simple C macro work? for a more formal description.

Side note: I wrote this current answer before noticing Jonathan's comment about doing it in a similar way.

Thus, you only need to do the change once and can turn debug printing on and off at the flip of a compile option. I've been using this technique for decades and it's served me quite well.

Note: You'll still need to do the global edit once to get this.

Here's a perl script that will do that (invoke via ./script < input > output):

#!/usr/bin/perl
# convert debug printf's

master(@ARGV);
exit(0);

# master -- master control
sub master
{

    while ($bf = <STDIN>) {
        chomp($bf);

        if ($bf =~ /^\s*printf[(]/) {
            doprintf($bf);
            next
        }

        print($bf,"\n");
    }
}

# doprintf -- process printf
sub doprintf
{
    my($bf) = @_;
    my($allowflg);

    $allowflg = ($bf =~ /ACCEPT|Reject/);
    unless ($allowflg) {
        $bf =~ s/printf/DEBUGPRINTF/;
    }

    print($bf,"\n");

    while (1) {
        last if ($bf =~ /;\s*$/);

        $bf = <STDIN>;
        last unless (defined($bf));
        chomp($bf);

        print($bf,"\n");
    }
}
Craig Estey
  • 30,627
  • 4
  • 24
  • 48
  • Maybe `$bf =~ /^\s*printf\s*[(]/` for the nuts that put a space before the opening paren? – David C. Rankin Apr 10 '16 at 17:36
  • @DavidC.Rankin Yes, IIRC, that's the "GNU" coding style, which I personally despise. My coding style, developed over many years, looks remarkably like the linux kernel style in `Documentation/CodingStyle`. From that: _"First off, I'd suggest printing out a copy of the GNU coding standards, and NOT read it. Burn them, it's a great symbolic gesture."_ – Craig Estey Apr 10 '16 at 19:38
1

A multiline solution with GNU sed :

sed '/ACCEPT\|Reject/!{/^[\t ]*printf(/{:a;s/^/\/\/ &/;/;/!{n;Ta}}}' file.c

Exluding all lines containing ACCEPT or Reject, it comments out all lines starting with printf and ending with ;.

If no ending ; is found on the printf line, it loops over and comments out subsequent lines until a ; is found.

SLePort
  • 15,211
  • 3
  • 34
  • 44
0

Quick, simple, effective, over-enthusiastic

It is fairly simple to comment out all the printf() lines in a file with sed, even multi-line ones, if you use:

sed -e '/printf(.*);/ { s%^%//%; n; }' -e '/printf(/,/);/ s%^%//%'

On the sample lines, this yields:

                   lower_bound_of_big_boy_counter++;
//                    printf("3387 strings_line_tokens[lower_bound_of_big_boy_counter] %s \n", 
//                    strings_line_tokens[lower_bound_of_big_boy_counter]);
//                    printf("3389 lower_bound_of_big_boy_counter %d \n", lower_bound_of_big_boy_counter);
                }
                strcpy(array_id1, strings_line_tokens[lower_bound_of_big_boy_counter]);
                integer_match_flag = 0; 
                float_match_flag = 0;
            }
        }
        if(keywords_match_flag1 != 1)
        {
            lower_bound_of_big_boy_counter++;
        }
        cmp_str9 = strcmp("return", strings_line_tokens[lower_bound_of_big_boy_counter ]);
//        printf("4006 lower_bound_of_big_boy_counter %d \n", lower_bound_of_big_boy_counter);
//        printf("4007 strings_line_tokens[lower_bound_of_big_boy_counter] %s \n", 
//        strings_line_tokens[lower_bound_of_big_boy_counter]);
        //int
        if(cmp_str9 == 0)
        {
//            printf("3402 checking return stuff \n");
            return_match_flag = 1;
            lower_bound_of_big_boy_counter++;
            get_function_type_for_proper_return(symbol_table_functions, type,id, 
                                     scope_char, symbol_table_functions_counter, function_type_for_proper_return);
//            printf("3407 lower_bound_of_big_boy_counter %d \n", lower_bound_of_big_boy_counter);
//            printf("3408 strings_line_tokens[lower_bound_of_big_boy_counter] %s \n", 
//            strings_line_tokens[lower_bound_of_big_boy_counter]);
//            printf("3410 function_type_for_proper_return %s \n", function_type_for_proper_return);

However, if any of the printf() statements contained ACCEPT or Reject, those lines would be commented out too. Given that you have hundreds of lines that should be commented out and a few (order of ten) that should not be commented, it is probably easiest to undo the incorrectly commented out lines.

Refined, complex, effective

I got an alternative working, and it handles printf statements with ACCEPT and Reject in the first line correctly. It won't spot those words in the second or subsequent lines of a printf statement.

${SED:-sed} \
    -e '/printf(.*ACCEPT.*);/ b' \
    -e '/printf(.*Reject.*);/ b' \
    -e '/printf(.*);/ { s%^%//%; b
        }' \
    -e '/printf(.*ACCEPT/, /);/ b' \
    -e '/printf(.*Reject/, /);/ b' \
    -e '/printf(/, /);/ s%^%//%' \
    frag.c

The odd newline is need to placate BSD (Mac OS X) sed.

Input:

                   lower_bound_of_big_boy_counter++;
                    printf("3387 strings_line_tokens[lower_bound_of_big_boy_counter] %s\n", 
                    strings_line_tokens[lower_bound_of_big_boy_counter]);
                    printf("3389 lower_bound_of_big_boy_counter %d\n", lower_bound_of_big_boy_counter);
                }
                strcpy(array_id1, strings_line_tokens[lower_bound_of_big_boy_counter]);
                integer_match_flag = 0; 
                float_match_flag = 0;
            }
        }
        if(keywords_match_flag1 != 1)
        {
            lower_bound_of_big_boy_counter++;
        }
        cmp_str9 = strcmp("return", strings_line_tokens[lower_bound_of_big_boy_counter ]);

        printf("4006 lower_bound_of_big_boy_counter %d\n", lower_bound_of_big_boy_counter);
        wimbol();
        printf("ACCEPT: lower_bound_of_big_boy_counter %d\n", lower_bound_of_big_boy_counter);
        wimbol();
printf("Testing ACCEPT %d\n", lower_bound_of_big_boy_counter);
        wimbol();
        printf("Reject: lower_bound_of_big_boy_counter %d\n", lower_bound_of_big_boy_counter);
        wimbol();
        printf("4007 strings_line_tokens[lower_bound_of_big_boy_counter] %s\n", 
                strings_line_tokens[lower_bound_of_big_boy_counter]);
        wimbol();
        printf("Reject: strings_line_tokens[lower_bound_of_big_boy_counter] %s\n", 
                strings_line_tokens[lower_bound_of_big_boy_counter]);
        wimbol();
        printf("ACCEPT: strings_line_tokens[lower_bound_of_big_boy_counter] %s\n", 
                strings_line_tokens[lower_bound_of_big_boy_counter]);
        wimbol();

        printf("4006 lower_bound_of_big_boy_counter %d\n", lower_bound_of_big_boy_counter);
        printf("ACCEPT: lower_bound_of_big_boy_counter %d\n", lower_bound_of_big_boy_counter);
printf("Testing ACCEPT %d\n", lower_bound_of_big_boy_counter);
        printf("Reject: lower_bound_of_big_boy_counter %d\n", lower_bound_of_big_boy_counter);
        printf("4007 strings_line_tokens[lower_bound_of_big_boy_counter] %s\n", 
                strings_line_tokens[lower_bound_of_big_boy_counter]);
        printf("Reject: strings_line_tokens[lower_bound_of_big_boy_counter] %s\n", 
                strings_line_tokens[lower_bound_of_big_boy_counter]);
        printf("ACCEPT: strings_line_tokens[lower_bound_of_big_boy_counter] %s\n", 
                strings_line_tokens[lower_bound_of_big_boy_counter]);

        //int
        if(cmp_str9 == 0)
        {
            printf("3402 checking return stuff\n");
            return_match_flag = 1;
            lower_bound_of_big_boy_counter++;
            get_function_type_for_proper_return(symbol_table_functions, type,id, 
                                     scope_char, symbol_table_functions_counter, function_type_for_proper_return);
            printf("3407 lower_bound_of_big_boy_counter %d\n", lower_bound_of_big_boy_counter);
            printf("3408 strings_line_tokens[lower_bound_of_big_boy_counter] %s\n", 
            strings_line_tokens[lower_bound_of_big_boy_counter]);
            printf("3410 function_type_for_proper_return %s\n", function_type_for_proper_return);

Output:

                   lower_bound_of_big_boy_counter++;
//                    printf("3387 strings_line_tokens[lower_bound_of_big_boy_counter] %s\n", 
//                    strings_line_tokens[lower_bound_of_big_boy_counter]);
//                    printf("3389 lower_bound_of_big_boy_counter %d\n", lower_bound_of_big_boy_counter);
                }
                strcpy(array_id1, strings_line_tokens[lower_bound_of_big_boy_counter]);
                integer_match_flag = 0; 
                float_match_flag = 0;
            }
        }
        if(keywords_match_flag1 != 1)
        {
            lower_bound_of_big_boy_counter++;
        }
        cmp_str9 = strcmp("return", strings_line_tokens[lower_bound_of_big_boy_counter ]);

//        printf("4006 lower_bound_of_big_boy_counter %d\n", lower_bound_of_big_boy_counter);
        wimbol();
        printf("ACCEPT: lower_bound_of_big_boy_counter %d\n", lower_bound_of_big_boy_counter);
        wimbol();
printf("Testing ACCEPT %d\n", lower_bound_of_big_boy_counter);
        wimbol();
        printf("Reject: lower_bound_of_big_boy_counter %d\n", lower_bound_of_big_boy_counter);
        wimbol();
//        printf("4007 strings_line_tokens[lower_bound_of_big_boy_counter] %s\n", 
//                strings_line_tokens[lower_bound_of_big_boy_counter]);
        wimbol();
        printf("Reject: strings_line_tokens[lower_bound_of_big_boy_counter] %s\n", 
                strings_line_tokens[lower_bound_of_big_boy_counter]);
        wimbol();
        printf("ACCEPT: strings_line_tokens[lower_bound_of_big_boy_counter] %s\n", 
                strings_line_tokens[lower_bound_of_big_boy_counter]);
        wimbol();

//        printf("4006 lower_bound_of_big_boy_counter %d\n", lower_bound_of_big_boy_counter);
        printf("ACCEPT: lower_bound_of_big_boy_counter %d\n", lower_bound_of_big_boy_counter);
printf("Testing ACCEPT %d\n", lower_bound_of_big_boy_counter);
        printf("Reject: lower_bound_of_big_boy_counter %d\n", lower_bound_of_big_boy_counter);
//        printf("4007 strings_line_tokens[lower_bound_of_big_boy_counter] %s\n", 
//                strings_line_tokens[lower_bound_of_big_boy_counter]);
        printf("Reject: strings_line_tokens[lower_bound_of_big_boy_counter] %s\n", 
                strings_line_tokens[lower_bound_of_big_boy_counter]);
        printf("ACCEPT: strings_line_tokens[lower_bound_of_big_boy_counter] %s\n", 
                strings_line_tokens[lower_bound_of_big_boy_counter]);

        //int
        if(cmp_str9 == 0)
        {
//            printf("3402 checking return stuff\n");
            return_match_flag = 1;
            lower_bound_of_big_boy_counter++;
            get_function_type_for_proper_return(symbol_table_functions, type,id, 
                                     scope_char, symbol_table_functions_counter, function_type_for_proper_return);
//            printf("3407 lower_bound_of_big_boy_counter %d\n", lower_bound_of_big_boy_counter);
//            printf("3408 strings_line_tokens[lower_bound_of_big_boy_counter] %s\n", 
//            strings_line_tokens[lower_bound_of_big_boy_counter]);
//            printf("3410 function_type_for_proper_return %s\n", function_type_for_proper_return);

I was previously having some issues; I am kicking myself for some of them (sequencing — it is crucial to deal with all the single-line printf() statements before starting on the multi-line ones). There's a more subtle difference between b (jump to end of script) and n (read next line), which is also crucial.

I'm testing with BSD sed on Mac OS X 10.11.4, JFTR. GNU sed doesn't require the extra newline in the script.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
0

using sed is a oneway conversion and requires a separate step before compiling.

A much better method is:

when debugging use the compiler parameter:

-DDEBUG=1 

when not debugging use the compiler parameter:

-DDEBUG=0 

Then, in the code use:

if( DEBUG )
{
     // your debugging printf()
    printf( ,,,, );
}

Then when the code must be certified, for instance to RTCA DO-178B there is no difference in the source code between the tested code and the released code.

user3629249
  • 16,402
  • 1
  • 16
  • 17