mirror of
https://github.com/samba-team/samba.git
synced 2024-12-24 21:34:56 +03:00
eee003da6a
so the same parser generator can be uses for cifs and rpc
(This used to be commit c7829fa0d8
)
225 lines
5.0 KiB
Awk
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;
|
|
}
|
|
|