From 059956376897b3fee0d019b8f5e27ac3b84acb5d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 12 May 2000 14:35:14 +0000 Subject: preliminary support for unions (This used to be commit 57a6cb52e6c646cd8a3d25f10f65a65e12d22a24) --- source3/aparser/Makefile | 2 +- source3/aparser/basic.awk | 43 +++++++++ source3/aparser/func.awk | 39 +++++++++ source3/aparser/parser.awk | 207 +++++++------------------------------------- source3/aparser/struct.awk | 158 +++++++++++++++++++++++++++++++++ source3/aparser/test.struct | 51 ++++++++--- source3/aparser/union.awk | 16 ++++ 7 files changed, 327 insertions(+), 189 deletions(-) create mode 100644 source3/aparser/basic.awk create mode 100644 source3/aparser/func.awk create mode 100644 source3/aparser/struct.awk create mode 100644 source3/aparser/union.awk (limited to 'source3') diff --git a/source3/aparser/Makefile b/source3/aparser/Makefile index e9ff8ad010..d088071090 100644 --- a/source3/aparser/Makefile +++ b/source3/aparser/Makefile @@ -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 diff --git a/source3/aparser/basic.awk b/source3/aparser/basic.awk new file mode 100644 index 0000000000..3dab8a4768 --- /dev/null +++ b/source3/aparser/basic.awk @@ -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); +} diff --git a/source3/aparser/func.awk b/source3/aparser/func.awk new file mode 100644 index 0000000000..fcf21a0a2e --- /dev/null +++ b/source3/aparser/func.awk @@ -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); +} + diff --git a/source3/aparser/parser.awk b/source3/aparser/parser.awk index a32d4b727b..dde43b91a2 100644 --- a/source3/aparser/parser.awk +++ b/source3/aparser/parser.awk @@ -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%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%s))\n\ - return False;\n\ -", elem, elem); +/^module/ { + module=$2; + next; } -function unistr2_parser(elem) { - printf("\ - if(!prs_uint32(\"%s_ptr\", ps, depth, &il->%s_ptr))\n\ - return False;\n\ -", elem, elem); +/^test/ { + test=$2; + next; } -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); +/^struct/ { + start_struct($2); + next; } -function nttime_parser(elem) { - printf("\ - if(!smb_io_time(\"%s\", &il->%s, ps, depth))\n\ - return False;\n\ -", elem, elem); +/^[ \t]*union/ { + start_union($2, $3); + next; } -function uint64_parser(elem) { - printf("\ - if(!prs_uint64(\"%s\", ps, depth, &il->%s))\n\ - return False;\n\ -", elem, elem); +/^[ \t]*case/ { + split($0,a,"[ \t;]*"); + parse_case(a[3],a[4],a[5]); + next; } -/^module/ { - module=$2; +/^\};/ { + end_struct(); + next; } -/^struct/ { - start_struct($2); +/^[ \t]*\}/ { + end_union(); + next; } - -/^\}/ { - end_struct(); +/^[ \t]*REF/ { + split($0,a,"[ \t;]*"); + add_elem(a[3],a[4], 1); + next; } -/uint32|UINT64_S|UNISTR2|BUFFER5|NTTIME/ { - split($0,a,"[ ;]*"); - add_elem(a[2], a[3]); +/.*;/ { + split($0,a,"[ \t;]*"); + add_elem(a[2], a[3], 0); } diff --git a/source3/aparser/struct.awk b/source3/aparser/struct.awk new file mode 100644 index 0000000000..0f25536d94 --- /dev/null +++ b/source3/aparser/struct.awk @@ -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%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%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++; +} + diff --git a/source3/aparser/test.struct b/source3/aparser/test.struct index 517197bac3..1f5c5b6519 100644 --- a/source3/aparser/test.struct +++ b/source3/aparser/test.struct @@ -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; + } +}; diff --git a/source3/aparser/union.awk b/source3/aparser/union.awk new file mode 100644 index 0000000000..4a26bd9c20 --- /dev/null +++ b/source3/aparser/union.awk @@ -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=""; +} + -- cgit