/*
Copyright (c) 1993 Xerox Corporation.  All rights reserved.
*/
/*
$Id$

$Date$
 *
 */
/* Chauser, October 28, 1993 3:42 pm PDT */

#ifndef ←←PCR←Cmd←h
#   define ←←PCR←Cmd←h 1

#include <config/PCR←StdTypes.h>

/*
 * Callbacks
 */

typedef PCR←ERes PCR←Cmd←GetCharProc(
    PCR←Any data
);
/*
    Read unsigned character (as int).
    Result <=0 will be treated as EOF.
*/

typedef PCR←ERes PCR←Cmd←PrintProc(
    PCR←Any data,
    char *fmt,
    ...
);
/*
    Behaves like printf, normally returns PCR←ERes←okay.
*/


typedef PCR←ERes PCR←Cmd←CmdProc(
    int argc,
    const char **argv,
    PCR←Cmd←GetCharProc *getCharProc,
    PCR←Any getCharData,
    PCR←Cmd←PrintProc *printProc,
    PCR←Any printData,
    PCR←Any data
);
/*
    Registered command procedure.
*/


typedef PCR←ERes PCR←Cmd←EnumProc(
    const char *cmdName,
    PCR←Cmd←CmdProc *cmdProc,
    PCR←Any cmdData,
    const char *helpMsg,
    PCR←Any data
);
/*
    Callback proc passed to PCR←Cmd←Enumerate.
    Called with all signals masked.
    Must return (may not exit() or longjmp()).
    Returning anything other than PCR←ERes←okay
      terminates the enumeration.
*/

/*
 * Procs
 */


extern void
PCR←Cmd←Register(
    const char *cmdName,
    PCR←Cmd←CmdProc *proc,
    PCR←Any data,
    const char *helpMsg
);
/*
    Register a command proc / data pair.
    String bodies of cmdName and helpMsg are shared, not copied.
    Registering a NIL proc unregisters.
*/

extern PCR←ERes
PCR←Cmd←Lookup(
    const char *cmdName,
    PCR←Cmd←CmdProc **procp,
    PCR←Any *datap,
    const char **helpMsgp
);
/*
    Lookup the named command.
    Any of procp, datap or helpMsgp may be NIL.
*/


extern PCR←ERes
PCR←Cmd←Enumerate(
    PCR←Cmd←EnumProc *enumProc,
    PCR←Any data
);
/*
    Enumerate all registered commands,
      call enumProc on each,
      return last result returned by enumProc.
    (If enumProc ever returns other than PCR←ERes←okay the
      enumeration terminates immediately).
*/


extern PCR←ERes
PCR←Cmd←Call(
    const char *cmdName,
    int argc,
    const char **argv,
    PCR←Cmd←GetCharProc *getCharProc,
    PCR←Any getCharData,
    PCR←Cmd←PrintProc *printProc,
    PCR←Any printData,
    PCR←Bool echo
);
/*
    Call the named command.
    Return its result,
      or PCR←ERes←FromErr(ESRCH) if not found.
*/


extern PCR←ERes
PCR←Cmd←ReadEvalPrint(
    PCR←Cmd←GetCharProc *getCharProc,
    PCR←Any getCharData,
    PCR←Cmd←PrintProc *printProc,
    PCR←Any printData,
    PCR←Bool echo,
    PCR←Bool prompt
);
/*
    Read-Eval-Print loop.
    Return result of last command executed.
*/


extern PCR←ERes
PCR←Cmd←EvalPrint(
    int argc, const char **argv,
    PCR←Cmd←GetCharProc *getCharProc,
    PCR←Any getCharData,
    PCR←Cmd←PrintProc *printProc,
    PCR←Any printData,
    PCR←Bool echo
);
/*
    Like ReadEvalPrint, but commands appear in argv
      separated by ';'.
    An initial backslash occuring in *(argv[i]) is removed,
      but inhibits interpretation of semicolons; thus, recursion is
      possible, with a command like

        do-twice echo a \; do-twice echo b \\; echo c \; echo d ; echo e 

      producing

        a b c b c d a b c b c d e

      This differs from Unix(tm) shells in that the number of backslashes
      grows linearly with the nesting depth rather than exponentially.
*/

extern PCR←Cmd←GetCharProc PCR←Cmd←FDGetCharProc;
extern PCR←Cmd←PrintProc PCR←Cmd←FDPrintProc;
/*
    Standard read/write procs.
    The data arg is a file descriptor: ((PCR←Any)(fd))
*/


/*
 * Startup
 */

extern PCR←ERes
PCR←Cmd←Run(void);

#endif /* !←←PCR←Base←h */
/*
$Log$
*/