ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/genacc
Revision: 1.10
Committed: Thu Oct 8 05:04:27 2009 UTC (14 years, 7 months ago) by root
Branch: MAIN
Changes since 1.9: +19 -0 lines
Log Message:
*** empty log message ***

File Contents

# Content
1 #! perl
2
3 # used to automatically create accessors/mutators and method interfaces
4 # to C++ classes for Perl.
5 # also write data structures as JSON object, for reflection
6
7 use JSON::XS;
8
9 my $class = shift;
10 my $curclass = "";
11 my (@scalar_member, @array_member);
12
13 # convert c member name to perl
14 sub c2perl($) {
15 local $_ = shift;
16
17 s/^([^.]+)\.\1_/$1\_/g; # tcpi.tcpi_xxx => tcpi_xxx
18
19 $_
20 }
21
22 for my $file (@ARGV) {
23 open my $fh, "<:utf8", $file
24 or die "$file: $!";
25
26 while (<$fh>) {
27 next if /^\s*\//; # skip lines starting with /
28 if ($curclass eq $class) {
29 while (/ACC\s*\(R([WO])\s*,\s*([^)\]]+)(?:\[(\S+)\])?\)/g) {
30 if ($3) {
31 push @array_member, [$1, $2, $3];
32 } else {
33 push @scalar_member, [$1, $2];
34 }
35 }
36 if (/MTH \s+ ([^(]*?) \s* ([A-Za-z_0-9]+) \s* \(([^)]*)\)/x) {
37 push @method_member, [$1, $2, $3];
38 }
39 }
40 while (/INTERFACE_CLASS\s*\((\S+)\)/g) {
41 $curclass = $1;
42 }
43 }
44 }
45
46 for (@method_member) {
47 my ($rettype, $name, $params) = @$_;
48
49 if ($rettype =~ s/static\s+//) {
50 my $args = join ", ", $params =~ m/.*?([a-zA-Z_0-9]+)(?:,\s*|$)/g;
51 if ($rettype ne "void") {
52 print "$rettype\n$name ($params)\n",
53 "\tCODE:\n",
54 "\tRETVAL = $class\::$name ($args);\n",
55 "\tOUTPUT:\n",
56 "\tRETVAL\n";
57 } else {
58 print "$rettype\n$name ($params)\n",
59 "\tCODE:\n",
60 "\t$class\::$name ($args);\n",
61 }
62 } else {
63 print "$rettype\n$class\::$name ($params)\n";
64 }
65
66 print "\n";
67 }
68
69 if (@scalar_member) {
70 print "SV *$scalar_member[0][1] ($class *self, SV *newval = 0)\n";
71 print "\tPROTOTYPE: \$;\$\n";
72
73 if (@scalar_member > 1) {
74 print "\tALIAS:\n";
75 for (1 .. $#scalar_member) {
76 print "\t\t" . (c2perl $scalar_member[$_][1]) . "\t= $_\n";
77 }
78 }
79
80 print "\tCODE:\n";
81
82 my $ix = @scalar_member == 1 ? 0 : "ix";
83
84 # read
85 print "\tif (GIMME_V == G_VOID)\n",
86 "\t RETVAL = &PL_sv_undef;\n",
87 "\telse\n",
88 "\t switch ($ix)\n",
89 "\t {\n",
90 (map "\t case $_: RETVAL = to_sv (self->$scalar_member[$_][1]); break;\n",
91 0 .. $#scalar_member),
92 "\t default: croak (\"scalar_member is write-only\");\n",
93 "\t };\n";
94
95 # write
96 print "\tif (newval)\n",
97 "\t switch ($ix)\n",
98 "\t {\n",
99 (map "\t case $_: sv_to (newval, self->$scalar_member[$_][1]); break;\n",
100 grep $scalar_member[$_][0] eq "W",
101 0 .. $#scalar_member),
102 "\t default: croak (\"scalar_member is read-only\");\n",
103 "\t };\n";
104
105 print "\tOUTPUT: RETVAL\n\n";
106 }
107
108 if (@array_member) {
109 print "SV *$array_member[0][1] ($class *self, int idx, SV *newval = 0)\n";
110 print "\tPROTOTYPE: \$;\$\n";
111
112 if (@array_member > 1) {
113 print "\tALIAS:\n";
114 for (1 .. $#array_member) {
115 print "\t\t" . (c2perl $array_member[$_][1]) . "\t= $_\n";
116 }
117 }
118
119 print "\tCODE:\n";
120
121 print "\tif (idx < 0) croak (\"negative array index\");\n";
122
123 my $ix = @array_member == 1 ? 0 : "ix";
124
125 # range
126 print "\t switch ($ix)\n",
127 "\t {\n",
128 (map "\t case $_: if (idx >= $array_member[$_][2]) croak (\"array index out of bounds\"); break;\n",
129 0 .. $#array_member),
130 "\t };\n";
131
132 # read
133 print "\tif (GIMME_V == G_VOID)\n",
134 "\t RETVAL = &PL_sv_undef;\n",
135 "\telse\n",
136 "\t switch ($ix)\n",
137 "\t {\n",
138 (map "\t case $_: RETVAL = to_sv (self->$array_member[$_][1] [idx]); break;\n",
139 0 .. $#array_member),
140 "\t default: croak (\"array_member is write-only\");\n",
141 "\t };\n";
142
143 # write
144 print "\tif (newval)\n",
145 "\t switch ($ix)\n",
146 "\t {\n",
147 (map "\t case $_: sv_to (newval, self->$array_member[$_][1] [idx]); break;\n",
148 grep $array_member[$_][0] eq "W",
149 0 .. $#array_member),
150 "\t default: croak (\"array_member is read-only\");\n",
151 "\t };\n";
152
153 print "\tOUTPUT: RETVAL\n\n";
154 }
155
156 my $json = JSON::XS->new->utf8->encode ({
157 class => $class,
158 methods => \@method_member,
159 scalars => \@scalar_member,
160 arrays => \@array_member,
161 });
162
163 $json = join "\n", map {
164 my $part = $_;
165 $part =~ s/(["\\])/\\$1/g;
166 "\"$part\""
167 } unpack "(a80)*", $json;
168
169 print "BOOT:\n",
170 "\tav_push (av_reflect, newSVpv ($json, 0));\n\n";
171