mirror of
https://github.com/samba-team/samba.git
synced 2025-01-29 21:47:30 +03:00
preliminary support for unions
This commit is contained in:
parent
7bc87d20ea
commit
57a6cb52e6
@ -2,7 +2,7 @@ CFLAGS=-Wall -g
|
||||
CC=gcc
|
||||
|
||||
%.h : %.struct
|
||||
awk -f parser.awk < $*.struct > $*.h
|
||||
igawk -f parser.awk < $*.struct > $*.h
|
||||
|
||||
OBJ = harness.o parser.o
|
||||
|
||||
|
43
source/aparser/basic.awk
Normal file
43
source/aparser/basic.awk
Normal file
@ -0,0 +1,43 @@
|
||||
function uint32_parser(elem) {
|
||||
printf("\
|
||||
if(!prs_uint32(\"%s\", ps, depth, &il->%s))\n\
|
||||
return False;\n\
|
||||
", elem, elem);
|
||||
}
|
||||
|
||||
function unistr2_parser(elem) {
|
||||
printf("\
|
||||
if(!prs_uint32(\"%s_ptr\", ps, depth, &il->%s_ptr))\n\
|
||||
return False;\n\
|
||||
", elem, elem);
|
||||
}
|
||||
|
||||
function buffer5_parser(elem) {
|
||||
printf("\
|
||||
if(!prs_uint32(\"%s_len\", ps, depth, &il->%s_len))\n\
|
||||
return False;\n\
|
||||
if(!prs_uint32(\"%s_ptr\", ps, depth, &il->%s_ptr))\n\
|
||||
return False;\n\
|
||||
", elem, elem, elem, elem);
|
||||
}
|
||||
|
||||
function nttime_parser(elem) {
|
||||
printf("\
|
||||
if(!smb_io_time(\"%s\", &il->%s, ps, depth))\n\
|
||||
return False;\n\
|
||||
", elem, elem);
|
||||
}
|
||||
|
||||
function uint64_parser(elem) {
|
||||
printf("\
|
||||
if(!prs_uint64(\"%s\", ps, depth, &il->%s))\n\
|
||||
return False;\n\
|
||||
", elem, elem);
|
||||
}
|
||||
|
||||
function generic_parser(type, elem) {
|
||||
printf("\
|
||||
if(!%s(\"%s\", &il->%s, ps, depth))\n\
|
||||
return False;\n\
|
||||
", "io_"tolower(type), elem, elem);
|
||||
}
|
39
source/aparser/func.awk
Normal file
39
source/aparser/func.awk
Normal file
@ -0,0 +1,39 @@
|
||||
function func_footer() {
|
||||
printf("\n\
|
||||
\n\
|
||||
return True;\n\
|
||||
}\n");
|
||||
}
|
||||
|
||||
function func_header(func_name, struct_name)
|
||||
{
|
||||
printf("\
|
||||
/*******************************************************************\n\
|
||||
parse a %s structure\n\
|
||||
********************************************************************/ \n\
|
||||
BOOL %s(char *desc, %s **q_u, \n\
|
||||
prs_struct *ps, int depth)\n\
|
||||
{ \n\
|
||||
%s *il;\n\
|
||||
\n\
|
||||
prs_debug(ps, depth, desc, \"%s\");\n\
|
||||
depth++;\n\
|
||||
\n\
|
||||
/* reading */\n\
|
||||
if (UNMARSHALLING(ps)) {\n\
|
||||
il=(%s *)malloc(sizeof(%s));\n\
|
||||
if(il == NULL)\n\
|
||||
return False;\n\
|
||||
ZERO_STRUCTP(il);\n\
|
||||
*q_u=il;\n\
|
||||
}\n\
|
||||
else {\n\
|
||||
il=*q_u;\n\
|
||||
}\n\
|
||||
\n\
|
||||
if(!prs_align(ps))\n\
|
||||
return False;\n\
|
||||
\n\
|
||||
", struct_name, func_name, struct_name, struct_name, func_name, struct_name, struct_name);
|
||||
}
|
||||
|
@ -1,9 +1,7 @@
|
||||
function add_elem(type, elem)
|
||||
{
|
||||
types[num_elems] = type;
|
||||
elems[num_elems] = elem;
|
||||
num_elems++;
|
||||
}
|
||||
@include basic.awk
|
||||
@include struct.awk
|
||||
@include union.awk
|
||||
@include func.awk
|
||||
|
||||
function produce_preamble() {
|
||||
printf("#define TEST_STRUCT %s\n", struct_name);
|
||||
@ -12,189 +10,50 @@ function produce_preamble() {
|
||||
printf("\n\n");
|
||||
}
|
||||
|
||||
function produce_header() {
|
||||
printf("\n/* %s structure */\n", struct_name);
|
||||
printf("typedef struct {\n");
|
||||
for (i=0;i<num_elems;i++) {
|
||||
if (types[i] == "UNISTR2") {
|
||||
printf("\tuint32 %s_ptr;\n", elems[i]);
|
||||
} else if (types[i] == "BUFFER5") {
|
||||
printf("\tuint32 %s_len;\n", elems[i]);
|
||||
printf("\tuint32 %s_ptr;\n", elems[i]);
|
||||
} else {
|
||||
printf("\t%s\t%s;\n", types[i], elems[i]);
|
||||
}
|
||||
}
|
||||
for (i=0;i<num_elems;i++) {
|
||||
if (types[i] == "UNISTR2" ||
|
||||
types[i] == "BUFFER5") {
|
||||
printf("\t%s\t%s;\n", types[i], elems[i]);
|
||||
}
|
||||
}
|
||||
printf("} %s;\n\n", struct_name);
|
||||
}
|
||||
|
||||
|
||||
function parse_structs() {
|
||||
printf("\n\t/* parse the structures in the packet */\n\n");
|
||||
for (i=0;i<num_elems;i++) {
|
||||
if (types[i] == "UNISTR2") {
|
||||
io_unistr2(elems[i]);
|
||||
}
|
||||
if (types[i] == "BUFFER5") {
|
||||
io_buffer5(elems[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function io_unistr2(elem) {
|
||||
printf("\
|
||||
if(!smb_io_unistr2(\"%s\", &il->%s, il->%s_ptr, ps, depth))\n\
|
||||
return False;\n\
|
||||
if(!prs_align(ps))\n\
|
||||
return False;\n\
|
||||
", elem, elem, elem);
|
||||
}
|
||||
|
||||
function io_buffer5(elem) {
|
||||
printf("\
|
||||
if (il->%s_ptr) {\n\
|
||||
if(!smb_io_buffer5(\"%s\", &il->%s, ps, depth))\n\
|
||||
return False;\n\
|
||||
if(!prs_align(ps))\n\
|
||||
return False;\n\
|
||||
}\n\
|
||||
", elem, elem, elem);
|
||||
}
|
||||
|
||||
function start_struct(name) {
|
||||
num_elems=0;
|
||||
struct_name=toupper(module"_"name);
|
||||
func_name=tolower(module"_io_"name);
|
||||
}
|
||||
|
||||
function parse_elems() {
|
||||
printf("\n\t/* parse the main elements the packet */\n\n");
|
||||
for (i=0;i<num_elems;i++) {
|
||||
if (types[i] == "uint32") {
|
||||
uint32_parser(elems[i]);
|
||||
}
|
||||
if (types[i] == "UINT64_S") {
|
||||
uint64_parser(elems[i]);
|
||||
}
|
||||
if (types[i] == "UNISTR2") {
|
||||
unistr2_parser(elems[i]);
|
||||
}
|
||||
if (types[i] == "BUFFER5") {
|
||||
buffer5_parser(elems[i]);
|
||||
}
|
||||
if (types[i] == "NTTIME") {
|
||||
nttime_parser(elems[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function end_struct() {
|
||||
produce_preamble();
|
||||
produce_header();
|
||||
func_header(func_name, struct_name);
|
||||
parse_elems();
|
||||
parse_structs();
|
||||
func_footer();
|
||||
}
|
||||
|
||||
|
||||
|
||||
function func_footer() {
|
||||
printf("\n\
|
||||
\n\
|
||||
return True;\n\
|
||||
}\n");
|
||||
}
|
||||
|
||||
function func_header(func_name, struct_name)
|
||||
{
|
||||
printf("\
|
||||
/*******************************************************************\n\
|
||||
parse a %s structure\n\
|
||||
********************************************************************/ \n\
|
||||
BOOL %s(char *desc, %s **q_u, \n\
|
||||
prs_struct *ps, int depth)\n\
|
||||
{ \n\
|
||||
%s *il;\n\
|
||||
\n\
|
||||
prs_debug(ps, depth, desc, \"%s\");\n\
|
||||
depth++;\n\
|
||||
\n\
|
||||
/* reading */\n\
|
||||
if (UNMARSHALLING(ps)) {\n\
|
||||
il=(%s *)malloc(sizeof(%s));\n\
|
||||
if(il == NULL)\n\
|
||||
return False;\n\
|
||||
ZERO_STRUCTP(il);\n\
|
||||
*q_u=il;\n\
|
||||
}\n\
|
||||
else {\n\
|
||||
il=*q_u;\n\
|
||||
}\n\
|
||||
\n\
|
||||
if(!prs_align(ps))\n\
|
||||
return False;\n\
|
||||
\n\
|
||||
", struct_name, func_name, struct_name, struct_name, func_name, struct_name, struct_name);
|
||||
}
|
||||
|
||||
function uint32_parser(elem) {
|
||||
printf("\
|
||||
if(!prs_uint32(\"%s\", ps, depth, &il->%s))\n\
|
||||
return False;\n\
|
||||
", elem, elem);
|
||||
}
|
||||
|
||||
function unistr2_parser(elem) {
|
||||
printf("\
|
||||
if(!prs_uint32(\"%s_ptr\", ps, depth, &il->%s_ptr))\n\
|
||||
return False;\n\
|
||||
", elem, elem);
|
||||
}
|
||||
|
||||
function buffer5_parser(elem) {
|
||||
printf("\
|
||||
if(!prs_uint32(\"%s_len\", ps, depth, &il->%s_len))\n\
|
||||
return False;\n\
|
||||
if(!prs_uint32(\"%s_ptr\", ps, depth, &il->%s_ptr))\n\
|
||||
return False;\n\
|
||||
", elem, elem, elem, elem);
|
||||
}
|
||||
|
||||
function nttime_parser(elem) {
|
||||
printf("\
|
||||
if(!smb_io_time(\"%s\", &il->%s, ps, depth))\n\
|
||||
return False;\n\
|
||||
", elem, elem);
|
||||
}
|
||||
|
||||
function uint64_parser(elem) {
|
||||
printf("\
|
||||
if(!prs_uint64(\"%s\", ps, depth, &il->%s))\n\
|
||||
return False;\n\
|
||||
", elem, elem);
|
||||
}
|
||||
|
||||
/^module/ {
|
||||
module=$2;
|
||||
next;
|
||||
}
|
||||
|
||||
/^test/ {
|
||||
test=$2;
|
||||
next;
|
||||
}
|
||||
|
||||
/^struct/ {
|
||||
start_struct($2);
|
||||
next;
|
||||
}
|
||||
|
||||
/^[ \t]*union/ {
|
||||
start_union($2, $3);
|
||||
next;
|
||||
}
|
||||
|
||||
/^\}/ {
|
||||
/^[ \t]*case/ {
|
||||
split($0,a,"[ \t;]*");
|
||||
parse_case(a[3],a[4],a[5]);
|
||||
next;
|
||||
}
|
||||
|
||||
/^\};/ {
|
||||
end_struct();
|
||||
next;
|
||||
}
|
||||
|
||||
/uint32|UINT64_S|UNISTR2|BUFFER5|NTTIME/ {
|
||||
split($0,a,"[ ;]*");
|
||||
add_elem(a[2], a[3]);
|
||||
/^[ \t]*\}/ {
|
||||
end_union();
|
||||
next;
|
||||
}
|
||||
|
||||
/^[ \t]*REF/ {
|
||||
split($0,a,"[ \t;]*");
|
||||
add_elem(a[3],a[4], 1);
|
||||
next;
|
||||
}
|
||||
|
||||
/.*;/ {
|
||||
split($0,a,"[ \t;]*");
|
||||
add_elem(a[2], a[3], 0);
|
||||
}
|
||||
|
158
source/aparser/struct.awk
Normal file
158
source/aparser/struct.awk
Normal file
@ -0,0 +1,158 @@
|
||||
function isaptr(elem) {
|
||||
if (substr(elem, 1, 1) == "*") {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
function header_elem1(type, elem, ref) {
|
||||
if (type == "BUFFER5") {
|
||||
printf("\tuint32 %s_len;\n", elem);
|
||||
}
|
||||
if (ref == 1) {
|
||||
printf("\tuint32 %s_ptr;\n", elem);
|
||||
} else {
|
||||
printf("\t%s\t%s;\n", type, elem);
|
||||
}
|
||||
}
|
||||
|
||||
function header_elem2(type, elem, ref) {
|
||||
if (ref) {
|
||||
printf("\t%s\t%s;\n", type, elem);
|
||||
}
|
||||
}
|
||||
|
||||
function produce_header1() {
|
||||
printf("\n/* %s structure */\n", struct_name);
|
||||
printf("typedef struct {\n");
|
||||
for (i=0;i<num_elems;i++) {
|
||||
if (unions[i] != unions[i-1]) {
|
||||
if (unions[i] != "") {
|
||||
printf("\tunion {\n");
|
||||
} else {
|
||||
printf("\t} %s;\n", unions[i-1]);
|
||||
}
|
||||
}
|
||||
if (isptr[i]) {
|
||||
header_elem1(types[i], "*"elems[i], isref[i]);
|
||||
} else {
|
||||
header_elem1(types[i], elems[i], isref[i]);
|
||||
}
|
||||
}
|
||||
if (unions[i-1] != "") {
|
||||
printf("\t} %s;\n", unions[i-1]);
|
||||
}
|
||||
}
|
||||
|
||||
function produce_header2() {
|
||||
for (i=0;i<num_elems;i++) {
|
||||
if (isptr[i]) {
|
||||
header_elem2(types[i], "*"elems[i], isref[i]);
|
||||
} else {
|
||||
header_elem2(types[i], elems[i], isref[i]);
|
||||
}
|
||||
}
|
||||
printf("} %s;\n\n", struct_name);
|
||||
}
|
||||
|
||||
function produce_header() {
|
||||
produce_header1();
|
||||
produce_header2();
|
||||
}
|
||||
|
||||
function parse_structs() {
|
||||
printf("\n\t/* parse the structures in the packet */\n\n");
|
||||
for (i=0;i<num_elems;i++) {
|
||||
if (types[i] == "UNISTR2") {
|
||||
io_unistr2(elems[i]);
|
||||
} else if (types[i] == "BUFFER5") {
|
||||
io_buffer5(elems[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function io_unistr2(elem) {
|
||||
printf("\
|
||||
if(!smb_io_unistr2(\"%s\", &il->%s, il->%s_ptr, ps, depth))\n\
|
||||
return False;\n\
|
||||
if(!prs_align(ps))\n\
|
||||
return False;\n\
|
||||
", elem, elem, elem);
|
||||
}
|
||||
|
||||
function io_buffer5(elem) {
|
||||
printf("\
|
||||
if (il->%s_ptr) {\n\
|
||||
if(!smb_io_buffer5(\"%s\", &il->%s, ps, depth))\n\
|
||||
return False;\n\
|
||||
if(!prs_align(ps))\n\
|
||||
return False;\n\
|
||||
}\n\
|
||||
", elem, elem, elem);
|
||||
}
|
||||
|
||||
function start_struct(name) {
|
||||
num_elems=0;
|
||||
union="";
|
||||
case="";
|
||||
struct_name=toupper(name);
|
||||
func_name=tolower("io_"name);
|
||||
if (name == test) {
|
||||
produce_preamble();
|
||||
}
|
||||
}
|
||||
|
||||
function parse_one(type, elem) {
|
||||
if (type == "uint32") {
|
||||
uint32_parser(elem);
|
||||
} else if (type == "UINT64_S") {
|
||||
uint64_parser(elem);
|
||||
} else if (type == "UNISTR2") {
|
||||
unistr2_parser(elem);
|
||||
} else if (type == "BUFFER5") {
|
||||
buffer5_parser(elem);
|
||||
} else if (type == "NTTIME") {
|
||||
nttime_parser(elem);
|
||||
} else {
|
||||
generic_parser(type, elem);
|
||||
}
|
||||
}
|
||||
|
||||
function parse_elems() {
|
||||
printf("\n\t/* parse the main elements of the packet */\n\n");
|
||||
for (i=0;i<num_elems;i++) {
|
||||
if (cases[i] != "") {
|
||||
printf("\tif (il->%s == %s) {\n",
|
||||
switches[i], cases[i]);
|
||||
parse_one(types[i], unions[i]"."elems[i]);
|
||||
printf("\t}\n");
|
||||
} else {
|
||||
parse_one(types[i], elems[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function end_struct() {
|
||||
produce_header();
|
||||
func_header(func_name, struct_name);
|
||||
parse_elems();
|
||||
parse_structs();
|
||||
func_footer();
|
||||
}
|
||||
|
||||
function add_elem(type, elem, ref)
|
||||
{
|
||||
types[num_elems] = type;
|
||||
elems[num_elems] = elem;
|
||||
switches[num_elems] = switch;
|
||||
cases[num_elems] = case;
|
||||
unions[num_elems] = union;
|
||||
isref[num_elems] = ref;
|
||||
isptr[num_elems] = isaptr(elem);
|
||||
if (isptr[num_elems] == 1) {
|
||||
elems[num_elems] = substr(elems[num_elems], 2);
|
||||
}
|
||||
num_elems++;
|
||||
}
|
||||
|
@ -1,23 +1,46 @@
|
||||
module spool
|
||||
test PRINTER_DRIVER_INFO
|
||||
|
||||
struct PRINTER_DRIVER_INFO_LEVEL_3 {
|
||||
uint32 cversion;
|
||||
REF UNISTR2 name;
|
||||
REF UNISTR2 environment;
|
||||
REF UNISTR2 driverpath;
|
||||
REF UNISTR2 datafile;
|
||||
REF UNISTR2 configfile;
|
||||
REF UNISTR2 helpfile;
|
||||
REF UNISTR2 monitorname;
|
||||
REF UNISTR2 defaultdatatype;
|
||||
REF BUFFER5 dependentfiles;
|
||||
};
|
||||
|
||||
struct PRINTER_DRIVER_INFO_LEVEL_6 {
|
||||
uint32 dummy1;
|
||||
uint32 version;
|
||||
UNISTR2 name;
|
||||
UNISTR2 environment;
|
||||
UNISTR2 driverpath;
|
||||
UNISTR2 datafile;
|
||||
UNISTR2 configfile;
|
||||
UNISTR2 helpfile;
|
||||
UNISTR2 monitorname;
|
||||
UNISTR2 defaultdatatype;
|
||||
BUFFER5 dependentfiles;
|
||||
BUFFER5 previousnames;
|
||||
REF UNISTR2 name;
|
||||
REF UNISTR2 environment;
|
||||
REF UNISTR2 driverpath;
|
||||
REF UNISTR2 datafile;
|
||||
REF UNISTR2 configfile;
|
||||
REF UNISTR2 helpfile;
|
||||
REF UNISTR2 monitorname;
|
||||
REF UNISTR2 defaultdatatype;
|
||||
REF BUFFER5 dependentfiles;
|
||||
REF BUFFER5 previousnames;
|
||||
NTTIME driverdate;
|
||||
UINT64_S driverversion;
|
||||
uint32 dummy4;
|
||||
UNISTR2 mfgname;
|
||||
UNISTR2 oemurl;
|
||||
UNISTR2 hardwareid;
|
||||
UNISTR2 provider;
|
||||
REF UNISTR2 mfgname;
|
||||
REF UNISTR2 oemurl;
|
||||
REF UNISTR2 hardwareid;
|
||||
REF UNISTR2 provider;
|
||||
};
|
||||
|
||||
|
||||
struct PRINTER_DRIVER_INFO {
|
||||
uint32 level;
|
||||
union level info {
|
||||
case 3 PRINTER_DRIVER_INFO_LEVEL_3 *info_3;
|
||||
case 6 PRINTER_DRIVER_INFO_LEVEL_6 *info_6;
|
||||
}
|
||||
};
|
||||
|
16
source/aparser/union.awk
Normal file
16
source/aparser/union.awk
Normal file
@ -0,0 +1,16 @@
|
||||
function start_union(elem, name) {
|
||||
switch=elem;
|
||||
union=name;
|
||||
}
|
||||
|
||||
function parse_case(value,type,elem) {
|
||||
case=value;
|
||||
add_elem(type, elem, 0);
|
||||
}
|
||||
|
||||
function end_union() {
|
||||
union="";
|
||||
case="";
|
||||
switch="";
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user