Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Select a block of text with V, press colon and then type:

s/^$/printf("@%d\\n", __LINE__);

To place a line printf on every empty line in the program, to quickly find out where your code crashes on the next run.

Obviates most of my need for external debuggers, and works over serial lines etc where setting up a debugger is going to be a hassle or simply not possible.



This requires that you put have lines between major pieces of codes.

Which I think is a good habit to have anyway. Some people use comments without preceding empty lines (oh why) to delineate code, so they'd have to change the regex a bit to make this work.


This is pretty cool! would you mind sharing the command to remove it too?


  :%s/^printf("@%d\\n", __LINE__);$//


Thank you!


u


Wouldn’t this prevent the code from running? It’s just moved into the string literal.

Would this be better?

s/^$/printf("@%d\\n", __LINE__);@


No, yours replaces empty lines with 'printf("@%d\n", __LINE);@'. The GP replaces empty lines with 'printf("@%d\n", __LINE__);' The replacement doesn't wrap any code. It annotates that certain points in the source have been reached at runtime. Yours wouldn't compile, which seriously limits its usefulness.


Ah, I misinterpreted. The trick only replaces blank lines, I thought it would work on any line because I thought that `@` was a special output token that would cause vim to insert a copy of the matched input. It isn't.


Digging into this a bit, here's the command I thought I wanted:

    :s/.*/printf("& -- %d\\n", __LINE__); &
This only works on lines that don't have string literals and behaves badly on lines that span block boundaries.

I had confused @ and &


Makes sense. I suppose one could also use a debug macro that stringifies the statement to avoid the problems you described. Might be something like:

  #define DEBUG_PRINT(stmt) printf(#stmt“ — %d\n”, __LINE__)
Then your replacement could be something like: s/.*/DEBUG_PRINT(&); &;

Which would print out the statement being executed and the line it is at in the program.

Also you’ll want :%s instead of :s, as the latter will only replace on the line on which the cursor is positioned.

Come to think of it, you’ll probably not want this to happen on lines which are themselves preprocessor directives or those with comments, function signatures, or (exclusively) punctuation like with braces. All this to say, I’m sure it could be done, but it gets into the weeds very quickly.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: