~ubuntu-branches/ubuntu/quantal/libglib-perl/quantal

« back to all changes in this revision

Viewing changes to lib/Glib/CodeGen.pm

  • Committer: Bazaar Package Importer
  • Author(s): Jeffrey Ratcliffe
  • Date: 2010-07-28 07:36:48 UTC
  • mfrom: (0.1.5 upstream)
  • Revision ID: james.westby@ubuntu.com-20100728073648-aiohmszaldj3bio4
Tags: 2:1.223-1
* New upstream release
* Bumped epoch to replace previous (unstable) release with this stable one.
* Standards-Version 3.9.1 (no changes)
* Add myself to Uploaders
* Update patched file paths, refresh all patches
* Updated watchfile to only report stable releases

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
package Glib::CodeGen;
2
 
 
3
 
use strict;
4
 
use warnings;
5
 
use Carp;
6
 
use IO::File;
7
 
 
8
 
our $VERSION = '0.03';
9
 
 
10
 
# type handlers should look like this:
11
 
#    sub gen_foo_stuff {
12
 
#        my ($typemacro, $classname, $base, $package) = @_;
13
 
#        ...
14
 
#    }
15
 
#
16
 
# DO NOT manipulate this data structure directly.  Use add_type_handler().
17
 
my %type_handler = (
18
 
        GEnum => \&gen_enum_stuff,
19
 
        GFlags => \&gen_flags_stuff,
20
 
        GBoxed => \&gen_boxed_stuff,
21
 
        GObject => \&gen_object_stuff,
22
 
 
23
 
        # we treat GInterfaces as GObjects for these purposes.
24
 
        GInterface => \&gen_object_stuff,
25
 
 
26
 
        GError => \&gen_error_domain_stuff,
27
 
);
28
 
 
29
 
 
30
 
=head1 NAME
31
 
 
32
 
Glib::CodeGen - code generation utilities for Glib-based bindings.
33
 
 
34
 
=head1 SYNOPSIS
35
 
 
36
 
 # usually in Makefile.PL
37
 
 use Glib::CodeGen;
38
 
 
39
 
 # most common, use all defaults
40
 
 Glib::CodeGen->parse_maps ('myprefix');
41
 
 Glib::CodeGen->write_boot;
42
 
 
43
 
 # more exotic, change everything
44
 
 Glib::CodeGen->parse_maps ('foo',
45
 
                            input => 'foo.maps',
46
 
                            header => 'foo-autogen.h',
47
 
                            typemap => 'foo.typemap',
48
 
                            register => 'register-foo.xsh');
49
 
 Glib::CodeGen->write_boot (filename => 'bootfoo.xsh',
50
 
                            glob => 'Foo*.xs',
51
 
                            ignore => '^(Foo|Foo::Bar)$');
52
 
 
53
 
 # add a custom type handler (rarely necessary)
54
 
 Glib::CodeGen->add_type_handler (FooType => \&gen_foo_stuff);
55
 
 # (see the section EXTENDING TYPE SUPPORT for more info.)
56
 
 
57
 
=head1 DESCRIPTION
58
 
 
59
 
This module packages some of the boilerplate code needed for performing code
60
 
generation typically used by perl bindings for gobject-based libraries, using
61
 
the Glib module as a base.
62
 
 
63
 
The default output filenames are in the subdirectory 'build', which usually
64
 
will be present if you are using ExtUtils::Depends (as most Glib-based
65
 
extensions probably should).
66
 
 
67
 
=head2 METHODS
68
 
 
69
 
=over
70
 
 
71
 
=item Glib::CodeGen->write_boot;
72
 
 
73
 
=item Glib::CodeGen->write_boot (KEY => VAL, ...)
74
 
 
75
 
Many GObject-based libraries to be bound to perl will be too large to put in
76
 
a single XS file; however, a single PM file typically only bootstraps one
77
 
XS file's code.  C<write_boot> generates an XSH file to be included from
78
 
the BOOT section of that one bootstrapped module, calling the boot code for
79
 
all the other XS files in the project.
80
 
 
81
 
Options are passed to the function in a set of key/val pairs, and all options
82
 
may default.
83
 
 
84
 
  filename     the name of the output file to be created.
85
 
               the default is 'build/boot.xsh'.
86
 
 
87
 
  glob         a glob pattern that specifies the names of
88
 
               the xs files to scan for MODULE lines.
89
 
               the default is 'xs/*.xs'.
90
 
 
91
 
  xs_files     use this to supply an explicit list of file
92
 
               names (as an array reference) to use instead
93
 
               of a glob pattern.  the default is to use
94
 
               the glob pattern.
95
 
 
96
 
  ignore       regular expression matching any and all 
97
 
               module names which should be ignored, i.e.
98
 
               NOT included in the list of symbols to boot.
99
 
               this parameter is extremely important for
100
 
               avoiding infinite loops at startup; see the
101
 
               discussion for an explanation and rationale.
102
 
               the default is '^[^:]+$', or, any name that
103
 
               contains no colons, i.e., any toplevel
104
 
               package name.
105
 
 
106
 
 
107
 
This function performs a glob (using perl's builtin glob operator) on the
108
 
pattern specified by the 'glob' option to retrieve a list of file names.
109
 
It then scans each file in that list for lines matching the pattern
110
 
"^MODULE" -- that is, the MODULE directive in an XS file.  The module
111
 
name is pulled out and matched against the regular expression specified
112
 
by the ignore parameter.  If this module is not to be ignored, we next
113
 
check to see if the name has been seen.  If not, the name will be converted
114
 
to a boot symbol (basically, s/:/_/ and prepend "boot_") and this symbol
115
 
will be added to a call to GPERL_CALL_BOOT in the generated file; it is then
116
 
marked as seen so we don't call it again.
117
 
 
118
 
 
119
 
What is this all about, you ask?  In order to bind an XSub to perl, the C
120
 
function must be registered with the interpreter.  This is the function of the
121
 
"boot" code, which is typically called in the bootstrapping process.  However,
122
 
when multiple XS files are used with only one PM file, some other mechanism
123
 
must call the boot code from each XS file before any of the function therein
124
 
will be available.
125
 
 
126
 
A typical setup for a multiple-XS, single-PM module will be to call the 
127
 
various bits of boot code from the BOOT: section of the toplevel module's
128
 
XS file.
129
 
 
130
 
To use Gtk2 as an example, when you do 'use Gtk2', Gtk2.pm calls bootstrap
131
 
on Gtk2, which calls the C function boot_Gtk2.  This function calls the
132
 
boot symbols for all the other xs files in the module.  The distinction
133
 
is that the toplevel module, Gtk2, has no colons in its name.
134
 
 
135
 
 
136
 
C<xsubpp> generates the boot function's name by replacing the 
137
 
colons in the MODULE name with underscores and prepending "boot_".
138
 
We need to be careful not to include the boot code for the bootstrapped module,
139
 
(say Toplevel, or Gtk2, or whatever) because the bootstrap code in 
140
 
Toplevel.pm will call boot_Toplevel when loaded, and boot_Toplevel
141
 
should actually include the file we are creating here.
142
 
 
143
 
The default value for the ignore parameter ignores any name not containing
144
 
colons, because it is assumed that this will be a toplevel module, and any
145
 
other packages/modules it boots will be I<below> this namespace, i.e., they
146
 
will contain colons.  This assumption holds true for Gtk2 and Gnome2, but
147
 
obviously fails for something like Gnome2::Canvas.  To boot that module
148
 
properly, you must use a regular expression such as "^Gnome2::Canvas$".
149
 
 
150
 
Note that you can, of course, match more than just one name, e.g.
151
 
"^(Foo|Foo::Bar)$", if you wanted to have Foo::Bar be included in the same
152
 
dynamically loaded object but only be booted when absolutely necessary.
153
 
(If you get that to work, more power to you.)
154
 
 
155
 
Also, since this code scans for ^MODULE, you must comment the MODULE section
156
 
out with leading # marks if you want to hide it from C<write_boot>.
157
 
 
158
 
=cut
159
 
 
160
 
sub write_boot {
161
 
        my $class = shift;
162
 
        my %opts = (
163
 
                ignore => '^[^:]+$',    # ignore package with no colons in it
164
 
                filename => 'build/boot.xsh',
165
 
                'glob' => 'xs/*.xs',
166
 
                @_,
167
 
        );
168
 
        my $ignore = $opts{ignore};
169
 
 
170
 
        my $file = IO::File->new (">$opts{filename}")
171
 
                or carp "Cannot write $opts{filename}: $!"; 
172
 
 
173
 
        print $file "\n\n/* This file is automatically generated, any changes made here will be lost! */\n\n";
174
 
 
175
 
        my %boot=();
176
 
 
177
 
        my @xs_files = 'ARRAY' eq ref $opts{xs_files}
178
 
                     ? @{ $opts{xs_files} }
179
 
                     : glob $opts{'glob'};
180
 
 
181
 
        foreach my $xsfile (@xs_files) {
182
 
                my $in = IO::File->new ($xsfile)
183
 
                                or die "can't open $xsfile: $!\n";
184
 
 
185
 
                while (<$in>) {
186
 
                        next unless m/^MODULE\s*=\s*(\S+)/;
187
 
                        #warn "found $1 in $&\n";
188
 
 
189
 
                        my $package = $1;
190
 
                        
191
 
                        next if $package =~ m/$ignore/;
192
 
 
193
 
                        $package =~ s/:/_/g;
194
 
                        my $sym = "boot_$package";
195
 
                        print $file "GPERL_CALL_BOOT ($sym);\n"
196
 
                                unless $boot{$sym};
197
 
                        $boot{$sym}++;
198
 
                }
199
 
 
200
 
                close $in;
201
 
        }
202
 
 
203
 
        close $file;
204
 
}
205
 
 
206
 
 
207
 
=item Glib::CodeGen->parse_maps (PREFIX, [KEY => VAL, ...])
208
 
 
209
 
Convention within Glib/Gtk2 and friends is to use preprocessor macros in the
210
 
style of SvMyType and newSVMyType to get values in and out of perl, and to
211
 
use those same macros from both hand-written code as well as the typemaps.
212
 
However, if you have a lot of types in your library (such as the nearly 200
213
 
types in Gtk+ 2.x), then writing those macros becomes incredibly tedious, 
214
 
especially so when you factor in all of the variants and such.
215
 
 
216
 
So, this function can turn a flat file containing terse descriptions of the
217
 
types into a header containing all the cast macros, a typemap file using them,
218
 
and an XSH file containing the proper code to register each of those types
219
 
(to be included by your module's BOOT code).
220
 
 
221
 
The I<PREFIX> is mandatory, and is used in some of the resulting filenames,
222
 
You can also override the defaults by providing key=>val pairs:
223
 
 
224
 
  input    input file name.  default is 'maps'.  if this
225
 
           key's value is an array reference, all the
226
 
           filenames in the array will be scanned.
227
 
  header   name of the header file to create, default is
228
 
           build/$prefix-autogen.h
229
 
  typemap  name of the typemap file to create, default is
230
 
           build/$prefix.typemap
231
 
  register name of the xsh file to contain all of the 
232
 
           type registrations, default is build/register.xsh
233
 
 
234
 
the maps file is a table of type descriptions, one per line, with fields
235
 
separated by whitespace.  the fields should be:
236
 
 
237
 
  TYPE macro    e.g., GTK_TYPE_WIDGET 
238
 
  class name    e.g. GtkWidget, name of the C type
239
 
  base type     one of GObject, GBoxed, GEnum, GFlags.
240
 
                To support other base types, see 
241
 
                EXTENDING TYPE SUPPORT for info on
242
 
                on how to add a custom type handler.
243
 
  package       name of the perl package to which this
244
 
                class name should be mapped, e.g.
245
 
                Gtk2::Widget
246
 
 
247
 
As a special case, you can also use this same format to register error
248
 
domains; in this case two of the four columns take on slightly different
249
 
meanings:
250
 
 
251
 
  domain macro     e.g., GDK_PIXBUF_ERROR
252
 
  enum type macro  e.g., GDK_TYPE_PIXBUF_ERROR
253
 
  base type        GError
254
 
  package          name of the Perl package to which this
255
 
                   class name should be mapped, e.g.,
256
 
                   Gtk2::Gdk::Pixbuf::Error.
257
 
 
258
 
=back
259
 
 
260
 
=cut
261
 
 
262
 
# when we parse the maps, type handlers will call several helper functions
263
 
# to add header lines, typemaps, and boot lines.  we store those here.
264
 
# these are private.  see the add_foo functions, below.
265
 
# there
266
 
my (@header, @typemap, @input, @output, @boot);
267
 
 
268
 
 
269
 
sub parse_maps {
270
 
        my $class = shift;
271
 
        my $prefix = shift;
272
 
        my %props = (
273
 
                input => 'maps',
274
 
                header => "build/$prefix-autogen.h",
275
 
                typemap => "build/$prefix.typemap",
276
 
                register => 'build/register.xsh',
277
 
                @_,
278
 
        );
279
 
 
280
 
        local *IN;
281
 
        local *OUT;
282
 
 
283
 
        my %seen = ();
284
 
 
285
 
        @header = ();
286
 
        @typemap = ();
287
 
        @input = ();
288
 
        @output = ();
289
 
        @boot = ();
290
 
 
291
 
        my @files = 'ARRAY' eq ref $props{input}
292
 
                  ? @{ $props{input} }
293
 
                  : $props{input};
294
 
 
295
 
        foreach my $file (@files) {
296
 
            open IN, "< $file"
297
 
                or die "can't open $file for reading: $!\n";
298
 
 
299
 
            my $n = 0;
300
 
 
301
 
            while (<IN>) {
302
 
                chomp;
303
 
                s/#.*//;
304
 
                my ($typemacro, $classname, $base, $package) = split;
305
 
                next unless defined $package;
306
 
                if (exists $type_handler{$base}) {
307
 
                        $type_handler{$base}->($typemacro, $classname,
308
 
                                               $base, $package);
309
 
                        $seen{$base}++;
310
 
 
311
 
                } else {
312
 
                        warn "unhandled type $typemacro $classname $base $package\n";
313
 
                        $seen{unhandled}++;
314
 
                }
315
 
                $n++;
316
 
            }
317
 
 
318
 
            close IN;
319
 
 
320
 
            #print "Loaded $n type definitions from $file\n";
321
 
        }
322
 
 
323
 
        # create output
324
 
 
325
 
        # the header
326
 
        open OUT, "> $props{header}"
327
 
                or die "can't open $props{header} for writing: $!\n";
328
 
        print OUT join("\n",
329
 
                "/* This file is automatically generated. Any changes made here will be lost. */\n",
330
 
                "/* This header defines simple perlapi-ish macros for creating SV wrappers",
331
 
                " * and extracting the GPerl value from SV wrappers.  These macros are used",
332
 
                " * by the autogenerated typemaps, and are defined here so that you can use",
333
 
                " * the same logic anywhere in your code (e.g., if you handle the argument",
334
 
                " * stack by hand instead of using the typemap). */\n",
335
 
                @header,
336
 
                );
337
 
        close OUT;
338
 
 
339
 
        # the typemaps
340
 
        open OUT, "> $props{typemap}"
341
 
                or die "can't open $props{typemap} for writing: $!\n";
342
 
        print OUT join("\n",
343
 
                        "# This file is automatically generated.  Any changes made here will be lost.",
344
 
                        "# This typemap is a trivial one-to-one mapping of each type, to avoid the",
345
 
                        "# need for bizarre typedefs and other tricks often used with XS.",
346
 
                        "TYPEMAP\n", @typemap,
347
 
                        "\nINPUT\n", @input,
348
 
                        "\nOUTPUT\n", @output);
349
 
        close OUT;
350
 
 
351
 
        # the boot code
352
 
        open OUT, "> $props{register}"
353
 
                or die "can't open $props{register} for writing: $!\n";
354
 
        print OUT join("\n",
355
 
                        "/* This file is automatically generated.  Any changes made here will be lost. */",
356
 
                        @boot,
357
 
                        );
358
 
        print OUT "\n";
359
 
        close OUT;
360
 
 
361
 
        # mini report to stdout
362
 
        # foreach (sort keys %seen) {
363
 
        #       printf "  %3d %s\n", $seen{$_}, $_;
364
 
        # }
365
 
 
366
 
        # fin.
367
 
}
368
 
 
369
 
=head1 EXTENDING TYPE SUPPORT
370
 
 
371
 
C<parse_maps> uses the base type entry in each maps record to decide how to
372
 
generate output for that type.  In the base module, type support is included
373
 
for the base types provided by Glib.  It is easy to add support for your own
374
 
types, by merely adding a type handler.  This type handler will call utility
375
 
functions to add typemaps, BOOT lines, and header lines.
376
 
 
377
 
=over
378
 
 
379
 
=item Glib::CodeGen->add_type_handler ($base_type => $handler)
380
 
 
381
 
=over
382
 
 
383
 
=item $base_type (string) C name of the base type to handle.
384
 
 
385
 
=item $handler (subroutine) Callback used to handle this type.
386
 
 
387
 
=back
388
 
 
389
 
Use I<$handler> to generate output for records whose base type is
390
 
I<$base_type>.  I<$base_type> is the C type name as found in the third
391
 
column of a maps file entry.
392
 
 
393
 
I<$handler> will be called with the (possibly preprocessed) contents of the
394
 
current maps file record, and should call the C<add_typemap>, C<add_register>,
395
 
and C<add_header> functions to set up the necessary C/XS glue for that type.
396
 
 
397
 
For example:
398
 
 
399
 
  Glib::CodeGen->add_type_handler (CoolThing => sub {
400
 
      my ($typemacro, $classname, $base, $package) = @_;
401
 
      
402
 
      # $typemacro is the C type macro, like COOL_TYPE_THING.
403
 
      # $classname is the actual C type name, like CoolFooThing.
404
 
      # $base is the C name of the base type.  If CoolFooThing
405
 
      #     isa CoolThing, $base will be CoolThing.  This
406
 
      #     parameter is useful when using the same type handler
407
 
      #     for multiple base types.
408
 
      # $package is the package name that corresponds to
409
 
      #     $classname, as specified in the maps file.
410
 
      
411
 
      ...
412
 
  });
413
 
 
414
 
=cut
415
 
 
416
 
sub add_type_handler {
417
 
        my (undef, $root_type, $handler) = @_;
418
 
        $type_handler{$root_type} = $handler;
419
 
}
420
 
 
421
 
=item add_typemap $type, $typemap [, $input, $output]
422
 
 
423
 
Add a typemap entry for C<$type>, named C<$typemap>.  If I<$input> and/or
424
 
I<$output> are defined, their text will be used as the C<INPUT> and/or
425
 
C<OUTPUT> typemap implementations (respectively) for I<$typemap>.  Note that in
426
 
general, you'll use C<T_GPERL_GENERIC_WRAPPER> or some other existing typemap
427
 
for I<$typemap>, so I<$input> and I<$output> are very rarely used.
428
 
 
429
 
Example:
430
 
 
431
 
  # map $classname pointers and all their variants to the generic
432
 
  # wrapper typemap.
433
 
  add_typemap "$classname *", "T_GPERL_GENERIC_WRAPPER";
434
 
  add_typemap "const $classname *", "T_GPERL_GENERIC_WRAPPER";
435
 
  add_typemap "$classname\_ornull *", "T_GPERL_GENERIC_WRAPPER";
436
 
  add_typemap "const $classname\_ornull *", "T_GPERL_GENERIC_WRAPPER";
437
 
  add_typemap "$classname\_own *", "T_GPERL_GENERIC_WRAPPER";
438
 
  add_typemap "$classname\_copy *", "T_GPERL_GENERIC_WRAPPER";
439
 
  add_typemap "$classname\_own_ornull *", "T_GPERL_GENERIC_WRAPPER";
440
 
 
441
 
  # custom code for an int-like enum:
442
 
  add_typemap $class => T_FOO,
443
 
              "\$var = foo_unwrap (\$arg);", # input
444
 
              "\$arg = foo_wrap (\$var);"; # output
445
 
 
446
 
=cut
447
 
 
448
 
sub add_typemap {
449
 
        my ($type, $typemap, $input, $output) = @_;
450
 
        push @typemap, "$type\t$typemap" if defined $typemap;
451
 
        push @input, $input if defined $input;
452
 
        push @output, $output if defined $output;
453
 
}
454
 
 
455
 
=item add_register $text
456
 
 
457
 
Add I<$text> to the generated C<register.xsh>.  This is usually used for
458
 
registering types with the bindings, e.g.:
459
 
 
460
 
   add_register "#ifdef $typemacro\n"
461
 
          . "gperl_register_object ($typemacro, \"$package\");\n"
462
 
          . "#endif /* $typemacro */";
463
 
 
464
 
=cut
465
 
 
466
 
sub add_register { push @boot, shift; }
467
 
 
468
 
=item add_header $text
469
 
 
470
 
Add I<$text> to the generated C header.  You'll put variant typedefs and
471
 
wrap/unwrap macros in the header, and will usually want to wrap the
472
 
declarations in C<#ifdef $typemacro> for safety.
473
 
 
474
 
=cut
475
 
 
476
 
sub add_header { push @header, shift; }
477
 
 
478
 
 
479
 
#
480
 
# generator subs
481
 
#
482
 
 
483
 
sub gen_enum_stuff {
484
 
        my ($typemacro, $classname, undef, $package) = @_;
485
 
        add_header "#ifdef $typemacro
486
 
  /* GEnum $classname */
487
 
# define Sv$classname(sv)       (($classname)gperl_convert_enum ($typemacro, sv))
488
 
# define newSV$classname(val)   (gperl_convert_back_enum ($typemacro, val))
489
 
#endif /* $typemacro */
490
 
";
491
 
        add_typemap $classname, "T_GPERL_GENERIC_WRAPPER";
492
 
        add_register "#ifdef $typemacro
493
 
gperl_register_fundamental ($typemacro, \"$package\");
494
 
#endif /* $typemacro */"
495
 
                unless $package eq '-';
496
 
}
497
 
 
498
 
sub gen_flags_stuff {
499
 
        my ($typemacro, $classname, undef, $package) = @_;
500
 
        add_header "#ifdef $typemacro
501
 
  /* GFlags $classname */
502
 
# define Sv$classname(sv)       (($classname)gperl_convert_flags ($typemacro, sv))
503
 
# define newSV$classname(val)   (gperl_convert_back_flags ($typemacro, val))
504
 
#endif /* $typemacro */
505
 
";
506
 
        add_typemap $classname, "T_GPERL_GENERIC_WRAPPER";
507
 
        add_register "#ifdef $typemacro
508
 
gperl_register_fundamental ($typemacro, \"$package\");
509
 
#endif /* $typemacro */"
510
 
                unless $package eq '-';
511
 
}
512
 
 
513
 
 
514
 
 
515
 
sub gen_boxed_stuff {
516
 
        my ($typemacro, $classname, undef, $package) = @_;
517
 
        add_header "#ifdef $typemacro
518
 
  /* GBoxed $classname */
519
 
  typedef $classname $classname\_ornull;
520
 
# define Sv$classname(sv)       (($classname *) gperl_get_boxed_check ((sv), $typemacro))
521
 
# define Sv$classname\_ornull(sv)       (gperl_sv_is_defined (sv) ? Sv$classname (sv) : NULL)
522
 
  typedef $classname $classname\_own;
523
 
  typedef $classname $classname\_copy;
524
 
  typedef $classname $classname\_own_ornull;
525
 
# define newSV$classname(val)   (gperl_new_boxed ((gpointer) (val), $typemacro, FALSE))
526
 
# define newSV$classname\_ornull(val)   ((val) ? newSV$classname(val) : &PL_sv_undef)
527
 
# define newSV$classname\_own(val)      (gperl_new_boxed ((gpointer) (val), $typemacro, TRUE))
528
 
# define newSV$classname\_copy(val)     (gperl_new_boxed_copy ((gpointer) (val), $typemacro))
529
 
# define newSV$classname\_own_ornull(val)       ((val) ? newSV$classname\_own(val) : &PL_sv_undef)
530
 
#endif /* $typemacro */
531
 
";
532
 
        add_typemap "$classname *", "T_GPERL_GENERIC_WRAPPER";
533
 
        add_typemap "const $classname *", "T_GPERL_GENERIC_WRAPPER";
534
 
        add_typemap "$classname\_ornull *", "T_GPERL_GENERIC_WRAPPER";
535
 
        add_typemap "const $classname\_ornull *", "T_GPERL_GENERIC_WRAPPER";
536
 
        add_typemap "$classname\_own *", "T_GPERL_GENERIC_WRAPPER";
537
 
        add_typemap "$classname\_copy *", "T_GPERL_GENERIC_WRAPPER";
538
 
        add_typemap "$classname\_own_ornull *", "T_GPERL_GENERIC_WRAPPER";
539
 
        add_register "#ifdef $typemacro
540
 
gperl_register_boxed ($typemacro, \"$package\", NULL);
541
 
#endif /* $typemacro */"
542
 
                unless $package eq '-';
543
 
}
544
 
 
545
 
 
546
 
 
547
 
sub gen_object_stuff {
548
 
        my ($typemacro, $classname, $root, $package) = @_;
549
 
        my $get_wrapper = 'gperl_new_object (G_OBJECT (val), FALSE)';
550
 
 
551
 
        my $header_text = "#ifdef $typemacro
552
 
  /* $root derivative $classname */
553
 
# define Sv$classname(sv)       (($classname*)gperl_get_object_check (sv, $typemacro))
554
 
# define newSV$classname(val)   ($get_wrapper)
555
 
  typedef $classname $classname\_ornull;
556
 
# define Sv$classname\_ornull(sv)       (gperl_sv_is_defined (sv) ? Sv$classname(sv) : NULL)
557
 
# define newSV$classname\_ornull(val)   (((val) == NULL) ? &PL_sv_undef : $get_wrapper)
558
 
";
559
 
 
560
 
        add_typemap "$classname *", "T_GPERL_GENERIC_WRAPPER";
561
 
        add_typemap "const $classname *", "T_GPERL_GENERIC_WRAPPER";
562
 
        add_typemap "$classname\_ornull *", "T_GPERL_GENERIC_WRAPPER";
563
 
        add_typemap "const $classname\_ornull *", "T_GPERL_GENERIC_WRAPPER";
564
 
        add_register "#ifdef $typemacro
565
 
gperl_register_object ($typemacro, \"$package\");
566
 
#endif /* $typemacro */";
567
 
 
568
 
        if ($root eq 'GObject') {
569
 
                # for GObjects, add a _noinc and a noinc_ornull variant for
570
 
                # returning GObjects from constructors.
571
 
                $header_text .= "typedef $classname $classname\_noinc;
572
 
#define newSV$classname\_noinc(val)     (gperl_new_object (G_OBJECT (val), TRUE))
573
 
typedef $classname $classname\_noinc_ornull;
574
 
#define newSV$classname\_noinc_ornull(val)      ((val) ? newSV$classname\_noinc(val) : &PL_sv_undef)
575
 
";
576
 
                add_typemap "$classname\_noinc *", "T_GPERL_GENERIC_WRAPPER";
577
 
                add_typemap "$classname\_noinc_ornull *", "T_GPERL_GENERIC_WRAPPER";
578
 
        }
579
 
 
580
 
        # close the header ifdef
581
 
        $header_text .= "#endif /* $typemacro */\n";
582
 
 
583
 
        add_header $header_text;
584
 
}
585
 
 
586
 
sub gen_error_domain_stuff {
587
 
        my ($domain, $enum, undef, $package) = @_;
588
 
 
589
 
        add_register "#if defined($domain) /* && defined($enum) */
590
 
gperl_register_error_domain ($domain, $enum, \"$package\");
591
 
#endif /* $domain */
592
 
";
593
 
}
594
 
 
595
 
1;
596
 
__END__
597
 
 
598
 
=back
599
 
 
600
 
=head1 BUGS
601
 
 
602
 
GInterfaces are mostly just ignored.
603
 
 
604
 
The code is ugly.
605
 
 
606
 
=head1 AUTHOR
607
 
 
608
 
muppet <scott at asofyet dot org>
609
 
 
610
 
=head1 COPYRIGHT
611
 
 
612
 
Copyright (C) 2003-2005 by the gtk2-perl team (see the file AUTHORS for the
613
 
full list)
614
 
 
615
 
This library is free software; you can redistribute it and/or modify it under
616
 
the terms of the GNU Library General Public License as published by the Free
617
 
Software Foundation; either version 2.1 of the License, or (at your option)
618
 
any later version.
619
 
 
620
 
This library is distributed in the hope that it will be useful, but WITHOUT
621
 
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
622
 
FOR A PARTICULAR PURPOSE.  See the GNU Library General Public License for
623
 
more details.
624
 
 
625
 
You should have received a copy of the GNU Library General Public License
626
 
along with this library; if not, write to the Free Software Foundation, Inc.,
627
 
59 Temple Place - Suite 330, Boston, MA  02111-1307  USA.
628
 
 
629
 
=cut