1# build the parse tree for a struct file
2
3function 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
12function 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
22function 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
30function parse_define(def1, def2,
31		      LOCAL, type, i)
32{
33	defines[def1]=def2;
34}
35
36function 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
46function 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
56function 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
93function 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
102function start_union(elem)
103{
104	current_union = add_struct_elem("union", elem);
105	unions[current_union, "num_elems"] = 0;
106}
107
108function start_union_notencap(switch)
109{
110	add_struct_elem("uint32", "switch_"switch);
111	start_union("UNKNOWN[switch_"switch"]");
112}
113
114function 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
123function 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
133function 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
145function 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
154function 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
165function 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
178function start_function(type, fname)
179{
180        start_struct(fname);
181	structs[current_struct, "recurse"] = "False";
182}
183
184function 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
208function 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
225