diff options
author | Andrew Tridgell <tridge@samba.org> | 2000-05-14 14:05:10 +0000 |
---|---|---|
committer | Andrew Tridgell <tridge@samba.org> | 2000-05-14 14:05:10 +0000 |
commit | b7022e94d2ab62d522b0a7c2886cce3afaff6872 (patch) | |
tree | 6663fe08efd72d9a95d9cf4cf70baa07ded15aca /source3 | |
parent | b7f9a2794273266a0c64a6c02f88d65d37554ea9 (diff) | |
download | samba-b7022e94d2ab62d522b0a7c2886cce3afaff6872.tar.gz samba-b7022e94d2ab62d522b0a7c2886cce3afaff6872.tar.bz2 samba-b7022e94d2ab62d522b0a7c2886cce3afaff6872.zip |
vastly improved awk based code generator
now handles recursive function definitions, unions etc
it is sufficient for some basic types like UNISTR2 and BUFFER5
to be defined in the *.struct file and used successfully
this generator uses templates (in *.tpl files) for all code
generation, allowing easy replacement of the backend functions
(This used to be commit 14ded82dc92ae6eff7639351f391a33b9cc31c0d)
Diffstat (limited to 'source3')
31 files changed, 612 insertions, 168 deletions
diff --git a/source3/aparser/Makefile b/source3/aparser/Makefile index e74e99de18..160b11155a 100644 --- a/source3/aparser/Makefile +++ b/source3/aparser/Makefile @@ -1,20 +1,17 @@ CFLAGS=-Wall -g CC=gcc -%.h : %.struct - igawk -f parser.awk < $*.struct > $*.h - OBJ = vluke.o parser.o +AWKPROGS=dump.awk harness.awk header.awk parsefn.awk main.awk parsetree.awk template.awk util.awk all: test.h vluke -test.h : test.struct +test.h : $(AWKPROGS) + igawk -f main.awk spool.struct vluke: test.h $(OBJ) $(CC) $(CFLAGS) -o vluke $(OBJ) clean: - rm -f *.o test.h + rm -f *.o test.h prs_*.[ch] -test: vluke - ./vluke test.dat > test.out diff --git a/source3/aparser/dump.awk b/source3/aparser/dump.awk new file mode 100644 index 0000000000..0a72bb8414 --- /dev/null +++ b/source3/aparser/dump.awk @@ -0,0 +1,55 @@ +# dump the current parse tree + +function dump_union(f, struct_num, union, + LOCAL, i) +{ + xprintf(f,"\tunion %s %s {\n", + structs[struct_num, "unions", union, "switch"], + union); + for (i=0;i<structs[struct_num, "unions", union, "num_elems"];i++) { + xprintf(f,"\t\tcase %d %s %s;\n", + structs[struct_num, "unions", union, i, "value"], + structs[struct_num, "unions", union, i, "type"], + structs[struct_num, "unions", union, i, "elem"]); + } + xprintf(f,"\t}\n"); +} + +function dump_array(f, struct_num, elem_num, + LOCAL, i) +{ + xprintf(f,"\t{%s} %s %s;\n", + structs[struct_num, elem_num, "array_len"], + structs[struct_num, elem_num, "type"], + structs[struct_num, elem_num, "elem"]); +} + +function dump_elem(f, struct_num, elem_num) +{ + if (structs[struct_num, elem_num, "type"] == "union") { + dump_union(f, struct_num, structs[struct_num, elem_num, "elem"]); + } else if (structs[struct_num, elem_num, "array_len"]) { + dump_array(f, struct_num, elem_num); + } else { + xprintf(f,"\t%s %s;\n", + structs[struct_num, elem_num, "type"], + structs[struct_num, elem_num, "elem"]); + } +} + +function dump_structs(f, NIL, + LOCAL, i, j) +{ + xprintf(f,"/* dump of parsed structures */\n\n\n"); + for (i=0;i < num_structs;i++) { + xprintf(f,"/* structure %d */\n", i); + xprintf(f,"struct %s {\n", structs[i, "name"]); + for (j=0;j<structs[i, "num_elems"];j++) { + dump_elem(f, i, j); + } + xprintf(f,"};\n\n"); + } + xprintf(f,"/* end dump */\n\n"); +} + + diff --git a/source3/aparser/harness.awk b/source3/aparser/harness.awk new file mode 100644 index 0000000000..345fd6e191 --- /dev/null +++ b/source3/aparser/harness.awk @@ -0,0 +1,13 @@ +function produce_harness(f, + LOCAL, v, struct_num) +{ + struct_num=structs[test]; + + v["MODULE"]=module; + v["TEST"]=test; + v["TEST_FUNC"]=moduletest; + v["STRUCTNAME"] = structs[struct_num, "name"]; + v["FUNCNAME"] = v["MODULE"] "_io_" v["STRUCTNAME"]; + + print_template(f, "harness_start.tpl", v); +} diff --git a/source3/aparser/header.awk b/source3/aparser/header.awk new file mode 100644 index 0000000000..e7e5b2cff4 --- /dev/null +++ b/source3/aparser/header.awk @@ -0,0 +1,60 @@ +# produce a header file for a parsed struct file + +function header_union(f, struct_num, union, + LOCAL, i) +{ + xprintf(f,"\tunion {\n"); + for (i=0;i<structs[struct_num, "unions", union, "num_elems"];i++) { + xprintf(f,"\t\t%s %s;\n", + structs[struct_num, "unions", union, i, "type"], + structs[struct_num, "unions", union, i, "elem"]); + } + xprintf(f,"\t} %s;\n", union); +} + +function header_array(f, struct_num, elem_num) +{ + xprintf(f,"\t%s *%s; /* array of length %s */ \n", + structs[struct_num, elem_num, "type"], + structs[struct_num, elem_num, "elem"], + structs[struct_num, elem_num, "array_len"]); +} + +function header_elem(f, struct_num, elem_num) +{ + if (structs[struct_num, elem_num, "type"] == ".align") return; + + if (structs[struct_num, elem_num, "type"] == "union") { + header_union(f, struct_num, structs[struct_num, elem_num, "elem"]); + } else if (structs[struct_num, elem_num, "array_len"]) { + header_array(f, struct_num, elem_num); + } else { + xprintf(f,"\t%s %s;\n", + structs[struct_num, elem_num, "type"], + structs[struct_num, elem_num, "elem"]); + } +} + +function header_struct(f, struct_num, + LOCAL, i) +{ + xprintf(f,"/* structure %s */\n", + structs[struct_num, "name"]); + xprintf(f,"typedef struct {\n"); + for (i=0;i < structs[struct_num, "num_elems"];i++) { + header_elem(f, struct_num, i); + } + xprintf(f,"} %s;\n\n\n", structs[struct_num, "name"]); +} + + +function produce_headers(f, NIL, + LOCAL, i) +{ + xprintf(f,"/* auto-generated headers for %s */\n\n\n", module); + for (i=0;i < num_structs;i++) { + header_struct(f, i); + } + xprintf(f,"/* end auto-generated headers */\n\n"); +} + diff --git a/source3/aparser/main.awk b/source3/aparser/main.awk new file mode 100644 index 0000000000..c3e8c2539c --- /dev/null +++ b/source3/aparser/main.awk @@ -0,0 +1,63 @@ +# the main program + +@include dump.awk +@include parsetree.awk +@include header.awk +@include util.awk +@include template.awk +@include parsefn.awk +@include harness.awk + +/^module/ { + start_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; +} + +/^[ \t]*\}/ { + end_union(); + next; +} + +/^[ \t]*\{.*\}.*;/ { + split($0,a,"[ \t;{}]*"); + add_array(a[2], a[3], a[4]); + next; +} + +/.*;/ { + split($0,a,"[ \t;]*"); + add_elem(a[2], a[3]); +} + +END { + dump_structs("debug.out"); + produce_headers("prs_"module".h"); + produce_parsers("prs_"module".c"); + produce_harness("test.h"); +} diff --git a/source3/aparser/parsefn.awk b/source3/aparser/parsefn.awk new file mode 100644 index 0000000000..b3421a7e54 --- /dev/null +++ b/source3/aparser/parsefn.awk @@ -0,0 +1,123 @@ +# build parse functions for a parsed struct file + +function parse_elem(f, v, struct_num, elem_num, + LOCAL, type, elem) +{ + type = structs[struct_num, elem_num, "type"]; + elem = structs[struct_num, elem_num, "elem"]; + v["ELEM"] = noptr(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); + } + } else { + print_template(f, "prs_"type".tpl", v); + } +} + + +function parse_pointer(f, v, struct_num, elem_num, + LOCAL, elem) +{ + elem = structs[struct_num, elem_num, "elem"]; + v["ELEM"] = noptr(elem); + print_template(f, "prs_pointer.tpl", v); +} + +function parse_array(f, v, struct_num, elem_num, + LOCAL, elem, type) +{ + 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; + v["TYPE"] = type; + print_template(f, "prs_array.tpl", v); +} + +function parse_union(f, v, struct_num, elem_num, + LOCAL, union, type, i, elem, value) +{ + union = structs[struct_num, elem_num, "elem"]; + v["UNION"] = noptr(union); + v["SWITCH"] = structs[struct_num, "unions", union, "switch"]; + + print_template(f, "union_start.tpl", v); + for (i=0;i<structs[struct_num, "unions", union, "num_elems"];i++) { + elem = structs[struct_num, "unions", union, i, "elem"]; + type = structs[struct_num, "unions", union, i, "type"]; + value = structs[struct_num, "unions", union, i, "value"]; + v["ELEM"] = v["UNION"]"->"noptr(elem); + v["TYPE"] = type; + v["VALUE"] = value; + print_template(f, "prs_case.tpl", v); + if (structs[type] != "") { + print_template(f, "prs_struct.tpl", v); + } else { + print_template(f, "prs_"type".tpl", v); + } + print_template(f, "prs_case_end.tpl", v); + } + + print_template(f, "union_end.tpl", v); +} + +function parse_ptr_elem(f, v, struct_num, elem_num, + LOCAL, elem, type) +{ + elem = structs[struct_num, elem_num, "elem"]; + type = structs[struct_num, elem_num, "type"]; + v["ELEM"] = noptr(elem); + print_template(f, "ifptr_start.tpl", v); + if (type == "union") { + parse_union(f, v, struct_num, elem_num); + } else { + parse_elem(f, v, struct_num, elem_num); + } + print_template(f, "ifptr_end.tpl", v); +} + + +function struct_parser(f, v, struct_num, + LOCAL, i) +{ + v["STRUCTNAME"] = structs[struct_num, "name"]; + v["FUNCNAME"] = v["MODULE"] "_io_" v["STRUCTNAME"]; + print_template(f, "fn_start.tpl", v); + + # first all the structure pointers, scalars and arrays + for (i=0;i<structs[struct_num, "num_elems"];i++) { + if (isaptr(structs[struct_num, i, "elem"])) { + parse_pointer(f, v, struct_num, i); + } else if (structs[struct_num, i, "array_len"]) { + parse_array(f, v, struct_num, i); + } else { + parse_elem(f, v, struct_num, i); + } + } + + # now the structures + for (i=0;i<structs[struct_num, "num_elems"];i++) { + if (!isaptr(structs[struct_num, i, "elem"])) continue; + parse_ptr_elem(f, v, struct_num, i); + } + + print_template(f, "fn_end.tpl", v); +} + +function produce_parsers(f, + LOCAL, v) +{ + v["MODULE"]=module; + + print_template(f, "module_start.tpl", v); + + for (i=0;i < num_structs;i++) { + struct_parser(f, v, i); + } + + print_template(f, "module_end.tpl", v); +} diff --git a/source3/aparser/parser.c b/source3/aparser/parser.c index f938c58e8b..72042ba9f7 100644 --- a/source3/aparser/parser.c +++ b/source3/aparser/parser.c @@ -198,101 +198,6 @@ BOOL prs_align(prs_struct *ps) return True; } -/******************************************************************* - Reads or writes an NTTIME structure. -********************************************************************/ - -BOOL smb_io_time(char *desc, NTTIME *nttime, prs_struct *ps, int depth) -{ - if (nttime == NULL) - return False; - - prs_debug(ps, depth, desc, "smb_io_time"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("low ", ps, depth, &nttime->low)) /* low part */ - return False; - if(!prs_uint32("high", ps, depth, &nttime->high)) /* high part */ - return False; - - return True; -} - - -/******************************************************************* - Reads or writes a UNISTR2 structure. - XXXX NOTE: UNISTR2 structures need NOT be null-terminated. - the uni_str_len member tells you how long the string is; - the uni_max_len member tells you how large the buffer is. -********************************************************************/ - -BOOL smb_io_unistr2(char *desc, UNISTR2 *uni2, uint32 buffer, prs_struct *ps, int depth) -{ - if (uni2 == NULL) - return False; - - if (buffer) { - - prs_debug(ps, depth, desc, "smb_io_unistr2"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("uni_max_len", ps, depth, &uni2->uni_max_len)) - return False; - if(!prs_uint32("undoc ", ps, depth, &uni2->undoc)) - return False; - if(!prs_uint32("uni_str_len", ps, depth, &uni2->uni_str_len)) - return False; - - /* oops! XXXX maybe issue a warning that this is happening... */ - if (uni2->uni_max_len > MAX_UNISTRLEN) - uni2->uni_max_len = MAX_UNISTRLEN; - if (uni2->uni_str_len > MAX_UNISTRLEN) - uni2->uni_str_len = MAX_UNISTRLEN; - - /* buffer advanced by indicated length of string - NOT by searching for null-termination */ - if(!prs_unistr2(True, "buffer ", ps, depth, uni2)) - return False; - - } else { - - prs_debug(ps, depth, desc, "smb_io_unistr2 - NULL"); - depth++; - memset((char *)uni2, '\0', sizeof(*uni2)); - - } - - return True; -} - -/****************************************************************** - Stream a unicode string, length/buffer specified separately, - in uint16 chars. We use DBG_RW_PCVAL, not DBG_RW_PSVAL here - as the unicode string is already in little-endian format. - ********************************************************************/ - -BOOL prs_unistr2(BOOL charmode, char *name, prs_struct *ps, int depth, UNISTR2 *str) -{ - char *p = (char *)str->buffer; - char *q = prs_mem_get(ps, str->uni_str_len * sizeof(uint16)); - if (q == NULL) - return False; - - /* If we're using big-endian, reverse to get little-endian. */ - if(ps->bigendian_data) - DBG_RW_PSVAL(charmode, name, depth, ps->data_offset, ps->io, ps->bigendian_data, q, p, str->uni_str_len) - else - DBG_RW_PCVAL(charmode, name, depth, ps->data_offset, ps->io, q, p, str->uni_str_len * 2) - ps->data_offset += (str->uni_str_len * sizeof(uint16)); - - return True; -} void print_asc(int level, unsigned char *buf,int len) { @@ -358,54 +263,44 @@ void dump_data(int level,char *buf1,int len) } /******************************************************************* - Stream a uint64_struct + Stream a pointer ********************************************************************/ -BOOL prs_uint64(char *desc, prs_struct *ps, int depth, UINT64_S *data64) +BOOL prs_pointer(char *desc, prs_struct *ps, int depth, void **p) { - prs_debug(ps, depth, desc, "prs_uint64"); - return prs_uint32("low", ps, depth+1, &data64->low) && - prs_uint32("high", ps, depth+1, &data64->high); + uint32 v; + if (!prs_uint32(desc, ps, depth, &v)) return False; + *p = (void *) (v ? 1 : 0); + return True; } +/****************************************************************** + Stream an array of uint16s. Length is number of uint16s. + ********************************************************************/ - -/******************************************************************* -reads or writes a BUFFER5 structure. -the buf_len member tells you how large the buffer is. -********************************************************************/ -BOOL smb_io_buffer5(char *desc, BUFFER5 *buf5, prs_struct *ps, int depth) +BOOL prs_uint16s(BOOL charmode, char *name, prs_struct *ps, int depth, uint16 *data16s, int len) { - prs_debug(ps, depth, desc, "smb_io_buffer5"); - depth++; - - if (buf5 == NULL) return False; - - prs_align(ps); - prs_uint32("buf_len", ps, depth, &(buf5->buf_len)); + char *q = prs_mem_get(ps, len * sizeof(uint16)); + if (q == NULL) + return False; - /* reading: alloc the buffer first */ - if ( ps->io ) - { - buf5->buffer=(uint16 *)malloc( sizeof(uint16)*buf5->buf_len ); - } - - prs_uint16s(True, "buffer", ps, depth, buf5->buffer, buf5->buf_len); + DBG_RW_PSVAL(charmode, name, depth, ps->data_offset, ps->io, ps->bigendian_data, q, data16s, len) + ps->data_offset += (len * sizeof(uint16)); return True; } /****************************************************************** - Stream an array of uint16s. Length is number of uint16s. + Stream an array of uint32s. Length is number of uint32s. ********************************************************************/ -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) { - char *q = prs_mem_get(ps, len * sizeof(uint16)); + char *q = prs_mem_get(ps, len * sizeof(uint32)); if (q == NULL) return False; - DBG_RW_PSVAL(charmode, name, depth, ps->data_offset, ps->io, ps->bigendian_data, q, data16s, len) - ps->data_offset += (len * sizeof(uint16)); + DBG_RW_PIVAL(charmode, name, depth, ps->data_offset, ps->io, ps->bigendian_data, q, data32s, len) + ps->data_offset += (len * sizeof(uint32)); return True; } diff --git a/source3/aparser/parser.h b/source3/aparser/parser.h index 196aa6b855..ec3fc7edc2 100644 --- a/source3/aparser/parser.h +++ b/source3/aparser/parser.h @@ -32,39 +32,10 @@ typedef char pstring[1024]; /* zero a structure given a pointer to the structure */ #define ZERO_STRUCTP(x) { if ((x) != NULL) memset((char *)(x), 0, sizeof(*(x))); } -typedef struct { - uint32 low; - uint32 high; -} UINT64_S; - -typedef struct -{ - uint32 low; - uint32 high; -} NTTIME; - #define MAX_UNISTRLEN 256 #define MAX_STRINGLEN 256 #define MAX_BUFFERLEN 512 -/* UNISTR2 - unicode string size (in uint16 unicode chars) and buffer */ -typedef struct unistr2_info -{ - uint32 uni_max_len; - uint32 undoc; - uint32 uni_str_len; - /* unicode characters. ***MUST*** be little-endian. **NOT** necessarily null-terminated */ - uint16 buffer[MAX_UNISTRLEN]; - -} UNISTR2; - -/* BUFFER5 */ -typedef struct buffer5_info -{ - uint32 buf_len; - uint16 *buffer; /* data */ -} BUFFER5; - typedef struct _prs_struct { BOOL io; /* parsing in or out of data stream */ @@ -86,13 +57,10 @@ 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); -BOOL smb_io_time(char *desc, NTTIME *nttime, prs_struct *ps, int depth); -BOOL smb_io_unistr2(char *desc, UNISTR2 *uni2, uint32 buffer, prs_struct *ps, int depth); -BOOL prs_unistr2(BOOL charmode, char *name, prs_struct *ps, int depth, UNISTR2 *str); 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_uint64(char *name, prs_struct *ps, int depth, UINT64_S *data64); -BOOL smb_io_buffer5(char *desc, BUFFER5 *buf5, prs_struct *ps, int depth); 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); diff --git a/source3/aparser/parsetree.awk b/source3/aparser/parsetree.awk new file mode 100644 index 0000000000..e0f946a663 --- /dev/null +++ b/source3/aparser/parsetree.awk @@ -0,0 +1,64 @@ +# build the parse tree for a struct file + +function start_module(name) +{ + module=name; + num_structs=0; +} + +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; +} + +function end_struct() +{ + num_structs++; + current_struct=""; +} + +function add_elem(type, elem, + LOCAL, elem_num) +{ + elem_num=structs[current_struct, "num_elems"]; + structs[current_struct, elem_num, "type"] = type; + structs[current_struct, elem_num, "elem"] = elem; + structs[current_struct, elem_num, "array_len"] = ""; + structs[current_struct, "num_elems"]++; + return elem_num; +} + +function add_array(array_len, type, elem, + LOCAL, elem_num) +{ + elem_num=add_elem(type, elem); + structs[current_struct, elem_num, "array_len"] = array_len; +} + +function start_union(switch, elem) +{ + current_union=elem; + add_elem("union", elem); + structs[current_struct, "unions", current_union, "switch"] = switch; + structs[current_struct, "unions", current_union, "num_elems"] = 0; +} + +function parse_case(value, type, elem, + LOCAL, elem_num) +{ + elem_num =structs[current_struct, "unions", current_union, "num_elems"]; + structs[current_struct, "unions", current_union, elem_num, "type"] = type; + structs[current_struct, "unions", current_union, elem_num, "elem"] = elem; + structs[current_struct, "unions", current_union, elem_num, "value"] = value; + structs[current_struct, "unions", current_union, "num_elems"]++; +} + +function end_union() +{ + current_union=""; +} + diff --git a/source3/aparser/spool.struct b/source3/aparser/spool.struct new file mode 100644 index 0000000000..319a09941d --- /dev/null +++ b/source3/aparser/spool.struct @@ -0,0 +1,76 @@ +module spool +test PRINTER_DRIVER_INFO_LEVEL_3 + +struct BUFFER5 { + .align 4; + uint32 buf_len; + {buf_len} uint16 buffer; +}; + +struct UNISTR2 { + .align 4; + uint32 max_len; + uint32 undoc; + uint32 str_len; + {str_len} uint16 buffer; +}; + +struct UINT64_S { + uint32 low; + uint32 high; +}; + +struct NTTIME { + uint32 low; + uint32 high; +}; + +struct PRINTER_DRIVER_INFO_LEVEL_3 { + .align 4; + uint32 cversion; + UNISTR2 *name; + UNISTR2 *environment; + UNISTR2 *driverpath; + UNISTR2 *datafile; + UNISTR2 *configfile; + UNISTR2 *helpfile; + UNISTR2 *monitorname; + UNISTR2 *defaultdatatype; + uint32 dependentfiles_len; + BUFFER5 *dependentfiles; +}; + +struct PRINTER_DRIVER_INFO_LEVEL_6 { + .align 4; + uint32 dummy1; + uint32 version; + UNISTR2 *name; + UNISTR2 *environment; + UNISTR2 *driverpath; + UNISTR2 *datafile; + UNISTR2 *configfile; + UNISTR2 *helpfile; + UNISTR2 *monitorname; + UNISTR2 *defaultdatatype; + uint32 dependentfiles_len; + BUFFER5 *dependentfiles; + uint32 previousnames_len; + BUFFER5 *previousnames; + NTTIME driverdate; + UINT64_S driverversion; + uint32 dummy4; + UNISTR2 *mfgname; + UNISTR2 *oemurl; + UNISTR2 *hardwareid; + UNISTR2 *provider; +}; + + +struct PRINTER_DRIVER_INFO { + .align 4; + 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/template.awk b/source3/aparser/template.awk new file mode 100644 index 0000000000..ddaa604b99 --- /dev/null +++ b/source3/aparser/template.awk @@ -0,0 +1,17 @@ +# template file handling + +function print_template(f, tplname, v, + LOCAL, i, pat, line) +{ + if (numlines(tplname) <= 0) fatal("no template "tplname); + while ((getline line < tplname) > 0) { + while ((i = match(line,"@[a-zA-Z_]*@")) != 0) { + pat=substr(line,i+1,RLENGTH-2); + if (v[pat] == "") fatal("no value for "pat" in "tplname); + gsub("@"pat"@", v[pat], line); + } + + xprintf(f, "%s\n", line); + } + close(tplname); +} diff --git a/source3/aparser/templates/fn_end.tpl b/source3/aparser/templates/fn_end.tpl new file mode 100644 index 0000000000..b5c36fff35 --- /dev/null +++ b/source3/aparser/templates/fn_end.tpl @@ -0,0 +1,33 @@ + + return True; + +fail: + ZERO_STRUCTP(il); + 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_start.tpl b/source3/aparser/templates/fn_start.tpl new file mode 100644 index 0000000000..deecc670e3 --- /dev/null +++ b/source3/aparser/templates/fn_start.tpl @@ -0,0 +1,9 @@ +/******************************************************************* +parse a @STRUCTNAME@ structure +********************************************************************/ +BOOL @FUNCNAME@(char *desc, @STRUCTNAME@ *il, + prs_struct *ps, int depth) +{ + prs_debug(ps, depth, desc, "@FUNCNAME@"); + depth++; + diff --git a/source3/aparser/templates/harness_start.tpl b/source3/aparser/templates/harness_start.tpl new file mode 100644 index 0000000000..375b110536 --- /dev/null +++ b/source3/aparser/templates/harness_start.tpl @@ -0,0 +1,7 @@ +#define TEST_STRUCT @STRUCTNAME@ +#define TEST_NAME "@TEST@" +#define TEST_FUNC @FUNCNAME@_alloc + + +#include "prs_@MODULE@.h" +#include "prs_@MODULE@.c" diff --git a/source3/aparser/templates/ifptr_end.tpl b/source3/aparser/templates/ifptr_end.tpl new file mode 100644 index 0000000000..990635cf45 --- /dev/null +++ b/source3/aparser/templates/ifptr_end.tpl @@ -0,0 +1 @@ + } diff --git a/source3/aparser/templates/ifptr_start.tpl b/source3/aparser/templates/ifptr_start.tpl new file mode 100644 index 0000000000..ffffe49e91 --- /dev/null +++ b/source3/aparser/templates/ifptr_start.tpl @@ -0,0 +1 @@ + if (il->@ELEM@) { diff --git a/source3/aparser/templates/module_end.tpl b/source3/aparser/templates/module_end.tpl new file mode 100644 index 0000000000..661f7edb95 --- /dev/null +++ b/source3/aparser/templates/module_end.tpl @@ -0,0 +1,3 @@ + + +/* end auto-generated structure parsers for @MODULE@ */ diff --git a/source3/aparser/templates/module_start.tpl b/source3/aparser/templates/module_start.tpl new file mode 100644 index 0000000000..fef9d296ff --- /dev/null +++ b/source3/aparser/templates/module_start.tpl @@ -0,0 +1,5 @@ +/* auto-generated structure parsers for @MODULE@ + generated by aparser +*/ + + diff --git a/source3/aparser/templates/prs_.align.tpl b/source3/aparser/templates/prs_.align.tpl new file mode 100644 index 0000000000..d5b2ceb082 --- /dev/null +++ b/source3/aparser/templates/prs_.align.tpl @@ -0,0 +1 @@ + if(!prs_align(ps)) goto fail; diff --git a/source3/aparser/templates/prs_array.tpl b/source3/aparser/templates/prs_array.tpl new file mode 100644 index 0000000000..ca707148db --- /dev/null +++ b/source3/aparser/templates/prs_array.tpl @@ -0,0 +1,7 @@ + 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; + } diff --git a/source3/aparser/templates/prs_case.tpl b/source3/aparser/templates/prs_case.tpl new file mode 100644 index 0000000000..2f81c35828 --- /dev/null +++ b/source3/aparser/templates/prs_case.tpl @@ -0,0 +1 @@ + case @VALUE@: diff --git a/source3/aparser/templates/prs_case_end.tpl b/source3/aparser/templates/prs_case_end.tpl new file mode 100644 index 0000000000..eb540f7be8 --- /dev/null +++ b/source3/aparser/templates/prs_case_end.tpl @@ -0,0 +1 @@ + break; diff --git a/source3/aparser/templates/prs_pointer.tpl b/source3/aparser/templates/prs_pointer.tpl new file mode 100644 index 0000000000..f268c259bc --- /dev/null +++ b/source3/aparser/templates/prs_pointer.tpl @@ -0,0 +1 @@ + if (!prs_pointer("@ELEM@_ptr", ps, depth+1, (void **)&il->@ELEM@)) goto fail; diff --git a/source3/aparser/templates/prs_struct.tpl b/source3/aparser/templates/prs_struct.tpl new file mode 100644 index 0000000000..ab8246db8e --- /dev/null +++ b/source3/aparser/templates/prs_struct.tpl @@ -0,0 +1 @@ + if (!@MODULE@_io_@TYPE@("@ELEM@", &il->@ELEM@, ps, depth+1)) goto fail; diff --git a/source3/aparser/templates/prs_struct_alloc.tpl b/source3/aparser/templates/prs_struct_alloc.tpl new file mode 100644 index 0000000000..9eae5c92fc --- /dev/null +++ b/source3/aparser/templates/prs_struct_alloc.tpl @@ -0,0 +1 @@ + if (!@MODULE@_io_@TYPE@_alloc("@ELEM@", &il->@ELEM@, ps, depth+1)) goto fail; diff --git a/source3/aparser/templates/prs_uint16.tpl b/source3/aparser/templates/prs_uint16.tpl new file mode 100644 index 0000000000..36b8298fb2 --- /dev/null +++ b/source3/aparser/templates/prs_uint16.tpl @@ -0,0 +1 @@ + if (!prs_uint16("@ELEM@", ps, depth+1, &il->@ELEM@)) goto fail; diff --git a/source3/aparser/templates/prs_uint32.tpl b/source3/aparser/templates/prs_uint32.tpl new file mode 100644 index 0000000000..2e2fd638e4 --- /dev/null +++ b/source3/aparser/templates/prs_uint32.tpl @@ -0,0 +1 @@ + if (!prs_uint32("@ELEM@", ps, depth+1, &il->@ELEM@)) goto fail; diff --git a/source3/aparser/templates/union_end.tpl b/source3/aparser/templates/union_end.tpl new file mode 100644 index 0000000000..511adbcf60 --- /dev/null +++ b/source3/aparser/templates/union_end.tpl @@ -0,0 +1,5 @@ + default: + DEBUG(5,("No handler for case %d in @FUNCNAME@\n", + (int)il->@SWITCH@)); + goto fail; + } diff --git a/source3/aparser/templates/union_start.tpl b/source3/aparser/templates/union_start.tpl new file mode 100644 index 0000000000..aa052be697 --- /dev/null +++ b/source3/aparser/templates/union_start.tpl @@ -0,0 +1 @@ + switch (il->@SWITCH@) { diff --git a/source3/aparser/util.awk b/source3/aparser/util.awk new file mode 100644 index 0000000000..93f9a4dcd2 --- /dev/null +++ b/source3/aparser/util.awk @@ -0,0 +1,33 @@ +function isaptr(elem) +{ + if (substr(elem, 1, 1) == "*") { + return 1; + } + return 0; +} + +function noptr(elem) +{ + if (!isaptr(elem)) return elem; + return substr(elem, 2); +} + +function xprintf(f, fmt, v1, v2, v3, v4, v5, v6, v7) +{ + printf(fmt, v1, v2, v3, v4, v5, v6) > f; +} + +function fatal(why) +{ + printf("FATAL: %s\n", why); + exit 1; +} + +function numlines(fname, + LOCAL, line, count) +{ + count=0; + while ((getline line < fname) > 0) count++; + close(fname); + return count; +} diff --git a/source3/aparser/vluke.c b/source3/aparser/vluke.c index fb7cc36b88..82dbf20036 100644 --- a/source3/aparser/vluke.c +++ b/source3/aparser/vluke.c @@ -29,10 +29,10 @@ int main(int argc, char *argv[]) prs_init(&ps, 0, 4, MARSHALL); ps.is_dynamic=True; prs_read(&ps, fd, st.st_size, 0); - dump_data(0, ps.data_p, ps.buffer_size); ps.data_offset = 0; ps.io = UNMARSHALL; ret = TEST_FUNC(desc, &q_u, &ps, 1); - printf("ret=%d\n", ret); + printf("\nret=%s\n\n\n", ret?"OK":"Bad"); + dump_data(0, ps.data_p, ps.buffer_size); return !ret; } |