1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-24 21:34:56 +03:00

another awk parser update

we can now handle arrays of structures, pointers to structures,
pointers in unions etc
This commit is contained in:
Andrew Tridgell 0001-01-01 00:00:00 +00:00
parent a70c7b9aef
commit 1df80cd1e8
19 changed files with 291 additions and 172 deletions

View File

@ -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);
}

View File

@ -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<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;
for (i=0;i<unions[elnum, "num_elems"];i++) {
v["CASE"] = elements[unions[elnum, i], "case"];
print_template(f, "prs_case.tpl", v);
if (structs[type] != "") {
print_template(f, "prs_struct.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 {
print_template(f, "prs_"type".tpl", v);
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_case_end.tpl", v);
print_template(f, "prs_break.tpl", v);
}
v["UNION"] = "";
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 parse_scalar(f, v, elnum,
LOCAL, elem, type)
function parse_scalar(f, v, elnum, flags)
{
if (elements[elnum, "type"] == "union") {
parse_union(f, v, elnum);
parse_union(f, v, elnum, flags);
} else if (elements[elnum, "array_len"]!="") {
parse_array(f, v, elnum);
parse_array(f, v, elnum, flags);
} else {
parse_element(f, v, elnum, flags);
}
elem = elements[elnum, "elem"];
v["ELEM"] = elem;
print_template(f, "prs_pointer.tpl", v);
}
function parse_pointer(f, v, elnum,
function parse_pointer(f, v, elnum, flags,
LOCAL, elem)
{
elem = elements[elnum, "elem"];
v["ELEM"] = elem;
v["ELEM"] = elem_name(v, elem);
v["FLAGS"] = flags;
print_template(f, "prs_pointer.tpl", v);
}
function parse_scalars(f, v, elnum)
function parse_scalars(f, v, elnum, flags)
{
if (elements[elnum, "ptr"] == "1") {
parse_pointer(f, v, elnum);
parse_pointer(f, v, elnum, flags);
} else {
parse_scalar(f, v, elnum);
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);
}
}
@ -108,24 +120,26 @@ function struct_parser(f, v, struct_num,
LOCAL, i)
{
v["STRUCTNAME"] = structs[struct_num, "name"];
v["FUNCNAME"] = "prs_" v["STRUCTNAME"];
v["FUNCNAME"] = "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++) {
parse_scalars(f, v, structs[struct_num, 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<structs[struct_num, "num_elems"];i++) {
parse_buffers(f, v, structs[struct_num, i]);
parse_buffers(f, v, structs[struct_num, i], "PARSE_BUFFERS");
}
print_template(f, "fn_end.tpl", v);
}
function produce_parsers(f,
LOCAL, v)
LOCAL, v, i)
{
v["MODULE"]=module;

View File

@ -125,23 +125,6 @@ char *prs_mem_get(prs_struct *ps, uint32 extra_size)
return &ps->data_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;
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;
}
/*******************************************************************
do IO on a uint16.
********************************************************************/
BOOL io_uint16(char *name, prs_struct *ps, int depth, uint16 *data16, unsigned flags)
{
char *q;
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;
}
/*******************************************************************
do IO on a uint8.
********************************************************************/
BOOL io_uint8(char *name, prs_struct *ps, int depth, uint8 *data8, unsigned flags)
{
char *q;
if (!(flags & PARSE_SCALARS)) return True;
q = prs_mem_get(ps, sizeof(uint8));
if (q == NULL) return False;
DBG_RW_IVAL(name, depth, ps->data_offset, ps->io, ps->bigendian_data, q, *data8)
ps->data_offset += sizeof(uint8);
return True;
}
/*******************************************************************
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;
v = (*p) ? 1 : 0;
if (!io_uint32(desc, ps, depth, &v, flags)) return False;
*p = (void *) (v ? 1 : 0);
return True;
}
/******************************************************************
Stream an array of uint16s. Length is number of uint16s.
do IO on a unicode array
********************************************************************/
BOOL prs_uint16s(BOOL charmode, char *name, prs_struct *ps, int depth, uint16 *data16s, int len)
BOOL io_wstring(char *name, prs_struct *ps, int depth, uint16 *data16s, int len, 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)
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;
}
/******************************************************************
Stream an array of uint32s. Length is number of uint32s.
allocate some memory for a parse structure
********************************************************************/
BOOL prs_uint32s(BOOL charmode, char *name, prs_struct *ps, int depth, uint32 *data32s, int len)
BOOL io_alloc(char *name, prs_struct *ps, void **ptr, unsigned size)
{
char *q = prs_mem_get(ps, len * sizeof(uint32));
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));
return True;
(*ptr) = (void *)malloc(size);
if (*ptr) return True;
return False;
}
/*******************************************************************
Stream a uint16.
********************************************************************/
BOOL prs_uint16(char *name, prs_struct *ps, int depth, uint16 *data16, BOOL scalars)
{
char *q = prs_mem_get(ps, sizeof(uint16));
if (q == NULL)
return False;
DBG_RW_SVAL(name, depth, ps->data_offset, ps->io, ps->bigendian_data, q, *data16)
ps->data_offset += sizeof(uint16);
return True;
}

View File

@ -1,6 +1,9 @@
#include <ctype.h>
#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);

View File

@ -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;
};

View File

@ -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;
}
};

View File

@ -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;
}

View File

@ -0,0 +1,6 @@
buffers:
if (!(flags & PARSE_BUFFERS)) goto end;
/* now parse the buffers */

View File

@ -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 */

View File

@ -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"

View File

@ -1 +1,2 @@
if (il->@ELEM@) {
if (!io_alloc("@ELEM@", ps, (void **)&il->@ELEM@, sizeof(*(il->@ELEM@)))) goto fail;

View File

@ -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<il->@ARRAY_LEN@;i++) {
if (!io_@TYPE@("@ELEM@...", ps, depth+1, &il->@ELEM@[i], @FLAGS@)) goto fail;
}
}

View File

@ -0,0 +1 @@
break;

View File

@ -1 +1 @@
case @VALUE@:
case @CASE@:

View File

@ -0,0 +1 @@
if (!io_@TYPE@("@ELEM@", ps, depth+1, @PTR@il->@ELEM@, @FLAGS@)) goto fail;

View File

@ -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;

View File

@ -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;

View File

@ -1,3 +1 @@
il->@ELEM@ = (void *)malloc(sizeof(*(il->@ELEM@)));
if (!il->@ELEM@) goto fail;
switch (il->@SWITCH@) {

View File

@ -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;