import HEAD into svn+ssh://svn.samba.org/home/svn/samba/trunk
[metze/old/v3-2-winbind-ndr.git] / source / aparser / parsetree.awk
1 # build the parse tree for a struct file
2
3 function find_structure(name, 
4                         LOCAL, i)
5 {
6   for (i=0;i<num_structs;i++) {
7     if (structs[i, "name"] == name) return i;
8   }
9   return "-1";
10 }
11
12 function start_module(name) 
13 {
14         module=name;
15         num_structs=0;
16         num_elements=0;
17         num_unions=0;
18         num_tests=0;
19         num_options=0;
20 }
21
22 function set_option(name, value) 
23 {
24         options[name] = value;
25         options[num_options, "name"] = name;
26         options[num_options, "value"] = value;
27         num_options++;
28 }
29
30 function parse_define(def1, def2,
31                       LOCAL, type, i)
32 {
33         defines[def1]=def2;
34 }
35
36 function start_struct(name) 
37 {
38         current_struct=num_structs;
39         structs[name]=current_struct;
40         structs[current_struct, "name"]=name;
41         structs[current_struct, "num_elems"]=0;
42         structs[current_struct, "num_unions"]=0;
43         structs[current_struct, "recurse"] = options["recurse"];
44 }
45
46 function end_struct(name) 
47 {
48         if (name!="") structs[num_structs, "name"]=name;
49         printf("struct %s with %d elements\n", 
50                structs[num_structs, "name"],
51                structs[num_structs, "num_elems"]);
52         num_structs++;
53         current_struct="";
54 }
55
56 function add_element(type, elem, case,
57                      LOCAL, elem_num, i, v)
58 {
59         while (defines[type]!="") {
60                 type=defines[type];
61         }
62         elem_num=num_elements;
63
64         if (substr(elem, 1, 1) == ".") {
65                 elem=substr(elem, 2);
66                 elements[elem_num, "nowire"]=1;
67         }
68
69         if (substr(elem, 1, 1) == "*") {
70                 elem=substr(elem, 2);
71                 elements[elem_num, "ptr"]=1;
72         }
73
74         i=match(elem,"[[]");
75         if (i != 0) {
76                 v = substr(elem, i+1, length(elem)-i-1);
77                 elem=substr(elem, 1, i-1);
78                 if (type=="union") {
79                         elements[elem_num, "switch"] = v;
80                 } else {
81                         elements[elem_num, "array_len"] = v;
82                 }
83         }
84
85         elements[elem_num, "type"] = type;
86         elements[elem_num, "elem"] = elem;
87         elements[elem_num, "case"] = case;
88
89         num_elements++;
90         return elem_num;
91 }
92
93 function add_struct_elem(type, elem, case,
94                          LOCAL, elem_num)
95 {
96         elem_num=structs[current_struct, "num_elems"];
97         structs[current_struct, elem_num] = add_element(type, elem, case);
98         structs[current_struct, "num_elems"]++;
99         return structs[current_struct, elem_num];
100 }
101
102 function start_union(elem)
103 {
104         current_union = add_struct_elem("union", elem);
105         unions[current_union, "num_elems"] = 0;
106 }
107
108 function start_union_notencap(switch)
109 {
110         add_struct_elem("uint32", "switch_"switch);
111         start_union("UNKNOWN[switch_"switch"]");
112 }
113
114 function start_union_encap(struct, type, switch, union)
115 {
116         start_struct(struct);
117         add_struct_elem(type, switch);
118         add_struct_elem(type, "switch_"switch);
119         start_union(union"[switch_"switch"]");
120         encap_union="1";
121 }
122
123 function parse_case(case, type, elem,
124                     LOCAL, elem_num) 
125 {
126         split(case, a, "[:]");
127         case = a[1];
128         elem_num = unions[current_union, "num_elems"];
129         unions[current_union, elem_num] = add_element(type, elem, case);
130         unions[current_union, "num_elems"]++;
131 }
132
133 function end_union(name) 
134 {
135         if (name!="") {
136                 elements[current_union, "elem"] = name;
137         }
138         current_union="";
139         if (encap_union=="1") {
140                 end_struct(name);
141                 encap_union="0";
142         }
143 }
144
145 function delete_element(struct, elnum,
146                         LOCAL, i)
147 {
148         for (i=elnum;i<structs[struct,"num_elems"]-1;i++) {
149                 structs[struct, i] = structs[struct, i+1];
150         }
151         structs[struct, "num_elems"]--;
152 }
153
154 function copy_struct(from, to,
155                      LOCAL, i)
156 {
157         for (i=0;i<structs[from,"num_elems"];i++) {
158                 structs[to, i] = structs[from, i];
159         }
160         structs[to, "name"] = structs[from, "name"];
161         structs[to, "num_elems"] = structs[from, "num_elems"];
162         structs[to, "num_unions"] = structs[from, "num_unions"];
163 }
164
165 function add_sizeis_array(count, type, elem)
166 {
167         copy_struct(current_struct, current_struct+1);
168         elem=substr(elem,2);
169         start_struct("array_"current_struct"_"elem);
170         add_struct_elem("uint32", count);
171         add_struct_elem(type, elem"["count"]");
172         end_struct("");
173         current_struct=num_structs;
174         add_struct_elem("array_"current_struct-1"_"elem, "*"elem"_ptr");
175 }
176
177
178 function start_function(type, fname)
179 {
180         start_struct(fname);
181         structs[current_struct, "recurse"] = "False";
182 }
183
184 function end_function(LOCAL, i)
185 {
186   copy_struct(num_structs, num_structs+1);
187   structs[num_structs, "name"] = "Q_"structs[num_structs, "name"];
188   for (i=0;i<structs[num_structs, "num_elems"];i++) {
189     if (match(elements[structs[num_structs, i], "properties"], "in") == 0) {
190       delete_element(num_structs, i);
191       i--;
192     }
193   }
194   end_struct();
195   current_struct=num_structs;
196   structs[num_structs, "name"] = "R_"structs[num_structs, "name"];
197   for (i=0;i<structs[num_structs, "num_elems"];i++) {
198     if (match(elements[structs[num_structs, i], "properties"], "out") == 0) {
199       delete_element(num_structs, i);
200       i--;
201     }
202   }
203   if (return_result!="void")
204     add_function_param("[out]", return_result, "status");
205   end_struct();
206 }
207
208 function add_function_param(properties, type, elem,
209                             LOCAL, elnum, len)
210 {
211   len=length(type);
212   if (substr(type, len) == "*") {
213     type=substr(type, 1, len-1);
214     elem="*"elem;
215   }
216   if (substr(elem,1,1) == "*" &&
217       (match(properties,"in") == 0 || 
218        find_structure(type) != "-1")) {
219     elem=substr(elem, 2);
220   }
221   elnum = add_struct_elem(type, elem);
222   elements[elnum, "properties"] = properties;
223 }
224