0

I have a file with function prototypes like this:

int func1(type1 arg, int x);

type2 funct2(int z, char* buffer);

I want to create a script (bash, sed, awk, whatever) that will print

function = func1 // first argument type = type1// second argument type = int
function = func1 // first argument type = int// second argument type = char*

In other words, tokenize every line and print the function names and arguments. Additionally I would like to hold these tokens as variables to print them later, eg echo $4.

thkala
  • 84,049
  • 23
  • 157
  • 201
cateof
  • 789
  • 3
  • 11
  • 24

2 Answers2

1

An alternative approach would be to compile with "-g" and read the debug information.
This answer may help you read the debug information and figure out function parameters (it's Python, not bash, but I'd recommend using Python or Perl instead of bash anyway).

The resulting solution would be much more robust than anything based on text parsing. It will deal with all the different ways in which a function might be defined, and even with crazy things like functions defined in macros.

To convince you better (or help you get it right if you're not convinced), here's a list of test cases that may break your parsing:

// Many lines
const
char
*

f
(
int
x
)
{
}

// Count parenthesis!
void f(void (*f)(void *f)) {}

// Old style
void f(a, b)
int a;
char *b
{
}

// Not a function
int f=sizeof(int);

// Nesting
int f() {
    int g() { return 1; }
    return g();
}

// Just one
void f(int x /*, int y */) { }

// what if?
void (int x
#ifdef ALSO_Y
     , int y
#endif
) { }

// A function called __attribute__?
static int __attribute__((always_inline)) f(int x) {}
Community
  • 1
  • 1
ugoren
  • 16,023
  • 3
  • 35
  • 65
0

here's a start.

#!/bin/bash
#bash 3.2+
while read -r line
do
  line="${line#* }"
  [[ $line =~ "^(.*)\((.*)\)" ]]
  echo  "function: ${BASH_REMATCH[1]}"
  echo  "args: ${BASH_REMATCH[2]}"
  ARGS=${BASH_REMATCH[2]}
  FUNCTION=${BASH_REMATCH[1]}
  # break down the arguments further.
  set -- $ARGS
  echo "first arg type:$1 , second arg type: $2"
done <"file"

output

$ ./shell.sh
function: func1
args: type1 arg, int x
first arg type:type1 , second arg type: arg,
function: funct2
args: int z, char* buffer
first arg type:int , second arg type: z,
ghostdog74
  • 327,991
  • 56
  • 259
  • 343
  • how can I store the backreference in sed? eg echo "abcd" | sed 's/ab\(.*\)/\1/' this prints "cd". How can I store cd in a variable? – cateof Jul 27 '10 at 09:45
  • `var=$(echo "abcd" | sed 's/ab(.*)/\1/')` – ghostdog74 Jul 27 '10 at 09:51
  • almost there. I have the line "int func(struct type1* tp, TYPE1 *name, TYPE2 *name2);". I want to store in a variable the TYPE1 and TYPE2 and print them later – cateof Jul 27 '10 at 10:13