From f3a3a05ade784ff6906e5c8b132c9440a8db44e5 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 16 May 2000 11:55:06 +0000 Subject: another awk parser update we can now handle arrays of structures, pointers to structures, pointers in unions etc (This used to be commit 1df80cd1e8475b6b2fe7b80b6c9089692ab7691b) --- source3/aparser/harness.awk | 2 +- source3/aparser/parsefn.awk | 150 +++++++++++++++------------- source3/aparser/parser.c | 118 +++++++++++++--------- source3/aparser/parser.h | 14 ++- source3/aparser/spool.struct | 16 ++- source3/aparser/srvsvc.struct | 73 ++++++++++++++ source3/aparser/templates/fn_end.tpl | 27 +---- source3/aparser/templates/fn_mid.tpl | 6 ++ source3/aparser/templates/fn_start.tpl | 10 +- source3/aparser/templates/harness_start.tpl | 2 +- source3/aparser/templates/ifptr_start.tpl | 1 + source3/aparser/templates/prs_array.tpl | 13 +-- source3/aparser/templates/prs_break.tpl | 1 + source3/aparser/templates/prs_case.tpl | 2 +- source3/aparser/templates/prs_element.tpl | 1 + source3/aparser/templates/prs_pointer.tpl | 4 +- source3/aparser/templates/prs_wstring.tpl | 2 + source3/aparser/templates/union_start.tpl | 2 - source3/aparser/vluke.c | 5 +- 19 files changed, 284 insertions(+), 165 deletions(-) create mode 100644 source3/aparser/srvsvc.struct create mode 100644 source3/aparser/templates/fn_mid.tpl create mode 100644 source3/aparser/templates/prs_break.tpl create mode 100644 source3/aparser/templates/prs_element.tpl create mode 100644 source3/aparser/templates/prs_wstring.tpl (limited to 'source3') diff --git a/source3/aparser/harness.awk b/source3/aparser/harness.awk index 345fd6e191..00e3f44a68 100644 --- a/source3/aparser/harness.awk +++ b/source3/aparser/harness.awk @@ -7,7 +7,7 @@ function produce_harness(f, v["TEST"]=test; v["TEST_FUNC"]=moduletest; v["STRUCTNAME"] = structs[struct_num, "name"]; - v["FUNCNAME"] = v["MODULE"] "_io_" v["STRUCTNAME"]; + v["FUNCNAME"] = "io_" v["STRUCTNAME"]; print_template(f, "harness_start.tpl", v); } diff --git a/source3/aparser/parsefn.awk b/source3/aparser/parsefn.awk index 7348984eaa..68f08618a6 100644 --- a/source3/aparser/parsefn.awk +++ b/source3/aparser/parsefn.awk @@ -1,106 +1,118 @@ # build parse functions for a parsed struct file -function parse_elem(f, v, struct_num, elem_num, - LOCAL, type, elem) +function elem_name(v, elem) { - type = structs[struct_num, elem_num, "type"]; - elem = structs[struct_num, elem_num, "elem"]; - v["ELEM"] = noptr(elem); + return v["UNION"]elem; +} + +function parse_array(f, v, elnum, flags, + LOCAL, type, elem) +{ + type = elements[elnum, "type"]; + elem = elements[elnum, "elem"]; + v["ELEM"] = elem_name(v, elem); v["TYPE"] = type; - if (structs[type] != "") { - if (isaptr(elem)) { - print_template(f, "prs_struct_alloc.tpl", v); - } else { - print_template(f, "prs_struct.tpl", v); - } + v["FLAGS"] = flags; + v["ARRAY_LEN"] = elements[elnum, "array_len"]; + + if (type == "uint16") { + print_template(f, "prs_wstring.tpl", v); } else { - print_template(f, "prs_"type".tpl", v); + print_template(f, "prs_array.tpl", v); } } + - -function parse_array(f, v, struct_num, elem_num, - LOCAL, elem, type) +function parse_element(f, v, elnum, flags, + LOCAL, type, elem) { - elem = structs[struct_num, elem_num, "elem"]; - type = structs[struct_num, elem_num, "type"]; - v["ARRAYLEN"] = structs[struct_num, elem_num, "array_len"] - v["ELEM"] = elem; + type = elements[elnum, "type"]; + elem = elements[elnum, "elem"]; + if (elements[elnum,"ptr"] == "") { + v["PTR"] = "\\&"; + } else { + v["PTR"] = " "; + } + v["ELEM"] = elem_name(v, elem); v["TYPE"] = type; - print_template(f, "prs_array.tpl", v); + v["FLAGS"] = flags; + print_template(f, "prs_element.tpl", v); } -function parse_union(f, v, struct_num, elem_num, - LOCAL, union, type, i, elem, value) +function parse_union(f, v, elnum, flags, + LOCAL, i) { - union = structs[struct_num, elem_num, "elem"]; - v["UNION"] = noptr(union); - v["SWITCH"] = structs[struct_num, "unions", union, "switch"]; + v["UNION"] = elements[elnum, "elem"]; + v["SWITCH"] = elements[elnum, "switch"]; + + if (elements[elnum, "ptr"] == "1") { + v["UNION"] = v["UNION"]"->"; + } else { + v["UNION"] = v["UNION"]"."; + } print_template(f, "union_start.tpl", v); - for (i=0;i"noptr(elem); - v["TYPE"] = type; - v["VALUE"] = value; + for (i=0;idata_p[ps->data_offset]; } - -/******************************************************************* - Stream a uint32. - ********************************************************************/ - -BOOL prs_uint32(char *name, prs_struct *ps, int depth, uint32 *data32, BOOL scalars) -{ - char *q = prs_mem_get(ps, sizeof(uint32)); - if (q == NULL) - return False; - - DBG_RW_IVAL(name, depth, ps->data_offset, ps->io, ps->bigendian_data, q, *data32) - ps->data_offset += sizeof(uint32); - - return True; -} - /******************************************************************* Initialise a parse structure - malloc the data if requested. ********************************************************************/ @@ -264,61 +247,102 @@ void dump_data(int level,char *buf1,int len) } } + /******************************************************************* - Stream a pointer + do IO on a uint32. ********************************************************************/ -BOOL prs_pointer(char *desc, prs_struct *ps, int depth, void **p, BOOL scalars) +BOOL io_uint32(char *name, prs_struct *ps, int depth, uint32 *data32, unsigned flags) { - uint32 v = (*p) ? 1 : 0; - if (!prs_uint32(desc, ps, depth, &v, True)) return False; - *p = (void *) (v ? 1 : 0); + char *q; + + if (!(flags & PARSE_SCALARS)) return True; + + q = prs_mem_get(ps, sizeof(uint32)); + if (q == NULL) return False; + + DBG_RW_IVAL(name, depth, ps->data_offset, ps->io, ps->bigendian_data, q, *data32) + ps->data_offset += sizeof(uint32); + return True; } -/****************************************************************** - Stream an array of uint16s. Length is number of uint16s. +/******************************************************************* + do IO on a uint16. ********************************************************************/ - -BOOL prs_uint16s(BOOL charmode, char *name, prs_struct *ps, int depth, uint16 *data16s, int len) +BOOL io_uint16(char *name, prs_struct *ps, int depth, uint16 *data16, unsigned flags) { - char *q = prs_mem_get(ps, len * sizeof(uint16)); - if (q == NULL) - return False; + char *q; - DBG_RW_PSVAL(charmode, name, depth, ps->data_offset, ps->io, ps->bigendian_data, q, data16s, len) - ps->data_offset += (len * sizeof(uint16)); + if (!(flags & PARSE_SCALARS)) return True; + + q = prs_mem_get(ps, sizeof(uint16)); + if (q == NULL) return False; + + DBG_RW_IVAL(name, depth, ps->data_offset, ps->io, ps->bigendian_data, q, *data16) + ps->data_offset += sizeof(uint16); return True; } -/****************************************************************** - Stream an array of uint32s. Length is number of uint32s. +/******************************************************************* + do IO on a uint8. ********************************************************************/ - -BOOL prs_uint32s(BOOL charmode, char *name, prs_struct *ps, int depth, uint32 *data32s, int len) +BOOL io_uint8(char *name, prs_struct *ps, int depth, uint8 *data8, unsigned flags) { - char *q = prs_mem_get(ps, len * sizeof(uint32)); - if (q == NULL) - return False; + char *q; + + if (!(flags & PARSE_SCALARS)) return True; + + q = prs_mem_get(ps, sizeof(uint8)); + if (q == NULL) return False; - DBG_RW_PIVAL(charmode, name, depth, ps->data_offset, ps->io, ps->bigendian_data, q, data32s, len) - ps->data_offset += (len * sizeof(uint32)); + DBG_RW_IVAL(name, depth, ps->data_offset, ps->io, ps->bigendian_data, q, *data8) + ps->data_offset += sizeof(uint8); return True; } /******************************************************************* - Stream a uint16. + do IO on a pointer ********************************************************************/ +BOOL io_pointer(char *desc, prs_struct *ps, int depth, void **p, unsigned flags) +{ + uint32 v; + + if (!(flags & PARSE_SCALARS)) return True; -BOOL prs_uint16(char *name, prs_struct *ps, int depth, uint16 *data16, BOOL scalars) + v = (*p) ? 1 : 0; + if (!io_uint32(desc, ps, depth, &v, flags)) return False; + *p = (void *) (v ? 1 : 0); + return True; +} + +/****************************************************************** + do IO on a unicode array + ********************************************************************/ +BOOL io_wstring(char *name, prs_struct *ps, int depth, uint16 *data16s, int len, unsigned flags) { - char *q = prs_mem_get(ps, sizeof(uint16)); - if (q == NULL) - return False; + char *q; - DBG_RW_SVAL(name, depth, ps->data_offset, ps->io, ps->bigendian_data, q, *data16) - ps->data_offset += sizeof(uint16); + if (!(flags & PARSE_SCALARS)) return True; + + q = prs_mem_get(ps, len * sizeof(uint16)); + if (q == NULL) return False; + + DBG_RW_PSVAL(True, name, depth, ps->data_offset, ps->io, ps->bigendian_data, q, data16s, len) + ps->data_offset += (len * sizeof(uint16)); return True; } + + +/****************************************************************** +allocate some memory for a parse structure + ********************************************************************/ +BOOL io_alloc(char *name, prs_struct *ps, void **ptr, unsigned size) +{ + (*ptr) = (void *)malloc(size); + if (*ptr) return True; + return False; +} + diff --git a/source3/aparser/parser.h b/source3/aparser/parser.h index 353a879cb7..7d4425ed3e 100644 --- a/source3/aparser/parser.h +++ b/source3/aparser/parser.h @@ -1,6 +1,9 @@ #include #include "../include/byteorder.h" +#define PARSE_SCALARS (1<<0) +#define PARSE_BUFFERS (1<<1) + #ifndef MIN #define MIN(a,b) ((a)<(b)?(a):(b)) #endif @@ -54,15 +57,16 @@ typedef struct _prs_struct char *prs_mem_get(prs_struct *ps, uint32 extra_size); -BOOL prs_uint32(char *name, prs_struct *ps, int depth, uint32 *data32); BOOL prs_init(prs_struct *ps, uint32 size, uint8 align, BOOL io); void prs_debug(prs_struct *ps, int depth, char *desc, char *fn_name); BOOL prs_align(prs_struct *ps); void print_asc(int level, unsigned char *buf,int len); BOOL prs_read(prs_struct *ps, int fd, size_t len, int timeout); void dump_data(int level,char *buf1,int len); -BOOL prs_uint16s(BOOL charmode, char *name, prs_struct *ps, int depth, uint16 *data16s, int len); -BOOL prs_uint32s(BOOL charmode, char *name, prs_struct *ps, int depth, uint32 *data32s, int len); -BOOL prs_pointer(char *desc, prs_struct *ps, int depth, void **p); -BOOL prs_uint16(char *name, prs_struct *ps, int depth, uint16 *data16); +BOOL io_alloc(char *name, prs_struct *ps, void **ptr, unsigned size); +BOOL io_uint32(char *name, prs_struct *ps, int depth, uint32 *data32, unsigned flags); +BOOL io_uint16(char *name, prs_struct *ps, int depth, uint16 *data16, unsigned flags); +BOOL io_uint8(char *name, prs_struct *ps, int depth, uint8 *data8, unsigned flags); +BOOL io_pointer(char *desc, prs_struct *ps, int depth, void **p, unsigned flags); +BOOL io_wstring(char *name, prs_struct *ps, int depth, uint16 *data16s, int len, unsigned flags); diff --git a/source3/aparser/spool.struct b/source3/aparser/spool.struct index 52b0e3aed9..43f50ba1d6 100644 --- a/source3/aparser/spool.struct +++ b/source3/aparser/spool.struct @@ -1,16 +1,16 @@ module spool -test PRINTER_DRIVER_INFO_LEVEL_6 +test R_GETPRINTERDRIVER2 struct BUFFER5 { uint32 buf_len; - uint16 *buffer[buf_len]; + uint16 buffer[buf_len]; }; struct UNISTR2 { uint32 max_len; uint32 undoc; uint32 str_len; - uint16 *buffer[str_len]; + uint16 buffer[str_len]; }; struct UINT64_S { @@ -69,3 +69,13 @@ struct PRINTER_DRIVER_INFO { case 6 PRINTER_DRIVER_INFO_LEVEL_6 info_6; } }; + + +struct R_GETPRINTERDATA { + uint32 type; + uint32 size; + uint8 *data; + uint32 needed; + uint32 status; +}; + diff --git a/source3/aparser/srvsvc.struct b/source3/aparser/srvsvc.struct new file mode 100644 index 0000000000..61e67c4f4a --- /dev/null +++ b/source3/aparser/srvsvc.struct @@ -0,0 +1,73 @@ +module srvsvc +test SRV_R_NET_SHARE_ENUM + +struct UNISTR2 { + uint32 max_len; + uint32 undoc; + uint32 str_len; + uint16 buffer[str_len]; +}; + +/* function 15 */ +struct SRV_SHARE_INFO_1 { + UNISTR2 *uni_netname; + uint32 type; + UNISTR2 *uni_remark; +}; + +struct SHARE_ENUM { + uint32 level; + uint32 num_entries; + union info[level] { + case 1 SRV_SHARE_INFO_1 entries[num_entries]; + } +}; + +struct SRV_R_NET_SHARE_ENUM { + uint32 level; + uint32 dummy; + SHARE_ENUM *shares; + uint32 *num_entries; +}; + + + +/* function 21 */ +struct SERVER_INFO_100 { + uint32 dwPlatformID; + UNISTR2 *pszName; +}; + +struct SERVER_INFO_101 { + uint32 dwPlatformID; + UNISTR2 *pszName; + uint32 dwVerMajor; + uint32 dwVerMinor; + uint32 dwType; + UNISTR2 *pszComment; +}; + +struct SERVER_INFO_102 { + uint32 dwPlatformID; + UNISTR2 *pszName; + uint32 dwVerMajor; + uint32 dwVerMinor; + uint32 dwType; + UNISTR2 *pszComment; + uint32 dwUsers; + uint32 lDisc; + uint32 bHidden; + uint32 dwAnnounce; + uint32 dwAnnDelta; + uint32 dwLicenses; + UNISTR2 *pszUserPath; +}; + +struct SRV_R_NET_SERVER_INFO { + uint32 level; + union info[level] { + case 100 SERVER_INFO_100 *sv100; + case 101 SERVER_INFO_101 *sv101; + case 102 SERVER_INFO_102 *sv102; + } +}; diff --git a/source3/aparser/templates/fn_end.tpl b/source3/aparser/templates/fn_end.tpl index a21decdd13..38cf10d1b2 100644 --- a/source3/aparser/templates/fn_end.tpl +++ b/source3/aparser/templates/fn_end.tpl @@ -1,3 +1,6 @@ + +end: + /* the parse is OK, just align and end */ if (!prs_align(ps)) goto fail; return True; @@ -7,28 +10,4 @@ fail: return False; } /* @FUNCNAME@ */ -/******************************************************************* -parse a @STRUCTNAME@ structure -********************************************************************/ -BOOL @FUNCNAME@_alloc(char *desc, @STRUCTNAME@ **q_u, - prs_struct *ps, int depth) -{ - @STRUCTNAME@ *il; - BOOL ret; - - if (!UNMARSHALLING(ps)) return False; - - il=(@STRUCTNAME@ *)malloc(sizeof(@STRUCTNAME@)); - if (il == NULL) return False; - ZERO_STRUCTP(il); - - ret = @FUNCNAME@(desc, il, ps, depth); - if (!ret) { - free(il); - return False; - } - *q_u = il; - return True; -} - diff --git a/source3/aparser/templates/fn_mid.tpl b/source3/aparser/templates/fn_mid.tpl new file mode 100644 index 0000000000..b81de92a5b --- /dev/null +++ b/source3/aparser/templates/fn_mid.tpl @@ -0,0 +1,6 @@ + +buffers: + if (!(flags & PARSE_BUFFERS)) goto end; + + /* now parse the buffers */ + diff --git a/source3/aparser/templates/fn_start.tpl b/source3/aparser/templates/fn_start.tpl index deecc670e3..017f894f78 100644 --- a/source3/aparser/templates/fn_start.tpl +++ b/source3/aparser/templates/fn_start.tpl @@ -1,9 +1,13 @@ /******************************************************************* parse a @STRUCTNAME@ structure ********************************************************************/ -BOOL @FUNCNAME@(char *desc, @STRUCTNAME@ *il, - prs_struct *ps, int depth) +BOOL @FUNCNAME@(char *desc, prs_struct *ps, int depth, + @STRUCTNAME@ *il, unsigned flags) { prs_debug(ps, depth, desc, "@FUNCNAME@"); depth++; - + + if (!(flags & PARSE_SCALARS)) goto buffers; + + ZERO_STRUCTP(il); + /* parse the scalars */ diff --git a/source3/aparser/templates/harness_start.tpl b/source3/aparser/templates/harness_start.tpl index 375b110536..7e6ab9dc3a 100644 --- a/source3/aparser/templates/harness_start.tpl +++ b/source3/aparser/templates/harness_start.tpl @@ -1,6 +1,6 @@ #define TEST_STRUCT @STRUCTNAME@ #define TEST_NAME "@TEST@" -#define TEST_FUNC @FUNCNAME@_alloc +#define TEST_FUNC @FUNCNAME@ #include "prs_@MODULE@.h" diff --git a/source3/aparser/templates/ifptr_start.tpl b/source3/aparser/templates/ifptr_start.tpl index ffffe49e91..228b84bac9 100644 --- a/source3/aparser/templates/ifptr_start.tpl +++ b/source3/aparser/templates/ifptr_start.tpl @@ -1 +1,2 @@ if (il->@ELEM@) { + if (!io_alloc("@ELEM@", ps, (void **)&il->@ELEM@, sizeof(*(il->@ELEM@)))) goto fail; diff --git a/source3/aparser/templates/prs_array.tpl b/source3/aparser/templates/prs_array.tpl index ca707148db..1bf3fa4b04 100644 --- a/source3/aparser/templates/prs_array.tpl +++ b/source3/aparser/templates/prs_array.tpl @@ -1,7 +1,8 @@ - if (il->@ARRAYLEN@ > 0) { - il->@ELEM@ = (@TYPE@ *)malloc(sizeof(@TYPE@)*il->@ARRAYLEN@); - if (!il->@ELEM@) goto fail; - if (!prs_@TYPE@s(True, "@ELEM@", ps, depth+1, il->@ELEM@, il->@ARRAYLEN@)) goto fail; - } else { - il->@ELEM@ = NULL; + if ((@FLAGS@ & PARSE_SCALARS) && + !io_alloc("@ELEM@", ps, (void **)&il->@ELEM@, sizeof(*(il->@ELEM@))*il->@ARRAY_LEN@)) goto fail; + { + int i; + for (i=0;i@ARRAY_LEN@;i++) { + if (!io_@TYPE@("@ELEM@...", ps, depth+1, &il->@ELEM@[i], @FLAGS@)) goto fail; + } } diff --git a/source3/aparser/templates/prs_break.tpl b/source3/aparser/templates/prs_break.tpl new file mode 100644 index 0000000000..eb540f7be8 --- /dev/null +++ b/source3/aparser/templates/prs_break.tpl @@ -0,0 +1 @@ + break; diff --git a/source3/aparser/templates/prs_case.tpl b/source3/aparser/templates/prs_case.tpl index 2f81c35828..06c1bd3ae6 100644 --- a/source3/aparser/templates/prs_case.tpl +++ b/source3/aparser/templates/prs_case.tpl @@ -1 +1 @@ - case @VALUE@: + case @CASE@: diff --git a/source3/aparser/templates/prs_element.tpl b/source3/aparser/templates/prs_element.tpl new file mode 100644 index 0000000000..e8bf5180ce --- /dev/null +++ b/source3/aparser/templates/prs_element.tpl @@ -0,0 +1 @@ + if (!io_@TYPE@("@ELEM@", ps, depth+1, @PTR@il->@ELEM@, @FLAGS@)) goto fail; diff --git a/source3/aparser/templates/prs_pointer.tpl b/source3/aparser/templates/prs_pointer.tpl index 6ad1b99a01..4ebcf19d83 100644 --- a/source3/aparser/templates/prs_pointer.tpl +++ b/source3/aparser/templates/prs_pointer.tpl @@ -1,2 +1,2 @@ - if (!prs_pointer("@ELEM@_ptr", ps, depth+1, - (void **)&il->@ELEM@, True)) goto fail; + if (!io_pointer("@ELEM@_ptr", ps, depth+1, + (void **)&il->@ELEM@, @FLAGS@)) goto fail; diff --git a/source3/aparser/templates/prs_wstring.tpl b/source3/aparser/templates/prs_wstring.tpl new file mode 100644 index 0000000000..022381c2d2 --- /dev/null +++ b/source3/aparser/templates/prs_wstring.tpl @@ -0,0 +1,2 @@ + if (!io_alloc("@ELEM@", ps, (void **)&il->@ELEM@, sizeof(*(il->@ELEM@))*il->@ARRAY_LEN@)) goto fail; + if (!io_wstring("@ELEM@", ps, depth+1, il->@ELEM@, il->@ARRAY_LEN@, @FLAGS@)) goto fail; diff --git a/source3/aparser/templates/union_start.tpl b/source3/aparser/templates/union_start.tpl index a46c99c1e1..aa052be697 100644 --- a/source3/aparser/templates/union_start.tpl +++ b/source3/aparser/templates/union_start.tpl @@ -1,3 +1 @@ - il->@ELEM@ = (void *)malloc(sizeof(*(il->@ELEM@))); - if (!il->@ELEM@) goto fail; switch (il->@SWITCH@) { diff --git a/source3/aparser/vluke.c b/source3/aparser/vluke.c index 6c712d193e..312eeceb2c 100644 --- a/source3/aparser/vluke.c +++ b/source3/aparser/vluke.c @@ -11,7 +11,7 @@ int main(int argc, char *argv[]) { BOOL ret; - TEST_STRUCT *q_u; + TEST_STRUCT *il; char *desc = TEST_NAME; char *fname = argv[1]; int fd; @@ -31,7 +31,8 @@ int main(int argc, char *argv[]) prs_read(&ps, fd, st.st_size, 0); ps.data_offset = 0; ps.io = UNMARSHALL; - ret = TEST_FUNC(desc, &q_u, &ps, 1); + il = (TEST_STRUCT *)malloc(sizeof(*il)); + ret = TEST_FUNC(desc, &ps, 1, il, PARSE_SCALARS|PARSE_BUFFERS); printf("\nret=%s\n\n\n", ret?"OK":"Bad"); dump_data(0, ps.data_p, ps.grow_size); return !ret; -- cgit