fix type parsing
[musl-tables] / type.sh
1 #!/bin/sh
2
3 export LC_ALL=C
4
5 # drop names from a declaration (hack to make prototypes comparable)
6 awk '
7 BEGIN {
8         # type is not typedefed so next unknown id is probably a variable name
9         split("void char short int long float double signed unsigned _Bool _Complex bool complex", a)
10         for (i in a)
11                 tok[a[i]] = "type"
12
13         # next token is an id, type is not typedefed
14         split("struct union enum", a)
15         for (i in a)
16                 tok[a[i]] = "struct"
17
18         # decoratoin that can be skipped
19         split("static extern auto register inline const volatile restrict", a)
20         for (i in a)
21                 tok[a[i]] = "decor"
22
23         # punctuators
24         split("( ) [ ] , ... *", a)
25         for (i in a)
26                 tok[a[i]] = "punct"
27 }
28
29 function put(tok) {
30         if (tok ~ /^[a-zA-Z_]/) {
31                 s = s sep tok
32                 sep = " "
33         } else {
34                 s = s tok
35                 sep = ""
36         }
37 }
38
39 {
40         # eat comments
41         gsub(/\/\*[^/]*\*\//, "")
42         gsub(/\/\/.*/, "")
43
44         gsub(/[^a-zA-Z0-9_.-]/," & ")
45         gsub(/\.\.\./, " & ")
46
47         state = "type"
48         sep = ""
49         s = ""
50         for (i = 1; i <= NF; i++) {
51                 if ($i == ";")
52                         break
53                 # drop restrict
54                 if ($i == "restrict")
55                         continue
56                 if (state == "type") {
57                         put($i)
58                         if (!tok[$i] || tok[$i] == "type")
59                                 state = "id"
60                         if (tok[$i] == "struct") {
61                                 i++
62                                 put($i)
63                                 state = "id"
64                         }
65                 } else if (state == "id") {
66                         if (!tok[$i]) {
67                                 state = "idfound"
68                                 continue
69                         }
70                         put($i)
71                         if ($i == ")")
72                                 state = "idfound"
73                         if ($i == ",")
74                                 state = "type"
75                 } else if (state == "idfound") {
76                         put($i)
77                         if ($i == "(" || $i == ",")
78                                 state = "type"
79                 }
80         }
81
82         # fixes
83         gsub(/\[[0-9]+\]/, "[]", s)
84         gsub(/unsigned int/, "unsigned", s)
85         gsub(/long int/, "long", s)
86
87         print s
88 }
89 '