44
|
1 #!/usr/bin/perl
|
|
2
|
|
3 use Getopt::Std;
|
|
4 use strict;
|
|
5
|
|
6 #
|
|
7 # generrate Gears OS context heaader and initializer from CbC sources
|
|
8 #
|
|
9 # CodeGear
|
|
10 #
|
|
11 # get stub information from # *.c
|
|
12 # __code taskManager_stub(struct Context* context) {
|
|
13 #
|
|
14 # generate CodeGear indexn in context.h
|
|
15 # C_taskManager,
|
|
16 #
|
|
17 # generate CodeGear stub reference in context.h
|
|
18 # extern __code taskManager_stub(struct Context*);
|
|
19 #
|
|
20 # generate CodeGear stub reference in $name-context.h for each module
|
|
21 # context->code[C_taskManager] = taskManager_stub;
|
|
22 #
|
|
23 # DataGear
|
|
24 #
|
|
25 # get DataGear information from context.h
|
|
26 # struct Worker {
|
|
27 # int id;
|
|
28 # struct Context* contexts;
|
|
29 # enum Code execute;
|
|
30 # enum Code taskSend;
|
|
31 # enum Code taskRecive;
|
|
32 # enum Code shutdown;
|
|
33 # struct Queue* tasks;
|
|
34 # } Worker;
|
|
35 #
|
|
36 # generate typedefs and DataGear index in context.h
|
|
37 # typedef struct Worker Worker;
|
|
38 # D_Worker,
|
|
39 #
|
|
40 # generate DataGear allocator in context.h
|
|
41 # ALLOC_DATA(context, Worker);
|
|
42 #
|
|
43
|
|
44 my $ddir = "c";
|
|
45
|
|
46 our($opt_o,$opt_d,$opt_h);
|
|
47 getopts('o:d:h');
|
|
48
|
|
49 my $name = $opt_o?$opt_o:"gears";
|
|
50
|
|
51 if ($opt_d) {
|
|
52 $ddir = $opt_d;
|
|
53 }
|
|
54
|
|
55 if ( ! -d $ddir) {
|
|
56 mkdir $ddir;
|
|
57 }
|
|
58
|
|
59 if ($opt_h) {
|
|
60 print "$0 [-d distdir] [-h]\n";
|
|
61 exit;
|
|
62 }
|
|
63
|
|
64 my %codeGear;
|
|
65 my %dataGear;
|
|
66 my %constructor;
|
|
67
|
|
68 # gather module Information for code table initialization
|
|
69 for (@ARGV) {
|
|
70 next if (/context.c/);
|
|
71 &getStubInfo($_);
|
|
72 }
|
|
73
|
|
74 my (%mCodeGear) = (%codeGear);
|
|
75
|
|
76 # anyway we gather all Gears Information
|
|
77 while (<*.c test/*.c>) {
|
|
78 next if (/context.c/);
|
|
79 &getStubInfo($_);
|
|
80 }
|
|
81
|
|
82 &generateContext();
|
|
83
|
|
84 sub getStubInfo {
|
|
85 my ($filename) = @_;
|
|
86 open my $fd,"<",$filename or die("can't open $filename $!");
|
|
87 while (<$fd>) {
|
|
88 if (/^__code (\w+)_stub\(struct *Context *\* *context\)/) {
|
|
89 $codeGear{$1} = $filename;
|
|
90 } elsif (/^(\w+)(\*)+ *create(\w+)\(([^]]*)\)/) {
|
|
91 my $interface = $1;
|
|
92 my $implementation = $3;
|
|
93 my $constructorArgs = $4;
|
|
94 $constructor{$implementation} = [$interface, $constructorArgs];
|
|
95 }
|
|
96 }
|
|
97
|
|
98 open my $cx,"<","context.h" or die("can't open context.h $!");
|
|
99 my $inUnionData = 0;
|
|
100 while (<$cx>) {
|
|
101 if (! $inUnionData) {
|
|
102 if ( /^union Data/) {
|
|
103 $inUnionData = 1;
|
|
104 }
|
|
105 next;
|
|
106 }
|
|
107 last if (/union Data end/);
|
|
108 if (/struct (\w+) \{/) {
|
|
109 $dataGear{$1} = 'struct';
|
|
110 } elsif (/^\s{4}(\w+) (\w+);/) { # primitive type
|
|
111 $dataGear{$1} = 'primitive';
|
|
112 }
|
|
113 $dataGear{"Context"} = "struct";
|
|
114 }
|
|
115 }
|
|
116
|
|
117 sub generateContext {
|
|
118 $codeGear{"start_code"} = "$ddir/$name-context.c";
|
|
119 $codeGear{"exit_code"} = "$ddir/$name-context.c";
|
|
120 $mCodeGear{"start_code"} = "$ddir/$name-context.c";
|
|
121 $mCodeGear{"exit_code"} = "$ddir/$name-context.c";
|
|
122 open my $fd,">","$ddir/extern.h" or die("can't open $ddir/extern.h $!");
|
|
123 for my $code ( sort keys %codeGear ) {
|
|
124 print $fd "extern __code ${code}_stub(struct Context*);\n";
|
|
125 }
|
|
126 for my $impl ( sort keys %constructor ) {
|
|
127 my ($interface, $constructorArgs) = @{$constructor{$impl}};
|
|
128 print $fd "extern ${interface}* create${impl}($constructorArgs);\n";
|
|
129 }
|
|
130 print $fd "\n";
|
|
131
|
|
132 open my $fd,">","$ddir/enumCode.h" or die("can't open $ddir/enumCode.h $!");
|
|
133 print $fd "enum Code {\n";
|
|
134 for my $code ( sort keys %codeGear ) {
|
|
135 print $fd " C_${code},\n";
|
|
136 }
|
|
137 print $fd "};\n";
|
|
138
|
|
139 my $code_init = '';
|
|
140 for my $code ( sort keys %mCodeGear ) {
|
|
141 $code_init .= " context->code[C_${code}] = ${code}_stub;\n";
|
|
142 }
|
|
143
|
|
144 my $data_num = keys(%dataGear);
|
|
145 $data_num++;
|
|
146 my $context_c = << "EOFEOF";
|
|
147 #include <stdlib.h>
|
|
148
|
|
149 #include "../context.h"
|
|
150
|
|
151 void initContext(struct Context* context) {
|
|
152 context->heapLimit = sizeof(union Data)*ALLOCATE_SIZE;
|
|
153 context->code = (__code(**) (struct Context*)) NEWN(ALLOCATE_SIZE, void*);
|
|
154 context->data = NEWN(ALLOCATE_SIZE, union Data*);
|
|
155 context->heapStart = NEWN(context->heapLimit, char);
|
|
156 context->heap = context->heapStart;
|
|
157 // context->codeNum = Exit;
|
|
158
|
|
159 $code_init
|
|
160
|
|
161 #include "dataGearInit.c"
|
|
162 context->dataNum = $data_num;
|
|
163 }
|
|
164 EOFEOF
|
|
165
|
|
166 open my $fd,">","$ddir/$name-context.c" or die("can't open $ddir/$name-context.c $!");
|
|
167 print $fd $context_c;
|
|
168
|
|
169 my $meta_call = <<"EOFEOF";
|
|
170 __code meta(struct Context* context, enum Code next) {
|
|
171 // printf("meta %d\\n",next);
|
45
|
172 goto (context->code[next])(context);
|
|
173 }
|
|
174
|
|
175 __code parGotoMeta(struct Context* context, enum Code next) {
|
44
|
176 context->task = NULL;
|
|
177 context->taskList = NULL;
|
|
178 goto (context->code[Gearef(context, TaskManager)->taskManager->TaskManager.spawnTasks])(context);
|
|
179 }
|
|
180
|
|
181 __code start_code(struct Context* context) {
|
|
182 goto meta(context, context->next);
|
|
183 }
|
|
184
|
|
185 __code start_code_stub(struct Context* context) {
|
|
186 goto start_code(context);
|
|
187 }
|
|
188
|
|
189 __code exit_code(struct Context* context) {
|
|
190 free(context->code);
|
|
191 free(context->data);
|
|
192 free(context->heapStart);
|
|
193 goto exit(0);
|
|
194 }
|
|
195
|
|
196 __code exit_code_stub(struct Context* context) {
|
|
197 goto exit_code(context);
|
|
198 }
|
|
199
|
|
200 // end context_c
|
|
201 EOFEOF
|
|
202
|
|
203 print $fd $meta_call;
|
|
204
|
|
205 open my $fd,">","$ddir/enumData.h" or die("can't open $ddir/enumData.h $!");
|
|
206 print $fd "enum DataType {\n";
|
|
207 print $fd " D_Code,\n";
|
|
208 for my $data ( sort keys %dataGear ) {
|
|
209 print $fd " D_${data},\n";
|
|
210 }
|
|
211 print $fd "};\n\n";
|
|
212
|
|
213 open my $fd,">","$ddir/typedefData.h" or die("can't open $ddir/typedefData.h $!");
|
|
214 for my $data ( sort keys %dataGear ) {
|
|
215 if ($dataGear{$data} eq 'struct') {
|
|
216 print $fd "typedef struct ${data} ${data};\n";
|
|
217 }
|
|
218 }
|
|
219
|
|
220 open my $fd,">","$ddir/dataGearInit.c" or die("can't open $ddir/dataGearInit.c $!");
|
|
221 for my $data ( sort keys %dataGear ) {
|
|
222 print $fd " ALLOC_DATA(context, ${data});\n";
|
|
223 }
|
|
224 }
|
|
225
|
|
226 # end
|