#! /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 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_\U$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);
}
