App-sh2p

 view release on metacpan or  search on metacpan

lib/App/sh2p/Utils.pm  view on Meta::CPAN

package App::sh2p::Utils;

use warnings;
use strict;

our $VERSION = '0.06';

require Exporter;
our (@ISA, @EXPORT);
@ISA = ('Exporter');
@EXPORT = qw (Register_variable  Register_env_variable
              Delete_variable    get_variable_type
              print_types_tokens reset_globals
              iout    out        pre_out   error_out    flush_out
              rd_iout rd_remove 
              get_special_var    set_special_var    can_var_interpolate
              mark_function      unmark_function    ina_function
              mark_subshell      unmark_subshell    ina_subshell
              inc_block_level    dec_block_level    get_block_level
              is_user_function   set_user_function  unset_user_function
              dec_indent         inc_indent         
              rem_empty_string   fix_print_arg
              no_semi_colon      reset_semi_colon   query_semi_colon
              set_in_quotes      unset_in_quotes    query_in_quotes
              out_to_buffer      off_out_to_buffer
              set_shell          which_shell
              open_out_file      close_out_file
              set_break          is_break);

############################################################################

my $g_indent_spacing = 4;

my %g_special_vars = (
      'IFS'      => '" \t\n"',
      'ERRNO'    => '$!',
      'HOME'     => '$ENV{HOME}',
      'PATH'     => '$ENV{PATH}',
      'FUNCNAME' => '(caller(0))[3]',    # Corrected 0.04
      '?'        => '($? >> 8)',
      '#'        => 'scalar(@ARGV)',
      '@'        => '"@ARGV"',
      '*'        => '"@ARGV"',    
      '-'        => 'not supported',
      '$'        => '$$',
      '!'        => 'not supported'
      );
      
# This hash keeps a key for each variable declared
# so we know if to put a 'my' prefix
my %g_variables;

# This hash keeps track of environment variables
my %g_env_variables;

my %g_user_functions;
my $g_new_line       = 1;
my $g_use_semi_colon = 1;
my $g_ina_function   = 0;
my $g_ina_subshell   = 0;
my $g_block_level    = 0;
my $g_indent         = 0;
my $g_errors         = 0;
my $g_is_in_quotes   = 0;
my $g_shell_in_use   = "ksh";

my $g_outh;
my $g_filename;
my $g_out_buffer;    # Main output buffer
my $g_err_buffer;    # INSPECT messages, for output before the statement
my $g_pre_buffer;    # For preamble, like declaring 'my' variables
my $g_ref_redirect;  # Redirect output to buffer instead of script file
my $g_break = \do{my $some_scalar};   # We have to define a 'break' somehow

# Remember position and length for later deletion
my $g_rd_pos = 0;
my $g_rd_len = 0;

#  For use by App::sh2p only
############################################################################
# Called by Handlers::interpolate
sub can_var_interpolate {

   my ($name) = @_;
   my $retn;
   
   $retn = get_special_var ($name, 1);
   
   if (defined $retn && $retn !~ /^[\$\@]/) {
       return 0
   }
   else {
       return 1
   }
}
########################################################
# This is primarily for [@] and [*].  Also to prevent globbing inside ""
sub query_in_quotes {
    return $g_is_in_quotes;

lib/App/sh2p/Utils.pm  view on Meta::CPAN

}

sub close_out_file {
    
    flush_out ();
    
    close ($g_outh);
    print STDERR "\n";
    $g_filename = undef;
}

#################################################################################
# Out to remember redirection position
sub rd_iout {

    $g_rd_pos = length ($g_out_buffer);
    iout (@_);
    $g_rd_len = length ($g_out_buffer) - $g_rd_pos;
}

sub rd_remove {

    if ($g_rd_len) {
        $g_out_buffer = substr ($g_out_buffer, 0, $g_rd_pos) .
                        substr ($g_out_buffer, $g_rd_pos + $g_rd_len);
    }
}

#################################################################################

sub out_to_buffer {
    flush_out();
    ($g_ref_redirect) = @_;
}

sub off_out_to_buffer {
    flush_out();
    $g_ref_redirect = undef;
}

#################################################################################
# Indented out
sub iout {

   #print $g_outh ' ' x ($g_indent * $g_indent_spacing);
   
   my (@args) = @_;
  
   if (query_semi_colon()) {
       unshift @args, (' ' x ($g_indent * $g_indent_spacing));
   }
   
   out (@args);
}

#################################################################################

sub out {
   
   local $" = '';   
   #my @caller = caller();
   #print STDERR "out: <@_> @caller\n";
  
   $g_out_buffer .= "@_";
      
   $g_new_line = 0;
   
}

################################################################################
# I don't like these hacks, but any other way is convoluted
sub fix_print_arg {
    # This avoids 'print (...) interpreted as function'
    #print STDERR "fix_print_arg: <$g_out_buffer>\n";
    
    if ($g_out_buffer =~ /print/) {
        $g_out_buffer =~ s/(^|[^\'\"]+)(print\s+)\(/$2\"\",(/;    
    }
}

sub rem_empty_string {
    
    return if $g_out_buffer =~ /print/;   # Often required

    # Remove "". at start of calls
    $g_out_buffer =~ s/\(\"\"\./(/;
    
    # Remove "". in assignments
    $g_out_buffer =~ s/= \"\"\./= /;
    
}

################################################################################

sub error_out {
    my $msg = shift;
    
    # 0.06
    if (defined $msg) {
        $g_err_buffer .= "# **** INSPECT: $msg\n";
    }
    else {
        $g_err_buffer .= "\n";
    }
    
    $g_errors++;
}

################################################################################

sub pre_out {
    my $msg = shift;
    
    if (!defined $msg) {
        $msg = "\n";
    }
    
    if (query_semi_colon()) {
        $g_pre_buffer .= (' ' x ($g_indent * $g_indent_spacing)).$msg;
    }
    else {

lib/App/sh2p/Utils.pm  view on Meta::CPAN

#################################################################################

sub flush_out {

   if (defined $g_ref_redirect) {
       $$g_ref_redirect .= $g_err_buffer if $g_err_buffer;
       $$g_ref_redirect .= $g_pre_buffer if $g_pre_buffer;
       $$g_ref_redirect .= $g_out_buffer;
       
       $g_ref_redirect = undef;
   }
   else {
       print $g_outh $g_err_buffer if $g_err_buffer;
       print $g_outh $g_pre_buffer if $g_pre_buffer;
       print $g_outh $g_out_buffer;
   }
   
   # Leading space for readability with multiple files
   $g_err_buffer =~ s/\#/ \#/g;
   print STDERR $g_err_buffer; 
   
   $g_out_buffer = '';
   $g_err_buffer = '';
   $g_pre_buffer = '';
   $g_rd_len     = 0;
   
}

#################################################################################

sub reset_globals {

    %g_variables      = ();
    %g_env_variables  = ();
    %g_user_functions = ();
    
    $g_out_buffer     = '';
    $g_err_buffer     = '';
    $g_pre_buffer     = '';
      
    $g_new_line       = 1;
    $g_use_semi_colon = 1;
    $g_ina_function   = 0;
    $g_ina_subshell   = 0;
    $g_block_level    = 0;
    $g_indent         = 0;
    $g_errors         = 0;
    $g_is_in_quotes   = 0;
    $g_shell_in_use   = "ksh";
    
    $g_rd_pos = 0;
    $g_rd_len = 0;
    
}

#################################################################################
# Debug purposes only
sub print_types_tokens {
    
    my ($types, $tokens) = @_;
    my $caller = (caller(1))[3];
    
    for (my $i = 0; $i < @$types; $i++) {
    
        if (defined $types->[$i][0]) {
            print STDERR "$caller Type: ".$types->[$i][0].", ";
            print STDERR "Token: ".$tokens->[$i]."\n";
        }
        else {
            print STDERR "**** Type undefined for Token: <".$tokens->[$i].">\n";
        }
    }
    
    if (@$types != @$tokens) {
        print STDERR "Types array: ".@$types.", Token array: ".@$tokens."\n";
    }
    print STDERR "\n";
}

#################################################################################

# Module end
1;



( run in 0.866 second using v1.01-cache-2.11-cpan-8f98c5d2c55 )