1

I have a huge chunk of C++ code with thousands of lines like this:

   case 14: //OrderSelect
      Execute_OrderSelect();
   break;
   case 15: // OrderGetDouble
      Execute_OrderGetDouble();
   break;
   case 16:   //OrderGetInteger
      Execute_OrderGetInteger();
   break;

My task is to make them look like this:

   case 14: Execute_OrderSelect();     break;   // OrderSelect
   case 15: Execute_OrderGetDouble();  break;   // OrderGetDouble
   case 16: Execute_OrderGetInteger(); break;   // OrderGetInteger

Note, that both the Execute... and comments can be any string.


I suppose that schematically we could write the original like this:

AAA NN BBB
CCC
DDD

and try to turn it into: AAA NN CCC DDD BBB.

I have tried unsuccessfully with all sorts of sed expressions, and the best I could do was the trivial operation of combining the Execute...() with the break;, but was not able to move the comment around. I am thinking I am using the wrong tool for this, and perhaps awk would be a better option or simpler to use?

Here are some awk variables:

FNR    The input record number in the current input file.
FS     The input field separator, a space by default.
NF     The number of fields in the current input record.
NR     The total number of input records seen so far.
OFMT   The output format for numbers, "%.6g", by default.
OFS    The output field separator, a space by default.
ORS    The output record separator, by default a newline.
RS     The input record separator, by default a newline.
RT     The  record terminator. Gawk sets RT to the input 
       text that matched the character or regular expression 
       specified by RS.
RSTART The index of the first character matched by match(); 0 if no match

How can I make my day brighter?


Related Questions:

not2qubit
  • 14,531
  • 8
  • 95
  • 135
  • I would just use a programming/scripting language you're familiar with, such as python, with good regex support and write a quick script to do this. – JoelFan Nov 24 '20 at 22:17
  • Anyone who needs you to tell them what some of the awk variables are won't be able to help you solve your problem. Awk is the right tool for this but even what it can do will be a best-effort and not robust since you'd need a parser for the C language to do this robustly. – Ed Morton Nov 24 '20 at 22:28

1 Answers1

2

Here's the bones, massage to suit;

$ cat tst.awk
/^[[:space:]]*case[[:space:]]/ {
    comment = ""
    if ( match($0,"//") ) {
        comment = substr($0,RSTART)
        $0 = substr($0,1,RSTART-1)
    }

    caseLineNr = 1
}

caseLineNr {
    if ( caseLineNr++ > 1 ) {
        sub(/^[[:space:]]+/,"")
    }
    sub(/[[:space:]]+$/,"")
    printf "%s\t", $0

    if ( /^break[[:space:]]*;/ ) {
        print comment
        caseLineNr = 0
    }
}

$ awk -f tst.awk file
   case 14:     Execute_OrderSelect();  break;  //OrderSelect
   case 15:     Execute_OrderGetDouble();       break;  // OrderGetDouble
   case 16:     Execute_OrderGetInteger();      break;  //OrderGetInteger
Ed Morton
  • 188,023
  • 17
  • 78
  • 185
  • 1
    Wow! How did you do this so quickly!? This worked perfectly for that part of the code, so in order prevent errors due to poor *robustness*, I simply pulled out the whole switch statement and ran the awk script on that, to be sure. There are only 4 switch statement in the whole file, so I suppose one should be able to also use that. I'll have to study this script a bit more. Thank you. – not2qubit Nov 24 '20 at 22:50
  • To extract the *first* switch statement, I used the following: `cat file.cpp | sed -r '1,/switch/d;/\}/,$d'`. – not2qubit Nov 26 '20 at 15:59
  • OK but you don't need to do anything like that. If you only want my code to run between `switch` and `}` statements for a bit of extra security then you could just add something like `/switch/{f=1} /}/{f=0} !f{print; next}` (untested but should be close) to the top of the awk script. If you ask a new question with more code in it about how to isolate a section of that code I'm sure you'll get a good answer. – Ed Morton Nov 26 '20 at 16:19
  • What does the `{f=1}` part do? Adding your line to the top, I noticed that it also meddles with the subsequent `switch` statements. My suspicion is that your awk statement is is over eager for the `}`, also including the very last one. – not2qubit Nov 26 '20 at 18:05
  • Sets a variable named `f` (for `found`) to 1. See https://stackoverflow.com/q/23934486/1745001. – Ed Morton Nov 26 '20 at 20:01