3

I have C function prototypes (certain windows api header files) that look like:

int
foo
(
int
a
,
int
*
b
)
;

(they seem to have no coding convention)

which I am trying to programmatically turn into a one-line prototype of the form (or something close to it):

int foo(int a, int * b);

I have looked into programs like ctags ( ctags multi-line C function prototypes ) and into various settings in uncrustify ( http://uncrustify.sourceforge.net/ ) however I haven't been able to make any headway in either. (any insight would be great, or perhaps one of the 385 uncrustify options that I missed does what I want).

Programmatically, I am trying to look for unique markers that signify a function prototype so that I can write a script that will format the code to my liking.

Without using a lexer and a parser this seems like it could get very convoluted very quickly; any suggestions?

Community
  • 1
  • 1
pseudosudo
  • 1,962
  • 1
  • 19
  • 30

4 Answers4

4

run them through indent -kr or astyle --style=kr

Dave
  • 10,964
  • 3
  • 32
  • 54
  • `indent -kr` is almost exactly what I'm looking for, the only thing it doesn't resolve is bringing up pointers onto the same line – pseudosudo Jul 25 '11 at 21:58
  • `astyle --style=kr` seems to be depricated, ( http://astyle.sourceforge.net/notes.html ) so I used `--style=k/r`. however it only did indentation, no newline changing. – pseudosudo Jul 25 '11 at 21:58
  • Better yet, `man indent` first and see what options are most to your liking :) – Karl Knechtel Jul 26 '11 at 03:13
  • `indent -kr` does not work because it doesn't move the `(` onto the same line as `foo`. – lord_nimon Jul 10 '20 at 20:20
1

Solution using vim?

put marker on int and do 11J

Fredrik Pihl
  • 44,604
  • 7
  • 83
  • 130
1
sed ':a;N;$!ba;s/\n/ /g' prototypes.file  | sed 's/; */;\n/g'

The first command - before the pipe - will replace all new-lines to spaces, and the next will put a new-line back after every semicolon.

Of course this will only work if there are nothing else but these prototypes in the file. If there are some other stuff that you want to keep as they are, you can use vim's visual selection and two substitution commands:

Select the region you want to join, than

:s/\n/ /

Select the joined line and

:s/; */;\r/g
beemtee
  • 831
  • 1
  • 8
  • 10
0

Another solution using vi:

do a regex search removing all newlines. Then take the resulting mess and do another regex search replacing each ; with ; \n\n. That should leave you with a list of prototypes with a line skipped between each one. Since we're marking the ends of the prototypes instead of the beginnings and all prototypes end the same way, we don't have to worry about not recognizing special cases.

Isaac
  • 625
  • 1
  • 12
  • 30