10 #include <IceUtil/DisableWarnings.h>
12 #include <Ice/ConsoleUtil.h>
18 # include <readline/readline.h>
19 # include <readline/history.h>
36 Ice::StringConverterPtr windowsConsoleConverter = 0;
44 class UnknownManagerException :
public Exception
48 UnknownManagerException(
const string& name,
const char* file,
int line) :
49 Exception(file, line),
54 #ifndef ICE_CPP11_COMPILER
56 ~UnknownManagerException()
throw()
64 return "::UnknownManagerException";
70 return new UnknownManagerException(*
this);
86 const map<Ice::Identity, TopicManagerPrx>& managers)
88 return new Parser(communicator, admin, managers);
95 "help Print this message.\n"
96 "exit, quit Exit this program.\n"
97 "create TOPICS Add TOPICS.\n"
98 "destroy TOPICS Remove TOPICS.\n"
99 "link FROM TO [COST] Link FROM to TO with the optional given COST.\n"
100 "unlink FROM TO Unlink TO from FROM.\n"
101 "links [INSTANCE-NAME] Display all links for the topics in the current topic\n"
102 " manager, or in the given INSTANCE-NAME.\n"
103 "topics [INSTANCE-NAME] Display the names of all topics in the current topic\n"
104 " manager, or in the given INSTANCE-NAME.\n"
105 "current [INSTANCE-NAME] Display the current topic manager, or change it to\n"
107 "replica [INSTANCE-NAME] Display replication information for the given INSTANCE-NAME.\n"
108 "subscribers TOPICS List TOPICS subscribers.\n"
113 Parser::create(
const list<string>& args)
117 error(
"`create' requires at least one argument (type `help' for more info)");
121 for (list<string>::const_iterator i = args.begin(); i != args.end() ; ++i)
127 manager->create(topicName);
129 catch (
const Ice::Exception& ex)
131 exception(ex, args.size() > 1);
137 Parser::destroy(
const list<string>& args)
141 error(
"`destroy' requires at least one argument (type `help' for more info)");
145 for (list<string>::const_iterator i = args.begin(); i != args.end() ; ++i)
149 findTopic(*i)->destroy();
151 catch (
const Ice::Exception& ex)
153 exception(ex, args.size() > 1);
159 Parser::link(
const list<string>& args)
161 if (args.size() != 2 && args.size() != 3)
163 error(
"`link' requires two or three arguments (type `help' for more info)");
169 list<string>::const_iterator p = args.begin();
171 TopicPrx fromTopic = findTopic(*p++);
173 Ice::Int cost = p != args.end() ? atoi(p->c_str()) : 0;
175 fromTopic->link(toTopic, cost);
177 catch (
const Exception& ex)
184 Parser::unlink(
const list<string>& args)
186 if (args.size() != 2)
188 error(
"`unlink' requires exactly two arguments (type `help' for more info)");
194 list<string>::const_iterator p = args.begin();
196 TopicPrx fromTopic = findTopic(*p++);
199 fromTopic->unlink(toTopic);
201 catch (
const Exception& ex)
208 Parser::links(
const list<string>& args)
212 error(
"`links' requires at most one argument (type `help' for more info)");
219 if (args.size() == 0)
221 manager = _defaultManager;
225 manager = findManagerByCategory(args.front());
228 TopicDict d = manager->retrieveAll();
229 for (TopicDict::iterator i = d.begin(); i != d.end(); ++i)
231 LinkInfoSeq links = i->second->getLinkInfoSeq();
232 for (LinkInfoSeq::const_iterator p = links.begin(); p != links.end(); ++p)
234 consoleOut << i->first <<
" to " << p->name <<
" with cost " << p->cost << endl;
238 catch (
const Exception& ex)
245 Parser::topics(
const list<string>& args)
249 error(
"`topics' requires at most one argument (type `help' for more info)");
256 if (args.size() == 0)
258 manager = _defaultManager;
262 manager = findManagerByCategory(args.front());
265 TopicDict d = manager->retrieveAll();
266 for (TopicDict::iterator i = d.begin(); i != d.end(); ++i)
268 consoleOut << i->first << endl;
271 catch (
const Exception& ex)
278 Parser::replica(
const list<string>& args)
282 error(
"`replica' requires at most one argument (type `help' for more info)");
289 if (args.size() == 0)
295 m = findManagerByCategory(args.front());
301 error(
"This topic is not replicated");
304 consoleOut <<
"replica count: " << nodes.size() << endl;
305 for (IceStormElection::NodeInfoSeq::const_iterator p = nodes.begin(); p != nodes.end(); ++p)
310 consoleOut << p->
id <<
": id: " << info.
id << endl;
311 consoleOut << p->id <<
": coord: " << info.
coord << endl;
312 consoleOut << p->id <<
": group name: " << info.
group << endl;
313 consoleOut << p->id <<
": state: ";
317 consoleOut <<
"inactive";
320 consoleOut <<
"election";
323 consoleOut <<
"reorganization";
326 consoleOut <<
"normal";
329 consoleOut <<
"unknown";
332 consoleOut << p->id <<
": group: ";
333 for (IceStormElection::GroupInfoSeq::const_iterator
q = info.
up.begin();
q != info.
up.end(); ++
q)
335 if (
q != info.
up.begin())
342 consoleOut << p->id <<
": max: " << info.
max
345 catch (
const Exception& ex)
347 consoleOut << p->id <<
": " << ex.ice_id() << endl;
351 catch (
const Exception& ex)
358 Parser::subscribers(
const list<string>& args)
362 error(
"subscribers' requires at least one argument (type `help' for more info) ");
367 for (list<string>::const_iterator i = args.begin(); i != args.end() ; ++i)
370 consoleOut << (*i) <<
": subscribers:" << endl;
371 IdentitySeq subscribers =
topic->getSubscribers();
372 for (IdentitySeq::const_iterator j = subscribers.begin(); j != subscribers.end(); ++j)
374 consoleOut <<
"\t" << _communicator->identityToString(*j) << endl;
378 catch (
const Exception& ex)
385 Parser::current(
const list<string>& args)
389 consoleOut << _communicator->identityToString(_defaultManager->ice_getIdentity()) << endl;
392 else if (args.size() > 1)
394 error(
"`current' requires at most one argument (type `help' for more info)");
402 _defaultManager = manager;
404 catch (
const Exception& ex)
413 consoleOut <<
"Ice " << ICE_STRING_VERSION <<
" Copyright (c) 2003-2017 ZeroC, Inc." << endl;
422 Parser::getInput(
char* buf,
int& result,
size_t maxSize)
424 size_t r =
static_cast<size_t>(result);
425 getInput(buf, r, maxSize);
426 result =
static_cast<int>(r);
430 Parser::getInput(
char* buf,
size_t& result,
size_t maxSize)
432 if (!_commands.empty())
434 if (_commands ==
";")
440 result =
min(maxSize, _commands.length());
441 strncpy(buf, _commands.c_str(), result);
442 _commands.erase(0, result);
443 if (_commands.empty())
454 char* line = readline(
const_cast<char*
>(prompt));
466 result = strlen(line) + 1;
467 if (result > maxSize)
470 error(
"input line too long");
488 char c =
static_cast<char>(getc(
yyin));
489 if (
c ==
static_cast<char>(EOF))
505 if (windowsConsoleConverter)
507 line = nativeToUTF8(line, windowsConsoleConverter);
510 result = line.length();
511 if (result > maxSize)
513 error(
"input line too long");
519 strcpy(buf, line.c_str());
527 Parser::continueLine()
535 assert(_commands.empty());
549 Parser::error(
const char*
s)
551 consoleErr <<
"error: " <<
s << endl;
556 Parser::error(
const string&
s)
562 Parser::warning(
const char*
s)
564 consoleErr <<
"warning: " <<
s << endl;
568 Parser::warning(
const string&
s)
574 Parser::invalidCommand(
const string&
s)
576 consoleErr <<
s << endl;
580 Parser::parse(FILE* file,
bool debug)
588 bool commands_empty = _commands.empty();
589 (void) commands_empty;
606 Parser::parse(
const std::string& commands,
bool debug)
614 _commands = commands;
615 assert(!_commands.empty());
631 Parser::findManagerById(
const string& full,
string& arg)
const
635 if (
id.category.empty())
637 return _defaultManager;
639 id.name =
"TopicManager";
640 map<Ice::Identity, TopicManagerPrx>::const_iterator p = _managers.find(
id);
641 if (p == _managers.end())
643 throw UnknownManagerException(
id.category, __FILE__, __LINE__);
649 Parser::findManagerByCategory(
const string& full)
const
653 id.name =
"TopicManager";
654 map<Ice::Identity, TopicManagerPrx>::const_iterator p = _managers.find(
id);
655 if (p == _managers.end())
657 throw UnknownManagerException(
id.category, __FILE__, __LINE__);
663 Parser::findTopic(
const string& full)
const
667 return manager->retrieve(topicName);
671 const map<Ice::Identity, TopicManagerPrx>& managers) :
672 _communicator(communicator),
673 _defaultManager(admin),
677 if (!windowsConsoleConverter)
679 windowsConsoleConverter = Ice::createWindowsStringConverter(GetConsoleOutputCP());
685 Parser::exception(
const Ice::Exception& ex,
bool warn)
692 catch (
const LinkExists& ex)
694 os <<
"link `" << ex.name <<
"' already exists";
696 catch (
const NoSuchLink& ex)
698 os <<
"couldn't find link `" << ex.name <<
"'";
700 catch (
const TopicExists& ex)
702 os <<
"topic `" << ex.name <<
"' exists";
704 catch (
const NoSuchTopic& ex)
706 os <<
"couldn't find topic `" << ex.name <<
"'";
708 catch (
const UnknownManagerException& ex)
710 os <<
"couldn't find IceStorm service `" << ex.name <<
"'";
712 catch (
const IdentityParseException& ex)
714 os <<
"invalid identity `" << ex.str <<
"'";
716 catch (
const Ice::LocalException& ex)
718 os <<
"couldn't reach IceStorm service:\n" << ex;
720 catch (
const Ice::Exception& ex)