0

(I have legacy C+ code that compiles with warnings with gcc and fails with errors with clang. The method signatures are either function(int,(char*),(char*)) or function(int,string,string). This method is used a lot throughout the code.)

So in trying to normalize the calls i'm giving it a go with sed. Assuming this input:

function(DEFINED_VAR, (char*)someMethod(OTHER_VAR).c_str() + more->stuff, (char*)"Class::method42()");   // 1
function(DEFINED_VAR,(char*)someMethod(OTHER_VAR).c_str() + more->stuff, (char*)"Class::method42()");    // 2
function(DEFINED_VAR, (char *)someMethod(OTHER_VAR).c_str() + more->stuff, "Class::method42()");         // 3
function(DEFINED_VAR, (char*) someMethod(OTHER_VAR).c_str() + more->stuff, "Class::method42()");         // 4
function(DEFINED_VAR, (char *)someMethod(OTHER_VAR).c_str() + more->stuff, (char*)"Class::method42()");  // 5
function(DEFINED_VAR, (char*)someMethod(OTHER_VAR).c_str() + more->stuff, (char*)"Class::method42()");   // 6
function(DEFINED_VAR, (char*)someMethod(OTHER_VAR).c_str() + more->stuff, (char *)"Class::method42()");  // 7
function(DEFINED_VAR, (char*)someMethod(OTHER_VAR).c_str() + more->stuff, ( char* )"Class::method42()"); // 8
function(DEFINED_VAR, (char*)someMethod(OTHER_VAR).c_str() + more->stuff, "Class::method42()");          // 9
function(DEFINED_VAR, (char*)someMethod(OTHER_VAR).c_str() + more->stuff, (char*)"Class::method42()");   // 10
function(DEFINED_VAR, ( char* )someMethod(OTHER_VAR).c_str() + more->stuff, "Class::method42()");        // 11
function(DEFINED_VAR, (char*)someMethod(OTHER_VAR).c_str() + more->stuff, (char*)"Class::method42()");   // 12

I want lines 3, 4, 9 and 11 to end with (char*)"whateverstring");

What i've tried so far:

sed -n '/^\s*function\s*(\s*\w.*,\s*(\s*char\s*\*.*,\s*\([^(]\|$\)/p' inputfile.cpp

but i can't quite exclude the second "(char*)" occurrence to skip the correct lines.

1831722 and 1831722 are close (i prefer the former) but the ( is eluding me.

What am i missing? I'm using GNU sed on Ubuntu Xenial. I'm cool with awk (but i don't think it allows for capturing pattern matches) or perl, if whatever is needed here isn't easy.

The VARs and "string" may vary and i'm already accounting for spaces.

vesperto
  • 804
  • 1
  • 6
  • 26

1 Answers1

2

Using address range, you could apply substitution on lines not matching two consecutive (char *\*):

sed '/\(char *\*\).*\(char *\*\)/!s/\("[^"]*");\)/(char*)&/' inputfile.cpp

Edit:

To make sure substitutions apply only on function definitions, just change the substitution pattern:

sed '/\(char *\*\).*\(char *\*\)/!s/\(^ *function.*\)\("[^"]*");\)/\1(char*)\2/' inputfile.cpp
SLePort
  • 15,211
  • 3
  • 34
  • 44
  • I'll have to look into that `s//!s///` syntax but it seems as though that would match *any* like with "char *" occurrences, not just these specific lines. – vesperto Dec 13 '20 at 13:54