preliminary support for unions
authorAndrew Tridgell <tridge@samba.org>
Fri, 12 May 2000 14:35:14 +0000 (14:35 +0000)
committerAndrew Tridgell <tridge@samba.org>
Fri, 12 May 2000 14:35:14 +0000 (14:35 +0000)
(This used to be commit 57a6cb52e6c646cd8a3d25f10f65a65e12d22a24)

source3/aparser/Makefile
source3/aparser/basic.awk [new file with mode: 0644]
source3/aparser/func.awk [new file with mode: 0644]
source3/aparser/parser.awk
source3/aparser/struct.awk [new file with mode: 0644]
source3/aparser/test.struct
source3/aparser/union.awk [new file with mode: 0644]

index e9ff8ad0104c37eb310eb42236ff47a89d9e7b39..d08807109097ac390fd2afefe7c8f589056ed2b5 100644 (file)
@@ -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 (file)
index 0000000..3dab8a4
--- /dev/null
@@ -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 (file)
index 0000000..fcf21a0
--- /dev/null
@@ -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);
+}
+
index a32d4b727b3b0f3d095057214faa0fd62a753dbc..dde43b91a272845058d61a1fb4ad129f102c8ddf 100644 (file)
@@ -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);
+/^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 (file)
index 0000000..0f25536
--- /dev/null
@@ -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++;
+}
+
index 517197bac38913a41467683cc066a513605cedef..1f5c5b6519667801f7819abc28cc77cc092a906b 100644 (file)
@@ -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 (file)
index 0000000..4a26bd9
--- /dev/null
@@ -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="";
+}
+