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 /source3/aparser | |
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)
Diffstat (limited to 'source3/aparser')
-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); |