12 #include <Ice/ConsoleUtil.h>
16 #include <IceUtil/DisableWarnings.h>
19 #include <readline/history.h>
20 #include <readline/readline.h>
37 Ice::StringConverterPtr windowsConsoleConverter = 0;
45 class UnknownManagerException :
public Exception
48 UnknownManagerException(
const string& name,
const char* file,
int line) :
49 Exception(file, line), name(name)
53 #ifndef ICE_CPP11_COMPILER
54 virtual ~UnknownManagerException()
throw()
62 return "::UnknownManagerException";
68 return new UnknownManagerException(*
this);
85 const map<Ice::Identity, TopicManagerPrx>& managers)
87 return new Parser(communicator, admin, managers);
94 <<
"help Print this message.\n"
95 "exit, quit Exit this program.\n"
96 "create TOPICS Add TOPICS.\n"
97 "destroy TOPICS Remove TOPICS.\n"
98 "link FROM TO [COST] Link FROM to TO with the optional given COST.\n"
99 "unlink FROM TO Unlink TO from FROM.\n"
100 "links [INSTANCE-NAME] Display all links for the topics in the current topic\n"
101 " manager, or in the given INSTANCE-NAME.\n"
102 "topics [INSTANCE-NAME] Display the names of all topics in the current topic\n"
103 " manager, or in the given INSTANCE-NAME.\n"
104 "current [INSTANCE-NAME] Display the current topic manager, or change it to\n"
106 "replica [INSTANCE-NAME] Display replication information for the given INSTANCE-NAME.\n"
107 "subscribers TOPICS List TOPICS subscribers.\n";
111 Parser::create(
const list<string>& args)
115 error(
"`create' requires at least one argument (type `help' for more info)");
119 for (list<string>::const_iterator i = args.begin(); i != args.end(); ++i)
125 manager->create(topicName);
127 catch (
const Ice::Exception& ex)
138 Parser::destroy(
const list<string>& args)
142 error(
"`destroy' requires at least one argument (type `help' for more info)");
146 for (list<string>::const_iterator i = args.begin(); i != args.end(); ++i)
150 findTopic(*i)->destroy();
152 catch (
const Ice::Exception& ex)
163 Parser::link(
const list<string>& args)
165 if (args.size() != 2 && args.size() != 3)
167 error(
"`link' requires two or three arguments (type `help' for more info)");
173 list<string>::const_iterator p = args.begin();
175 TopicPrx fromTopic = findTopic(*p++);
177 Ice::Int cost = p != args.end() ? atoi(p->c_str()) : 0;
179 fromTopic->link(toTopic, cost);
181 catch (
const Exception& ex)
188 Parser::unlink(
const list<string>& args)
190 if (args.size() != 2)
192 error(
"`unlink' requires exactly two arguments (type `help' for more info)");
198 list<string>::const_iterator p = args.begin();
200 TopicPrx fromTopic = findTopic(*p++);
203 fromTopic->unlink(toTopic);
205 catch (
const Exception& ex)
212 Parser::links(
const list<string>& args)
216 error(
"`links' requires at most one argument (type `help' for more info)");
223 if (args.size() == 0)
225 manager = _defaultManager;
229 manager = findManagerByCategory(args.front());
232 TopicDict d = manager->retrieveAll();
233 for (TopicDict::iterator i = d.begin(); i != d.end(); ++i)
235 LinkInfoSeq links = i->second->getLinkInfoSeq();
236 for (LinkInfoSeq::const_iterator p = links.begin(); p != links.end(); ++p)
238 consoleOut << i->first <<
" to " << p->name <<
" with cost " << p->cost << endl;
242 catch (
const Exception& ex)
249 Parser::topics(
const list<string>& args)
253 error(
"`topics' requires at most one argument (type `help' for more info)");
260 if (args.size() == 0)
262 manager = _defaultManager;
266 manager = findManagerByCategory(args.front());
269 TopicDict d = manager->retrieveAll();
270 for (TopicDict::iterator i = d.begin(); i != d.end(); ++i)
272 consoleOut << i->first << endl;
275 catch (
const Exception& ex)
282 Parser::replica(
const list<string>& args)
286 error(
"`replica' requires at most one argument (type `help' for more info)");
293 if (args.size() == 0)
299 m = findManagerByCategory(args.front());
305 error(
"This topic is not replicated");
308 consoleOut <<
"replica count: " << nodes.size() << endl;
309 for (IceStormElection::NodeInfoSeq::const_iterator p = nodes.begin(); p != nodes.end(); ++p)
314 consoleOut << p->
id <<
": id: " << info.
id << endl;
315 consoleOut << p->id <<
": coord: " << info.
coord << endl;
316 consoleOut << p->id <<
": group name: " << info.
group << endl;
317 consoleOut << p->id <<
": state: ";
321 consoleOut <<
"inactive";
324 consoleOut <<
"election";
327 consoleOut <<
"reorganization";
330 consoleOut <<
"normal";
333 consoleOut <<
"unknown";
336 consoleOut << p->id <<
": group: ";
337 for (IceStormElection::GroupInfoSeq::const_iterator
q = info.
up.begin();
341 if (
q != info.
up.begin())
348 consoleOut << p->id <<
": max: " << info.
max << endl;
350 catch (
const Exception& ex)
352 consoleOut << p->id <<
": " << ex.ice_id() << endl;
356 catch (
const Exception& ex)
363 Parser::subscribers(
const list<string>& args)
367 error(
"subscribers' requires at least one argument (type `help' for more info) ");
372 for (list<string>::const_iterator i = args.begin(); i != args.end(); ++i)
375 consoleOut << (*i) <<
": subscribers:" << endl;
376 IdentitySeq subscribers =
topic->getSubscribers();
377 for (IdentitySeq::const_iterator j = subscribers.begin(); j != subscribers.end(); ++j)
379 consoleOut <<
"\t" << _communicator->identityToString(*j) << endl;
383 catch (
const Exception& ex)
390 Parser::current(
const list<string>& args)
394 consoleOut << _communicator->identityToString(_defaultManager->ice_getIdentity()) << endl;
397 else if (args.size() > 1)
399 error(
"`current' requires at most one argument (type `help' for more info)");
407 _defaultManager = manager;
409 catch (
const Exception& ex)
418 consoleOut <<
"Ice " << ICE_STRING_VERSION <<
" Copyright (c) 2003-2017 ZeroC, Inc." << endl;
427 Parser::getInput(
char* buf,
int& result,
size_t maxSize)
429 size_t r =
static_cast<size_t>(result);
430 getInput(buf, r, maxSize);
431 result =
static_cast<int>(r);
435 Parser::getInput(
char* buf,
size_t& result,
size_t maxSize)
437 if (!_commands.empty())
439 if (_commands ==
";")
445 result =
min(maxSize, _commands.length());
446 strncpy(buf, _commands.c_str(), result);
447 _commands.erase(0, result);
448 if (_commands.empty())
459 char* line = readline(
const_cast<char*
>(prompt));
471 result = strlen(line) + 1;
472 if (result > maxSize)
475 error(
"input line too long");
493 char c =
static_cast<char>(getc(
yyin));
494 if (
c ==
static_cast<char>(EOF))
510 if (windowsConsoleConverter)
512 line = nativeToUTF8(line, windowsConsoleConverter);
515 result = line.length();
516 if (result > maxSize)
518 error(
"input line too long");
524 strcpy(buf, line.c_str());
532 Parser::continueLine()
540 assert(_commands.empty());
554 Parser::error(
const char*
s)
556 consoleErr <<
"error: " <<
s << endl;
561 Parser::error(
const string&
s)
567 Parser::warning(
const char*
s)
569 consoleErr <<
"warning: " <<
s << endl;
573 Parser::warning(
const string&
s)
579 Parser::invalidCommand(
const string&
s)
581 consoleErr <<
s << endl;
585 Parser::parse(FILE* file,
bool debug)
593 bool commands_empty = _commands.empty();
594 (void)commands_empty;
611 Parser::parse(
const std::string& commands,
bool debug)
619 _commands = commands;
620 assert(!_commands.empty());
636 Parser::findManagerById(
const string& full,
string& arg)
const
640 if (
id.category.empty())
642 return _defaultManager;
644 id.name =
"TopicManager";
645 map<Ice::Identity, TopicManagerPrx>::const_iterator p = _managers.find(
id);
646 if (p == _managers.end())
648 throw UnknownManagerException(
id.category, __FILE__, __LINE__);
654 Parser::findManagerByCategory(
const string& full)
const
658 id.name =
"TopicManager";
659 map<Ice::Identity, TopicManagerPrx>::const_iterator p = _managers.find(
id);
660 if (p == _managers.end())
662 throw UnknownManagerException(
id.category, __FILE__, __LINE__);
668 Parser::findTopic(
const string& full)
const
672 return manager->retrieve(topicName);
677 const map<Ice::Identity, TopicManagerPrx>& managers) :
678 _communicator(communicator), _defaultManager(admin), _managers(managers)
681 if (!windowsConsoleConverter)
683 windowsConsoleConverter = Ice::createWindowsStringConverter(GetConsoleOutputCP());
689 Parser::exception(
const Ice::Exception& ex,
bool warn)
696 catch (
const LinkExists& ex)
698 os <<
"link `" << ex.name <<
"' already exists";
700 catch (
const NoSuchLink& ex)
702 os <<
"couldn't find link `" << ex.name <<
"'";
704 catch (
const TopicExists& ex)
706 os <<
"topic `" << ex.name <<
"' exists";
708 catch (
const NoSuchTopic& ex)
710 os <<
"couldn't find topic `" << ex.name <<
"'";
712 catch (
const UnknownManagerException& ex)
714 os <<
"couldn't find IceStorm service `" << ex.name <<
"'";
716 catch (
const IdentityParseException& ex)
718 os <<
"invalid identity `" << ex.str <<
"'";
720 catch (
const Ice::LocalException& ex)
722 os <<
"couldn't reach IceStorm service:\n" << ex;
724 catch (
const Ice::Exception& ex)