# 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_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_align2 ( f , v , elnum , flags ,
LOCAL , elem )
{
elem = elements [ elnum , "elem" ] ;
v [ "OFFSET" ] = elem_name ( v , elem ) ;
print_template ( f , "prs_align2.tpl" , v ) ;
}
function parse_align4 ( f , v , elnum , flags ,
LOCAL , elem )
{
elem = elements [ elnum , "elem" ] ;
v [ "OFFSET" ] = elem_name ( v , elem ) ;
print_template ( f , "prs_align4.tpl" , v ) ;
}
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_scalar_fn ( m , v , elnum ,
LOCAL , elem , type )
{
elem = elements [ elnum , "elem" ] ;
type = elements [ elnum , "type" ]
xprintf ( m , "%s %s" , type , elem_name ( v , elem ) ) ;
if ( type == "union" ) {
} else if ( elements [ elnum , "array_len" ] != "" ) {
} else {
}
}
function parse_pointer_fn ( f , v , elnum , flags ,
LOCAL , elem )
{
elem = elements [ elnum , "elem" ] ;
v [ "ELEM" ] = elem_name ( v , elem ) ;
v [ "FLAGS" ] = flags ;
xprintf ( m , "%s\n" , v [ "ELEM" ] ) ;
}
function parse_scalars_fn ( m , v , elnum , flags )
{
if ( elements [ elnum , "type" ] == ".align2" ) {
}
else if ( elements [ elnum , "type" ] == ".align4" ) {
}
else if ( elements [ elnum , "ptr" ] == "1" ) {
parse_pointer_fn ( m , v , elnum , flags ) ;
} else {
parse_scalar_fn ( m , v , elnum , flags ) ;
}
}
function parse_scalars ( f , v , elnum , flags )
{
if ( elements [ elnum , "type" ] == ".align2" ) {
parse_align2 ( f , v , elnum , flags ) ;
}
else if ( elements [ elnum , "type" ] == ".align4" ) {
parse_align4 ( f , v , elnum , flags ) ;
}
else 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 , "type" ] == ".align2" ) {
}
else if ( elements [ elnum , "type" ] == ".align4" ) {
} else 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_parser ( f , m , v , struct_num ,
LOCAL , i , n1 , f1 , num_elems )
{
f1 = - 1 ;
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 ) ;
for ( n1 = 0 ; n1 < num_elems ; n1 ++ ) {
if ( elements [ structs [ struct_num , n1 ] , "type" ] == ".trailer" ) {
f1 = n1 ;
break ;
}
}
# first all the structure pointers, scalars and arrays
for ( i = 0 ; i < n1 ; 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 < n1 ; i ++ ) {
parse_buffers ( f , v , structs [ struct_num , i ] , "PARSE_BUFFERS" ) ;
}
# and any trailers
for ( i = n1 ; i < num_elems ; i ++ ) {
parse_scalars ( f , v , structs [ struct_num , i ] , "PARSE_SCALARS" ) ;
parse_buffers ( f , v , structs [ struct_num , i ] , "PARSE_BUFFERS" ) ;
}
if ( i > 0 ) {
print_template ( f , "fn_end.tpl" , v ) ;
}
else {
print_template ( f , "fn_end0.tpl" , v ) ;
}
if ( f1 == - 1 )
return ;
xprintf ( m , "void fn_%s(\n" , v [ "STRUCTNAME" ] ) ;
for ( i = f1 + 1 ; i < num_elems ; i ++ ) {
parse_scalars_fn ( m , v , structs [ struct_num , i ] ) ;
if ( i != num_elems - 1 )
xprintf ( m , ", \n" ) ;
}
xprintf ( m , ")\n{\n}\n" ) ;
}
function produce_parsers ( f , m ,
LOCAL , v , i )
{
v [ "MODULE" ] = module ;
print_template ( f , "module_start.tpl" , v ) ;
for ( i = 0 ; i < num_structs ; i ++ ) {
struct_parser ( f , m , v , i ) ;
}
print_template ( f , "module_end.tpl" , v ) ;
}