Subclasses Class::Base. Removed error_out, error, in favor Class::Base::error.
[dbsrgits/SQL-Translator.git] / lib / SQL / Translator.pm
CommitLineData
16dc9970 1package SQL::Translator;
2
b346d8f1 3# ----------------------------------------------------------------------
c2d3a526 4# $Id: Translator.pm,v 1.9 2002-07-23 19:21:16 dlc Exp $
b346d8f1 5# ----------------------------------------------------------------------
077ebf34 6# Copyright (C) 2002 Ken Y. Clark <kycl4rk@users.sourceforge.net>,
7# darren chamberlain <darren@cpan.org>
1fd8c91f 8#
077ebf34 9# This program is free software; you can redistribute it and/or
10# modify it under the terms of the GNU General Public License as
11# published by the Free Software Foundation; version 2.
ca10f295 12#
077ebf34 13# This program is distributed in the hope that it will be useful, but
14# WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16# General Public License for more details.
ca10f295 17#
077ebf34 18# You should have received a copy of the GNU General Public License
19# along with this program; if not, write to the Free Software
20# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21# 02111-1307 USA
ca10f295 22# -------------------------------------------------------------------
23
24=head1 NAME
25
26SQL::Translator - convert schema from one database to another
27
28=head1 SYNOPSIS
29
30 use SQL::Translator;
31 my $translator = SQL::Translator->new;
077ebf34 32
b346d8f1 33 my $output = $translator->translate(
34 from => "MySQL",
35 to => "Oracle",
36 filename => $file,
37 ) or die $translator->error;
ca10f295 38 print $output;
39
40=head1 DESCRIPTION
41
42This module attempts to simplify the task of converting one database
7a8e1f51 43create syntax to another through the use of Parsers (which understand
44the sourced format) and Producers (which understand the destination
45format). The idea is that any Parser can be used with any Producer in
46the conversion process. So, if you wanted PostgreSQL-to-Oracle, you
47would use the PostgreSQL parser and the Oracle producer.
ca10f295 48
49=cut
16dc9970 50
51use strict;
c2d3a526 52use vars qw($VERSION $DEFAULT_SUB $DEBUG $ERROR);
53use base qw(Class::Base);
54
55$VERSION = sprintf "%d.%02d", q$Revision: 1.9 $ =~ /(\d+)\.(\d+)/;
ca10f295 56$DEBUG = 1 unless defined $DEBUG;
c2d3a526 57$ERROR = "";
58
59use Carp qw(carp);
16dc9970 60
b346d8f1 61# ----------------------------------------------------------------------
62# The default behavior is to "pass through" values (note that the
63# SQL::Translator instance is the first value ($_[0]), and the stuff
64# to be parsed is the second value ($_[1])
65# ----------------------------------------------------------------------
66$DEFAULT_SUB = sub { $_[1] } unless defined $DEFAULT_SUB;
16dc9970 67
ca10f295 68=head1 CONSTRUCTOR
16dc9970 69
077ebf34 70The constructor is called B<new>, and accepts a optional hash of options.
ca10f295 71Valid options are:
16dc9970 72
ca10f295 73=over 4
74
75=item parser (aka from)
76
9398955f 77=item parser_args
78
ca10f295 79=item producer (aka to)
80
9398955f 81=item producer_args
82
83=item filename (aka file)
84
85=item data
86
87=item debug
ca10f295 88
89=back
90
91All options are, well, optional; these attributes can be set via
b346d8f1 92instance methods. Internally, they are; no (non-syntactical)
93advantage is gained by passing options to the constructor.
ca10f295 94
95=cut
96
b346d8f1 97# ----------------------------------------------------------------------
c2d3a526 98# init([ARGS])
b346d8f1 99# The constructor.
dfb4c915 100#
b346d8f1 101# new takes an optional hash of arguments. These arguments may
102# include a parser, specified with the keys "parser" or "from",
103# and a producer, specified with the keys "producer" or "to".
dfb4c915 104#
b346d8f1 105# The values that can be passed as the parser or producer are
106# given directly to the parser or producer methods, respectively.
107# See the appropriate method description below for details about
108# what each expects/accepts.
b346d8f1 109# ----------------------------------------------------------------------
c2d3a526 110sub init {
111 my ($self, $config) = @_;
1fd8c91f 112
b346d8f1 113 # ------------------------------------------------------------------
114 # Set the parser and producer.
ca10f295 115 #
b346d8f1 116 # If a 'parser' or 'from' parameter is passed in, use that as the
117 # parser; if a 'producer' or 'to' parameter is passed in, use that
118 # as the producer; both default to $DEFAULT_SUB.
119 # ------------------------------------------------------------------
c2d3a526 120 $self->parser( $config->{'parser'} || $config->{'from'} || $DEFAULT_SUB);
121 $self->producer($config->{'producer'} || $config->{'to'} || $DEFAULT_SUB);
ca10f295 122
b346d8f1 123 # ------------------------------------------------------------------
e2158c40 124 # Set the parser_args and producer_args
125 # ------------------------------------------------------------------
126 for my $pargs (qw(parser_args producer_args)) {
c2d3a526 127 $self->$pargs($config->{$pargs}) if defined $config->{$pargs};
e2158c40 128 }
129
130 # ------------------------------------------------------------------
9398955f 131 # Set the data source, if 'filename' or 'file' is provided.
132 # ------------------------------------------------------------------
c2d3a526 133 $config->{'filename'} ||= $config->{'file'} || "";
134 $self->filename($config->{'filename'}) if $config->{'filename'};
9398955f 135
136 # ------------------------------------------------------------------
137 # Finally, if there is a 'data' parameter, use that in preference
138 # to filename and file
139 # ------------------------------------------------------------------
c2d3a526 140 if (my $data = $config->{'data'}) {
9398955f 141 $self->data($data);
142 }
143
144 $self->{'debug'} = $DEBUG;
c2d3a526 145 $self->{'debug'} = $config->{'debug'} if (defined $config->{'debug'});
ca10f295 146
147 return $self;
dfb4c915 148}
1fd8c91f 149
ca10f295 150=head1 METHODS
151
ca10f295 152=head2 B<producer>
153
154The B<producer> method is an accessor/mutator, used to retrieve or
155define what subroutine is called to produce the output. A subroutine
b346d8f1 156defined as a producer will be invoked as a function (not a method) and
157passed 2 parameters: its container SQL::Translator instance and a
158data structure. It is expected that the function transform the data
159structure to a string. The SQL::Transformer instance is provided for
160informational purposes; for example, the type of the parser can be
161retrieved using the B<parser_type> method, and the B<error> and
162B<debug> methods can be called when needed.
163
164When defining a producer, one of several things can be passed
165in: A module name (e.g., My::Groovy::Producer), a module name
166relative to the SQL::Translator::Producer namespace (e.g., MySQL), a
167module name and function combination (My::Groovy::Producer::transmogrify),
168or a reference to an anonymous subroutine. If a full module name is
169passed in (for the purposes of this method, a string containing "::"
170is considered to be a module name), it is treated as a package, and a
171function called "produce" will be invoked: $modulename::produce. If
172$modulename cannot be loaded, the final portion is stripped off and
173treated as a function. In other words, if there is no file named
174My/Groovy/Producer/transmogrify.pm, SQL::Translator will attempt to load
175My/Groovy/Producer.pm and use transmogrify as the name of the function,
176instead of the default "produce".
ca10f295 177
178 my $tr = SQL::Translator->new;
179
077ebf34 180 # This will invoke My::Groovy::Producer::produce($tr, $data)
ca10f295 181 $tr->producer("My::Groovy::Producer");
182
077ebf34 183 # This will invoke SQL::Translator::Producer::Sybase::produce($tr, $data)
ca10f295 184 $tr->producer("Sybase");
185
b346d8f1 186 # This will invoke My::Groovy::Producer::transmogrify($tr, $data),
187 # assuming that My::Groovy::Producer::transmogrify is not a module
188 # on disk.
e2158c40 189 $tr->producer("My::Groovy::Producer::transmogrify");
b346d8f1 190
077ebf34 191 # This will invoke the referenced subroutine directly, as
192 # $subref->($tr, $data);
ca10f295 193 $tr->producer(\&my_producer);
194
077ebf34 195There is also a method named B<producer_type>, which is a string
196containing the classname to which the above B<produce> function
197belongs. In the case of anonymous subroutines, this method returns
198the string "CODE".
199
e2158c40 200Finally, there is a method named B<producer_args>, which is both an
201accessor and a mutator. Arbitrary data may be stored in name => value
202pairs for the producer subroutine to access:
203
204 sub My::Random::producer {
205 my ($tr, $data) = @_;
206 my $pr_args = $tr->producer_args();
207
208 # $pr_args is a hashref.
209
210Extra data passed to the B<producer> method is passed to
211B<producer_args>:
212
213 $tr->producer("xSV", delimiter => ',\s*');
214
215 # In SQL::Translator::Producer::xSV:
216 my $args = $tr->producer_args;
7a8e1f51 217 my $delimiter = $args->{'delimiter'}; # value is ,\s*
e2158c40 218
ca10f295 219=cut
ca10f295 220
7a8e1f51 221# producer and producer_type
ca10f295 222sub producer {
1fd8c91f 223 my $self = shift;
b346d8f1 224
7a8e1f51 225 # producer as a mutator
ca10f295 226 if (@_) {
227 my $producer = shift;
b346d8f1 228
7a8e1f51 229 # Passed a module name (string containing "::")
ca10f295 230 if ($producer =~ /::/) {
077ebf34 231 my $func_name;
b346d8f1 232
7a8e1f51 233 # Module name was passed directly
b346d8f1 234 # We try to load the name; if it doesn't load, there's
235 # a possibility that it has a function name attached to
236 # it.
077ebf34 237 if (load($producer)) {
238 $func_name = "produce";
7a8e1f51 239 }
b346d8f1 240
7a8e1f51 241 # Module::function was passed
b346d8f1 242 else {
243 # Passed Module::Name::function; try to recover
077ebf34 244 my @func_parts = split /::/, $producer;
245 $func_name = pop @func_parts;
246 $producer = join "::", @func_parts;
b346d8f1 247
248 # If this doesn't work, then we have a legitimate
249 # problem.
077ebf34 250 load($producer) or die "Can't load $producer: $@";
7a8e1f51 251 }
077ebf34 252
7a8e1f51 253 # get code reference and assign
077ebf34 254 $self->{'producer'} = \&{ "$producer\::$func_name" };
255 $self->{'producer_type'} = $producer;
e2158c40 256 $self->debug("Got producer: $producer\::$func_name");
7a8e1f51 257 }
b346d8f1 258
7a8e1f51 259 # passed an anonymous subroutine reference
b346d8f1 260 elsif (isa($producer, 'CODE')) {
ca10f295 261 $self->{'producer'} = $producer;
077ebf34 262 $self->{'producer_type'} = "CODE";
9398955f 263 $self->debug("Got producer: code ref");
7a8e1f51 264 }
b346d8f1 265
7a8e1f51 266 # passed a string containing no "::"; relative package name
b346d8f1 267 else {
ca10f295 268 my $Pp = sprintf "SQL::Translator::Producer::$producer";
269 load($Pp) or die "Can't load $Pp: $@";
077ebf34 270 $self->{'producer'} = \&{ "$Pp\::produce" };
271 $self->{'producer_type'} = $Pp;
ca10f295 272 $self->debug("Got producer: $Pp");
7a8e1f51 273 }
b346d8f1 274
ca10f295 275 # At this point, $self->{'producer'} contains a subroutine
b346d8f1 276 # reference that is ready to run
e2158c40 277
7a8e1f51 278 # Anything left? If so, it's producer_args
279 $self->producer_args(@_) if (@_);
280 }
b346d8f1 281
ca10f295 282 return $self->{'producer'};
283};
077ebf34 284
7a8e1f51 285# ----------------------------------------------------------------------
286# producer_type
287#
e2158c40 288# producer_type is an accessor that allows producer subs to get
289# information about their origin. This is poptentially important;
290# since all producer subs are called as subroutine refernces, there is
291# no way for a producer to find out which package the sub lives in
292# originally, for example.
7a8e1f51 293# ----------------------------------------------------------------------
294sub producer_type { $_[0]->{'producer_type'} }
e2158c40 295
7a8e1f51 296# ----------------------------------------------------------------------
297# producer_args
298#
e2158c40 299# Arbitrary name => value pairs of paramters can be passed to a
300# producer using this method.
7a8e1f51 301# ----------------------------------------------------------------------
e2158c40 302sub producer_args {
303 my $self = shift;
304 if (@_) {
305 my $args = isa($_[0], 'HASH') ? shift : { @_ };
306 $self->{'producer_args'} = $args;
307 }
308 $self->{'producer_args'};
7a8e1f51 309}
ca10f295 310
311=head2 B<parser>
312
313The B<parser> method defines or retrieves a subroutine that will be
314called to perform the parsing. The basic idea is the same as that of
315B<producer> (see above), except the default subroutine name is
077ebf34 316"parse", and will be invoked as $module_name::parse($tr, $data).
317Also, the parser subroutine will be passed a string containing the
318entirety of the data to be parsed (or possibly a reference to a string?).
ca10f295 319
320 # Invokes SQL::Translator::Parser::MySQL::parse()
321 $tr->parser("MySQL");
322
323 # Invokes My::Groovy::Parser::parse()
324 $tr->parser("My::Groovy::Parser");
325
326 # Invoke an anonymous subroutine directly
327 $tr->parser(sub {
077ebf34 328 my $dumper = Data::Dumper->new([ $_[1] ], [ "SQL" ]);
ca10f295 329 $dumper->Purity(1)->Terse(1)->Deepcopy(1);
330 return $dumper->Dump;
331 });
332
e2158c40 333There is also B<parser_type> and B<parser_args>, which perform
334analogously to B<producer_type> and B<producer_args>
335
ca10f295 336=cut
337
ca10f295 338sub parser {
339 my $self = shift;
b346d8f1 340
7a8e1f51 341 # parser as a mutator
ca10f295 342 if (@_) {
343 my $parser = shift;
b346d8f1 344
7a8e1f51 345 # Passed a module name (string containing "::")
ca10f295 346 if ($parser =~ /::/) {
b346d8f1 347 my $func_name;
348
7a8e1f51 349 # Module name was passed directly
b346d8f1 350 # We try to load the name; if it doesn't load, there's
351 # a possibility that it has a function name attached to
352 # it.
353 if (load($parser)) {
354 $func_name = "parse";
7a8e1f51 355 }
b346d8f1 356
7a8e1f51 357 # Module::function was passed
b346d8f1 358 else {
359 # Passed Module::Name::function; try to recover
360 my @func_parts = split /::/, $parser;
361 $func_name = pop @func_parts;
362 $parser = join "::", @func_parts;
363
364 # If this doesn't work, then we have a legitimate
365 # problem.
366 load($parser) or die "Can't load $parser: $@";
7a8e1f51 367 }
b346d8f1 368
7a8e1f51 369 # get code reference and assign
b346d8f1 370 $self->{'parser'} = \&{ "$parser\::$func_name" };
077ebf34 371 $self->{'parser_type'} = $parser;
b346d8f1 372 $self->debug("Got parser: $parser\::$func_name");
7a8e1f51 373 }
b346d8f1 374
7a8e1f51 375 # passed an anonymous subroutine reference
b346d8f1 376 elsif (isa($parser, 'CODE')) {
ca10f295 377 $self->{'parser'} = $parser;
077ebf34 378 $self->{'parser_type'} = "CODE";
9398955f 379 $self->debug("Got parser: code ref");
7a8e1f51 380 }
b346d8f1 381
7a8e1f51 382 # passed a string containing no "::"; relative package name
b346d8f1 383 else {
384 my $Pp = sprintf "SQL::Translator::Parser::$parser";
ca10f295 385 load($Pp) or die "Can't load $Pp: $@";
386 $self->{'parser'} = \&{ "$Pp\::parse" };
077ebf34 387 $self->{'parser_type'} = $Pp;
ca10f295 388 $self->debug("Got parser: $Pp");
7a8e1f51 389 }
b346d8f1 390
391 # At this point, $self->{'parser'} contains a subroutine
392 # reference that is ready to run
b346d8f1 393
e2158c40 394 $self->parser_args(@_) if (@_);
7a8e1f51 395 }
b346d8f1 396
ca10f295 397 return $self->{'parser'};
16dc9970 398}
1fd8c91f 399
077ebf34 400sub parser_type { $_[0]->{'parser_type'} }
e2158c40 401
7a8e1f51 402# parser_args
e2158c40 403sub parser_args {
404 my $self = shift;
405 if (@_) {
406 my $args = isa($_[0], 'HASH') ? shift : { @_ };
407 $self->{'parser_args'} = $args;
408 }
409 $self->{'parser_args'};
7a8e1f51 410}
16dc9970 411
ca10f295 412=head2 B<translate>
413
414The B<translate> method calls the subroutines referenced by the
415B<parser> and B<producer> data members (described above). It accepts
416as arguments a number of things, in key => value format, including
417(potentially) a parser and a producer (they are passed directly to the
418B<parser> and B<producer> methods).
419
420Here is how the parameter list to B<translate> is parsed:
421
422=over
423
424=item *
425
4261 argument means it's the data to be parsed; which could be a string
b346d8f1 427(filename) or a refernce to a scalar (a string stored in memory), or a
428reference to a hash, which is parsed as being more than one argument
429(see next section).
ca10f295 430
431 # Parse the file /path/to/datafile
432 my $output = $tr->translate("/path/to/datafile");
433
b346d8f1 434 # Parse the data contained in the string $data
ca10f295 435 my $output = $tr->translate(\$data);
436
437=item *
438
077ebf34 439More than 1 argument means its a hash of things, and it might be
440setting a parser, producer, or datasource (this key is named
b346d8f1 441"filename" or "file" if it's a file, or "data" for a SCALAR reference.
ca10f295 442
443 # As above, parse /path/to/datafile, but with different producers
444 for my $prod ("MySQL", "XML", "Sybase") {
445 print $tr->translate(
446 producer => $prod,
447 filename => "/path/to/datafile",
448 );
449 }
450
451 # The filename hash key could also be:
ca10f295 452 datasource => \$data,
453
454You get the idea.
455
456=back
457
9398955f 458=head2 B<filename>, B<data>
459
460Using the B<filename> method, the filename of the data to be parsed
461can be set. This method can be used in conjunction with the B<data>
462method, below. If both the B<filename> and B<data> methods are
463invoked as mutators, the data set in the B<data> method is used.
464
465 $tr->filename("/my/data/files/create.sql");
466
467or:
468
469 my $create_script = do {
470 local $/;
471 open CREATE, "/my/data/files/create.sql" or die $!;
472 <CREATE>;
473 };
474 $tr->data(\$create_script);
475
476B<filename> takes a string, which is interpreted as a filename.
38254289 477B<data> takes a reference to a string, which is used as the data to be
9398955f 478parsed. If a filename is set, then that file is opened and read when
479the B<translate> method is called, as long as the data instance
480variable is not set.
481
ca10f295 482=cut
483
7a8e1f51 484# filename - get or set the filename
9398955f 485sub filename {
486 my $self = shift;
487 if (@_) {
7a8e1f51 488 my $filename = shift;
489 if (-d $filename) {
490 my $msg = "Cannot use directory '$filename' as input source";
c2d3a526 491 return $self->error($msg);
7a8e1f51 492 } elsif (-f _ && -r _) {
493 $self->{'filename'} = $filename;
494 $self->debug("Got filename: $self->{'filename'}");
495 } else {
496 my $msg = "Cannot use '$filename' as input source: ".
497 "file does not exist or is not readable.";
c2d3a526 498 return $self->error($msg);
7a8e1f51 499 }
9398955f 500 }
7a8e1f51 501
9398955f 502 $self->{'filename'};
7a8e1f51 503}
9398955f 504
7a8e1f51 505# data - get or set the data
9398955f 506# if $self->{'data'} is not set, but $self->{'filename'} is, then
507# $self->{'filename'} is opened and read, whith the results put into
508# $self->{'data'}.
509sub data {
510 my $self = shift;
511
7a8e1f51 512 # Set $self->{'data'} to $_[0], if it is provided.
9398955f 513 if (@_) {
514 my $data = shift;
515 if (isa($data, "SCALAR")) {
516 $self->{'data'} = $data;
517 }
518 elsif (! ref $data) {
519 $self->{'data'} = \$data;
520 }
521 }
9398955f 522
7a8e1f51 523 # If we have a filename but no data yet, populate.
9398955f 524 if (not $self->{'data'} and my $filename = $self->filename) {
525 $self->debug("Opening '$filename' to get contents...");
526 local *FH;
527 local $/;
528 my $data;
529
530 unless (open FH, $filename) {
c2d3a526 531 return $self->error("Can't open $filename for reading: $!");
9398955f 532 }
533
534 $data = <FH>;
535 $self->{'data'} = \$data;
536
537 unless (close FH) {
c2d3a526 538 return $self->error("Can't close $filename: $!");
9398955f 539 }
540 }
9398955f 541
542 return $self->{'data'};
7a8e1f51 543}
9398955f 544
7a8e1f51 545# translate
16dc9970 546sub translate {
ca10f295 547 my $self = shift;
7a8e1f51 548 my ($args, $parser, $parser_type, $producer, $producer_type);
549 my ($parser_output, $producer_output);
ca10f295 550
7a8e1f51 551 # Parse arguments
9398955f 552 if (@_ == 1) {
7a8e1f51 553 # Passed a reference to a hash?
ca10f295 554 if (isa($_[0], 'HASH')) {
7a8e1f51 555 # yep, a hashref
077ebf34 556 $self->debug("translate: Got a hashref");
ca10f295 557 $args = $_[0];
558 }
9398955f 559
7a8e1f51 560 # Passed a reference to a string containing the data
ca10f295 561 elsif (isa($_[0], 'SCALAR')) {
9398955f 562 # passed a ref to a string
077ebf34 563 $self->debug("translate: Got a SCALAR reference (string)");
9398955f 564 $self->data($_[0]);
ca10f295 565 }
9398955f 566
7a8e1f51 567 # Not a reference; treat it as a filename
b346d8f1 568 elsif (! ref $_[0]) {
ca10f295 569 # Not a ref, it's a filename
077ebf34 570 $self->debug("translate: Got a filename");
9398955f 571 $self->filename($_[0]);
ca10f295 572 }
9398955f 573
7a8e1f51 574 # Passed something else entirely.
b346d8f1 575 else {
576 # We're not impressed. Take your empty string and leave.
38254289 577 # return "";
578
7a8e1f51 579 # Actually, if data, parser, and producer are set, then we
580 # can continue. Too bad, because I like my comment
581 # (above)...
38254289 582 return "" unless ($self->data &&
583 $self->producer &&
584 $self->parser);
b346d8f1 585 }
16dc9970 586 }
587 else {
b346d8f1 588 # You must pass in a hash, or you get nothing.
589 return "" if @_ % 2;
ca10f295 590 $args = { @_ };
7a8e1f51 591 }
16dc9970 592
9398955f 593 # ----------------------------------------------------------------------
594 # Can specify the data to be transformed using "filename", "file",
7a8e1f51 595 # "data", or "datasource".
9398955f 596 # ----------------------------------------------------------------------
7a8e1f51 597 if (my $filename = ($args->{'filename'} || $args->{'file'})) {
9398955f 598 $self->filename($filename);
599 }
ca10f295 600
7a8e1f51 601 if (my $data = ($self->{'data'} || $self->{'datasource'})) {
9398955f 602 $self->data($data);
16dc9970 603 }
ca10f295 604
9398955f 605 # ----------------------------------------------------------------
606 # Get the data.
607 # ----------------------------------------------------------------
608 my $data = $self->data;
7a8e1f51 609 unless (length $$data) {
c2d3a526 610 return $self->error("Empty data file!");
9398955f 611 }
077ebf34 612
9398955f 613 # ----------------------------------------------------------------
ca10f295 614 # Local reference to the parser subroutine
9398955f 615 # ----------------------------------------------------------------
ca10f295 616 if ($parser = ($args->{'parser'} || $args->{'from'})) {
617 $self->parser($parser);
16dc9970 618 }
7a8e1f51 619 $parser = $self->parser;
620 $parser_type = $self->parser_type;
16dc9970 621
9398955f 622 # ----------------------------------------------------------------
ca10f295 623 # Local reference to the producer subroutine
9398955f 624 # ----------------------------------------------------------------
ca10f295 625 if ($producer = ($args->{'producer'} || $args->{'to'})) {
626 $self->producer($producer);
16dc9970 627 }
7a8e1f51 628 $producer = $self->producer;
629 $producer_type = $self->producer_type;
16dc9970 630
9398955f 631 # ----------------------------------------------------------------
7a8e1f51 632 # Execute the parser, then execute the producer with that output.
633 # Allowances are made for each piece to die, or fail to compile,
634 # since the referenced subroutines could be almost anything. In
635 # the future, each of these might happen in a Safe environment,
636 # depending on how paranoid we want to be.
9398955f 637 # ----------------------------------------------------------------
7a8e1f51 638 eval { $parser_output = $parser->($self, $$data) };
639 if ($@ || ! $parser_output) {
640 my $msg = sprintf "translate: Error with parser '%s': %s",
641 $parser_type, ($@) ? $@ : " no results";
c2d3a526 642 return $self->error($msg);
7a8e1f51 643 }
644
645 eval { $producer_output = $producer->($self, $parser_output) };
646 if ($@ || ! $producer_output) {
647 my $msg = sprintf "translate: Error with producer '%s': %s",
648 $producer_type, ($@) ? $@ : " no results";
c2d3a526 649 return $self->error($msg);
7a8e1f51 650 }
651
652 return $producer_output;
16dc9970 653}
ca10f295 654
ca10f295 655sub load {
656 my $module = do { my $m = shift; $m =~ s[::][/]g; "$m.pm" };
657 return 1 if $INC{$module};
658
659 eval { require $module };
660
661 return if ($@);
662 return 1;
1fd8c91f 663}
16dc9970 664
c2d3a526 665sub isa { UNIVERSAL::isa($_[0], $_[1]) }
666
16dc9970 6671;
668
ca10f295 669__END__
16dc9970 670#-----------------------------------------------------
671# Rescue the drowning and tie your shoestrings.
672# Henry David Thoreau
673#-----------------------------------------------------
674
7a8e1f51 675=head1 AUTHORS
16dc9970 676
ca10f295 677Ken Y. Clark, E<lt>kclark@logsoft.comE<gt>,
678darren chamberlain E<lt>darren@cpan.orgE<gt>
dfb4c915 679
ca10f295 680=head1 COPYRIGHT
16dc9970 681
ca10f295 682This program is free software; you can redistribute it and/or modify
683it under the terms of the GNU General Public License as published by
684the Free Software Foundation; version 2.
dfb4c915 685
ca10f295 686This program is distributed in the hope that it will be useful, but
687WITHOUT ANY WARRANTY; without even the implied warranty of
688MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
689General Public License for more details.
16dc9970 690
ca10f295 691You should have received a copy of the GNU General Public License
692along with this program; if not, write to the Free Software
693Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
694USA
16dc9970 695
696=head1 SEE ALSO
697
ca10f295 698L<perl>, L<Parse::RecDescent>
16dc9970 699
700=cut