If you are conforming to style(6), awk can generate stub functions quite easily.

        # turns lines of the form
        #               valid type name
        #               name ( argument-list )
        # into
        #               valid type name
        #               stub_ ## name ( argument-list )
        #               {
        #                       [return] name ( argument-list );
        #               }
        # and skips other lines
        
        NF == 0 { next } # skip blank lines
        /^[^A-Za-z_]/ { next } # skip lines that begin badly
        /[;{}]/ { next } # skip declarations or blocks
        
        {
                typename = $0
                getline
                if (NF == 0) {
print "bad function line" | "cat 1>&2" # awk is ape, use sh syntax, not rc
                        next
                }
                print typename # print type name
                $0 = "stub_" $0
                fname = $0
                print
                print "{"
                n = split(fname, fields, "[(),]+")
                printf "\t%s%s(", (typename != "void" ? "return " : ""), 
fields[1]
                for (i = 2; i < n; i++) {
                        # drop non-alphanumeric characters
                        m = split(fields[i], arg, "[^A-Za-z0-9_]+")
                        printf "%s%s", arg[m], (i == n - 1 ? ");" : ",")
                        delete arg # deletes whole array - added to one true 
awk after book
                }
                delete fields
                printf "\n}\n"
        }


This isn't perfect -- it doesn't handle function pointers or arrays as arguments -- but it should work.

If you need to just split into the arguments, a simple modification:

        {
                typename = $0
                getline
                if (NF == 0) {
print "bad function line" | "cat 1>&2" # awk is ape, use sh syntax, not rc
                        next
                }
                n = split($0, fields, "[(),]+")
                printf "%s#", fields[1]
                for (i = 2; i < n; i++) {
                        # drop non-alphanumeric characters
                        m = split(fields[i], arg, "[^A-Za-z0-9_]+")
                        printf "%s|%s#", arg[m], fields[i]
                        delete arg
                }
                delete fields
                print typename
        }


On Jun 5, 2008, at 10:18 AM, Steve Simon wrote:

Anyone know of some nice simple code to parse C prototype definitions
and split them into nicely awk'able bits so I can generate stub functions:

I have been playing with mkptypes | awk which works well
for simple stuff, say my source contains:

        void
        func(int a, char *b)


and I want to generate

        void
        stub_func(int a, char *b)
        {
                func(a, b);
        }

however when you get into

        int syspipe(int fd[2])

let alone

        int sysnotify(void (*func)(void*, char*))

it is starting to push at the limits of what awk is good for.

I guess I am looking for some yacc and lex which
parses C and spits out somthing like this:

        func#a|int a#b|char *b
        syspipe#fd|int fd[2]
        sysnotify#func|void (*func)(void*, char*)

I understand knowledge of types is harder but if I use just basic types this sounds doable to me. Before I write it, does anyone seem such a beast?

-Steve



Reply via email to