#!/usr/bin/perl use Getopt::Std; use strict; # # generrate Gears OS context heaader and initializer from CbC sources # # CodeGear # # get stub information from # *.c # __code taskManager_stub(struct Context* context) { # # generate CodeGear indexn in context.h # C_taskManager, # # generate CodeGear stub reference in context.h # extern __code taskManager_stub(struct Context*); # # generate CodeGear stub reference in $name-context.h for each module # context->code[C_taskManager] = taskManager_stub; # # DataGear # # get DataGear information from context.h # struct Worker { # int id; # struct Context* contexts; # enum Code execute; # enum Code taskSend; # enum Code taskRecive; # enum Code shutdown; # struct Queue* tasks; # } Worker; # # generate typedefs and DataGear index in context.h # typedef struct Worker Worker; # D_Worker, # # generate DataGear allocator in context.h # ALLOC_DATA(context, Worker); # my $ddir = "c"; our($opt_o,$opt_d,$opt_h); getopts('o:d:h'); my $name = $opt_o; if ($opt_d) { $ddir = $opt_d; } if ( ! -d $ddir) { mkdir $ddir; } if ($opt_h) { print "$0 [-d distdir] [-h]\n"; exit; } my %codeGear; my %dataGear; for (@ARGV) { next if (/context.c/); &getStubInfo($_); } my (%mCodeGear) = (%codeGear); while (<*.c>) { next if (/context.c/); &getStubInfo($_); } &generateContext(); sub getStubInfo { my ($filename) = @_; open my $fd,"<",$filename or die("can't open $filename $!"); while (<$fd>) { if (/^__code (\w+)_stub\(struct Context\* context\)/ or /^\s__code (\w+)_stub\(struct Context\* context\)/) { $codeGear{$1} = $filename; } } open my $cx,"<","context.h" or die("can't open context.h $!"); my $inUnionData = 0; while (<$cx>) { if (! $inUnionData) { if ( /^union Data/) { $inUnionData = 1; } next; } last if (/union Data end/); if (/struct (\w+) \{/) { $dataGear{$1} = $1; } } } sub generateContext { open my $fd,">","$ddir/extern.h" or die("can't open $ddir/extern.h $!"); for my $code ( sort keys %codeGear ) { print $fd "extern __code ${code}_stub(struct Context*);\n"; } print $fd "\n"; open my $fd,">","$ddir/enumCode.h" or die("can't open $ddir/enumCode.h $!"); print $fd "enum Code {\n"; for my $code ( sort keys %codeGear ) { print $fd " C_${code},\n"; } print $fd "};\n"; my $code_init = ''; for my $code ( sort keys %mCodeGear ) { $code_init .= " context->code[C_${code}] = ${code}_stub;\n"; } my $context_c = << "EOFEOF"; #include #include "../context.h" #include "extern.h" void initContext(struct Context* context) { context->heapLimit = sizeof(union Data)*ALLOCATE_SIZE; context->code = (__code(**) (struct Context*)) NEWN(ALLOCATE_SIZE, void*); context->data = NEWN(ALLOCATE_SIZE, union Data*); context->heapStart = NEWN(context->heapLimit, char); context->heap = context->heapStart; // context->codeNum = Exit; $code_init #include "dataGearInit.c" // context->data[D_ActiveQueue] = createSynchronizedQueue(context); // context->data[D_WaitQueue] = createSynchronizedQueue(context); context->dataNum = D_Queue; } EOFEOF open my $fd,">","$ddir/$name-context.c" or die("can't open $ddir/$name-context.c $!"); print $fd $context_c; open my $fd,">","$ddir/enumData.h" or die("can't open $ddir/enumData.h $!"); print $fd "enum DataType {\n"; for my $data ( sort keys %dataGear ) { print $fd " D_${data},\n"; } print $fd "};\n\n"; open my $fd,">","$ddir/typedefData.h" or die("can't open $ddir/typedefData.h $!"); for my $data ( sort keys %dataGear ) { print $fd "typedef struct ${data} ${data};\n"; } open my $fd,">","$ddir/dataGearInit.c" or die("can't open $ddir/dataGearInit.c $!"); for my $data ( sort keys %dataGear ) { print $fd " ALLOC_DATA(context, ${data});\n"; } } # end