release 1.12.1
[descalc.git] / dct.pl
diff --git a/dct.pl b/dct.pl
index d2e411c64b36bdfc696ea29b08766ee1d507b62c..d871555a16e02c5b1981df664a974e035319a8a8 100755 (executable)
--- a/dct.pl
+++ b/dct.pl
@@ -10,18 +10,14 @@ use warnings;
 use utf8;
 
 use Data::Dumper;
-use Term::ReadKey;
 
-our $VERSION = "1.11.2";
+our $VERSION = "1.12.1";
 
 use vars qw(@stack %val %set %alias %action %hook);
-my $redraw = 2;  # set flag to refresh whole screen
 
 %set = (
        base     => 10,  # decimal; set using commands bin/oct/dec/hex/base
 #      numb     =>  0,  # fixed scientific engineering
-#      coord    =>  0,  # cartesian polar spherical
-#      complex  =>  0,  # real complex
 
        height   =>  4,  # stack depth (lines of stack plus one)
        width    => 42,  # limit value precision, stetch menu
@@ -56,6 +52,8 @@ my $redraw = 2;  # set flag to refresh whole screen
 ); # %action
 
 
+my $redraw = 2;  # set flag to refresh whole screen
+
 sub redraw($) {
        # queue a redraw of level $_[0]
        $redraw = $_[0] if $_[0]>$redraw;
@@ -104,32 +102,14 @@ sub showval {
 } # showval
 
 
-our %modules;
-for my $module (sort glob "*.pm") {
-       next unless $module =~ /^\d{2}_([a-z0-9-]+)(?:_(\w+))?\.pm$/;  # filename 00_class_name.pm
-       next if defined $modules{$1};  # no such module already loaded
-#      next if $1 eq "disp" and $2 eq "curses";
-       defined ($_ = do $module)  # return value means no errors
-       ? (ref $_ and $modules{$1} = $_, $modules{$1}{name} = $2 || "")
-       : print STDERR $@, "error loading $module\n\n";
-} # load modules
-
-printf STDERR "DCT %s by Shiar (%s)\n", $VERSION, join "; ",
-       map join(" ", grep $_, $_, $modules{$_}{name}, $modules{$_}{version}), keys %modules;
-
-ReadMode 3;  # cbreak mode
-END { ReadMode 0; } # restore terminal on quit
-
-$_->() for @{$hook{init}};
-
-LOOP: while (1) {
+sub draw {
        if ($redraw) {
                if ($redraw>1) {
                        $_->() for @{$hook{refresh}};
                }
                $_->() for @{$hook{showstack}};
                $redraw = 0;
-       } # refresh
+       } # do necessary redrawing
 
        {
                my $entry = showval($val{i}, $set{base}, $val{ex});
@@ -137,21 +117,20 @@ LOOP: while (1) {
                $entry .= $val{alpha} if exists $val{alpha};
                $_->($entry) for @{$hook{showentry}};
        } # show entry
+} # draw
 
-       my $key = ReadKey;  # wait for user input
-       if ($key eq chr 27) {
-               $key .= $_ while defined ($_ = ReadKey(-1));  # read additional keys
-       } # escape sequence
+sub onkey($) {
+       my $key = shift;
        $_ = exists $alias{$key} ? $alias{$key} : $key;  # command (alias maps keys to commands)
-       $_ = delete $val{alpha} if $_ eq "enter" and exists $val{alpha};  # use manual command
+       $_ eq "enter" and exists $val{alpha} and $_ = delete $val{alpha};  # use manual command
 
        for my $cmd (@{$hook{precmd}}) {
-               $cmd->() and next LOOP;  # command was handled by function if returns true
+               $cmd->() and return;  # command was handled by function if returns true
        } # precmd functions
 
-       last if $_ eq 'quit';  # break out of loop
+       exit if $_ eq "quit";  # break out of loop
 
-       if ($_ eq 'refresh') {
+       if ($_ eq "refresh") {
                redraw(2);
        } # refresh
 
@@ -222,5 +201,32 @@ LOOP: while (1) {
                        . (m/^\w*$/ ? qq{"$_"} : join ' ', map ord, split //, $_)
                );
        } # error
-} # input loop
+} # onkey
+
+
+our %modules;
+{
+       my %modskip;
+       $modskip{substr $_, 1}++ for grep /^-/, @ARGV;
+       opendir my $moddir, ".";
+       for my $module (sort readdir $moddir) { # glob "*.pm"
+               $module =~ /^\d{2}_([a-z0-9-]+)(?:_(\w+))?\.pm$/ or next;
+               # files named 00_class_name.pm; ($1, $2) = (class, name)
+               next if exists $modskip{$1} or $2 && exists $modskip{$2};
+               next if defined $modules{$1};  # no such module already loaded
+               defined ($_ = do $module)  # return value means no errors
+               ? (ref $_ and $modules{$1} = $_, $modules{$1}{name} = $2 || "")
+               : print STDERR $@, "error loading $module\n\n";
+       } # load modules
+       closedir $moddir;
+} # find external modules
+
+printf STDERR "DCT %s by Shiar (%s)\n", $VERSION, join "; ",
+       map join(" ", grep $_, $_, $modules{$_}{name}, $modules{$_}{version}),
+       keys %modules;
+
+
+$_->() for @{$hook{init}};
+
+$hook{main}->();