See attached. Description is in patch header.

This patch brings consistency to the help display and changes the
behavior of some commands:

 - ]BOXING without an argument displays the current state
 - ]USERCMD REMOVE-ALL works
 - ]USERCMD without an argument displays defined user commands
 - ]HELP and )HELP no longer display defined user commands
 - ]SYMBOL error messages are less cryptic
 - )HIST checks for invalid argument
 - ]COLOR and ]XTERM check for invalid argument
 - ]COLOR ON and ]XTERM ON are inhibited if environment TERM=dumb
 - ]XTERM or ]COLOR without an argument displays the current state
 - )DROP has proper tab-completion hinting

Index: src/Command.cc
===================================================================
--- src/Command.cc	(revision 490)
+++ src/Command.cc	(working copy)
@@ -389,10 +389,44 @@
 }
 //-----------------------------------------------------------------------------
 void 
+Command::cmd_XTERM(ostream & out, const UCS_string & arg)
+{
+   const char * term = getenv("TERM");
+   if (!strncmp(term, "dumb", 4) && arg.starts_iwith("ON"))
+      {
+        out << "impossible on dumb terminal" << endl;
+      }
+   else if (arg.starts_iwith("OFF") || arg.starts_iwith("ON"))
+      {
+        Output::toggle_color(arg);
+      }
+   else if (arg.size() == 0)
+      {
+        out << "]COLOR/XTERM ";
+        if (Output::color_enabled()) out << "ON"; else out << "OFF";
+        out << endl;
+      }
+   else
+      {
+        out << "BAD COMMAND" << endl;
+        return;
+      }
+}
+//-----------------------------------------------------------------------------
+void 
 Command::cmd_BOXING(ostream & out, const UCS_string & arg)
 {
 int format = arg.atoi();
 
+   if (arg.size() == 0)
+      {
+        
+        out << "]BOXING ";
+        if (boxing_format == -1) out << "OFF"; else out << boxing_format;
+        out << endl;
+        return;
+      }
+
    if (arg.starts_iwith("OFF"))   format = -1;
 
    switch (format)
@@ -615,26 +649,14 @@
 #define cmd_def(cmd_str, _cod, arg, _hint) \
    CERR << "      " cmd_str " " #arg << endl;
 #include "Command.def"
-   out << endl;
-
-   if (user_commands.size())
-      {
-        out << "User defined commands:" << endl;
-        loop(u, user_commands.size())
-           {
-             out << "      " << user_commands[u].prefix << " → ";
-             if (user_commands[u].mode)   out << "A ";
-             out << user_commands[u].apl_function << " B"
-                 << " (mode " << user_commands[u].mode << ")" << endl;
-           }
-      }
 }
 //-----------------------------------------------------------------------------
 void 
 Command::cmd_HISTORY(ostream & out, const UCS_string & arg)
 {
-   if (arg.starts_iwith("CLEAR"))   LineInput::clear_history(out);
-   else                             LineInput::print_history(out);
+   if (arg.size() == 0)                  LineInput::print_history(out);
+   else if (arg.starts_iwith("CLEAR"))   LineInput::clear_history(out);
+   else                                  out << "BAD COMMAND" << endl;
 }
 //-----------------------------------------------------------------------------
 void
@@ -1172,16 +1194,24 @@
 Command::cmd_USERCMD(ostream & out, const UCS_string & cmd,
                      vector<UCS_string> & args)
 {
+   // ]USERCMD
    // ]USERCMD REMOVE-ALL
    // ]USERCMD REMOVE        ]existing-command
    // ]USERCMD ]new-command  APL-fun
    // ]USERCMD ]new-command  APL-fun  mode
    //
-   if (args.size() < 2)
+   if (args.size() == 0)
       {
-        out << "BAD COMMAND" << endl;
-        Workspace::more_error() =
-                   UCS_string("too few parameters in command ]USERCMD");
+        if (user_commands.size())
+           {
+             loop(u, user_commands.size())
+                {
+                  out << user_commands[u].prefix << " → ";
+                  if (user_commands[u].mode)   out << "A ";
+                  out << user_commands[u].apl_function << " B"
+                      << " (mode " << user_commands[u].mode << ")" << endl;
+                }
+           }
         return;
       }
 
Index: src/Output.cc
===================================================================
--- src/Output.cc	(revision 490)
+++ src/Output.cc	(working copy)
@@ -385,13 +385,16 @@
 void 
 Output::toggle_color(const UCS_string & arg)
 {
-int a = 0;
-   while (a < arg.size() && arg[a] < UNI_ASCII_SPACE)   ++a;
-
    if (arg.starts_iwith("ON"))         colors_enabled = true;
    else if (arg.starts_iwith("OFF"))   colors_enabled = false;
    else                                colors_enabled = !colors_enabled;
 }
+//-----------------------------------------------------------------------------
+bool
+Output::color_enabled()
+{
+   return Output::colors_enabled;
+}
 //=============================================================================
 void
 CIN_ostream::set_cursor(int y, int x)
Index: src/SymbolTable.cc
===================================================================
--- src/SymbolTable.cc	(revision 490)
+++ src/SymbolTable.cc	(working copy)
@@ -168,7 +168,7 @@
         Tokenizer tokenizer(PM_STATEMENT_LIST, LOC);
         if (tokenizer.tokenize(buf, tos) != E_NO_ERROR)
            {
-             CERR << "parse error 1 in )SYMBOL command." << endl;
+             CERR << "invalid token" << endl;
              return out;
            }
       }
@@ -175,13 +175,13 @@
 
    if (tos.size() == 0)   // empty argument
       {
-        CERR << "parse error 2 in )SYMBOL command" << endl;
+        CERR << "no symbol" << endl;
         return out;
       }
 
    if (tos[0].get_ValueType() != TV_SYM)
       {
-        CERR << "parse error 3 in )SYMBOL command" << endl;
+        CERR << "not a symbol" << endl;
         return out;
       }
 
Index: src/Command.hh
===================================================================
--- src/Command.hh	(revision 490)
+++ src/Command.hh	(working copy)
@@ -180,6 +180,9 @@
    static void cmd_USERCMD(ostream & out, const UCS_string & arg,
                            vector<UCS_string> & args);
 
+   /// enable and disable colors
+   static void cmd_XTERM(ostream & out, const UCS_string & args);
+
    /// execute a user defined command
    static void do_USERCMD(ostream & out, UCS_string & line,
                           const UCS_string & line1, const UCS_string & cmd,
Index: src/Output.hh
===================================================================
--- src/Output.hh	(revision 490)
+++ src/Output.hh	(working copy)
@@ -179,6 +179,10 @@
    /// read/append an ESC sequence in str and store it in \b dest
    static int read_ESC_sequence(char * dest, int destlen, int append,
                                 const char * capname, char * str, int p1);
+
+   // true if xterm/color is on
+   static bool color_enabled();
+
 protected:
    /// true if colors were changed (and then reset_colors() shall reset
    /// them when leaving the interpreter
Index: src/Command.def
===================================================================
--- src/Command.def	(revision 490)
+++ src/Command.def	(working copy)
@@ -24,27 +24,29 @@
 cmd_def(")CHECK"    , cmd_CHECK(out);                       ,                        , EH_NO_PARAM)
 cmd_def(")CLEAR"    , Workspace::clear_WS(out, false);      ,                        , EH_NO_PARAM)
 cmd_def(")CONTINUE" , cmd_CONTINUE(out);                    ,                        , EH_NO_PARAM)
-cmd_def(")COPY"     , Workspace::copy_WS(out, args, false); , [lib] ws-name [objects], EH_oLIB_WSNAME)
-cmd_def(")DROP"     , cmd_DROP(out, args);                  ,                        , EH_NO_PARAM)
-cmd_def(")DUMP"     , Workspace::dump_WS(out, args);        , [[lib] ws-name]        , EH_oLIB_WSNAME)
+cmd_def(")COPY"     , Workspace::copy_WS(out, args, false); ,
+                                                           [lib] wsname [object ...] , EH_oLIB_WSNAME)
+cmd_def(")DROP"     , cmd_DROP(out, args);                  , [[lib] wsname]         , EH_oLIB_WSNAME)
+cmd_def(")DUMP"     , Workspace::dump_WS(out, args);        , [[lib] wsname]         , EH_oLIB_WSNAME)
 cmd_def(")ERASE"    , cmd_ERASE(CERR, args);                , symbol ...             , EH_SYMBOLS)
 cmd_def(")FNS"      , Workspace::list(out, LIST_FUNS, arg); , [from-to]              , EH_oFROM_oTO)
 cmd_def(")HELP"     , cmd_HELP(CERR);                       ,                        , EH_NO_PARAM)
 cmd_def(")HIST"     , cmd_HISTORY(out, arg);                , [CLEAR]                , EH_oCLEAR)
 cmd_def(")HOST"     , cmd_HOST(out, arg);                   , command                , EH_HOSTCMD)
-cmd_def(")IN"       , cmd_IN(out, args, false);             , filename [objects]     , EH_FILENAME)
-cmd_def(")LIBS"     , cmd_LIBS(out, args);                  , [[lib] path]             , EH_oLIB_oPATH)
-cmd_def(")LIB"      , cmd_LIB1(out, arg);                   , [lib or path]          , EH_DIR_OR_LIB)
-cmd_def(")LOAD"     , Workspace::load_WS(out, args, line);  , [lib] ws-name          , EH_oLIB_WSNAME)
+cmd_def(")IN"       , cmd_IN(out, args, false);             , filename [object ...]  , EH_FILENAME)
+cmd_def(")LIBS"     , cmd_LIBS(out, args);                  , [[lib] path]           , EH_oLIB_oPATH)
+cmd_def(")LIB"      , cmd_LIB1(out, arg);                   , [lib|path]             , EH_DIR_OR_LIB)
+cmd_def(")LOAD"     , Workspace::load_WS(out, args, line);  , [lib] wsname           , EH_oLIB_WSNAME)
 cmd_def(")MORE"     , cmd_MORE(out);                        ,                        , EH_NO_PARAM)
 cmd_def(")NMS"      , Workspace::list(out, LIST_NAMES, arg);, [from-to]              , EH_oFROM_oTO)
 cmd_def(")OFF"      , cmd_OFF(0);                           ,                        , EH_NO_PARAM)
 cmd_def(")OPS"      , Workspace::list(out, LIST_OPERS, arg);, [from-to]              , EH_oFROM_oTO)
-cmd_def(")OUT"      , cmd_OUT(out, args);                   , filename [objects]     , EH_FILENAME)
-cmd_def(")PCOPY"    , Workspace::copy_WS(out, args, true);  , [lib] ws-name [objects], EH_oLIB_WSNAME)
-cmd_def(")PIN"      , cmd_IN(out, args, true);              , filename [objects]     , EH_FILENAME)
+cmd_def(")OUT"      , cmd_OUT(out, args);                   , filename [object ...]  , EH_FILENAME)
+cmd_def(")PCOPY"    , Workspace::copy_WS(out, args, true);  , [lib] wsname [object ...]
+                                                                                     , EH_oLIB_WSNAME)
+cmd_def(")PIN"      , cmd_IN(out, args, true);              , filename [object ...]  , EH_FILENAME)
 cmd_def(")RESET"    , Workspace::clear_SI(out);             ,                        , EH_NO_PARAM)
-cmd_def(")SAVE"     , Workspace::save_WS(out, args);        , [[lib] ws-name]        , EH_oLIB_WSNAME)
+cmd_def(")SAVE"     , Workspace::save_WS(out, args);        , [[lib] wsname]         , EH_oLIB_WSNAME)
 cmd_def(")SIC"      , Workspace::clear_SI(out);             ,                        , EH_NO_PARAM)
 cmd_def(")SINL"     , Workspace::list_SI(out, SIM_SINL);    ,                        , EH_NO_PARAM)
 cmd_def(")SIS"      , Workspace::list_SI(out, SIM_SIS);     ,                        , EH_NO_PARAM)
@@ -52,24 +54,25 @@
 cmd_def(")SYMBOLS"  , Workspace::list(out, LIST_NONE, arg); , [count]                , EH_COUNT)
 cmd_def(")VALUES"   , Value::list_all(out, false);          ,                        , EH_NO_PARAM)
 cmd_def(")VARS"     , Workspace::list(out, LIST_VARS, arg); , [from-to]              , EH_oFROM_oTO)
-cmd_def(")WSID"     , Workspace::wsid(out, arg);            , [ws-name]              , EH_oWSNAME)
+cmd_def(")WSID"     , Workspace::wsid(out, arg);            , [wsname]               , EH_oWSNAME)
 
-cmd_def("]BOXING"   , cmd_BOXING(out, arg);                 , OFF or 2-4 or 7-9      , EH_BOXING)
-cmd_def("]COLOR"    , Output::toggle_color(arg);            , [ON or OFF]            , EH_oON_OFF)
+cmd_def("]BOXING"   , cmd_BOXING(out, arg);                 , [OFF|2|3|4|7|8|9]      , EH_BOXING)
+cmd_def("]COLOR"    , cmd_XTERM(out, arg)                   , [ON|OFF]               , EH_oON_OFF)
 cmd_def("]NEXTFILE" , IO_Files::next_file();                ,                        , EH_NO_PARAM)
-cmd_def("]EXPECT"   , IO_Files::expect_apl_errors(arg);     , error count            , EH_COUNT)
+cmd_def("]EXPECT"   , IO_Files::expect_apl_errors(arg);     , error_count            , EH_COUNT)
 cmd_def("]HELP"     , cmd_HELP(out);                        ,                        , EH_NO_PARAM)
 cmd_def("]KEYB"     , cmd_KEYB(out);                        ,                        , EH_NO_PARAM)
-cmd_def("]LIB"      , cmd_LIB2(out, arg);                   , [lib or path]          , EH_DIR_OR_LIB)
+cmd_def("]LIB"      , cmd_LIB2(out, arg);                   , [lib|path]             , EH_DIR_OR_LIB)
 cmd_def("]LOG"      , cmd_LOG(out, arg);                    , [facility]             , EH_LOG_NUM)
 cmd_def("]OWNERS"   , Value::list_all(out, true);           ,                        , EH_NO_PARAM)
-cmd_def("]PSTAT"    , cmd_PSTAT(out, arg);                  , [CLEAR or SAVE]        , EH_oCLEAR_SAVE)
+cmd_def("]PSTAT"    , cmd_PSTAT(out, arg);                  , [CLEAR|SAVE]           , EH_oCLEAR_SAVE)
 cmd_def("]SIS"      , Workspace::list_SI(out, SIM_SIS_dbg); ,                        , EH_NO_PARAM)
 cmd_def("]SI"       , Workspace::list_SI(out, SIM_SI_dbg);  ,                        , EH_NO_PARAM)
 cmd_def("]SVARS"    , Svar_DB::print(out);                  ,                        , EH_NO_PARAM)
-cmd_def("]SYMBOL"   , Workspace::get_symbol_table().list_symbol(out, arg); , symbol  , EH_SYMNAME)
+cmd_def("]SYMBOL"   , Workspace::get_symbol_table().list_symbol(out, arg); ,
+                                                              symbol                 , EH_SYMNAME)
 cmd_def("]USERCMD"  , cmd_USERCMD(out, arg, args);          ,
-        ]command APL-function [mode]  (or: REMOVE ]command)                          , EH_UCOMMAND)
-cmd_def("]XTERM"    , Output::toggle_color(arg);                        , [ON or OFF], EH_oON_OFF)
+                                    [ ]ucmd fn_name [mode]|REMOVE ]ucmd|REMOVE-ALL ] , EH_UCOMMAND)
+cmd_def("]XTERM"    , cmd_XTERM(out, arg)                   , [ON|OFF]               , EH_oON_OFF)
 
 #undef cmd_def

Reply via email to