3 # parse a C declaration by recursive descent
5 # decl.awk with extra escapes \
7 ################################################
8 ############################################
11 # lexical scanner -- gobble()
12 # input : string s -- treated as a regular expression
13 # gobble eats SPACE, then eats longest match of s off front
14 # of global variable line.
15 # Cuts the matched part off of line
21 sub( /^ /, "", line) # eat SPACE if any
23 # surround s with parenthesis to make sure ^ acts on the
26 match(line, "^" "(" s ")")
27 x = substr(line, 1, RLENGTH)
28 line = substr(line, RLENGTH+1)
33 function ptr_to(n, x) # print "pointer to" , n times
35 if ( n <= 0 ) return ""
36 x = "pointer to" ; n--
37 while ( n-- ) x = x " pointer to"
42 #recursively get a decl
43 # returns an english description of the declaration or
44 # "" if not a C declaration.
46 function decl( x, t, ptr_part)
49 x = gobble("[* ]+") # get list of *** ...
50 gsub(/ /, "", x) # remove all SPACES
51 ptr_part = ptr_to( length(x) )
53 # We expect to see either an identifier or '('
58 # this is the recursive descent part
59 # we expect to match a declaration and closing ')'
60 # If not return "" to indicate failure
62 if ( (x = decl()) == "" || gobble( "\\)" ) == "" ) return ""
65 else # expecting an identifier
67 if ( (x = gobble(id)) == "" ) return ""
75 if ( gobble( funct_mark ) ) x = x " function returning"
77 if ( t = gobble( array_mark ) )
79 x = x " array" t " of"
89 BEGIN { id = "[_A-Za-z][_A-Za-z0-9]*"
90 funct_mark = "\\([ \t]*\\)"
91 array_mark = "\\[[ \t]*[_A-Za-z0-9]*[ \t]*\\]"
93 # I've assumed types are keywords or all CAPS or end in _t
94 # Other conventions could be added.
96 type0 = "int|char|short|long|double|float|void"
97 type1 = "[_A-Z][_A-Z0-9]*" # types are CAPS
98 type2 = "[_A-Za-z][_A-Za-z0-9]*_t" # end in _t
100 types = "(" type0 "|" type1 "|" type2 ")"
106 gsub( /\/\*([^*]|\*[^\/])*(\*\/|$)/ , " ") # remove comments
107 gsub( /[ \t]+/, " ") # squeeze white space to a single space
112 scope = gobble( "extern|static" )
114 if ( type = gobble("(struct|union|enum) ") )
115 type = type gobble(id) # get the tag
119 type = gobble("(un)?signed ") gobble( types )
125 if ( (x = decl()) && gobble( ";") )
128 if ( scope ) x = x " (" scope ")"
129 gsub( / +/, " ", x) #