diff options
author | gbrandl <devnull@localhost> | 2009-09-15 11:45:12 +0200 |
---|---|---|
committer | gbrandl <devnull@localhost> | 2009-09-15 11:45:12 +0200 |
commit | 99ec92d58608ce41944126b7908167e19332eb88 (patch) | |
tree | 7bbd8649fb3d975ab7a38e3048903e6ecc10c66a /tests/examplefiles/perl_perl5db | |
parent | ce4a827a93ef39929fc4c2b89ffb4770fe2dc3bb (diff) | |
download | pygments-99ec92d58608ce41944126b7908167e19332eb88.tar.gz |
Fix test suite failures and set today as release date.
Diffstat (limited to 'tests/examplefiles/perl_perl5db')
-rw-r--r-- | tests/examplefiles/perl_perl5db | 998 |
1 files changed, 998 insertions, 0 deletions
diff --git a/tests/examplefiles/perl_perl5db b/tests/examplefiles/perl_perl5db new file mode 100644 index 00000000..ab9d5e30 --- /dev/null +++ b/tests/examplefiles/perl_perl5db @@ -0,0 +1,998 @@ + +=head1 NAME + +perl5db.pl - the perl debugger + +=head1 SYNOPSIS + + perl -d your_Perl_script + +=head1 DESCRIPTION + +After this routine is over, we don't have user code executing in the debugger's +context, so we can use C<my> freely. + +=cut + +############################################## Begin lexical danger zone + +# 'my' variables used here could leak into (that is, be visible in) +# the context that the code being evaluated is executing in. This means that +# the code could modify the debugger's variables. +# +# Fiddling with the debugger's context could be Bad. We insulate things as +# much as we can. + +sub eval { + + # 'my' would make it visible from user code + # but so does local! --tchrist + # Remember: this localizes @DB::res, not @main::res. + local @res; + { + + # Try to keep the user code from messing with us. Save these so that + # even if the eval'ed code changes them, we can put them back again. + # Needed because the user could refer directly to the debugger's + # package globals (and any 'my' variables in this containing scope) + # inside the eval(), and we want to try to stay safe. + local $otrace = $trace; + local $osingle = $single; + local $od = $^D; + + # Untaint the incoming eval() argument. + { ($evalarg) = $evalarg =~ /(.*)/s; } + + # $usercontext built in DB::DB near the comment + # "set up the context for DB::eval ..." + # Evaluate and save any results. + @res = eval "$usercontext $evalarg;\n"; # '\n' for nice recursive debug + + # Restore those old values. + $trace = $otrace; + $single = $osingle; + $^D = $od; + } + + # Save the current value of $@, and preserve it in the debugger's copy + # of the saved precious globals. + my $at = $@; + + # Since we're only saving $@, we only have to localize the array element + # that it will be stored in. + local $saved[0]; # Preserve the old value of $@ + eval { &DB::save }; + + # Now see whether we need to report an error back to the user. + if ($at) { + local $\ = ''; + print $OUT $at; + } + + # Display as required by the caller. $onetimeDump and $onetimedumpDepth + # are package globals. + elsif ($onetimeDump) { + if ( $onetimeDump eq 'dump' ) { + local $option{dumpDepth} = $onetimedumpDepth + if defined $onetimedumpDepth; + dumpit( $OUT, \@res ); + } + elsif ( $onetimeDump eq 'methods' ) { + methods( $res[0] ); + } + } ## end elsif ($onetimeDump) + @res; +} ## end sub eval + +############################################## End lexical danger zone + +# After this point it is safe to introduce lexicals. +# The code being debugged will be executing in its own context, and +# can't see the inside of the debugger. +# +# However, one should not overdo it: leave as much control from outside as +# possible. If you make something a lexical, it's not going to be addressable +# from outside the debugger even if you know its name. + +# This file is automatically included if you do perl -d. +# It's probably not useful to include this yourself. +# +# Before venturing further into these twisty passages, it is +# wise to read the perldebguts man page or risk the ire of dragons. +# +# (It should be noted that perldebguts will tell you a lot about +# the underlying mechanics of how the debugger interfaces into the +# Perl interpreter, but not a lot about the debugger itself. The new +# comments in this code try to address this problem.) + +# Note that no subroutine call is possible until &DB::sub is defined +# (for subroutines defined outside of the package DB). In fact the same is +# true if $deep is not defined. + +# Enhanced by ilya@math.ohio-state.edu (Ilya Zakharevich) + +# modified Perl debugger, to be run from Emacs in perldb-mode +# Ray Lischner (uunet!mntgfx!lisch) as of 5 Nov 1990 +# Johan Vromans -- upgrade to 4.0 pl 10 +# Ilya Zakharevich -- patches after 5.001 (and some before ;-) + +# (We have made efforts to clarify the comments in the change log +# in other places; some of them may seem somewhat obscure as they +# were originally written, and explaining them away from the code +# in question seems conterproductive.. -JM) + +=head1 DEBUGGER INITIALIZATION + +The debugger starts up in phases. + +=head2 BASIC SETUP + +First, it initializes the environment it wants to run in: turning off +warnings during its own compilation, defining variables which it will need +to avoid warnings later, setting itself up to not exit when the program +terminates, and defaulting to printing return values for the C<r> command. + +=cut + +# Needed for the statement after exec(): +# +# This BEGIN block is simply used to switch off warnings during debugger +# compiliation. Probably it would be better practice to fix the warnings, +# but this is how it's done at the moment. + +BEGIN { + $ini_warn = $^W; + $^W = 0; +} # Switch compilation warnings off until another BEGIN. + +# test if assertions are supported and actived: +BEGIN { + $ini_assertion = eval "sub asserting_test : assertion {1}; 1"; + + # $ini_assertion = undef => assertions unsupported, + # " = 1 => assertions supported + # print "\$ini_assertion=$ini_assertion\n"; +} + +local ($^W) = 0; # Switch run-time warnings off during init. + +=head2 THREADS SUPPORT + +If we are running under a threaded Perl, we require threads and threads::shared +if the environment variable C<PERL5DB_THREADED> is set, to enable proper +threaded debugger control. C<-dt> can also be used to set this. + +Each new thread will be announced and the debugger prompt will always inform +you of each new thread created. It will also indicate the thread id in which +we are currently running within the prompt like this: + + [tid] DB<$i> + +Where C<[tid]> is an integer thread id and C<$i> is the familiar debugger +command prompt. The prompt will show: C<[0]> when running under threads, but +not actually in a thread. C<[tid]> is consistent with C<gdb> usage. + +While running under threads, when you set or delete a breakpoint (etc.), this +will apply to all threads, not just the currently running one. When you are +in a currently executing thread, you will stay there until it completes. With +the current implementation it is not currently possible to hop from one thread +to another. + +The C<e> and C<E> commands are currently fairly minimal - see C<h e> and C<h E>. + +Note that threading support was built into the debugger as of Perl version +C<5.8.6> and debugger version C<1.2.8>. + +=cut + +BEGIN { + # ensure we can share our non-threaded variables or no-op + if ($ENV{PERL5DB_THREADED}) { + require threads; + require threads::shared; + import threads::shared qw(share); + $DBGR; + share(\$DBGR); + lock($DBGR); + print "Threads support enabled\n"; + } else { + *lock = sub(*) {}; + *share = sub(*) {}; + } +} + +# This would probably be better done with "use vars", but that wasn't around +# when this code was originally written. (Neither was "use strict".) And on +# the principle of not fiddling with something that was working, this was +# left alone. +warn( # Do not ;-) + # These variables control the execution of 'dumpvar.pl'. + $dumpvar::hashDepth, + $dumpvar::arrayDepth, + $dumpvar::dumpDBFiles, + $dumpvar::dumpPackages, + $dumpvar::quoteHighBit, + $dumpvar::printUndef, + $dumpvar::globPrint, + $dumpvar::usageOnly, + + # used to save @ARGV and extract any debugger-related flags. + @ARGS, + + # used to control die() reporting in diesignal() + $Carp::CarpLevel, + + # used to prevent multiple entries to diesignal() + # (if for instance diesignal() itself dies) + $panic, + + # used to prevent the debugger from running nonstop + # after a restart + $second_time, + ) + if 0; + +foreach my $k (keys (%INC)) { + &share(\$main::{'_<'.$filename}); +}; + +# Command-line + PERLLIB: +# Save the contents of @INC before they are modified elsewhere. +@ini_INC = @INC; + +# This was an attempt to clear out the previous values of various +# trapped errors. Apparently it didn't help. XXX More info needed! +# $prevwarn = $prevdie = $prevbus = $prevsegv = ''; # Does not help?! + +# We set these variables to safe values. We don't want to blindly turn +# off warnings, because other packages may still want them. +$trace = $signal = $single = 0; # Uninitialized warning suppression + # (local $^W cannot help - other packages!). + +# Default to not exiting when program finishes; print the return +# value when the 'r' command is used to return from a subroutine. +$inhibit_exit = $option{PrintRet} = 1; + +=head1 OPTION PROCESSING + +The debugger's options are actually spread out over the debugger itself and +C<dumpvar.pl>; some of these are variables to be set, while others are +subs to be called with a value. To try to make this a little easier to +manage, the debugger uses a few data structures to define what options +are legal and how they are to be processed. + +First, the C<@options> array defines the I<names> of all the options that +are to be accepted. + +=cut + +@options = qw( + CommandSet + hashDepth arrayDepth dumpDepth + DumpDBFiles DumpPackages DumpReused + compactDump veryCompact quote + HighBit undefPrint globPrint + PrintRet UsageOnly frame + AutoTrace TTY noTTY + ReadLine NonStop LineInfo + maxTraceLen recallCommand ShellBang + pager tkRunning ornaments + signalLevel warnLevel dieLevel + inhibit_exit ImmediateStop bareStringify + CreateTTY RemotePort windowSize + DollarCaretP OnlyAssertions WarnAssertions +); + +@RememberOnROptions = qw(DollarCaretP OnlyAssertions); + +=pod + +Second, C<optionVars> lists the variables that each option uses to save its +state. + +=cut + +%optionVars = ( + hashDepth => \$dumpvar::hashDepth, + arrayDepth => \$dumpvar::arrayDepth, + CommandSet => \$CommandSet, + DumpDBFiles => \$dumpvar::dumpDBFiles, + DumpPackages => \$dumpvar::dumpPackages, + DumpReused => \$dumpvar::dumpReused, + HighBit => \$dumpvar::quoteHighBit, + undefPrint => \$dumpvar::printUndef, + globPrint => \$dumpvar::globPrint, + UsageOnly => \$dumpvar::usageOnly, + CreateTTY => \$CreateTTY, + bareStringify => \$dumpvar::bareStringify, + frame => \$frame, + AutoTrace => \$trace, + inhibit_exit => \$inhibit_exit, + maxTraceLen => \$maxtrace, + ImmediateStop => \$ImmediateStop, + RemotePort => \$remoteport, + windowSize => \$window, + WarnAssertions => \$warnassertions, +); + +=pod + +Third, C<%optionAction> defines the subroutine to be called to process each +option. + +=cut + +%optionAction = ( + compactDump => \&dumpvar::compactDump, + veryCompact => \&dumpvar::veryCompact, + quote => \&dumpvar::quote, + TTY => \&TTY, + noTTY => \&noTTY, + ReadLine => \&ReadLine, + NonStop => \&NonStop, + LineInfo => \&LineInfo, + recallCommand => \&recallCommand, + ShellBang => \&shellBang, + pager => \&pager, + signalLevel => \&signalLevel, + warnLevel => \&warnLevel, + dieLevel => \&dieLevel, + tkRunning => \&tkRunning, + ornaments => \&ornaments, + RemotePort => \&RemotePort, + DollarCaretP => \&DollarCaretP, + OnlyAssertions=> \&OnlyAssertions, +); + +=pod + +Last, the C<%optionRequire> notes modules that must be C<require>d if an +option is used. + +=cut + +# Note that this list is not complete: several options not listed here +# actually require that dumpvar.pl be loaded for them to work, but are +# not in the table. A subsequent patch will correct this problem; for +# the moment, we're just recommenting, and we are NOT going to change +# function. +%optionRequire = ( + compactDump => 'dumpvar.pl', + veryCompact => 'dumpvar.pl', + quote => 'dumpvar.pl', +); + +=pod + +There are a number of initialization-related variables which can be set +by putting code to set them in a BEGIN block in the C<PERL5DB> environment +variable. These are: + +=over 4 + +=item C<$rl> - readline control XXX needs more explanation + +=item C<$warnLevel> - whether or not debugger takes over warning handling + +=item C<$dieLevel> - whether or not debugger takes over die handling + +=item C<$signalLevel> - whether or not debugger takes over signal handling + +=item C<$pre> - preprompt actions (array reference) + +=item C<$post> - postprompt actions (array reference) + +=item C<$pretype> + +=item C<$CreateTTY> - whether or not to create a new TTY for this debugger + +=item C<$CommandSet> - which command set to use (defaults to new, documented set) + +=back + +=cut + +# These guys may be defined in $ENV{PERL5DB} : +$rl = 1 unless defined $rl; +$warnLevel = 1 unless defined $warnLevel; +$dieLevel = 1 unless defined $dieLevel; +$signalLevel = 1 unless defined $signalLevel; +$pre = [] unless defined $pre; +$post = [] unless defined $post; +$pretype = [] unless defined $pretype; +$CreateTTY = 3 unless defined $CreateTTY; +$CommandSet = '580' unless defined $CommandSet; + +share($rl); +share($warnLevel); +share($dieLevel); +share($signalLevel); +share($pre); +share($post); +share($pretype); +share($rl); +share($CreateTTY); +share($CommandSet); + +=pod + +The default C<die>, C<warn>, and C<signal> handlers are set up. + +=cut + +warnLevel($warnLevel); +dieLevel($dieLevel); +signalLevel($signalLevel); + +=pod + +The pager to be used is needed next. We try to get it from the +environment first. if it's not defined there, we try to find it in +the Perl C<Config.pm>. If it's not there, we default to C<more>. We +then call the C<pager()> function to save the pager name. + +=cut + +# This routine makes sure $pager is set up so that '|' can use it. +pager( + + # If PAGER is defined in the environment, use it. + defined $ENV{PAGER} + ? $ENV{PAGER} + + # If not, see if Config.pm defines it. + : eval { require Config } + && defined $Config::Config{pager} + ? $Config::Config{pager} + + # If not, fall back to 'more'. + : 'more' + ) + unless defined $pager; + +=pod + +We set up the command to be used to access the man pages, the command +recall character (C<!> unless otherwise defined) and the shell escape +character (C<!> unless otherwise defined). Yes, these do conflict, and +neither works in the debugger at the moment. + +=cut + +setman(); + +# Set up defaults for command recall and shell escape (note: +# these currently don't work in linemode debugging). +&recallCommand("!") unless defined $prc; +&shellBang("!") unless defined $psh; + +=pod + +We then set up the gigantic string containing the debugger help. +We also set the limit on the number of arguments we'll display during a +trace. + +=cut + +sethelp(); + +# If we didn't get a default for the length of eval/stack trace args, +# set it here. +$maxtrace = 400 unless defined $maxtrace; + +=head2 SETTING UP THE DEBUGGER GREETING + +The debugger I<greeting> helps to inform the user how many debuggers are +running, and whether the current debugger is the primary or a child. + +If we are the primary, we just hang onto our pid so we'll have it when +or if we start a child debugger. If we are a child, we'll set things up +so we'll have a unique greeting and so the parent will give us our own +TTY later. + +We save the current contents of the C<PERLDB_PIDS> environment variable +because we mess around with it. We'll also need to hang onto it because +we'll need it if we restart. + +Child debuggers make a label out of the current PID structure recorded in +PERLDB_PIDS plus the new PID. They also mark themselves as not having a TTY +yet so the parent will give them one later via C<resetterm()>. + +=cut + +# Save the current contents of the environment; we're about to +# much with it. We'll need this if we have to restart. +$ini_pids = $ENV{PERLDB_PIDS}; + +if ( defined $ENV{PERLDB_PIDS} ) { + + # We're a child. Make us a label out of the current PID structure + # recorded in PERLDB_PIDS plus our (new) PID. Mark us as not having + # a term yet so the parent will give us one later via resetterm(). + $pids = "[$ENV{PERLDB_PIDS}]"; + $ENV{PERLDB_PIDS} .= "->$$"; + $term_pid = -1; +} ## end if (defined $ENV{PERLDB_PIDS... +else { + + # We're the parent PID. Initialize PERLDB_PID in case we end up with a + # child debugger, and mark us as the parent, so we'll know to set up + # more TTY's is we have to. + $ENV{PERLDB_PIDS} = "$$"; + $pids = "{pid=$$}"; + $term_pid = $$; +} + +$pidprompt = ''; + +# Sets up $emacs as a synonym for $slave_editor. +*emacs = $slave_editor if $slave_editor; # May be used in afterinit()... + +=head2 READING THE RC FILE + +The debugger will read a file of initialization options if supplied. If +running interactively, this is C<.perldb>; if not, it's C<perldb.ini>. + +=cut + +# As noted, this test really doesn't check accurately that the debugger +# is running at a terminal or not. + +if ( -e "/dev/tty" ) { # this is the wrong metric! + $rcfile = ".perldb"; +} +else { + $rcfile = "perldb.ini"; +} + +=pod + +The debugger does a safety test of the file to be read. It must be owned +either by the current user or root, and must only be writable by the owner. + +=cut + +# This wraps a safety test around "do" to read and evaluate the init file. +# +# This isn't really safe, because there's a race +# between checking and opening. The solution is to +# open and fstat the handle, but then you have to read and +# eval the contents. But then the silly thing gets +# your lexical scope, which is unfortunate at best. +sub safe_do { + my $file = shift; + + # Just exactly what part of the word "CORE::" don't you understand? + local $SIG{__WARN__}; + local $SIG{__DIE__}; + + unless ( is_safe_file($file) ) { + CORE::warn <<EO_GRIPE; +perldb: Must not source insecure rcfile $file. + You or the superuser must be the owner, and it must not + be writable by anyone but its owner. +EO_GRIPE + return; + } ## end unless (is_safe_file($file... + + do $file; + CORE::warn("perldb: couldn't parse $file: $@") if $@; +} ## end sub safe_do + +# This is the safety test itself. +# +# Verifies that owner is either real user or superuser and that no +# one but owner may write to it. This function is of limited use +# when called on a path instead of upon a handle, because there are +# no guarantees that filename (by dirent) whose file (by ino) is +# eventually accessed is the same as the one tested. +# Assumes that the file's existence is not in doubt. +sub is_safe_file { + my $path = shift; + stat($path) || return; # mysteriously vaporized + my ( $dev, $ino, $mode, $nlink, $uid, $gid ) = stat(_); + + return 0 if $uid != 0 && $uid != $<; + return 0 if $mode & 022; + return 1; +} ## end sub is_safe_file + +# If the rcfile (whichever one we decided was the right one to read) +# exists, we safely do it. +if ( -f $rcfile ) { + safe_do("./$rcfile"); +} + +# If there isn't one here, try the user's home directory. +elsif ( defined $ENV{HOME} && -f "$ENV{HOME}/$rcfile" ) { + safe_do("$ENV{HOME}/$rcfile"); +} + +# Else try the login directory. +elsif ( defined $ENV{LOGDIR} && -f "$ENV{LOGDIR}/$rcfile" ) { + safe_do("$ENV{LOGDIR}/$rcfile"); +} + +# If the PERLDB_OPTS variable has options in it, parse those out next. +if ( defined $ENV{PERLDB_OPTS} ) { + parse_options( $ENV{PERLDB_OPTS} ); +} + +=pod + +The last thing we do during initialization is determine which subroutine is +to be used to obtain a new terminal when a new debugger is started. Right now, +the debugger only handles X Windows and OS/2. + +=cut + +# Set up the get_fork_TTY subroutine to be aliased to the proper routine. +# Works if you're running an xterm or xterm-like window, or you're on +# OS/2. This may need some expansion: for instance, this doesn't handle +# OS X Terminal windows. + +if ( + not defined &get_fork_TTY # no routine exists, + and defined $ENV{TERM} # and we know what kind + # of terminal this is, + and $ENV{TERM} eq 'xterm' # and it's an xterm, +# and defined $ENV{WINDOWID} # and we know what window this is, <- wrong metric + and defined $ENV{DISPLAY} # and what display it's on, + ) +{ + *get_fork_TTY = \&xterm_get_fork_TTY; # use the xterm version +} ## end if (not defined &get_fork_TTY... +elsif ( $^O eq 'os2' ) { # If this is OS/2, + *get_fork_TTY = \&os2_get_fork_TTY; # use the OS/2 version +} + +# untaint $^O, which may have been tainted by the last statement. +# see bug [perl #24674] +$^O =~ m/^(.*)\z/; +$^O = $1; + +# Here begin the unreadable code. It needs fixing. + +=head2 RESTART PROCESSING + +This section handles the restart command. When the C<R> command is invoked, it +tries to capture all of the state it can into environment variables, and +then sets C<PERLDB_RESTART>. When we start executing again, we check to see +if C<PERLDB_RESTART> is there; if so, we reload all the information that +the R command stuffed into the environment variables. + + PERLDB_RESTART - flag only, contains no restart data itself. + PERLDB_HIST - command history, if it's available + PERLDB_ON_LOAD - breakpoints set by the rc file + PERLDB_POSTPONE - subs that have been loaded/not executed, and have actions + PERLDB_VISITED - files that had breakpoints + PERLDB_FILE_... - breakpoints for a file + PERLDB_OPT - active options + PERLDB_INC - the original @INC + PERLDB_PRETYPE - preprompt debugger actions + PERLDB_PRE - preprompt Perl code + PERLDB_POST - post-prompt Perl code + PERLDB_TYPEAHEAD - typeahead captured by readline() + +We chug through all these variables and plug the values saved in them +back into the appropriate spots in the debugger. + +=cut + +if ( exists $ENV{PERLDB_RESTART} ) { + + # We're restarting, so we don't need the flag that says to restart anymore. + delete $ENV{PERLDB_RESTART}; + + # $restart = 1; + @hist = get_list('PERLDB_HIST'); + %break_on_load = get_list("PERLDB_ON_LOAD"); + %postponed = get_list("PERLDB_POSTPONE"); + + share(@hist); + share(@truehist); + share(%break_on_load); + share(%postponed); + + # restore breakpoints/actions + my @had_breakpoints = get_list("PERLDB_VISITED"); + for ( 0 .. $#had_breakpoints ) { + my %pf = get_list("PERLDB_FILE_$_"); + $postponed_file{ $had_breakpoints[$_] } = \%pf if %pf; + } + + # restore options + my %opt = get_list("PERLDB_OPT"); + my ( $opt, $val ); + while ( ( $opt, $val ) = each %opt ) { + $val =~ s/[\\\']/\\$1/g; + parse_options("$opt'$val'"); + } + + # restore original @INC + @INC = get_list("PERLDB_INC"); + @ini_INC = @INC; + + # return pre/postprompt actions and typeahead buffer + $pretype = [ get_list("PERLDB_PRETYPE") ]; + $pre = [ get_list("PERLDB_PRE") ]; + $post = [ get_list("PERLDB_POST") ]; + @typeahead = get_list( "PERLDB_TYPEAHEAD", @typeahead ); +} ## end if (exists $ENV{PERLDB_RESTART... + +=head2 SETTING UP THE TERMINAL + +Now, we'll decide how the debugger is going to interact with the user. +If there's no TTY, we set the debugger to run non-stop; there's not going +to be anyone there to enter commands. + +=cut + +if ($notty) { + $runnonstop = 1; + share($runnonstop); +} + +=pod + +If there is a TTY, we have to determine who it belongs to before we can +proceed. If this is a slave editor or graphical debugger (denoted by +the first command-line switch being '-emacs'), we shift this off and +set C<$rl> to 0 (XXX ostensibly to do straight reads). + +=cut + +else { + + # Is Perl being run from a slave editor or graphical debugger? + # If so, don't use readline, and set $slave_editor = 1. + $slave_editor = + ( ( defined $main::ARGV[0] ) and ( $main::ARGV[0] eq '-emacs' ) ); + $rl = 0, shift(@main::ARGV) if $slave_editor; + + #require Term::ReadLine; + +=pod + +We then determine what the console should be on various systems: + +=over 4 + +=item * Cygwin - We use C<stdin> instead of a separate device. + +=cut + + if ( $^O eq 'cygwin' ) { + + # /dev/tty is binary. use stdin for textmode + undef $console; + } + +=item * Unix - use C</dev/tty>. + +=cut + + elsif ( -e "/dev/tty" ) { + $console = "/dev/tty"; + } + +=item * Windows or MSDOS - use C<con>. + +=cut + + elsif ( $^O eq 'dos' or -e "con" or $^O eq 'MSWin32' ) { + $console = "con"; + } + +=item * MacOS - use C<Dev:Console:Perl Debug> if this is the MPW version; C<Dev: +Console> if not. + +Note that Mac OS X returns C<darwin>, not C<MacOS>. Also note that the debugger doesn't do anything special for C<darwin>. Maybe it should. + +=cut + + elsif ( $^O eq 'MacOS' ) { + if ( $MacPerl::Version !~ /MPW/ ) { + $console = + "Dev:Console:Perl Debug"; # Separate window for application + } + else { + $console = "Dev:Console"; + } + } ## end elsif ($^O eq 'MacOS') + +=item * VMS - use C<sys$command>. + +=cut + + else { + + # everything else is ... + $console = "sys\$command"; + } + +=pod + +=back + +Several other systems don't use a specific console. We C<undef $console> +for those (Windows using a slave editor/graphical debugger, NetWare, OS/2 +with a slave editor, Epoc). + +=cut + + if ( ( $^O eq 'MSWin32' ) and ( $slave_editor or defined $ENV{EMACS} ) ) { + + # /dev/tty is binary. use stdin for textmode + $console = undef; + } + + if ( $^O eq 'NetWare' ) { + + # /dev/tty is binary. use stdin for textmode + $console = undef; + } + + # In OS/2, we need to use STDIN to get textmode too, even though + # it pretty much looks like Unix otherwise. + if ( defined $ENV{OS2_SHELL} and ( $slave_editor or $ENV{WINDOWID} ) ) + { # In OS/2 + $console = undef; + } + + # EPOC also falls into the 'got to use STDIN' camp. + if ( $^O eq 'epoc' ) { + $console = undef; + } + +=pod + +If there is a TTY hanging around from a parent, we use that as the console. + +=cut + + $console = $tty if defined $tty; + +=head2 SOCKET HANDLING + +The debugger is capable of opening a socket and carrying out a debugging +session over the socket. + +If C<RemotePort> was defined in the options, the debugger assumes that it +should try to start a debugging session on that port. It builds the socket +and then tries to connect the input and output filehandles to it. + +=cut + + # Handle socket stuff. + + if ( defined $remoteport ) { + + # If RemotePort was defined in the options, connect input and output + # to the socket. + require IO::Socket; + $OUT = new IO::Socket::INET( + Timeout => '10', + PeerAddr => $remoteport, + Proto => 'tcp', + ); + if ( !$OUT ) { die "Unable to connect to remote host: $remoteport\n"; } + $IN = $OUT; + } ## end if (defined $remoteport) + +=pod + +If no C<RemotePort> was defined, and we want to create a TTY on startup, +this is probably a situation where multiple debuggers are running (for example, +a backticked command that starts up another debugger). We create a new IN and +OUT filehandle, and do the necessary mojo to create a new TTY if we know how +and if we can. + +=cut + + # Non-socket. + else { + + # Two debuggers running (probably a system or a backtick that invokes + # the debugger itself under the running one). create a new IN and OUT + # filehandle, and do the necessary mojo to create a new tty if we + # know how, and we can. + create_IN_OUT(4) if $CreateTTY & 4; + if ($console) { + + # If we have a console, check to see if there are separate ins and + # outs to open. (They are assumed identiical if not.) + + my ( $i, $o ) = split /,/, $console; + $o = $i unless defined $o; + + # read/write on in, or just read, or read on STDIN. + open( IN, "+<$i" ) + || open( IN, "<$i" ) + || open( IN, "<&STDIN" ); + + # read/write/create/clobber out, or write/create/clobber out, + # or merge with STDERR, or merge with STDOUT. + open( OUT, "+>$o" ) + || open( OUT, ">$o" ) + || open( OUT, ">&STDERR" ) + || open( OUT, ">&STDOUT" ); # so we don't dongle stdout + + } ## end if ($console) + elsif ( not defined $console ) { + + # No console. Open STDIN. + open( IN, "<&STDIN" ); + + # merge with STDERR, or with STDOUT. + open( OUT, ">&STDERR" ) + || open( OUT, ">&STDOUT" ); # so we don't dongle stdout + $console = 'STDIN/OUT'; + } ## end elsif (not defined $console) + + # Keep copies of the filehandles so that when the pager runs, it + # can close standard input without clobbering ours. + $IN = \*IN, $OUT = \*OUT if $console or not defined $console; + } ## end elsif (from if(defined $remoteport)) + + # Unbuffer DB::OUT. We need to see responses right away. + my $previous = select($OUT); + $| = 1; # for DB::OUT + select($previous); + + # Line info goes to debugger output unless pointed elsewhere. + # Pointing elsewhere makes it possible for slave editors to + # keep track of file and position. We have both a filehandle + # and a I/O description to keep track of. + $LINEINFO = $OUT unless defined $LINEINFO; + $lineinfo = $console unless defined $lineinfo; + # share($LINEINFO); # <- unable to share globs + share($lineinfo); # + +=pod + +To finish initialization, we show the debugger greeting, +and then call the C<afterinit()> subroutine if there is one. + +=cut + + # Show the debugger greeting. + $header =~ s/.Header: ([^,]+),v(\s+\S+\s+\S+).*$/$1$2/; + unless ($runnonstop) { + local $\ = ''; + local $, = ''; + if ( $term_pid eq '-1' ) { + print $OUT "\nDaughter DB session started...\n"; + } + else { + print $OUT "\nLoading DB routines from $header\n"; + print $OUT ( + "Editor support ", + $slave_editor ? "enabled" : "available", ".\n" + ); + print $OUT +"\nEnter h or `h h' for help, or `$doccmd perldebug' for more help.\n\n"; + } ## end else [ if ($term_pid eq '-1') + } ## end unless ($runnonstop) +} ## end else [ if ($notty) + +# XXX This looks like a bug to me. +# Why copy to @ARGS and then futz with @args? +@ARGS = @ARGV; +for (@args) { + # Make sure backslashes before single quotes are stripped out, and + # keep args unless they are numeric (XXX why?) + # s/\'/\\\'/g; # removed while not justified understandably + # s/(.*)/'$1'/ unless /^-?[\d.]+$/; # ditto +} + +# If there was an afterinit() sub defined, call it. It will get +# executed in our scope, so it can fiddle with debugger globals. +if ( defined &afterinit ) { # May be defined in $rcfile + &afterinit(); +} + +# Inform us about "Stack dump during die enabled ..." in dieLevel(). +$I_m_init = 1; + + |