#! /usr/bin/perl -w
#
# Build the server/trace.c and server/request.h files
# from the contents of include/server.h.
#
# Copyright (C) 1998 Alexandre Julliard
#

%formats =
(
    "int"           => "%d",
    "char"          => "%c",
    "unsigned char" => "%02x",
    "unsigned short"=> "%04x",
    "unsigned int"  => "%08x",
    "void*"         => "%p",
    "time_t"        => "%ld",
    "handle_t"      => "%d",
);

my @requests = ();
my %replies = ();

open(SERVER,"include/server.h") or die "Can't open include/server.h";

### Parse server.h to find request/reply structure definitions

my @trace_lines = ();
my $protocol = 0;  # server protocol version

while (<SERVER>)
{
    if (/^struct +(\w+)_request/) { &DO_REQUEST($1); }
    if (/^\#define SERVER_PROTOCOL_VERSION (\d+)/) { $protocol = $1 + 1; }
}

### Output the dumping function tables

push @trace_lines, "static const dump_func req_dumpers[REQ_NB_REQUESTS] = {\n";
foreach $req (@requests)
{
    push @trace_lines, "    (dump_func)dump_${req}_request,\n";
}
push @trace_lines, "};\n\n";

push @trace_lines, "static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {\n";
foreach $req (@requests)
{
    push @trace_lines, "    (dump_func)", $replies{$req} ? "dump_${req}_reply,\n" : "0,\n";
}
push @trace_lines, "};\n\n";

push @trace_lines, "static const char * const req_names[REQ_NB_REQUESTS] = {\n";
foreach $req (@requests)
{
    push @trace_lines, "    \"$req\",\n";
}
push @trace_lines, "};\n";

REPLACE_IN_FILE( "server/trace.c", @trace_lines );

### Replace the request list in server.h by the new values

my @server_lines = ();

push @server_lines, "enum request\n{\n";
foreach $req (@requests) { push @server_lines, "    REQ_$req,\n"; }
push @server_lines, "    REQ_NB_REQUESTS\n};\n\n";
push @server_lines, "union generic_request\n{\n";
push @server_lines, "    struct request_max_size max_size;\n";
push @server_lines, "    struct request_header header;\n";
foreach $req (@requests) { push @server_lines, "    struct ${req}_request $req;\n"; }
push @server_lines, "};\n\n";
push @server_lines, "#define SERVER_PROTOCOL_VERSION $protocol\n";

REPLACE_IN_FILE( "include/server.h", @server_lines );

### Output the request handlers list

my @request_lines = ();

foreach $req (@requests) { push @request_lines, "DECL_HANDLER($req);\n"; }
push @request_lines, "\n#ifdef WANT_REQUEST_HANDLERS\n\n";
push @request_lines, "typedef void (*req_handler)( void *req );\n";
push @request_lines, "static const req_handler req_handlers[REQ_NB_REQUESTS] =\n{\n";
foreach $req (@requests)
{
    push @request_lines, "    (req_handler)req_$req,\n";
}
push @request_lines, "};\n#endif  /* WANT_REQUEST_HANDLERS */\n";

REPLACE_IN_FILE( "server/request.h", @request_lines );

### Handle a request structure definition

sub DO_REQUEST
{
    my $name = shift;
    my @in_struct = ();
    my @out_struct = ();
    my $got_header = 0;
    while (<SERVER>)
    {
	my ($dir, $type, $var);
	last if /^};$/;
        next if /^{$/;
	s!/\*.*\*/!!g;
	next if /^\s*$/;
        if (/REQUEST_HEADER/)
        {
            die "Duplicated header" if $got_header;
            die "Header must be first" if ($#in_struct != -1 || $#out_struct != -1);
            $got_header++;
            next;
        }
        if (/^\s*(IN|OUT)\s*VARARG\((\w+),(\w+)\)/)
        {
            $dir = $1;
            $var = $2;
            $type = "&dump_varargs_" . $3;
        }
	elsif (/^\s*(IN|OUT)\s*(\w+\**(\s+\w+\**)*)\s+(\w+)(\[[1]\])?;/)
        {
            $dir = $1;
            $type = $2 . ($5 || "");
            $var = $4;
            die "Unrecognized type $type" unless (defined($formats{$type}) || $5);
        }
        else
        {
            die "Unrecognized syntax $_";
        }
	if ($dir =~ /IN/) { push @in_struct, $type, $var; }
	if ($dir =~ /OUT/) { push @out_struct, $type, $var; }
    }
    die "Missing header" unless $got_header;
    push @requests, $name;
    &DO_DUMP_FUNC( $name, "request", @in_struct);
    if ($#out_struct >= 0)
    {
	$replies{$name} = 1;
	&DO_DUMP_FUNC( $name, "reply", @out_struct);
    }
}

### Generate a dumping function

sub DO_DUMP_FUNC
{
    my $name = shift;
    my $req = shift;
    push @trace_lines, "static void dump_${name}_$req( const struct ${name}_request *req )\n{\n";
    while ($#_ >= 0)
    {
	my $type = shift;
	my $var = shift;
	if (defined($formats{$type}))
	{
            if ($formats{$type} =~ /^&(.*)/)
            {
                my $func = $1;
                push @trace_lines, "    fprintf( stderr, \" $var=\" );\n";
                if ($type =~ /[1]/) { push @trace_lines, "    $func( req, req->$var );\n"; }
                else { push @trace_lines, "    $func( req, &req->$var );\n"; }
                push @trace_lines, "    fprintf( stderr, \",\" );\n" if ($#_ > 0);
            }
            else
            {
                push @trace_lines, "    fprintf( stderr, \" $var=$formats{$type}";
                push @trace_lines, "," if ($#_ > 0);
                push @trace_lines, "\", ";
                push @trace_lines, "req->$var );\n";
            }
	}
	else  # must be some varargs format
	{
            if ($type =~ /^&(.*)/)
            {
                my $func = $1;
                push @trace_lines, "    fprintf( stderr, \" $var=\" );\n";
                push @trace_lines, "    cur_pos += $func( req );\n";
                push @trace_lines, "    fputc( ',', stderr );\n" if ($#_ > 0);
            }
            else
            {
                push @trace_lines, "    fprintf( stderr, \" $var=\" );\n";
                push @trace_lines, "    dump_varargs_${name}_${req}( req );\n";
            }
        }
    }
    push @trace_lines, "}\n\n";
}

### Replace the contents of a file between ### make_requests ### marks

sub REPLACE_IN_FILE
{
    my $name = shift;
    my @data = @_;
    my @lines = ();
    open(FILE,$name) or die "Can't open $name";
    while (<FILE>)
    {
	push @lines, $_;
	last if /\#\#\# make_requests begin \#\#\#/;
    }
    push @lines, "\n", @data;
    while (<FILE>)
    {
	if (/\#\#\# make_requests end \#\#\#/) { push @lines, "\n", $_; last; }
    }
    push @lines, <FILE>;
    open(FILE,">$name") or die "Can't modify $name";
    print FILE @lines;
    close(FILE);
}
