How to convert a K&R function declaration to an ANSI function declaration automatically?

2.9k Views Asked by At
// K&R syntax
int foo(a, p) 
int a; 
char *p; 
{ 
    return 0; 
}

// ANSI syntax
int foo(int a, char *p) 
{ 
    return 0; 
}

As you see, in K&R style, the types of variables are declared in new lines instead of in the braces. How to convert a K&R function declaration to an ANSI function declaration automatically? Does anybody know such an easy-to-use tool in Linux?

4

There are 4 best solutions below

5
On

You can use cproto or protoize (part of GCC) to generate function prototypes or convert old style (K&R) functions to ANSI format.

1
On

Since You wanna convert a multiline string, you chould consider perl

you have

void old_style( c , a ) char c; int a; { /* some multiline code */ }

and must have

void old_style( char c, int a) {}

So

perl -i.bkp -nle 's/\((void|int|char|float|long) [a-zA-Z0-9_-]*\)([a-zA-Z0-9_-] ?,[a-zA-Z0-9_-] ?)\(.*{\)/\1(\2)/g'

or something like it, would do the trick.

It would be easier to tackle down the correct regex to this if you try it out and post in comments the output of

diff file.c file.c.bkp

for each of your source files.

2
On
  1. if you want to create standard C prototypes for a .h file use mkproto.c

mkproto thisoldfile.c > thisoldfile.h

You then could also paste over the old K&R code in the C file definition if desired.


Another answer by Robert contained the following (useful) information before it was deleted for being a 'link-only' answer:

You can find mkproto.c at:

https://www.pcorner.com/list/C

There are plenty of other utilities there.

The site hosts two versions of "mkproto" — MKPROTO.ZIP dated 1989-09-07 and MKPROTOB.ZIP dated 1992-06-27. You have to register with the host site, The Programmer's Corner, to download the files. The files appear about 2/3 of the way down a long page of possible downloads.

0
On

My gcc installation had neither cproto nor mkproto. But I did have Vim and I figured out a global substitute to do this one parameter at a time...

:%s/^\(\%(\w\+\%(\s*\*\+\s*\|\s\+\)\)\+\)\(\w\+\)\s*(\@=\(.\{-}\)\([(,)]\)\s*\(\w\+\)\s*\([,)].*\)\n\s*\(.\{-}\)\5\([^;]*\);/\1\2\3\4\7\5\8\6/

where the recorded subexpressions are:

  1. the function return type
  2. the function name
  3. the already-prototyped parameters (if any)
  4. the delimiter before the next K&R parameter to fix - '(' or ','
  5. the next K&R parameter to fix
  6. the following delimiter - ',' or ')' followed by any remaining (unprocessed) K&R parameter identifiers and closing ')'
  7. the parameter's type
  8. the parameter's post-identifier characters (e.g., brackets)

Repeat until no more matches in the file. Note, the pattern presumes the K&R function declaration is on one line, followed by individual parameter declarations on successive lines.

Two applications of this substitute successfully processes:

int main(argc,argv)
  int argc;
  char *argv[];
{
  printf("Hello world!\n");
  return 0;
}

into:

int main(int argc,char *argv[])
{
  printf("Hello world!\n");
  return 0;
}