diff options
author | Andrew Tridgell <tridge@samba.org> | 2000-06-09 02:59:50 +0000 |
---|---|---|
committer | Andrew Tridgell <tridge@samba.org> | 2000-06-09 02:59:50 +0000 |
commit | eee003da6aee5ffc00e318fc0390e6b19151a675 (patch) | |
tree | 3cdb43304603d5bc38c2b2609fa8696731c898d5 | |
parent | c3487b00dd1dde7fa0511211f466acc1c05d8f3d (diff) | |
download | samba-eee003da6aee5ffc00e318fc0390e6b19151a675.tar.gz samba-eee003da6aee5ffc00e318fc0390e6b19151a675.tar.bz2 samba-eee003da6aee5ffc00e318fc0390e6b19151a675.zip |
started adding support for relative, plus options for autoalignment
so the same parser generator can be uses for cifs and rpc
(This used to be commit c7829fa0d87081d9b3f33468527583e3b763916b)
-rw-r--r-- | source3/aparser/Makefile | 2 | ||||
-rwxr-xr-x | source3/aparser/build | 2 | ||||
-rw-r--r-- | source3/aparser/cifs.struct | 3 | ||||
-rw-r--r-- | source3/aparser/dump.awk | 6 | ||||
-rw-r--r-- | source3/aparser/header.awk | 10 | ||||
-rw-r--r-- | source3/aparser/main.awk | 9 | ||||
-rw-r--r-- | source3/aparser/parser.c | 20 | ||||
-rw-r--r-- | source3/aparser/parser.h | 19 | ||||
-rw-r--r-- | source3/aparser/parserel.awk | 213 | ||||
-rw-r--r-- | source3/aparser/parsetree.awk | 12 | ||||
-rw-r--r-- | source3/aparser/spool.struct | 36 | ||||
-rw-r--r-- | source3/aparser/srvsvc2.struct | 5 | ||||
-rw-r--r-- | source3/aparser/templates/module_start.tpl | 1 | ||||
-rw-r--r-- | source3/aparser/token.awk | 5 | ||||
-rw-r--r-- | source3/aparser/util.awk | 6 | ||||
-rw-r--r-- | source3/aparser/util.c | 112 | ||||
-rw-r--r-- | source3/aparser/vluke.c | 2 |
17 files changed, 421 insertions, 42 deletions
diff --git a/source3/aparser/Makefile b/source3/aparser/Makefile index 68e63193c2..953743b234 100644 --- a/source3/aparser/Makefile +++ b/source3/aparser/Makefile @@ -1,7 +1,7 @@ CFLAGS=-Wall -g CC=gcc -OBJ = vluke.o parser.o util.o +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 diff --git a/source3/aparser/build b/source3/aparser/build index 574cad9620..4cdf2901f8 100755 --- a/source3/aparser/build +++ b/source3/aparser/build @@ -8,6 +8,6 @@ if ! igawk -f main.awk $file; then fi echo compiling vluke -gcc -Wall -o vluke parser.c vluke.c util.c +gcc -Wall -g -o vluke parser.c vluke.c util.c echo done. diff --git a/source3/aparser/cifs.struct b/source3/aparser/cifs.struct index 9bafa1f930..202f0d7e61 100644 --- a/source3/aparser/cifs.struct +++ b/source3/aparser/cifs.struct @@ -1,5 +1,8 @@ module cifs +option autoalign False + + #define BOOL uint32 #define UCHAR uint8 #define WCHAR uint16 diff --git a/source3/aparser/dump.awk b/source3/aparser/dump.awk index 65e5675513..11bfb107e4 100644 --- a/source3/aparser/dump.awk +++ b/source3/aparser/dump.awk @@ -52,6 +52,12 @@ function dump_structs(f, NIL, LOCAL, i, j) { xprintf(f,"/* dump of parsed structures */\n\n\n"); + + for (i=0;i < num_options;i++) { + xprintf(f,"option %s %s\n", options[i, "name"], options[i, "value"]); + } + xprintf(f,"\n\n"); + for (i=0;i < num_structs;i++) { xprintf(f,"/* structure %d */\n", i); xprintf(f,"struct %s {\n", structs[i, "name"]); diff --git a/source3/aparser/header.awk b/source3/aparser/header.awk index 900985b84b..ba7117436b 100644 --- a/source3/aparser/header.awk +++ b/source3/aparser/header.awk @@ -7,7 +7,7 @@ function header_elstring(elnum, elem=elements[elnum, "elem"]; if (elements[elnum, "ptr"]=="1") elem="*"elem; if (array_len!="") { - if (match(array_len,"[0-9]") == 1) { + if (is_constant(array_len) == 1) { elem=elem"["array_len"]"; } else { elem="*"elem; @@ -63,6 +63,14 @@ function produce_headers(f, NIL, xprintf(f,"/* auto-generated headers for %s */\n\n\n", module); xprintf(f,"#ifndef _%s_\n", module); xprintf(f,"#define _%s_\n", module); + + xprintf(f,"\n\n"); + for (i=0;i < num_options;i++) { + xprintf(f,"#define OPTION_%s %s\n", + options[i, "name"], options[i, "value"]); + } + xprintf(f,"\n\n"); + for (i=0;i < num_structs;i++) { header_struct(f, i); } diff --git a/source3/aparser/main.awk b/source3/aparser/main.awk index 7163dbc829..4969f2217a 100644 --- a/source3/aparser/main.awk +++ b/source3/aparser/main.awk @@ -4,7 +4,8 @@ @include header.awk @include util.awk @include template.awk -@include parsefn.awk +#@include parsefn.awk +@include parserel.awk @include harness.awk @include parsetree.awk @include token.awk @@ -13,8 +14,10 @@ END { dump_structs("dump.out"); printf("Producing headers...\n"); produce_headers("prs_"module".h"); - printf("Producing parsers...\n"); - produce_parsers("prs_"module".c", "mod_"module".c"); +# printf("Producing parsers...\n"); +# produce_parsers("prs_"module".c", "mod_"module".c"); + printf("Producing relative parsers...\n"); + produce_relative("prs_"module".c"); printf("Producing harness...\n"); produce_harness("test.h"); printf("Done.\n"); diff --git a/source3/aparser/parser.c b/source3/aparser/parser.c index f831393973..c2348b84f9 100644 --- a/source3/aparser/parser.c +++ b/source3/aparser/parser.c @@ -1,5 +1,4 @@ -#include "includes.h" - +#include "parser.h" /******************************************************************* Attempt, if needed, to grow a data buffer. @@ -33,12 +32,7 @@ BOOL io_grow(io_struct *ps, uint32 extra_space) extra_space -= (ps->buffer_size - ps->data_offset); if(ps->buffer_size == 0) { - /* - * Ensure we have at least a PDU's length, or extra_space, whichever - * is greater. - */ - - new_size = MAX(MAX_PDU_FRAG_LEN,extra_space); + new_size = extra_space; if((new_data = malloc(new_size)) == NULL) { DEBUG(0,("io_grow: Malloc failure for size %u.\n", (unsigned int)new_size)); @@ -169,10 +163,12 @@ BOOL io_align4(io_struct *ps, int offset) BOOL io_align(io_struct *ps, int align) { - uint32 mod = ps->data_offset & (align-1); + uint32 mod; + + if (!ps->autoalign) return True; + + mod = ps->data_offset & (align-1); - return True; /* HACK! */ - if (align != 0 && mod != 0) { uint32 extra_space = (align - mod); if(!io_grow(ps, extra_space)) @@ -430,7 +426,7 @@ BOOL io_wstring(char *name, io_struct *ps, int depth, uint16 *data16s, int len, q = io_mem_get(ps, len * sizeof(uint16)); if (q == NULL) return False; - DBG_RW_PSVAL(False, name, depth, ps->data_offset, ps->io, ps->bigendian_data, q, data16s, len) + 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; diff --git a/source3/aparser/parser.h b/source3/aparser/parser.h index e5e5a757cb..3d6540d8a7 100644 --- a/source3/aparser/parser.h +++ b/source3/aparser/parser.h @@ -1,4 +1,9 @@ #include <ctype.h> +#include <stdio.h> +#include <malloc.h> +#include <unistd.h> +#include <sys/stat.h> +#include <fcntl.h> #include "../include/byteorder.h" #define PARSE_SCALARS (1<<0) @@ -11,10 +16,9 @@ #ifndef MAX #define MAX(a,b) ((a)>(b)?(a):(b)) #endif -/* Maximum PDU fragment size. */ -#define MAX_PDU_FRAG_LEN 0x1630 #define DEBUG(lvl, str) printf str; +#define DEBUGADD(lvl, str) printf str; #define MARSHALL 0 #define UNMARSHALL 1 @@ -24,11 +28,15 @@ typedef int BOOL; typedef unsigned char uint8; +typedef unsigned char uchar; typedef unsigned short uint16; typedef unsigned short wchar; typedef unsigned uint32; typedef char *SMBSTR; +/* a null terminated unicode string */ +typedef uint16 ZUSTRING; + #ifndef _PSTRING #define PSTRING_LEN 1024 @@ -59,6 +67,7 @@ typedef struct _io_struct */ BOOL bigendian_data; BOOL is_dynamic; /* Do we own this memory or not ? */ + BOOL autoalign; /* should we auto-align all elements? */ uint32 data_offset; /* Current working offset into data. */ uint32 buffer_size; /* Current size of the buffer. */ uint32 grow_size; /* size requested via io_grow() calls */ @@ -72,7 +81,6 @@ void io_debug(io_struct *ps, int depth, char *desc, char *fn_name); BOOL io_align(io_struct *ps, int align); BOOL io_align4(io_struct *ps, int align); BOOL io_align2(io_struct *ps, int align); -void print_asc(int level, unsigned char *buf,int len); BOOL io_read(io_struct *ps, int fd, size_t len, int timeout); void dump_data(int level,char *buf1,int len); BOOL io_alloc(char *name, io_struct *ps, void **ptr, unsigned size); @@ -88,5 +96,8 @@ BOOL io_uint8s(char *name, io_struct *ps, int depth, uint8 **data8s, int len, un char *tab_depth(int depth); void *Realloc(void *p,size_t size); -void print_asc(int level, unsigned char *buf,int len); void dump_data(int level,char *buf1,int len); +void print_asc(int level, uchar const *buf, int len); +BOOL io_ZUSTRING(char *name, io_struct *ps, int depth, uint16 **ustr, unsigned flags); +size_t strlen_w(void *src); + diff --git a/source3/aparser/parserel.awk b/source3/aparser/parserel.awk new file mode 100644 index 0000000000..6d80f0607e --- /dev/null +++ b/source3/aparser/parserel.awk @@ -0,0 +1,213 @@ +# build parse functions for a parsed struct file + +function elem_name(v, elem) +{ + return v["UNION"]elem; +} + +function parse_array(f, v, elnum, flags, + LOCAL, type, elem, array_len) +{ + type = elements[elnum, "type"]; + elem = elements[elnum, "elem"]; + array_len = elements[elnum, "array_len"]; + v["ELEM"] = elem_name(v, elem); + v["TYPE"] = type; + v["FLAGS"] = flags; + v["ARRAY_LEN"] = array_len; + + if (array_len=="+") { + print_template(f,"prs_array_optional.tpl", v); + return; + } + + if (array_len=="&") { + print_template(f,"prs_array_null.tpl", v); + return; + } + + if (array_len=="*") { + print_template(f,"prs_array_remainder.tpl", v); + return; + } + + if (type == "wchar" || type == "uint16") { + if (match(array_len,"[0-9]") == 1) { + print_template(f, "prs_wstring_fixed.tpl", v); + } else { + print_template(f, "prs_wstring.tpl", v); + } + } else if (type == "uint8") { + if (match(array_len,"[0-9]") == 1) { + print_template(f, "prs_uint8s_fixed.tpl", v); + } else { + print_template(f, "prs_uint8s.tpl", v); + } + } else { + print_template(f, "prs_array.tpl", v); + } +} + + +function parse_element(f, v, elnum, flags, + LOCAL, type, elem) +{ + if (elements[elnum,"nowire"] != "") { + return; + } + type = elements[elnum, "type"]; + if (substr(type,1,1) == ".") return; + elem = elements[elnum, "elem"]; + if (elements[elnum,"ptr"] == "") { + v["PTR"] = "\\&"; + } else { + v["PTR"] = " "; + } + v["ELEM"] = elem_name(v, elem); + v["TYPE"] = type; + v["FLAGS"] = flags; + print_template(f, "prs_element.tpl", v); +} + +function parse_union(f, v, elnum, flags, + LOCAL, i) +{ + 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<unions[elnum, "num_elems"];i++) { + v["CASE"] = elements[unions[elnum, i], "case"]; + print_template(f, "prs_case.tpl", v); + if (elements[elnum, "ptr"] == "1") { + parse_scalars(f, v, unions[elnum, i], "PARSE_SCALARS"); + parse_buffers(f, v, unions[elnum, i], "PARSE_BUFFERS"); + } else { + if (flags == "PARSE_SCALARS") { + parse_scalars(f, v, unions[elnum, i], flags); + } else { + parse_buffers(f, v, unions[elnum, i], flags); + } + } + print_template(f, "prs_break.tpl", v); + } + v["UNION"] = ""; + + print_template(f, "union_end.tpl", v); +} + +function parse_scalar(f, v, elnum, flags) +{ + if (elements[elnum, "type"] == "union") { + parse_union(f, v, elnum, flags); + } else if (elements[elnum, "array_len"]!="") { + parse_array(f, v, elnum, flags); + } else { + parse_element(f, v, elnum, flags); + } +} + +function parse_pointer(f, v, elnum, flags, + LOCAL, elem) +{ + elem = elements[elnum, "elem"]; + v["ELEM"] = elem_name(v, elem); + v["FLAGS"] = flags; + print_template(f, "prs_pointer.tpl", v); +} + +function parse_scalars(f, v, elnum, flags) +{ + if (elements[elnum, "ptr"] == "1") { + parse_pointer(f, v, elnum, flags); + } else { + parse_scalar(f, v, elnum, flags); + } +} + +function parse_buffers(f, v, elnum, flags, + LOCAL, elem, type) +{ + elem = elements[elnum, "elem"]; + type = elements[elnum, "type"]; + v["ELEM"] = elem_name(v, elem); + if (elements[elnum, "ptr"] == "1") { + print_template(f, "ifptr_start.tpl", v); + parse_scalar(f, v, elnum, "PARSE_SCALARS|PARSE_BUFFERS"); + print_template(f, "ifptr_end.tpl", v); + } else { + parse_scalar(f, v, elnum, flags); + } +} + +function struct_immediate(f, v, struct_num, + LOCAL, i, n1, num_elems) +{ + num_elems = structs[struct_num, "num_elems"]; + v["STRUCTNAME"] = structs[struct_num, "name"]; + v["FUNCNAME"] = "io_" v["STRUCTNAME"]; + + print_template(f, "fn_i_start.tpl", v); + + for (i=0;i<num_elems;i++) { + parse_scalars(f, v, structs[struct_num, i], "PARSE_SCALARS"); + parse_buffers(f, v, structs[struct_num, i], "PARSE_BUFFERS"); + } + + print_template(f, "fn_i_end.tpl", v); +} + + +function struct_recursive(f, v, struct_num, + LOCAL, i, n1, num_elems) +{ + num_elems = structs[struct_num, "num_elems"]; + v["STRUCTNAME"] = structs[struct_num, "name"]; + v["FUNCNAME"] = "io_" v["STRUCTNAME"]; + + print_template(f, "fn_start.tpl", v); + +# first all the structure pointers, scalars and arrays + for (i=0;i<num_elems;i++) { + parse_scalars(f, v, structs[struct_num, i], "PARSE_SCALARS"); + } + + print_template(f, "fn_mid.tpl", v); + +# now the buffers + for (i=0;i<num_elems;i++) { + parse_buffers(f, v, structs[struct_num, i], "PARSE_BUFFERS"); + } + + print_template(f, "fn_end.tpl", v); +} + +function struct_parser(f, v, struct_num, + LOCAL, i, n1, num_elems) +{ + if (structs[struct_num, "recurse"] == "True") { + struct_recursive(f, v, struct_num); + } else { + struct_immediate(f, v, struct_num); + } +} + +function produce_relative(f, + LOCAL, v, i) +{ + 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/parsetree.awk b/source3/aparser/parsetree.awk index bb1160b954..80587a0111 100644 --- a/source3/aparser/parsetree.awk +++ b/source3/aparser/parsetree.awk @@ -16,6 +16,15 @@ function start_module(name) num_elements=0; num_unions=0; num_tests=0; + num_options=0; +} + +function set_option(name, value) +{ + options[name] = value; + options[num_options, "name"] = name; + options[num_options, "value"] = value; + num_options++; } function parse_define(def1, def2, @@ -31,6 +40,7 @@ function start_struct(name) structs[current_struct, "name"]=name; structs[current_struct, "num_elems"]=0; structs[current_struct, "num_unions"]=0; + structs[current_struct, "recurse"] = options["recurse"]; } function end_struct(name) @@ -168,7 +178,7 @@ function add_sizeis_array(count, type, elem) function start_function(type, fname) { start_struct(fname); - add_function_param("[in,out]",".trailer", ""); + structs[current_struct, "recurse"] = "False"; } function end_function(LOCAL, i) diff --git a/source3/aparser/spool.struct b/source3/aparser/spool.struct index 29bd9bc55f..1563ba5be0 100644 --- a/source3/aparser/spool.struct +++ b/source3/aparser/spool.struct @@ -50,24 +50,24 @@ struct PRINTER_DRIVER_INFO_LEVEL_3 { }; struct PRINTER_DRIVER_INFO_LEVEL_6 { - DWORD dummy1; - DWORD version; - LPWSTR name; - LPWSTR environment; - LPWSTR driverpath; - LPWSTR datafile; - LPWSTR configfile; - LPWSTR helpfile; - LPWSTR monitorname; - LPWSTR defaultdatatype; - BUFFERP dependentfiles; - BUFFERP previousnames; - NTTIME driverdate; - VERSION driverversion; - LPWSTR mfgname; - LPWSTR oemurl; - LPWSTR hardwareid; - LPWSTR provider; + DWORD dummy1; + DWORD version; + LPWSTR name; + LPWSTR environment; + LPWSTR driverpath; + LPWSTR datafile; + LPWSTR configfile; + LPWSTR helpfile; + LPWSTR monitorname; + LPWSTR defaultdatatype; + BUFFERP dependentfiles; + BUFFERP previousnames; + NTTIME driverdate; + VERSION driverversion; + LPWSTR mfgname; + LPWSTR oemurl; + LPWSTR hardwareid; + LPWSTR provider; }; diff --git a/source3/aparser/srvsvc2.struct b/source3/aparser/srvsvc2.struct index bc80d3bc05..362d121e37 100644 --- a/source3/aparser/srvsvc2.struct +++ b/source3/aparser/srvsvc2.struct @@ -1,5 +1,10 @@ module srvsvc +option autoalign True +option relative False +option recurse True +option foo blah + #define BOOL uint32 #define LONG uint32 #define DWORD uint32 diff --git a/source3/aparser/templates/module_start.tpl b/source3/aparser/templates/module_start.tpl index 5bcdbf3275..ac6a3c9d98 100644 --- a/source3/aparser/templates/module_start.tpl +++ b/source3/aparser/templates/module_start.tpl @@ -1,6 +1,5 @@ /* auto-generated structure parsers for @MODULE@ generated by aparser */ -#include "includes.h" #include "prs_@MODULE@.h" diff --git a/source3/aparser/token.awk b/source3/aparser/token.awk index 9920de562b..25ac06f6e3 100644 --- a/source3/aparser/token.awk +++ b/source3/aparser/token.awk @@ -34,6 +34,11 @@ function parse_error(msg) { {if (module=="") parse_error("you must specify the module name first");} +/^[ \t]*option/ { + set_option($2, $3); + next; +} + /^[ \t]*typedef struct.*\{/ { {if (current_struct!="") parse_error("you cannot have nested structures");} start_struct($3); diff --git a/source3/aparser/util.awk b/source3/aparser/util.awk index 93f9a4dcd2..6c5594da68 100644 --- a/source3/aparser/util.awk +++ b/source3/aparser/util.awk @@ -31,3 +31,9 @@ function numlines(fname, close(fname); return count; } + +# return 1 if the string is a constant +function is_constant(s) +{ + return match(s,"^[0-9]+$"); +} diff --git a/source3/aparser/util.c b/source3/aparser/util.c new file mode 100644 index 0000000000..ffa84dbfab --- /dev/null +++ b/source3/aparser/util.c @@ -0,0 +1,112 @@ +#include "parser.h" + + +/******************************************************************* + Count the number of characters (not bytes) in a unicode string. +********************************************************************/ +size_t strlen_w(void *src) +{ + size_t len; + + for (len = 0; SVAL(src, len*2); len++) ; + + return len; +} + +/**************************************************************************** +expand a pointer to be a particular size +****************************************************************************/ +void *Realloc(void *p,size_t size) +{ + void *ret=NULL; + + if (size == 0) { + if (p) free(p); + DEBUG(5,("Realloc asked for 0 bytes\n")); + return NULL; + } + + if (!p) + ret = (void *)malloc(size); + else + ret = (void *)realloc(p,size); + + if (!ret) + DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",(int)size)); + + return(ret); +} + + +char *tab_depth(int depth) +{ + static pstring spaces; + memset(spaces, ' ', depth * 4); + spaces[depth * 4] = 0; + return spaces; +} + +void print_asc(int level, uchar const *buf, int len) +{ + int i; + for (i = 0; i < len; i++) + { + DEBUGADD(level, ("%c", isprint(buf[i]) ? buf[i] : '.')); + } +} + +void dump_data(int level, char *buf1, int len) +{ + uchar const *buf = (uchar const *)buf1; + int i = 0; + if (buf == NULL) + { + DEBUG(level, ("dump_data: NULL, len=%d\n", len)); + return; + } + if (len < 0) + return; + if (len == 0) + { + DEBUG(level, ("\n")); + return; + } + + DEBUG(level, ("[%03X] ", i)); + for (i = 0; i < len;) + { + DEBUGADD(level, ("%02X ", (int)buf[i])); + i++; + if (i % 8 == 0) + DEBUGADD(level, (" ")); + if (i % 16 == 0) + { + print_asc(level, &buf[i - 16], 8); + DEBUGADD(level, (" ")); + print_asc(level, &buf[i - 8], 8); + DEBUGADD(level, ("\n")); + if (i < len) + DEBUGADD(level, ("[%03X] ", i)); + } + } + + if (i % 16 != 0) /* finish off a non-16-char-length row */ + { + int n; + + n = 16 - (i % 16); + DEBUGADD(level, (" ")); + if (n > 8) + DEBUGADD(level, (" ")); + while (n--) + DEBUGADD(level, (" ")); + + n = MIN(8, i % 16); + print_asc(level, &buf[i - (i % 16)], n); + DEBUGADD(level, (" ")); + n = (i % 16) - n; + if (n > 0) + print_asc(level, &buf[i - n], n); + DEBUGADD(level, ("\n")); + } +} diff --git a/source3/aparser/vluke.c b/source3/aparser/vluke.c index 87664267d0..d3868f2753 100644 --- a/source3/aparser/vluke.c +++ b/source3/aparser/vluke.c @@ -1,3 +1,4 @@ +#include "parser.h" #include "test.h" int main(int argc, char *argv[]) @@ -29,6 +30,7 @@ int main(int argc, char *argv[]) ps.data_offset = 0; ps.buffer_size = ps.grow_size; ps.io = UNMARSHALL; + ps.autoalign = OPTION_autoalign; ret = run_test(test, &ps, PARSE_SCALARS|PARSE_BUFFERS); printf("\nret=%s\n", ret?"OK":"Bad"); printf("Trailer is %d bytes\n\n", ps.grow_size - ps.data_offset); |