From: <sg...@us...> - 2003-12-10 19:57:09
|
Update of /cvsroot/libfunutil/libfunutil/lib/toolbox/src In directory sc8-pr-cvs1:/tmp/cvs-serv16731/lib/toolbox/src Added Files: aliaser.h Log Message: egg --- NEW FILE: aliaser.h --- #ifndef TOOLBOX_NAMESPACE_ALIASER_H_INCLUDED #define TOOLBOX_NAMESPACE_ALIASER_H_INCLUDED 1 #include <map> #include <string> #include <TOOLBOX_NAMESPACE/debuggering_macros.h> // COUT/CERR namespace TOOLBOX_NAMESPACE { /** aliaser is a helper class for mapping single-token aliases to arbitrary strings, e.g., similarly to typical Unix shell alias support. Parameterized on: - ContextType: all aliasers with the same ContextType share the same aliases map. This class was written to support the creation of a command-line-interface framework, thus it is designed to allow disparate shell components to get at the same aliases easily, without having to track an instance all around the world. */ template <typename ContextType> struct aliaser { typedef ContextType context_type; typedef std::map<std::string,std::string> map_type; typedef aliaser<ContextType> ThisType; /** Returns the map of aliases-to-expansions. */ static map_type & map() { static map_type bob; return bob; } /** Aliases <code>al</code> as a shortcut for <code>expanded</code>. al should be exactly one token. */ static void alias( const std::string & al, const std::string & expanded ) { // CERR << "alias("<<al<<",["<<expanded<<"])"<<std::endl; if( expanded.empty() ) { map_type::iterator it = map().find( al ); if( map().end() != it ) { map().erase( it ); } return; } map()[al] = expanded; } /** Works similarly to Unix shells' alias expansion: Expands the input token as an alias. This expansion continues until the token can no longer be expanded to a new string. It returns the expanded string, which may be identical to the input. input should be exactly one token. */ static std::string expand( const std::string & input ) { if( input.empty() ) return input; string arg = input.substr( 0, input.find_first_of(" \t\n") ); map_type::const_iterator it = map().find( arg ); if( map().end() == it ) { return input; } string code = (*it).second; if( code == arg ) { return arg; } string tmp = code + ( (arg.size() == input.size()) ? string() : input.substr( arg.size() ) ); // skip the first token // CERR << "alias resolution for ["<<input<<"] = ["<<tmp<<"]"<<std::endl; // not thread safe: static unsigned int loopblocker = 0; if( ++loopblocker > 9 ) { CERR << "******************** WARNING ********************\n" << "expand() has been through "<<loopblocker << " iterations. That's probably too many, so we're aborting alias expansion. " << "You probably have aliases which expand to each other. Please check this content for possible problems: ["<<input<<"]." << "\nIf you believe this to be a bug, please fix it in " << __FILE__ <<", line " <<__LINE__<<"." << endl; loopblocker = 0; return tmp; } tmp = expand( tmp ); --loopblocker; return tmp; } private: aliaser(){} ~aliaser(){} aliaser & operator=( const aliaser & ); // not implemented aliaser( const aliaser & ); // not implemented }; } // namespace TOOLBOX_NAMESPACE #endif // TOOLBOX_NAMESPACE_ALIASER_H_INCLUDED |