/* * Copyright 1995, 1996 Perforce Software. All rights reserved. * * This file is part of Perforce - the FAST SCM System. */ class Enviro; class HostEnv; class FileSys; class VarArray; class Options; class Client; class StrDict; class RegMatch; class StrPtrLineReader; /* * Class and function definitions for the aliasing facility of the command line. * * - ClientCommand * - CommandAlias * - CommandPattern * - CommandTransformation * - ClientAliases * - ClientUserStrBuf * - OperatorP4Subst */ int clientRunCommand( int argc, char **argv, Options &opts, ClientUser *ui, int &uidebug, Error *e ); void clientParseOptions( Options &opts, int &argc, StrPtr *&argv, Error *e ); void clientParseOptions( Options &opts, int &argc, char **&argv, Error *e ); void clientSetVariables( Client &client, Options &opts ); int clientPrepareEnv ( Client &client, Options &opts, Enviro &enviro ); class CommandPattern; /* * ClientUserStrBuf: Enables aliases to capture the output of a command, * as well as to provide the input of a command. */ class ClientUserStrBuf : public ClientUserMunge { public: ClientUserStrBuf( Options &opts, int autoLoginPrompt = 1 ); ~ClientUserStrBuf(); virtual void OutputInfo( char level, const char *data ); virtual void OutputError( const char *errBuf ); virtual void OutputText( const char *data, int length ); virtual void OutputStat( StrDict *dict ); virtual void HandleError( Error *err ); virtual void Message( Error *err ); virtual void InputData( StrBuf *strbuf, Error *e ); void SetFormat( const StrPtr *fmt ); void SetInputData( const StrPtr *data ); const StrPtr *GetOutput(); int GetSeverity(); int CommandFailed(); private: void Append( const char *s ); StrBuf input; StrBuf output; StrBuf format; int severity; int autoLogin; } ; /* * A ClientCommand is a single command to be run. The actual command is * constructed by processing the user's command according to the alias * definitions. Initially, the user's command is read, and stored in * a semi-parsed format. Then we iteratively transform that command, possibly * multiple times, until we arrive at a command that we're ready to run, * and then we run it. */ class ClientCommand { public: ClientCommand(); ~ClientCommand(); int RunCommand( StrDict *dict, Error *e ); void CopyArguments( int argc, char **argv, Error *e ); void ParseOptions( Error *e ); void UpdateWorkingCommand( int n_argn, StrBuf *n_args, Error *e ); int Matches( CommandPattern *, StrPtr *text ); void Transform( int actual, char **vec, int numNamedArgs, StrDict *namedArgs, ClientCommand *result, Error *e ); void GetActual( int ac, StrRef *val ); const StrPtr *GetInput(); const StrPtr *GetOutput(); void SetInput( const StrPtr *); void SetOutput( const StrPtr *); private: void PrepareIO( StrDict *dict, Error *e ); void HandleOutput( StrDict *dict, Error *e ); void FormatCommand( StrBuf &b ); int FunctionMatches( StrPtr *text ); int HandleSpecialOperators( int argc, char **argv, Options &opts, Error *e ); void SplitArgs( Error *e ); int w_argc; // #args starting with the function word int w_argn; // total #args, including client args int w_argf; // position of the function word in args StrPtr *w_argv; // pointer to the function word StrRef *w_argp; // array of pointers, for option parsing StrBuf *w_args; // the complete set of arguments Options *w_opts; // the parsed client arguments. char **c_args; // the args passed to clientRunCommand. StrBuf inputVariable; StrBuf outputVariable; ClientUserStrBuf *ui; } ; /* * A CommandPattern is the "left hand side" of an alias, and describes which * user commands should be transformed by this alias. */ class CommandPattern { public: CommandPattern(); ~CommandPattern(); void Set( const StrPtr s ); void Compile( Error *e ); void Show( StrBuf &buf ); int Matches( ClientCommand *cmd ); int Formals(); void GetFormal( int ac, StrRef *var ); int IsAVariable( int ac ); private: void ValidateFormals( Error *e ); StrBuf text; StrBuf wordsBuf; char **vec; int maxVec; int actual; StrRef w0; StrBuf *formals; int *formalTypes; enum FormalTypes { LITERAL = 1, VARIABLE = 2 } ; } ; /* * A CommandTransformation is the "right hand side" of an alias, and * describes how to modify the command and its arguments. */ class CommandTransformation { public: CommandTransformation(); ~CommandTransformation(); void Set( const StrPtr *s ); void Compile( Error *e ); void Show( StrBuf &buf ); void Transform( ClientCommand *cmd, int transformNo, int numTransforms, int numNamedArgs, StrDict *namedArgs, VarArray *resultCommands, Error *e ); const StrPtr *GetInput(); const StrPtr *GetOutput(); private: void CompileRedirection( Error *e ); void CompileSpecialOperators( Error *e ); static int Words( StrBuf &tmp, const char *w, char *vec[], int maxVec ); StrBuf text; StrBuf wordsBuf; char **vec; int maxVec; int actual; Options *opts; int argc; char **argv; int fulcrum; StrBuf inputVariable; StrBuf outputVariable; } ; /* * A CommandAlias combines a CommandPattern and 1+ CommandTransformation(s) */ class CommandAlias { public: CommandAlias(); ~CommandAlias(); void Consume( StrPtr *line ); int Complete(); void Compile( Error *e ); void Show( StrBuf &buf ); int AlreadyUsed(); int Matches( ClientCommand *cmd ); void Transform( ClientCommand *cmd, VarArray *resultCommands, Error *e ); private: void AddTransform( const StrPtr *xf, Error *e ); void CompileTransforms( const StrPtr *xfms, Error *e ); void BuildDictionary( ClientCommand *cmd, Error *e ); StrBuf text; CommandPattern pattern; VarArray *transforms; int used; StrDict *dict; } ; /* * ClientAliases: manages the overall set of aliases, from the aliases file. * * Also provides a single static function that is the hook from ClientMain. */ class ClientAliases { public: ClientAliases( int argc, char **argv, Enviro *env, HostEnv *hostEnv, Error *e ); ~ClientAliases(); static int ProcessAliases( int argc, char **argv, int &result, Error *e ); void LoadAliases( Error *e ); int HasCharsetError(); int HasAliases(); int HasAliasesDisabled(); void ShowAliases(); void ExpandAliases( int argc, char **argv, Error *e ); int WasExpanded(); int RunCommands( Error *e ); private: void ReadAliasesFile( Error *e ); int IsComment( StrPtr *line ); void UpdateCommands( int c, VarArray *resultCommands ); int CheckDryRun( int argc, char **argv, Error *e ); int WasAliasesCommand( int &result, Error *e ); int hasAliases; int wasExpanded; Enviro *env; HostEnv *hostEnv; StrBuf aliasesFilePath; FileSys *aliasesFile; VarArray *aliases; VarArray *commands; StrBufDict *ioDict; int hasCharsetError; int hasAliasesDisabled; int parsedArgc; char **parsedArgv; } ; /* * AliasSubstitution: utilities for handling variable substitutions. */ class AliasSubstitution { public: AliasSubstitution( Client *c, StrDict *d ); ~AliasSubstitution(); int Substitute( StrBuf *b ); private: void GetValue( StrPtr &var, StrBuf *val ); Client *client; StrDict *dict; } ; /* * OperatorP4Subst: uses our Regex engine to perform text substitutions. */ class OperatorP4Subst { public: OperatorP4Subst(); ~OperatorP4Subst(); void Substitute( int argc, char **argv, Options &opts, ClientUser *ui, Error *e ); private: void UpdateLine( StrBuf *line, StrBuf *result, RegMatch *matcher, const char *replace ); StrBuf rawData; StrPtrLineReader *splr; } ;