1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-24 21:34:56 +03:00
samba-mirror/source/aparser/parsetree.awk
Andrew Tridgell c7829fa0d8 started adding support for relative, plus options for autoalignment
so the same parser generator can be uses for cifs and rpc
0001-01-01 00:00:00 +00:00

225 lines
5.0 KiB
Awk

# build the parse tree for a struct file
function find_structure(name,
LOCAL, i)
{
for (i=0;i<num_structs;i++) {
if (structs[i, "name"] == name) return i;
}
return "-1";
}
function start_module(name)
{
module=name;
num_structs=0;
num_elements=0;
num_unions=0;
num_tests=0;
num_options=0;
}
function set_option(name, value)
{
options[name] = value;
options[num_options, "name"] = name;
options[num_options, "value"] = value;
num_options++;
}
function parse_define(def1, def2,
LOCAL, type, i)
{
defines[def1]=def2;
}
function start_struct(name)
{
current_struct=num_structs;
structs[name]=current_struct;
structs[current_struct, "name"]=name;
structs[current_struct, "num_elems"]=0;
structs[current_struct, "num_unions"]=0;
structs[current_struct, "recurse"] = options["recurse"];
}
function end_struct(name)
{
if (name!="") structs[num_structs, "name"]=name;
printf("struct %s with %d elements\n",
structs[num_structs, "name"],
structs[num_structs, "num_elems"]);
num_structs++;
current_struct="";
}
function add_element(type, elem, case,
LOCAL, elem_num, i, v)
{
while (defines[type]!="") {
type=defines[type];
}
elem_num=num_elements;
if (substr(elem, 1, 1) == ".") {
elem=substr(elem, 2);
elements[elem_num, "nowire"]=1;
}
if (substr(elem, 1, 1) == "*") {
elem=substr(elem, 2);
elements[elem_num, "ptr"]=1;
}
i=match(elem,"[[]");
if (i != 0) {
v = substr(elem, i+1, length(elem)-i-1);
elem=substr(elem, 1, i-1);
if (type=="union") {
elements[elem_num, "switch"] = v;
} else {
elements[elem_num, "array_len"] = v;
}
}
elements[elem_num, "type"] = type;
elements[elem_num, "elem"] = elem;
elements[elem_num, "case"] = case;
num_elements++;
return elem_num;
}
function add_struct_elem(type, elem, case,
LOCAL, elem_num)
{
elem_num=structs[current_struct, "num_elems"];
structs[current_struct, elem_num] = add_element(type, elem, case);
structs[current_struct, "num_elems"]++;
return structs[current_struct, elem_num];
}
function start_union(elem)
{
current_union = add_struct_elem("union", elem);
unions[current_union, "num_elems"] = 0;
}
function start_union_notencap(switch)
{
add_struct_elem("uint32", "switch_"switch);
start_union("UNKNOWN[switch_"switch"]");
}
function start_union_encap(struct, type, switch, union)
{
start_struct(struct);
add_struct_elem(type, switch);
add_struct_elem(type, "switch_"switch);
start_union(union"[switch_"switch"]");
encap_union="1";
}
function parse_case(case, type, elem,
LOCAL, elem_num)
{
split(case, a, "[:]");
case = a[1];
elem_num = unions[current_union, "num_elems"];
unions[current_union, elem_num] = add_element(type, elem, case);
unions[current_union, "num_elems"]++;
}
function end_union(name)
{
if (name!="") {
elements[current_union, "elem"] = name;
}
current_union="";
if (encap_union=="1") {
end_struct(name);
encap_union="0";
}
}
function delete_element(struct, elnum,
LOCAL, i)
{
for (i=elnum;i<structs[struct,"num_elems"]-1;i++) {
structs[struct, i] = structs[struct, i+1];
}
structs[struct, "num_elems"]--;
}
function copy_struct(from, to,
LOCAL, i)
{
for (i=0;i<structs[from,"num_elems"];i++) {
structs[to, i] = structs[from, i];
}
structs[to, "name"] = structs[from, "name"];
structs[to, "num_elems"] = structs[from, "num_elems"];
structs[to, "num_unions"] = structs[from, "num_unions"];
}
function add_sizeis_array(count, type, elem)
{
copy_struct(current_struct, current_struct+1);
elem=substr(elem,2);
start_struct("array_"current_struct"_"elem);
add_struct_elem("uint32", count);
add_struct_elem(type, elem"["count"]");
end_struct("");
current_struct=num_structs;
add_struct_elem("array_"current_struct-1"_"elem, "*"elem"_ptr");
}
function start_function(type, fname)
{
start_struct(fname);
structs[current_struct, "recurse"] = "False";
}
function end_function(LOCAL, i)
{
copy_struct(num_structs, num_structs+1);
structs[num_structs, "name"] = "Q_"structs[num_structs, "name"];
for (i=0;i<structs[num_structs, "num_elems"];i++) {
if (match(elements[structs[num_structs, i], "properties"], "in") == 0) {
delete_element(num_structs, i);
i--;
}
}
end_struct();
current_struct=num_structs;
structs[num_structs, "name"] = "R_"structs[num_structs, "name"];
for (i=0;i<structs[num_structs, "num_elems"];i++) {
if (match(elements[structs[num_structs, i], "properties"], "out") == 0) {
delete_element(num_structs, i);
i--;
}
}
if (return_result!="void")
add_function_param("[out]", return_result, "status");
end_struct();
}
function add_function_param(properties, type, elem,
LOCAL, elnum, len)
{
len=length(type);
if (substr(type, len) == "*") {
type=substr(type, 1, len-1);
elem="*"elem;
}
if (substr(elem,1,1) == "*" &&
(match(properties,"in") == 0 ||
find_structure(type) != "-1")) {
elem=substr(elem, 2);
}
elnum = add_struct_elem(type, elem);
elements[elnum, "properties"] = properties;
}