use strict; use warnings; package Boilerplater::Binding::Core::File; use Boilerplater::Util qw( a_isa_b verify_args ); use Boilerplater::Binding::Core::Class; use File::Spec::Functions qw( catfile splitpath ); use File::Path qw( mkpath ); use Scalar::Util qw( blessed ); use Fcntl; use Carp; my %write_h_PARAMS = ( file => undef, dest_dir => undef, header => undef, footer => undef, ); # Generate a C header file containing all class declarations and literal C # blocks. sub write_h { my ( undef, %args ) = @_; verify_args( \%write_h_PARAMS, %args ) or confess $@; my $file = $args{file}; my $h_path = $file->h_path( $args{dest_dir} ); print "Writing $h_path\n"; # Unlink then open file. my ( undef, $out_dir, undef ) = splitpath($h_path); mkpath $out_dir unless -d $out_dir; confess("Can't make dir '$out_dir'") unless -d $out_dir; unlink $h_path; sysopen( my $fh, $h_path, O_CREAT | O_EXCL | O_WRONLY ) or confess("Can't open '$h_path' for writing"); my $include_guard_start = $file->guard_start; my $include_guard_close = $file->guard_close; # Aggregate block content. my $content = ""; for my $block ( $file->blocks ) { if ( a_isa_b( $block, 'Boilerplater::Parcel' ) ) { } elsif ( a_isa_b( $block, 'Boilerplater::Class' ) ) { my $class_binding = Boilerplater::Binding::Core::Class->new( client => $block, ); $content .= $class_binding->to_c_header . "\n"; } elsif ( a_isa_b( $block, 'Boilerplater::CBlock' ) ) { $content .= $block->get_contents . "\n"; } else { confess("Invalid block: $block"); } } print $fh < undef, dest_dir => undef, header => undef, footer => undef, ); # Generate a C file containing autogenerated code. sub write_c { my ( undef, %args ) = @_; verify_args( \%write_h_PARAMS, %args ) or confess $@; my $file = $args{file}; my $c_path = $file->c_path( $args{dest_dir} ); print "Writing $c_path\n"; # Unlink then open file. my ( undef, $out_dir, undef ) = splitpath($c_path); mkpath $out_dir unless -d $out_dir; confess("Can't make dir '$out_dir'") unless -d $out_dir; unlink $c_path; sysopen( my $fh, $c_path, O_CREAT | O_EXCL | O_WRONLY ) or confess("Can't open '$c_path' for writing"); # Aggregate content. my $content = ""; my $c_file_syms = ""; for my $block ( $file->blocks ) { if ( blessed($block) ) { if ( $block->isa('Boilerplater::Class') ) { my $bound = Boilerplater::Binding::Core::Class->new( client => $block, ); $content .= $bound->to_c . "\n"; my $c_file_sym = "C_" . uc( $block->full_struct_sym ); $c_file_syms .= "#define $c_file_sym\n"; } } } print $fh <