//-----------------------------------------------------------
// Copyright Christian Arnault LAL-Orsay CNRS
// arnault@lal.in2p3.fr
// See the complete license in cmt_license.txt "http://www.cecill.info". 
//-----------------------------------------------------------

#include "cmt_commands.h"
#include "cmt_tag.h"
#include "cmt_symbol.h"
#include "cmt_project.h"

ArgParser::ArgParser (CmtContext& context) : cmt(context), argc(0), argv(0), mode(Csh)
{
  arguments.clear ();

  int i = 0;

  parsers.add ("awk", i);
  pv.push_back (&ArgParser::do_awk); i++;

  parsers.add ("br", i);
  parsers.add ("bro", i);
  parsers.add ("broa", i);
  parsers.add ("broad", i);
  parsers.add ("broadc", i);
  parsers.add ("broadca", i);
  parsers.add ("broadcas", i);
  parsers.add ("broadcast", i);
  pv.push_back (&ArgParser::do_broadcast); i++;

  parsers.add ("bu", i);
  parsers.add ("bui", i);
  parsers.add ("buil", i);
  parsers.add ("build", i);
  pv.push_back (&ArgParser::do_build); i++;

  parsers.add ("check", i);
  pv.push_back (&ArgParser::do_check); i++;

  parsers.add ("check_f", i);
  parsers.add ("check_fi", i);
  parsers.add ("check_fil", i);
  parsers.add ("check_file", i);
  parsers.add ("check_files", i);
  pv.push_back (&ArgParser::do_check_files); i++;

  parsers.add ("co", i);
  parsers.add ("checkout", i);
  pv.push_back (&ArgParser::do_checkout); i++;

  parsers.add ("cl", i);
  parsers.add ("cle", i);
  parsers.add ("clea", i);
  parsers.add ("clean", i);
  parsers.add ("cleanu", i);
  parsers.add ("cleanup", i);
  pv.push_back (&ArgParser::do_cleanup); i++;

  parsers.add ("con", i);
  parsers.add ("conf", i);
  parsers.add ("confi", i);
  parsers.add ("config", i);
  pv.push_back (&ArgParser::do_config); i++;

  parsers.add ("create", i);
  pv.push_back (&ArgParser::do_create); i++;

  parsers.add ("create_project", i);
  pv.push_back (&ArgParser::do_create_project); i++;

  parsers.add ("cvsb", i);
  parsers.add ("cvsbr", i);
  parsers.add ("cvsbra", i);
  parsers.add ("cvsbran", i);
  parsers.add ("cvsbranc", i);
  parsers.add ("cvsbranch", i);
  parsers.add ("cvsbranche", i);
  parsers.add ("cvsbranches", i);
  pv.push_back (&ArgParser::do_cvsbranches); i++;

  parsers.add ("cvssubpa", i);
  parsers.add ("cvssubpac", i);
  parsers.add ("cvssubpack", i);
  parsers.add ("cvssubpacka", i);
  parsers.add ("cvssubpackag", i);
  parsers.add ("cvssubpackage", i);
  parsers.add ("cvssubpackages", i);
  pv.push_back (&ArgParser::do_cvssubpackages); i++;

  parsers.add ("cvssubpr", i);
  parsers.add ("cvssubpro", i);
  parsers.add ("cvssubproj", i);
  parsers.add ("cvssubproje", i);
  parsers.add ("cvssubprojec", i);
  parsers.add ("cvssubproject", i);
  parsers.add ("cvssubprojects", i);
  pv.push_back (&ArgParser::do_cvssubprojects); i++;

  parsers.add ("cvst", i);
  parsers.add ("cvsta", i);
  parsers.add ("cvstag", i);
  parsers.add ("cvstags", i);
  pv.push_back (&ArgParser::do_cvstags); i++;

  parsers.add ("d", i);
  parsers.add ("do", i);
  pv.push_back (&ArgParser::do_do); i++;

  parsers.add ("e", i);
  parsers.add ("ex", i);
  parsers.add ("exp", i);
  parsers.add ("expa", i);
  parsers.add ("expan", i);
  parsers.add ("expand", i);
  pv.push_back (&ArgParser::do_expand); i++;

  parsers.add ("f", i);
  parsers.add ("fi", i);
  parsers.add ("fil", i);
  parsers.add ("filt", i);
  parsers.add ("filte", i);
  parsers.add ("filter", i);
  pv.push_back (&ArgParser::do_filter); i++;

  parsers.add ("h", i);
  parsers.add ("he", i);
  parsers.add ("hel", i);
  parsers.add ("help", i);
  pv.push_back (&ArgParser::do_help); i++;

  parsers.add ("l", i);
  parsers.add ("lo", i);
  parsers.add ("loc", i);
  parsers.add ("lock", i);
  pv.push_back (&ArgParser::do_lock); i++;

  parsers.add ("re", i);
  parsers.add ("rem", i);
  parsers.add ("remo", i);
  parsers.add ("remov", i);
  parsers.add ("remove", i);
  pv.push_back (&ArgParser::do_remove); i++;

  parsers.add ("run", i);
  pv.push_back (&ArgParser::do_run); i++;

  parsers.add ("run_sequence", i);
  pv.push_back (&ArgParser::do_run_sequence); i++;

  parsers.add ("set", i);
  pv.push_back (&ArgParser::do_set); i++;

  parsers.add ("setup", i);
  pv.push_back (&ArgParser::do_setup); i++;

  parsers.add ("sh", i);
  parsers.add ("sho", i);
  parsers.add ("show", i);
  pv.push_back (&ArgParser::do_show); i++;

  parsers.add ("sy", i);
  parsers.add ("sys", i);
  parsers.add ("syst", i);
  parsers.add ("syste", i);
  parsers.add ("system", i);
  pv.push_back (&ArgParser::do_system); i++;

  parsers.add ("u", i);
  parsers.add ("un", i);
  parsers.add ("unl", i);
  parsers.add ("unlo", i);
  parsers.add ("unloc", i);
  parsers.add ("unlock", i);
  pv.push_back (&ArgParser::do_unlock); i++;

  parsers.add ("v", i);
  parsers.add ("ve", i);
  parsers.add ("ver", i);
  parsers.add ("vers", i);
  parsers.add ("versi", i);
  parsers.add ("versio", i);
  parsers.add ("version", i);
  parsers.add ("--version", i);
  pv.push_back (&ArgParser::do_version); i++;

  parsers.add ("-b", i);
  parsers.add ("-ba", i);
  parsers.add ("-bat", i);
  pv.push_back (&ArgParser::option_bat); i++;

  parsers.add ("-c", i);
  parsers.add ("-cs", i);
  parsers.add ("-csh", i);
  pv.push_back (&ArgParser::option_csh); i++;

  parsers.add ("-e", i);
  pv.push_back (&ArgParser::option_e); i++;

  parsers.add ("-f", i);
  pv.push_back (&ArgParser::option_f); i++;

  parsers.add ("-h", i);
  parsers.add ("-he", i);
  parsers.add ("-hel", i);
  parsers.add ("-help", i);
  parsers.add ("--h", i);
  parsers.add ("--he", i);
  parsers.add ("--hel", i);
  parsers.add ("--help", i);
  pv.push_back (&ArgParser::option_help); i++;

  parsers.add ("-ho", i);
  parsers.add ("-hom", i);
  parsers.add ("-home", i);
  pv.push_back (&ArgParser::option_home); i++;

  parsers.add ("-n", i);
  pv.push_back (&ArgParser::option_n); i++;

  parsers.add ("-no_c", i);
  parsers.add ("-no_cl", i);
  parsers.add ("-no_cle", i);
  parsers.add ("-no_clea", i);
  parsers.add ("-no_clean", i);
  parsers.add ("-no_cleanu", i);
  parsers.add ("-no_cleanup", i);
  pv.push_back (&ArgParser::option_no_cleanup); i++;

  parsers.add ("-pac", i);
  parsers.add ("-pack", i);
  pv.push_back (&ArgParser::option_pack); i++;

  parsers.add ("-pat", i);
  parsers.add ("-path", i);
  pv.push_back (&ArgParser::option_path); i++;

  parsers.add ("-pr", i);
  parsers.add ("-pri", i);
  parsers.add ("-priv", i);
  parsers.add ("-priva", i);
  parsers.add ("-privat", i);
  parsers.add ("-private", i);
  pv.push_back (&ArgParser::option_private); i++;

  parsers.add ("-pu", i);
  parsers.add ("-pub", i);
  parsers.add ("-publ", i);
  parsers.add ("-publi", i);
  parsers.add ("-public", i);
  pv.push_back (&ArgParser::option_public); i++;

  parsers.add ("-s", i);
  parsers.add ("-sh", i);
  pv.push_back (&ArgParser::option_sh); i++;

  parsers.add ("-q", i);
  parsers.add ("-qu", i);
  parsers.add ("-qui", i);
  parsers.add ("-quie", i);
  parsers.add ("-quiet", i);
  pv.push_back (&ArgParser::option_quiet); i++;

  parsers.add ("-tag", i);
  pv.push_back (&ArgParser::option_tag); i++;

  parsers.add ("-tag_add", i);
  pv.push_back (&ArgParser::option_tag_add); i++;

  parsers.add ("-tag_remove", i);
  pv.push_back (&ArgParser::option_tag_remove); i++;

  parsers.add ("-u", i);
  parsers.add ("-us", i);
  parsers.add ("-use", i);
  pv.push_back (&ArgParser::option_use); i++;

  parsers.add ("-user", i);
  parsers.add ("-user_", i);
  parsers.add ("-user_c", i);
  parsers.add ("-user_co", i);
  parsers.add ("-user_con", i);
  parsers.add ("-user_cont", i);
  parsers.add ("-user_conte", i);
  parsers.add ("-user_contex", i);
  parsers.add ("-user_context", i);
  pv.push_back (&ArgParser::option_user_context); i++;

  parsers.add ("-v", i);
  parsers.add ("-ve", i);
  parsers.add ("-ver", i);
  parsers.add ("-vers", i);
  parsers.add ("-versi", i);
  parsers.add ("-versio", i);
  parsers.add ("-version", i);
  pv.push_back (&ArgParser::option_version); i++;

  parsers.add ("-warn", i);
  parsers.add ("-warni", i);
  parsers.add ("-warnin", i);
  parsers.add ("-warning", i);
  parsers.add ("-warnings", i);
  pv.push_back (&ArgParser::option_warnings); i++;

  parsers.add ("-with_v", i);
  parsers.add ("-with_ve", i);
  parsers.add ("-with_ver", i);
  parsers.add ("-with_vers", i);
  parsers.add ("-with_versi", i);
  parsers.add ("-with_versio", i);
  parsers.add ("-with_version", i);
  parsers.add ("-with_version_", i);
  parsers.add ("-with_version_d", i);
  parsers.add ("-with_version_di", i);
  parsers.add ("-with_version_dir", i);
  parsers.add ("-with_version_dire", i);
  parsers.add ("-with_version_direc", i);
  parsers.add ("-with_version_direct", i);
  parsers.add ("-with_version_directo", i);
  parsers.add ("-with_version_director", i);
  parsers.add ("-with_version_directory", i);
  pv.push_back (&ArgParser::option_with_version_directory); i++;

  parsers.add ("-without_v", i);
  parsers.add ("-without_ve", i);
  parsers.add ("-without_ver", i);
  parsers.add ("-without_vers", i);
  parsers.add ("-without_versi", i);
  parsers.add ("-without_versio", i);
  parsers.add ("-without_version", i);
  parsers.add ("-without_version_", i);
  parsers.add ("-without_version_d", i);
  parsers.add ("-without_version_di", i);
  parsers.add ("-without_version_dir", i);
  parsers.add ("-without_version_dire", i);
  parsers.add ("-without_version_direc", i);
  parsers.add ("-without_version_direct", i);
  parsers.add ("-without_version_directo", i);
  parsers.add ("-without_version_director", i);
  parsers.add ("-without_version_directory", i);
  pv.push_back (&ArgParser::option_without_version_directory); i++;

}

void ArgParser::shift ()
{
  if (argc > 0)
    {
      argc--;
      argv++;
    }
}

void ArgParser::unshift ()
{
  argc++;
  argv--;
}

void ArgParser::fill_arguments ()
{
  while (argc > 0)
    {
      cmt_string& s = arguments.add ();
      s = argv[0];

      //cerr << "Getting arg[" << s << "] " << endl;

      shift ();
    }  
}

cmt_string& ArgParser::fill_one_argument ()
{
  if (argc > 0)
    {
      cmt_string& s = arguments.add ();
      s = argv[0];

      //cerr << "Getting arg[" << s << "] " << endl;

      shift ();

      return (s);
    }
  else
    {
      static cmt_string empty = "";
      return (empty);
    }
}

cmt_string& ArgParser::fill_one_argument_filtered ()
{
  if (argc > 0)
    {
      cmt_string& s = arguments.add ();
      s = argv[0];

      if (s[0] == '-')
	{
	  s = "";
	}

      //cerr << "Getting arg[" << s << "] " << endl;

      shift ();

      return (s);
    }
  else
    {
      static cmt_string empty = "";
      return (empty);
    }
}

void ArgParser::parse ()
{
  ArgParser& me = *this;

  help_action = action_none;
  arguments.clear ();
  extra_line.erase (0);
  extra_file.erase (0);
  mode = Csh;

  /// Skip first argument ("cmt")
  shift ();

  cmt.m_action = action_none;

  while (argc > 0)
    {
      arg = argv[0];

      shift ();

      /// Suppress trailing carriage-return
      int cr = arg.find ('\r');
      if (cr != cmt_string::npos) arg.erase (cr);

      /// Suppress enclosing quotes
      if ((arg[0] == '\"') && (arg[arg.size () - 1] == '\"'))
	{
	  arg.erase (0, 1);
	  arg.erase (arg.size () - 1, 1);
	}

      /// Detect and split arguments of the form a=b
      /// left and right part of this argument
      cmt_string reduced_arg = arg;
      int pos = reduced_arg.find ('=');
      if (pos != cmt_string::npos)
	{
	  reduced_arg.erase (pos);
	  arg.erase (0, pos+1);
	}
      else
	{
	  arg = "";
	}

      //cerr << "argc=" << argc << " reduced_arg=[" << reduced_arg << "] arg=[" << arg << "]" << endl;

      if (parsers.has (reduced_arg))
	{
	  // This argument corresponds to a known command

	  int i = (*parsers.find (reduced_arg));

	  parser p = pv[i];
	  (me.*p) ();
	}
      else if (cmt.m_action != action_none)
	{
	  // We have unexpected arguments (not handled by the command handler). This may sign 
	  // an unprotected handler implementation.
	  if (!cmt.m_quiet) cerr << "#CMT> warning : unexpected parameter " << reduced_arg << endl;
	}
      else
	{
	  // This argument does not correspond to a known command. We expect then an action
	  // to be executed with that name

	  unshift ();
	  do_do ();

	  /*
	      if (!cmt.m_quiet) cerr << "#CMT> syntax error : bad command parameter " << arg << endl;
	      help_action = action_none;
	  */
	}
    }
}

void ArgParser::do_awk ()
{
  fill_arguments ();
  cmt.m_action = action_awk;
}

void ArgParser::do_broadcast ()
{
  fill_arguments ();
  cmt.m_action = action_broadcast;
  
  if (cmt.m_scope_filtering_mode == default_filtering_mode)
    {
      cmt.m_scope_filtering_mode = reach_private_uses;
    }
}

void ArgParser::do_build ()
{
  if (argc > 0)
    {
      arg = argv[0];

      if (arg == "-nmake")
	{
	  cmt.m_build_nmake = true;
	  shift ();
	}
    }

  if (argc > 0)
    {
      arg = argv[0];

      shift ();

      if (arg == "constituent_makefile")
	{
	  if (argc > 0)
	    {
	      fill_one_argument ();
	      cmt.m_action = action_build_constituent_makefile;
	    }
	  else
	    {
	      if (!cmt.m_quiet) cerr << "#CMT> syntax error : constituent name missing" << endl;
	      cmt.m_action = action_build_constituent_makefile;
	      help_action = action_help;
	    }
	}
      else if (arg == "constituents_makefile")
	{
	  fill_arguments ();
	  cmt.m_action = action_build_constituents_makefile;
	}
      else if (arg == "dependencies")
	{
	  if (argc > 0)
	    {
	      fill_arguments ();
	      cmt.m_action = action_build_dependencies;
	    }
	  else
	    {
	      if (!cmt.m_quiet) cerr << "#CMT> syntax error : arguments missing " << endl;
	      help_action = action_help;
	      cmt.m_action = action_build_dependencies;
	    }
	}
      else if (arg == "library_links")
	{
	  cmt.m_action = action_build_library_links;
	}
      else if (arg == "make_setup")
	{
	  cmt.m_action = action_build_make_setup;
	}
      else if (arg == "msdev")
	{
	  if (argc > 0)
	    {
	      fill_one_argument_filtered ();
	    }

	  cmt.m_action = action_build_msdev;
	}
      else if (arg == "CMT_pacman")
	{
	  cmt.m_action = action_build_CMT_pacman;
	}
      else if (arg == "vsnet") 
	{
	  if (argc > 0)
	    {
	      fill_one_argument_filtered ();
	    }
                                                                    
	  cmt.m_action = action_build_vsnet;                 
	}                                              
      else if (arg == "os9_makefile")
	{
	  if (argc > 0)
	    {
	      fill_one_argument ();
	      cmt.m_action = action_build_os9_makefile;
	    }
	  else
	    {
	      if (!cmt.m_quiet) cerr << "#CMT> syntax error : arguments missing " << endl;
	      help_action = action_help;
	      cmt.m_action = action_build_os9_makefile;
	    }
	}
      else if (arg == "prototype")
	{
	  if (argc > 0)
	    {
	      fill_one_argument ();
	      cmt.m_action = action_build_prototype;
	    }
	  else
	    {
	      if (!cmt.m_quiet) cerr << "#CMT> syntax error : arguments missing" << endl;
	      help_action = action_help;
	      cmt.m_action = action_build_prototype;
	    }
	}
      else if (arg == "readme")
	{
	  cmt.m_action = action_build_readme;

	  fill_arguments ();
	}
      else if (arg == "tag_makefile")
	{
	  cmt.m_action = action_build_tag_makefile;
	}
      else if (arg == "temporary_name")
	{
	  cmt.m_action = action_build_temporary_name;
	}
      else if (arg == "triggers")
	{
	  if (argc > 0)
	    {
	      fill_one_argument ();
	      cmt.m_action = action_build_triggers;
	    }
	  else
	    {
	      if (!cmt.m_quiet) cerr << "#CMT> syntax error : arguments missing" << endl;
	      help_action = action_help;
	      cmt.m_action = action_build_triggers;
	    }
	}
      else if (arg == "windefs")
	{
	  if (argc > 0)
	    {
	      fill_one_argument ();
	      cmt.m_action = action_build_windefs;
	    }
	  else
	    {
	      if (!cmt.m_quiet) cerr << "#CMT> syntax error : arguments missing" << endl;
	      help_action = action_help;
	      cmt.m_action = action_build_windefs;
	    }
	}
      else
	{
	  if (!cmt.m_quiet) cerr << "#CMT> syntax error : wrong build argument" << endl;
	  help_action = action_help;
	  cmt.m_action = action_build;
	}
    }
  else
    {
      if (!cmt.m_quiet) cerr << "#CMT> syntax error : don't know what to build" << endl;
      help_action = action_help;
      cmt.m_action = action_build;
    }
}

void ArgParser::do_check ()
{
  if (argc > 0)
    {
      arg = argv[0];

      shift ();

      if (arg == "configuration")
	{
	  cmt.m_action = action_check_configuration;
	}
      else if (arg == "files")
	{
	  if (argc > 0)
	    {
	      fill_one_argument ();
	      if (argc > 0)
		{
		  fill_one_argument ();
		  cmt.m_action = action_check_files;
		}
	      else
		{
		  if (!cmt.m_quiet) cerr << "#CMT> syntax error : reference file name missing" 
					 << endl;
		  help_action = action_help;
		  cmt.m_action = action_check_files;
		}
	    }
	  else
	    {
	      if (!cmt.m_quiet) cerr << "#CMT> syntax error : file name missing" << endl;
	      help_action = action_help;
	      cmt.m_action = action_check_files;
	    }
	}
      else if (arg == "version")
	{
	  if (argc > 0)
	    {
	      fill_one_argument ();
	      cmt.m_action = action_check_version;
	    }
	  else
	    {
	      if (!cmt.m_quiet) cerr << "#CMT> syntax error : package name missing" << endl;
	      help_action = action_help;
	      cmt.m_action = action_check_version;
	    }
	}
      else
	{
	  if (!cmt.m_quiet) cerr << "#CMT> syntax error : bad check option" << endl;
	  help_action = action_help;
	  cmt.m_action = action_check;
	}
    }
  else
    {
      if (!cmt.m_quiet) cerr << "#CMT> syntax error : don't know what to check" << endl;
      help_action = action_help;
      cmt.m_action = action_check;
    }
}

void ArgParser::do_check_files ()
{
  if (argc > 0)
    {
      fill_one_argument ();
      if (argc > 0)
	{
	  fill_one_argument ();
	  cmt.m_action = action_check_files;
	}
      else
	{
	  if (!cmt.m_quiet) cerr << "#CMT> syntax error : reference file missing" << endl;
	  help_action = action_help;
	  cmt.m_action = action_check_files;
	}
    }
  else
    {
      if (!cmt.m_quiet) cerr << "#CMT> syntax error : file name missing" << endl;
      help_action = action_help;
      cmt.m_action = action_check_files;
    }
}

void ArgParser::do_checkout ()
{
  if (argc > 0)
    {
      fill_arguments ();
      cmt.m_action = action_checkout;
    }
  else
    {
      if (!cmt.m_quiet) cerr << "#CMT> syntax error : checkout arguments missing" << endl;
      help_action = action_help;
      cmt.m_action = action_checkout;
    }
}

void ArgParser::do_cleanup ()
{
  cmt.m_action = action_cleanup;
}

void ArgParser::do_config ()
{
  cmt.m_action = action_config;
}

void ArgParser::do_create ()
{
  if (argc > 0)
    {
      fill_arguments ();
      cmt.m_action = action_create;
    }
  else
    {
      if (!cmt.m_quiet) cerr << "#CMT> syntax error : create arguments missing" << endl;
      help_action = action_help;
      cmt.m_action = action_create;
    }
}

void ArgParser::do_create_project ()
{
  if (argc > 0)
    {
      fill_arguments ();
      cmt.m_action = action_create_project;
    }
  else
    {
      if (!cmt.m_quiet) cerr << "#CMT> syntax error : create_project arguments missing" << endl;
      help_action = action_help;
      cmt.m_action = action_create_project;
    }
}

void ArgParser::do_cvsbranches ()
{
  if (argc > 0)
    {
      fill_one_argument ();
      cmt.m_action = action_cvsbranches;
    }
  else
    {
      if (!cmt.m_quiet) cerr << "#CMT> syntax error : cvsbranches arguments missing" << endl;
      help_action = action_help;
      cmt.m_action = action_cvsbranches;
    }
}

void ArgParser::do_cvssubpackages ()
{
  if (argc > 0)
    {
      fill_one_argument ();
    }

  cmt.m_action = action_cvssubpackages;
}

void ArgParser::do_cvssubprojects ()
{
  if (argc > 0)
    {
      fill_one_argument ();
    }

  cmt.m_action = action_cvssubprojects;
}

void ArgParser::do_cvstags ()
{
  if (argc > 0)
    {
      fill_arguments ();
      cmt.m_action = action_cvstags;
    }
  else
    {
      if (!cmt.m_quiet) cerr << "#CMT> syntax error : package name missing" << endl;
      help_action = action_help;
      cmt.m_action = action_cvstags;
    }
}

void ArgParser::do_do ()
{
  if (argc > 0)
    {
      fill_arguments ();
		  
      {
	cmt_string tag_name = "target_";
	tag_name += arguments[0];

	Tag* tag;
	tag = Tag::add (tag_name, PriorityUserTag, "action", 0);                      
	tag->mark ();
      }

      cmt.m_action = action_do;
    }
  else
    {
      if (!cmt.m_quiet) cerr << "#CMT> syntax error : action not specified" << endl;
      help_action = action_help;
      cmt.m_action = action_do;
    }
}

void ArgParser::do_expand ()
{
  if (argc > 0)
    {
      arg = argv[0];

      shift ();
      if (arg == "model")
	{
	  if (argc > 0)
	    {
	      fill_arguments ();
	      cmt.m_action = action_expand_model;
	    }
	  else
	    {
	      if (!cmt.m_quiet) cerr << "#CMT> syntax error : model not specified" << endl;
	      help_action = action_help;
	      cmt.m_action = action_expand_model;
	    }
	}
      else
	{
	  if (!cmt.m_quiet) cerr << "#CMT> syntax error : bad expand option" << endl;
	  help_action = action_help;
	  cmt.m_action = action_expand_model;
	}
    }
  else
    {
      if (!cmt.m_quiet) cerr << "#CMT> syntax error : don't know what to expand" << endl;
      help_action = action_help;
      cmt.m_action = action_expand_model;
    }
}

void ArgParser::do_filter ()
{
  if (argc > 0)
    {
      fill_arguments ();
      cmt.m_action = action_filter;
    }
  else
    {
      if (!cmt.m_quiet) cerr << "#CMT> syntax error : file to filter not specified" << endl;
      help_action = action_help;
      cmt.m_action = action_filter;
    }
}

void ArgParser::do_help ()
{
  help_action = action_help;
}

void ArgParser::do_lock ()
{
  if (argc > 0)
    {
      cmt.m_current_package = fill_one_argument ();
      cmt.m_current_version.erase (0);
      cmt.m_current_path.erase (0);

      if (argc > 0)
	{
	  cmt.m_current_version = fill_one_argument ();
	  cmt.m_action = action_lock;

	  if (argc > 0)
	    {
	      cmt.m_current_path = fill_one_argument_filtered ();
	    }

	  cmt.m_current_access = UserMode;
	  (Use::current()).set (cmt.m_current_package, 
				cmt.m_current_version, 
				cmt.m_current_path);

	}
      else
	{
	  if (!cmt.m_quiet) cerr << "#CMT> syntax error : version missing" << endl;
	  help_action = action_help;
	  cmt.m_action = action_lock;
	}
    }
  else
    {
      cmt.m_action = action_lock;
    }
}

void ArgParser::do_remove ()
{
  if (argc > 0)
    {
      arg = argv[0];

      if (arg == "library_links")
	{
	  shift ();
	  cmt.m_action = action_remove_library_links;
	}
      else
	{
	  cmt.m_current_package = fill_one_argument ();
	  cmt.m_current_version.erase (0);
	  cmt.m_current_path.erase (0);
                      
	  if (argc > 0)
	    {
	      cmt.m_current_version = fill_one_argument ();

	      if (argc > 0)
		{
		  cmt.m_current_path = fill_one_argument_filtered ();
		}
                            
	      cmt.m_action = action_remove;
	    }
	  else
	    {
	      if (!cmt.m_quiet) cerr << "#CMT> syntax error : version missing" << endl;
	      help_action = action_help;
	      cmt.m_action = action_remove;
	    }
	}
    }
  else
    {
      if (!cmt.m_quiet) cerr << "#CMT> syntax error : don't know what to remove" << endl;
      help_action = action_help;
      cmt.m_action = action_remove;
    }
}

void ArgParser::do_run ()
{
  if (argc > 0)
    {
      fill_arguments ();
      cmt.m_action = action_run;
    }
  else
    {
      if (!cmt.m_quiet) cerr << "#CMT> syntax error : run arguments missing" << endl;
      help_action = action_help;
      cmt.m_action = action_run;
    }
}

void ArgParser::do_run_sequence ()
{
  if (argc > 0)
    {
      fill_one_argument ();
      cmt.m_action = action_run_sequence;
    }
  else
    {
      if (!cmt.m_quiet) cerr << "#CMT> syntax error : run_sequence arguments missing" << endl;
      help_action = action_help;
      cmt.m_action = action_run_sequence;
    }
}

void ArgParser::do_set ()
{
  if (argc > 0)
    {
      arg = argv[0];

      shift ();

      if (arg == "version")
	{
	  fill_arguments ();
	  cmt.m_action = action_set_version;
	}
      else if (arg == "versions")
	{
	  fill_arguments ();

	  cmt.m_action = action_set_versions;

	  if (cmt.m_scope_filtering_mode == default_filtering_mode)
	    {
	      cmt.m_scope_filtering_mode = reach_private_uses;
	    }
	}
      else
	{
	  if (!cmt.m_quiet) cerr << "#CMT> syntax error : bad set argument" << endl;
	  help_action = action_help;
	  //cmt.m_action = action_set;
	}
    }
  else
    {
      if (!cmt.m_quiet) cerr << "#CMT> syntax error : don't know what to set" << endl;
      help_action = action_help;
      //cmt.m_action = action_set;
    }
}

void ArgParser::do_setup ()
{
  cmt.m_action = action_setup;
}

void ArgParser::do_show ()
{
  if (argc > 0)
    {
      arg = argv[0];

      //cerr << "Running show arg=" << arg << endl;

      shift ();

      if (arg == "action")
	{
	  if (argc > 0)
	    {
	      cmt.m_current_target = fill_one_argument ();
	      cmt.m_action = action_show_action;
	    }
	  else
	    {
	      if (!cmt.m_quiet) cerr << "#CMT> syntax error : action name missing" << endl;
	      help_action = action_help;
	      cmt.m_action = action_show_action;
	    }
	}
      else if (arg == "action_names")
	{
	  if (argc > 0)
	    {
	      fill_one_argument ();
	    }

	  cmt.m_action = action_show_action_names;
	}
      else if (arg == "action_value")
	{
	  cmt.m_quiet = true;
	  if (argc > 0)
	    {
	      cmt.m_current_target = fill_one_argument ();
	      cmt.m_action = action_show_action_value;
	    }
	  else
	    {
	      if (!cmt.m_quiet) cerr << "#CMT> syntax error : action name missing" << endl;
	      help_action = action_help;
	      cmt.m_action = action_show_action_value;
	    }
	}
      else if (arg == "actions")
	{
	  if (argc > 0)
	    {
	      fill_one_argument ();
	    }

	  cmt.m_action = action_show_actions;
	}
      else if (arg == "all_tags")
	{
	  cmt.m_action = action_show_all_tags;
	}
      else if (arg == "applied_patterns")
	{
	  cmt.m_action = action_show_applied_patterns;
	}
      else if (arg == "author")
	{
	  cmt.m_action = action_show_author;
	}
      else if (arg == "branches")
	{
	  cmt.m_action = action_show_branches;
	}
      else if (arg == "clients")
	{
	  if (argc > 0)
	    {
	      cmt.m_current_target = fill_one_argument ();

	      cmt.m_action = action_show_clients;

	      if (argc > 0)
		{
		  fill_one_argument ();
		  if (argc > 0)
		    {
		      fill_one_argument ();
		    }
		}
	    }
	  else
	    {
	      if (!cmt.m_quiet) cerr << "#CMT> syntax error : package name missing" << endl;
	      help_action = action_help;
	      cmt.m_action = action_show_clients;
	    }
	}
      else if (arg == "cmtpath_patterns")
	{
	  cmt.m_action = action_show_cmtpath_patterns;
	}
      else if (arg == "constituent")
	{
	  if (argc > 0)
	    {
	      cmt.m_current_target = fill_one_argument ();
	      cmt.m_action = action_show_constituent;
	    }
	  else
	    {
	      if (!cmt.m_quiet) cerr << "#CMT> syntax error : constituent name missing" << endl;
	      help_action = action_help;
	      cmt.m_action = action_show_constituent;
	    }
	}
      else if (arg == "constituent_names")
	{
	  cmt.m_action = action_show_constituent_names;
	}
      else if (arg == "constituents")
	{
	  cmt.m_action = action_show_constituents;
	}
      else if (arg == "cycles")
	{
	  cmt.m_action = action_show_cycles;
	}
      else if (arg == "fragment")
	{
	  if (argc > 0)
	    {
	      cmt.m_current_target = fill_one_argument ();
	      cmt.m_action = action_show_fragment;
	    }
	  else
	    {
	      if (!cmt.m_quiet) cerr << "#CMT> syntax error : fragment name missing" << endl;
	      help_action = action_help;
	      cmt.m_action = action_show_fragment;
	    }
	}
      else if (arg == "fragments")
	{
	  cmt.m_action = action_show_fragments;
	}
      else if (arg == "groups")
	{
	  cmt.m_action = action_show_groups;
	}
      else if (arg == "include_dirs")
	{
	  cmt.m_action = action_show_include_dirs;
	}
      else if (arg == "language")
	{
	  if (argc > 0)
	    {
	      cmt.m_current_target = fill_one_argument ();
	      cmt.m_action = action_show_language;
	    }
	  else
	    {
	      if (!cmt.m_quiet) cerr << "#CMT> syntax error : language name missing" << endl;
	      help_action = action_help;
	      cmt.m_action = action_show_language;
	    }
	}
      else if (arg == "languages")
	{
	  cmt.m_action = action_show_languages;
	}
      else if (arg == "macro")
	{
	  if (argc > 0)
	    {
	      cmt.m_current_target = fill_one_argument ();
	      cmt.m_action = action_show_macro;
	    }
	  else
	    {
	      if (!cmt.m_quiet) cerr << "#CMT> syntax error : macro name missing" << endl;
	      help_action = action_help;
	      cmt.m_action = action_show_macro;
	    }
	}
      else if (arg == "macro_names")
	{
	  if (argc > 0)
	    {
	      fill_one_argument ();
	    }

	  cmt.m_action = action_show_macro_names;
	}
      else if (arg == "macro_value")
	{
	  cmt.m_quiet = true;
	  if (argc > 0)
	    {
	      cmt.m_current_target = fill_one_argument ();
	      cmt.m_action = action_show_macro_value;
	    }
	  else
	    {
	      if (!cmt.m_quiet) cerr << "#CMT> syntax error : macro name missing" << endl;
	      help_action = action_help;
	      cmt.m_action = action_show_macro_value;
	    }
	}
      else if (arg == "macros")
	{
	  if (argc > 0)
	    {
	      fill_one_argument ();
	    }

	  cmt.m_action = action_show_macros;
	}
      else if (arg == "manager")
	{
	  cmt.m_action = action_show_manager;
	}
      else if (arg == "packages")
	{
	  if (argc > 0)
	    {
	      cmt.m_current_target = fill_one_argument ();
	    }

	  cmt.m_action = action_show_packages;
	}
      else if (arg == "path")
	{
	  cmt.m_action = action_show_path;
	}
      else if (arg == "pattern")
	{
	  if (argc > 0)
	    {
	      cmt.m_current_target = fill_one_argument ();
	      cmt.m_action = action_show_pattern;
	    }
	  else
	    {
	      if (!cmt.m_quiet) cerr << "#CMT> syntax error : pattern name missing" << endl;
	      help_action = action_help;
	      cmt.m_action = action_show_pattern;
	    }
	}
      else if (arg == "pattern_names")
	{
	  cmt.m_action = action_show_pattern_names;
	}
      else if (arg == "patterns")
	{
	  cmt.m_action = action_show_patterns;
	}
      else if (arg == "projects")
	{
	  cmt.m_action = action_show_projects;
	}
      else if (arg == "pwd")
	{
	  cmt.m_action = action_show_pwd;
	}
      else if (arg == "setup")
	{
	  cmt.m_action = action_show_setup;

	  if (cmt.m_scope_filtering_mode == default_filtering_mode)
	    {
	      cmt.m_scope_filtering_mode = reach_private_uses;
	    }
	}
      else if (arg == "set_names")
	{
	  if (argc > 0)
	    {
	      fill_one_argument ();
	    }

	  cmt.m_action = action_show_set_names;
	}
      else if (arg == "set_value")
	{
	  cmt.m_quiet = true;
	  if (argc > 0)
	    {
	      cmt.m_current_target = fill_one_argument ();
	      cmt.m_action = action_show_set_value;
	    }
	  else
	    {
	      if (!cmt.m_quiet) cerr << "#CMT> syntax error : set name missing" << endl;
	      help_action = action_help;
	      cmt.m_action = action_show_set_value;
	    }
	}
      else if (arg == "set")
	{
	  if (argc > 0)
	    {
	      cmt.m_current_target = fill_one_argument ();
	      cmt.m_action = action_show_set;
	    }
	  else
	    {
	      if (!cmt.m_quiet) cerr << "#CMT> syntax error : set name missing" << endl;
	      help_action = action_help;
	      cmt.m_action = action_show_set;
	    }
	}
      else if (arg == "sets")
	{
	  if (argc > 0)
	    {
	      fill_one_argument ();
	    }

	  cmt.m_action = action_show_sets;
	}
      else if (arg == "strategies")
	{
	  cmt.m_action = action_show_strategies;
	}
      else if (arg == "tags")
	{
	  cmt.m_action = action_show_tags;
	}
      else if (arg == "use_paths")
	{
	  if (argc > 0)
	    {
	      while (argc > 0)
		{
		  if (strcmp (argv[0], "-private") == 0)
		    {
		      cmt.m_scope_filtering_mode = reach_private_uses;
		    }
		  else if (strcmp (argv[0], "--private") == 0)
		    {
		      cmt.m_scope_filtering_mode = reach_private_uses;
		    }
		  else
		    {
		      cmt_string& s = arguments.add ();
		      s = argv[0];
		    }

		  shift ();
		}

	      cmt.m_action = action_show_use_paths;
	    }
	  else
	    {
	      if (!cmt.m_quiet) cerr << "#CMT> syntax error : package name missing" << endl;
	      help_action = action_help;
	      cmt.m_action = action_show_use_paths;
	    }
	}
      else if ((arg == "u") ||
	       (arg == "us") ||
	       (arg == "use") ||
	       (arg == "uses"))
	{
	  cmt.m_action = action_show_uses;

	  if (cmt.m_scope_filtering_mode == default_filtering_mode)
	    {
	      cmt.m_scope_filtering_mode = reach_private_uses;
	    }
	}
      else if (arg == "version")
	{
	  cmt.m_action = action_show_version;
	}
      else if (arg == "versions")
	{
	  if (argc > 0)
	    {
	      cmt.m_current_target = fill_one_argument ();
	      cmt.m_action = action_show_versions;
	    }
	  else
	    {
	      if (!cmt.m_quiet) cerr << "#CMT> syntax error : package name missing" << endl;
	      help_action = action_help;
	      cmt.m_action = action_show_versions;
	    }
	}
      else
	{
	  if (!cmt.m_quiet) cerr << "#CMT> syntax error : bad show argument" << endl;
	  help_action = action_help;
	  cmt.m_action = action_show;
	}
    }
  else
    {
      if (!cmt.m_quiet) cerr << "#CMT> syntax error : don't know what to show" << endl;
      help_action = action_help;
      cmt.m_action = action_show;
    }
}

void ArgParser::do_system ()
{
  cmt.m_action = action_system;
}

void ArgParser::do_unlock ()
{
  if (argc > 0)
    {
      cmt.m_current_package = fill_one_argument ();
      cmt.m_current_version.erase (0);
      cmt.m_current_path.erase (0);
                                        
      if (argc > 0)
	{
	  cmt.m_current_version = fill_one_argument ();
	  cmt.m_action = action_unlock;

	  if (argc > 0)
	    {
	      cmt.m_current_path = fill_one_argument_filtered ();
	    }
                                                
	  cmt.m_current_access = UserMode;
	  (Use::current()).set (cmt.m_current_package, 
				cmt.m_current_version, 
				cmt.m_current_path);

	}
      else
	{
	  if (!cmt.m_quiet) cerr << "#CMT> syntax error : version missing" << endl;
	  help_action = action_help;
	  cmt.m_action = action_unlock;
	}
    }
  else
    {
      cmt.m_action = action_unlock;
    }
}

void ArgParser::do_version ()
{
  cmt.m_action = action_version;
}

void ArgParser::option_help ()
{
  help_action = action_help;
}

void ArgParser::option_n ()
{
  cmt.m_simulation = true;
}

void ArgParser::option_quiet ()
{
  cmt.m_quiet = true;
}

void ArgParser::option_warnings ()
{
  cmt.m_warnings = true;
}

void ArgParser::option_csh ()
{
  mode = Csh;
}

void ArgParser::option_sh ()
{
  mode = Sh;
}

void ArgParser::option_bat ()
{
  mode = Bat;
}

void ArgParser::option_use ()
{
  if (cmt.m_action != action_create)
    {
      CmtSystem::cmt_string_vector words;

      CmtSystem::split (arg, ":", words);

      cmt.m_current_access = UserMode;

      if (words.size () > 0) cmt.m_current_package = words[0];
      if (words.size () > 1) cmt.m_current_version = words[1];
      if (words.size () > 2) cmt.m_current_path    = words[2];
      (Use::current()).set (cmt.m_current_package, 
			    cmt.m_current_version, 
			    cmt.m_current_path);
    }
}

void ArgParser::option_pack ()
{
  if ((cmt.m_action != action_create) && (cmt.m_current_package != arg))
    {
      //CmtSystem::cd (cmt.m_default_path);

      cmt.m_current_access = UserMode;

      cmt.m_current_package = arg;
      cmt.m_current_version = "";

      /*
      cerr << "ArgParser::option_pack> "
	   << " cp=" << cmt.m_current_package
	   << " cv=" << cmt.m_current_version
	   << " cp=" << cmt.m_current_path << endl;
      */

      (Use::current()).set (cmt.m_current_package, 
			    cmt.m_current_version, 
			    cmt.m_current_path);
    }
}

void ArgParser::option_version ()
{
  if ((cmt.m_action != action_create) && (cmt.m_current_version != arg))
    {
      cmt.m_current_access = UserMode;
      cmt.m_current_version = arg;

      /*
      cerr << "ArgParser::option_version> "
	   << " cp=" << cmt.m_current_package
	   << " cv=" << cmt.m_current_version
	   << " cp=" << cmt.m_current_path << endl;
      */

      (Use::current()).set (cmt.m_current_package, 
			    cmt.m_current_version, 
			    cmt.m_current_path);
    }
}

void ArgParser::option_path ()
{
  if ((cmt.m_action != action_create) && (cmt.m_current_path != arg))
    {
      cmt.m_current_access = UserMode;
      cmt.m_current_path = arg;

      /*
      cerr << "ArgParser::option_path> "
	   << " cp=" << cmt.m_current_package
	   << " cv=" << cmt.m_current_version
	   << " cp=" << cmt.m_current_path << endl;
      */

      (Use::current()).set (cmt.m_current_package, 
			    cmt.m_current_version, 
			    cmt.m_current_path);

      //IProjectFactory& factory = ProjectFactory::instance ();
      //CmtSystem::add_cmt_path (cmt.m_current_path, "argument", factory);
    }
}

void ArgParser::option_f ()
{
  extra_file = arg;
}

void ArgParser::option_e ()
{
  cerr << "#CMT> Warning: extra statement = " << arg << endl;
  extra_line = arg;
}

void ArgParser::option_home ()
{
  if (CmtSystem::test_directory (arg))
    {
      cmt.m_cmt_home = arg;
    }
}

void ArgParser::option_tag ()
{
  /*
    Here we are going to change the complete tag set
  */
	      
  if (arg != "")
    {
      Tag* tag;
      CmtSystem::cmt_string_vector words;

      // First reset selection of all existing tags
      //Tag::clear_all ();
      Tag::unmark_all ();
      cmt.m_extra_tags = ",";
		    
      // Then restore CMTSITE
      Cmt::configure_version_tag ();
      Cmt::configure_site_tag (0);
      Cmt::configure_uname_tag ();
      Cmt::configure_hosttype_tag ();
      Cmt::configure_config_tag ();
      Cmt::configure_home (0);
      Cmt::guess_current_project ();

      CmtSystem::split (arg, " \t,", words);
		  
      for (int i = 0; i < words.size (); i++)
	{
	  const cmt_string& a = words[i];
		      
	  cmt_string s = ",";
	  s += a;
	  s += ",";
		      
	  if (i == 0)
	    {
	      cmt.m_current_tag = a;
			  
	      if (CmtSystem::testenv ("TAGDEBUG")) cerr 
		<< "parse_argument(tag_add)> current_tag=" << cmt.m_current_tag << endl;
	    }
		      
	  if (cmt.m_extra_tags.find (s) == cmt_string::npos)
	    {
	      //if (!cmt.m_quiet) cerr << "  a=[" << a << "]" << endl;
			  
	      // Then restore uname if the specified tag is CMTCONFIG
	      if (a == CmtSystem::get_cmt_config ())
		{
		  Cmt::configure_uname_tag ();
		}
			  
	      tag = Tag::add (a, PriorityArgument, "arguments", 0);
			  
	      tag->mark ();
			  
	      cmt.m_extra_tags += a;
	      cmt.m_extra_tags += ",";
	    }
	}
    }
}

void ArgParser::option_tag_add ()
{
  Tag* tag;
  CmtSystem::cmt_string_vector words;
              
  //if (!cmt.m_quiet) cerr << "-tag_add=" << arg << endl;

  CmtSystem::split (arg, " \t,", words);

  for (int i = 0; i < words.size (); i++)
    {
      const cmt_string& a = words[i];

      cmt_string s = ",";
      s += a;
      s += ",";

      if (cmt.m_extra_tags.find (s) == cmt_string::npos)
	{
	  //if (!cmt.m_quiet) cerr << "  a=[" << a << "]" << endl;

	  /// Then restore uname if the specified tag is CMTCONFIG
	  if (a == CmtSystem::get_cmt_config ())
	    {
	      Cmt::configure_uname_tag ();
	    }
                      
	  tag = Tag::add (a, PriorityUserTag, "arguments", 0);
                      
	  tag->mark ();

	  cmt.m_extra_tags += a;
	  cmt.m_extra_tags += ",";
	}
    }
}

void ArgParser::option_tag_remove ()
{
  Tag::TagPtrVector tags = Tag::tags ();
  int i;
  Tag* tag;

  /*
    for (i = 0; i < tags.size (); i++)
    {
    tag = tags[i];
    if ((tag != 0) &&
    (tag->selected))
    {
    if (!cmt.m_quiet) cerr << "  original tag_list=" << tag->name << tag->priority << endl;
    }
    }
  */

  CmtSystem::cmt_string_vector words;

  //if (!cmt.m_quiet) cerr << "-arg_remove=" << arg << endl;

  CmtSystem::split (arg, " \t,", words);

  //
  // Now erase all entries in the old list that match
  // the specified tags 
  //

  for (i = 0; i < words.size (); i++)
    {
      const cmt_string& a = words[i];

      cmt_string s = ",";
      s += a;
      s += ",";

      int pos;

      pos = cmt.m_extra_tags.find (s);

      if (pos != cmt_string::npos)
	{
	  cmt.m_extra_tags.erase (pos, s.size () - 1);
	}

      //if (!cmt.m_quiet) cerr << "  tag_list=[" << tag_list << "]" << endl;
    }

  //
  // Now reinject the purged list of tags into the database
  // exactly as when using -tag=<tag-list>
  //

  /// First forget about all existing tags
      Tag::unmark_all ();

      /// Then restore CMTSITE
	Cmt::configure_version_tag ();
	Cmt::configure_site_tag (0);
	Cmt::configure_uname_tag ();
	Cmt::configure_hosttype_tag ();
              
	CmtSystem::split (cmt.m_extra_tags, " \t,", words);

	for (i = 0; i < words.size (); i++)
	  {
	    const cmt_string& a = words[i];

	    //fprintf (stderr, "  a=[%s]\n", a.c_str ());

	    /// Then restore uname if the specified tag is CMTCONFIG
	      if (a == CmtSystem::get_cmt_config ())
		{
		  Cmt::configure_uname_tag ();
		}

	      if (i == 0)
		{
		  cmt.m_current_tag = a;

		  //if (!cmt.m_quiet) cerr << "parse_argument(tag_remove)> current_tag=" 
		  //<< cmt.m_current_tag << endl;

		  tag = Tag::add (a, PriorityTag, "restore configuration", 0);
		}
	      else
		{
		  tag = Tag::add (a, PriorityUserTag, "restore configuration", 0);
		}

	      tag->mark ();
	  }
}

void ArgParser::option_user_context ()
{
  if (CmtSystem::test_directory (arg))
    {
      cmt.m_cmt_user_context = arg;
    }
}

void ArgParser::option_with_version_directory ()
{
  cmt.m_current_structuring_style = with_version_directory;

  StrategyDef* def = StrategyMgr::find_strategy ("VersionDirectory");
  if (def != 0)
    {
      def->m_default_value = true;
      def->m_priority_value = false;
    }
}

void ArgParser::option_without_version_directory ()
{
  cmt.m_current_structuring_style = without_version_directory;

  StrategyDef* def = StrategyMgr::find_strategy ("VersionDirectory");
  if (def != 0)
    {
      def->m_default_value = false;
      def->m_priority_value = true;
    }
}

void ArgParser::option_no_cleanup ()
{
  //cmt.m_current_setup_strategy |= SetupNoCleanup;
}

void ArgParser::option_private ()
{
  cmt.m_scope_filtering_mode = reach_private_uses;
}

void ArgParser::option_public ()
{
  cmt.m_scope_filtering_mode = block_private_uses;
}






CommandHelp::HelpMap& CommandHelp::get_help ()
{
  static CommandHelp& me = instance ();

  return (me.m_help);
}

CommandHelp::HelpTexts& CommandHelp::get_help_texts ()
{
  static CommandHelp& me = instance ();

  return (me.m_help_texts);
}

const cmt_string& CommandHelp::get_help_text (ActionType key)
{
  static const HelpTexts& help = get_help_texts ();

  const cmt_string& h = help[key];
  return (h);
}

void CommandHelp::show_all ()
{
  static HelpTexts& help_texts = get_help_texts ();

  cerr << "#> cmt command [option...]" << endl;
  cerr << "# command :" << endl;

  int i;

  for (i = 0; ; i++)
    {
      const cmt_string& s = help_texts[i];
      if (s == "") break;
      cerr << "#   " << s << endl;
    }

  cerr << "# global options :" << endl;

  cerr << "#   -quiet                  : don't print errors" << endl;
  cerr << "#   -use=<p>:<v>:<path>     : set package version path" << endl;
  cerr << "#   -pack=<package>         : set package" << endl;
  cerr << "#   -version=<version>      : set version" << endl;
  cerr << "#   -path=<path>            : set root path" << endl;
  cerr << "#   -f=<requirement-file>   : set input file" << endl;
  cerr << "#   -e=<statement>          : add a one line statement" << endl;
  cerr << "#   -tag=<tag-list>         : select a new tag-set" << endl;
  cerr << "#   -tag_add=<tag-list>     : add specific comma-separated tag(s)" << endl;
  cerr << "#   -tag_remove=<tag-list>  : remove specific comma-separated tag(s)" << endl;
  cerr << "#   -warnings               : display various warnings" << endl;
  cerr << "#   -with_version_directory : reset to default structuring style" << endl;
  cerr << "#   -without_version_directory : switch structuring style" << endl;
  cerr << "#   -cleanup                : activate install area cleanup" << endl;
  cerr << "#   -no_cleanup             : inhibit install area cleanup" << endl;
}

void CommandHelp::show (ActionType action)
{
  //cerr << "CommandHelp::show> action = " << action << endl;

  static HelpTexts& help_texts = get_help_texts ();

  if (action == action_build)
    {
      int i;

      for (i = action_build_constituent_makefile; i <= action_build_windefs; i++)
	{
	  const cmt_string& s = help_texts[i];
	  cerr << "#   " << s << endl;
	}
    }
  if (action == action_check)
    {
      int i;

      for (i = action_check_configuration; i <= action_check_version; i++)
	{
	  const cmt_string& s = help_texts[i];
	  cerr << "#   " << s << endl;
	}
    }
  else if (action == action_show)
    {
      int i;

      for (i = (action_show + 1); i <= action_show_versions; i++)
	{
	  const cmt_string& s = help_texts[i];
	  cerr << "#   " << s << endl;
	}
    }
  else
    {
      const cmt_string& s = get_help_text (action);
      cerr << "#" << s << endl;
    }
}

CommandHelp& CommandHelp::instance ()
{
  static CommandHelp me;
  return (me);
}

CommandHelp::CommandHelp ()
{
  static HelpMap& help = m_help;

  static HelpTexts& help_texts = m_help_texts;

  help_texts.clear ();

  help_texts.add () =  "none";
  help_texts.add () =  "awk";
  help_texts.add () =  "broadcast [-select=list] [-exclude=list] [-local] [-global] [-begin=pattern] [-depth=n] <command> : apply a command to [some of] the used packages";
  help_texts.add () =  "build <option>          : build actions. (Try cmt help build)";
  help_texts.add () =  "build constituent_makefile <constituent>  : generate constituent Makefile fragment";
  help_texts.add () =  "build constituents_makefile : generate constituents.make";
  help_texts.add () =  "build dependencies      : generate dependencies";
  help_texts.add () =  "build library_links     : build symbolic links towards all imported libraries";
  help_texts.add () =  "build make_setup        : build a compiled version of setup scripts";
  help_texts.add () =  "build msdev             : generate MSDEV files";
  help_texts.add () =  "build CMT_pacman        : generate PACMAN manifest file for CMT";
  help_texts.add () =  "build vsnet             : generate VS.NET files";
  help_texts.add () =  "build os9_makefile      : generate Makefile for OS9";
  help_texts.add () =  "build prototype         : generate prototype file";
  help_texts.add () =  "build readme            : generate README.html";
  help_texts.add () =  "build tag_makefile      : generate tag specific Makefile";
  help_texts.add () =  "build temporary_name    : generate a name for a temprary file";
  help_texts.add () =  "build triggers <constituent> : generate library trigger file";
  help_texts.add () =  "build windefs <library_name> : generate def file for Windows shared libraries";
  help_texts.add () =  "check <option>          : check actions. (Try cmt help check)";
  help_texts.add () =  "check configuration     : check configuration";
  help_texts.add () =  "check files <old> <new> : compare two files and overrides <old> by <new> if different";
  help_texts.add () =  "check version <name>    : check if a name follows a version tag syntax ";
  help_texts.add () =  "co | checkout           : perform a cvs checkout over a CMT package";
  help_texts.add () =  "cleanup [-csh|-sh|-bat] : generate a cleanup script";
  help_texts.add () =  "config                  : generate setup and cleanup scripts";
  help_texts.add () =  "create <package> <version> [<path>] : create and configure a new package";
  help_texts.add () =  "create_project <project> <name> [<path>] : create and configure a new project";
  help_texts.add () =  "cvsbranches <module>      : display the subdirectories for a module";
  help_texts.add () =  "cvssubpackages <module>   : display the subpackages for a module";
  help_texts.add () =  "cvssubprojects <module>   : display the subprojects for a module";
  help_texts.add () =  "cvstags <module>          : display the CVS tags for a module";
  help_texts.add () =  "do <action> [<param>=<value>] ... : Execute an action";
  help_texts.add () =  "expand model <model>    : ";
  help_texts.add () =  "filter <in> <out>       : filter a file against CMT macros and env. variables";
  help_texts.add () =  "help | -help | --help   : display this help";
  help_texts.add () =  "load";
  help_texts.add () =  "lock [<p> <v> [<path>]] : lock a package";
  help_texts.add () =  "remove <package> <version> [<path>] : remove a package version";
  help_texts.add () =  "remove library_links    : remove symbolic links towards all imported libraries";
  help_texts.add () =  "run '<command>'         : apply a command";
  help_texts.add () =  "run_sequence <sequence file> : execute a cmt equence file";
  help_texts.add () =  "set version <version>   : generate a version file in the current package";
  help_texts.add () =  "set versions            : generate version files into packages";
  help_texts.add () =  "setup [-csh|-sh|-bat]   : generate a setup script";
  help_texts.add () =  "show <option>           : query actions. (Try cmt help show)";
  help_texts.add () =  "show  action <name>     :  a formatted action definition";
  help_texts.add () =  "show  action_value <name> :  a raw action definition";
  help_texts.add () =  "show  action_names      :  all action names";
  help_texts.add () =  "show  actions           :  all action definitions";
  help_texts.add () =  "show  all_tags          :  all defined tags";
  help_texts.add () =  "show  applied_patterns  :  all patterns actually applied";
  help_texts.add () =  "show  author            :  package author";
  help_texts.add () =  "show  branches          :  added branches";
  help_texts.add () =  "show  clients           :  package clients";
  help_texts.add () =  "show  cmtpath_patterns  :  cmtpath_patterns";
  help_texts.add () =  "show  constituent <name>:  constituent definition";
  help_texts.add () =  "show  constituent_names :  constituent names";
  help_texts.add () =  "show  constituents      :  constituent definitions";
  help_texts.add () =  "show  cycles            :  cycles in the use graph";
  help_texts.add () =  "show  fragment <name>   :  one fragment definition";
  help_texts.add () =  "show  fragments         :  fragment definitions";
  help_texts.add () =  "show  groups            :  group definitions";
  help_texts.add () =  "show  include_dirs      :  ";
  help_texts.add () =  "show  language <name>   :  language definition";
  help_texts.add () =  "show  languages         :  language definitions";
  help_texts.add () =  "show  macro <name>      :  a formatted macro definition";
  help_texts.add () =  "show  macro_value <name>  :  a raw macro definition";
  help_texts.add () =  "show  macro_names       :  all macro names";
  help_texts.add () =  "show  macros            :  all macro definitions";
  help_texts.add () =  "show  manager           :  package manager";
  help_texts.add () =  "show  packages          :  packages reachable from the current context";
  help_texts.add () =  "show  path              :  the package search list";
  help_texts.add () =  "show  pattern <name>    :  the pattern definition and usages";
  help_texts.add () =  "show  pattern_names     :  pattern names";
  help_texts.add () =  "show  patterns          :  the pattern definitions";
  help_texts.add () =  "show  projects          :  project definitions";
  help_texts.add () =  "show  setup             :  setup definitions";
  help_texts.add () =  "show  pwd               :  filtered current directory";
  help_texts.add () =  "show  set <name>        :  a formatted set definition";
  help_texts.add () =  "show  set_names         :  set names";
  help_texts.add () =  "show  set_value <name>  :  a raw set definition";
  help_texts.add () =  "show  sets              :  set definitions";
  help_texts.add () =  "show  strategies        :  all strategies (build & version)";
  help_texts.add () =  "show  tags              :  all currently active tags";
  help_texts.add () =  "show  use_paths <pack>  :  all paths to the used package";
  help_texts.add () =  "show  uses              :  used packages";
  help_texts.add () =  "show  version           :  version of the current package";
  help_texts.add () =  "show  versions <name>   :  visible versions of the selected package";
  help_texts.add () =  "system                  : display the system tag";
  help_texts.add () =  "unlock [<p> <v> [<path>]] : unlock a package";
  help_texts.add () =  "version                 : version of CMT";
  help_texts.add () =  "";

  //"build <key>             : build various components :"
  //"show <key>              : display various infos on :"

  help.add (action_none, help_texts[action_none]);
  help.add (action_awk, help_texts[action_awk]);
  help.add (action_broadcast, help_texts[action_broadcast]);
  help.add (action_build, help_texts[action_build]);
  help.add (action_build_constituent_makefile, help_texts[action_build_constituent_makefile]);
  help.add (action_build_constituents_makefile, help_texts[action_build_constituents_makefile]);
  help.add (action_build_dependencies, help_texts[action_build_dependencies]);
  help.add (action_build_library_links, help_texts[action_build_library_links]);
  help.add (action_build_make_setup, help_texts[action_build_make_setup]);
  help.add (action_build_msdev, help_texts[action_build_msdev]);
  help.add (action_build_CMT_pacman, help_texts[action_build_CMT_pacman]);
  help.add (action_build_vsnet, help_texts[action_build_vsnet]);
  help.add (action_build_os9_makefile, help_texts[action_build_os9_makefile]);
  help.add (action_build_prototype, help_texts[action_build_prototype]);
  help.add (action_build_readme, help_texts[action_build_readme]);
  help.add (action_build_tag_makefile, help_texts[action_build_tag_makefile]);
  help.add (action_build_temporary_name, help_texts[action_build_temporary_name]);
  help.add (action_build_triggers, help_texts[action_build_triggers]);
  help.add (action_build_windefs, help_texts[action_build_windefs]);
  help.add (action_check_configuration, help_texts[action_check_configuration]);
  help.add (action_check_files, help_texts[action_check_files]);
  help.add (action_check_version, help_texts[action_check_version]);
  help.add (action_checkout, help_texts[action_checkout]);
  help.add (action_cleanup, help_texts[action_cleanup]);
  help.add (action_config, help_texts[action_config]);
  help.add (action_create, help_texts[action_create]);
  help.add (action_create_project, help_texts[action_create_project]);
  help.add (action_cvsbranches, help_texts[action_cvsbranches]);
  help.add (action_cvssubpackages, help_texts[action_cvssubpackages]);
  help.add (action_cvssubprojects, help_texts[action_cvssubprojects]);
  help.add (action_cvstags, help_texts[action_cvstags]);
  help.add (action_do, help_texts[action_do]);
  help.add (action_expand_model, help_texts[action_expand_model]);
  help.add (action_filter, help_texts[action_filter]);
  help.add (action_help, help_texts[action_help]);
  help.add (action_load, help_texts[action_load]);
  help.add (action_lock, help_texts[action_lock]);
  help.add (action_remove, help_texts[action_remove]);
  help.add (action_remove_library_links, help_texts[action_remove_library_links]);
  help.add (action_run, help_texts[action_run]);
  help.add (action_run_sequence, help_texts[action_run_sequence]);
  help.add (action_set_version, help_texts[action_set_version]);
  help.add (action_set_versions, help_texts[action_set_versions]);
  help.add (action_setup, help_texts[action_setup]);
  help.add (action_show, help_texts[action_show]);
  help.add (action_show_action, help_texts[action_show_action]);
  help.add (action_show_action_value, help_texts[action_show_action_value]);
  help.add (action_show_action_names, help_texts[action_show_action_names]);
  help.add (action_show_actions, help_texts[action_show_actions]);
  help.add (action_show_all_tags, help_texts[action_show_all_tags]);
  help.add (action_show_applied_patterns, help_texts[action_show_applied_patterns]);
  help.add (action_show_author, help_texts[action_show_author]);
  help.add (action_show_branches, help_texts[action_show_branches]);
  help.add (action_show_clients, help_texts[action_show_clients]);
  help.add (action_show_cmtpath_patterns, help_texts[action_show_cmtpath_patterns]);
  help.add (action_show_constituent, help_texts[action_show_constituent]);
  help.add (action_show_constituent_names, help_texts[action_show_constituent_names]);
  help.add (action_show_constituents, help_texts[action_show_constituents]);
  help.add (action_show_cycles, help_texts[action_show_cycles]);
  help.add (action_show_fragment, help_texts[action_show_fragment]);
  help.add (action_show_fragments, help_texts[action_show_fragments]);
  help.add (action_show_groups, help_texts[action_show_groups]);
  help.add (action_show_include_dirs, help_texts[action_show_include_dirs]);
  help.add (action_show_language, help_texts[action_show_language]);
  help.add (action_show_languages, help_texts[action_show_languages]);
  help.add (action_show_macro, help_texts[action_show_macro]);
  help.add (action_show_macro_value, help_texts[action_show_macro_value]);
  help.add (action_show_macro_names, help_texts[action_show_macro_names]);
  help.add (action_show_macros, help_texts[action_show_macros]);
  help.add (action_show_manager, help_texts[action_show_manager]);
  help.add (action_show_packages, help_texts[action_show_packages]);
  help.add (action_show_path, help_texts[action_show_path]);
  help.add (action_show_pattern, help_texts[action_show_pattern]);
  help.add (action_show_pattern_names, help_texts[action_show_pattern_names]);
  help.add (action_show_patterns, help_texts[action_show_patterns]);
  help.add (action_show_projects, help_texts[action_show_projects]);
  help.add (action_show_setup, help_texts[action_show_setup]);
  help.add (action_show_pwd, help_texts[action_show_pwd]);
  help.add (action_show_set, help_texts[action_show_set]);
  help.add (action_show_set_names, help_texts[action_show_set_names]);
  help.add (action_show_set_value, help_texts[action_show_set_value]);
  help.add (action_show_sets, help_texts[action_show_sets]);
  help.add (action_show_strategies, help_texts[action_show_strategies]);
  help.add (action_show_tags, help_texts[action_show_tags]);
  help.add (action_show_use_paths, help_texts[action_show_use_paths]);
  help.add (action_show_uses, help_texts[action_show_uses]);
  help.add (action_show_version, help_texts[action_show_version]);
  help.add (action_show_versions, help_texts[action_show_versions]);
  help.add (action_system, help_texts[action_system]);
  help.add (action_unlock, help_texts[action_unlock]);
  help.add (action_version, help_texts[action_version]);
}

