102 std::map<std::string, PropertyItem>
data;
112 auto it =
data.find(key);
113 if (it ==
data.end()) {
121 auto entry =
data.find(key);
122 if (entry ==
data.end()) {
127 entry =
data.find(key);
130 return &(entry->second);
133 void put(
const std::string& key,
const std::string& val)
166 p->
backing = std::make_unique<Property>();
175 bool check(
const std::string& key)
const
178 if (
owner->getMonitor() !=
nullptr) {
181 report.isFound = (p !=
nullptr);
182 owner->reportToMonitor(report);
192 if (
owner->getMonitor() !=
nullptr) {
195 report.isFound =
true;
197 owner->reportToMonitor(report);
201 if (
owner->getMonitor() !=
nullptr) {
204 owner->reportToMonitor(report);
206 return Value::getNullValue();
265 bool qualified =
false;
266 for (
int i = 0; i < argc; i++) {
267 std::string work = argv[i];
269 if (work.length() >= 2) {
270 if (work[0] ==
'-' && work[1] ==
'-') {
271 work = work.substr(2, work.length() - 2);
273 if (work.find(
"::") != std::string::npos) {
285 if (work.find(
'\\') != std::string::npos) {
290 for (
char i : work) {
299 accum.
add(Value::makeValue(work));
312 for (
size_t i = 0; i < total.
size(); i++) {
315 if (term ==
nullptr) {
319 std::string base = key;
320 while (key.length() > 0) {
322 size_t at = key.find(
"::");
323 if (at != std::string::npos) {
324 base = key.substr(0, at);
325 key = key.substr(at + 2);
331 if (cursor ==
nullptr) {
341 if (cursor !=
nullptr) {
348 bool readDir(
const std::string& dirname, yarp::os::impl::DIR*& dir, std::string& result,
const std::string& section = std::string())
351 yCDebug(PROPERTY,
"reading directory %s", dirname.c_str());
353 yarp::os::impl::dirent** namelist;
354 yarp::os::impl::closedir(dir);
356 int n = yarp::os::impl::scandir(dirname.c_str(), &namelist,
nullptr, yarp::os::impl::alphasort);
360 for (
int i = 0; i < n; i++) {
361 std::string name = namelist[i]->d_name;
363 auto len =
static_cast<int>(name.length());
367 if (name.substr(len - 4) !=
".ini") {
370 std::string fname = std::string(dirname) +
"/" + name;
371 std::replace(fname.begin(), fname.end(),
'\\',
'/');
372 if (section.empty()) {
373 ok = ok &&
readFile(fname, result,
false);
376 result.append(
"[include ").append(section).append(
" \"").append(fname).append(
"\" \"").append(fname).append(
"\"]\n");
383 bool readFile(
const std::string& fname, std::string& result,
bool allowDir)
386 yarp::os::impl::DIR* dir = yarp::os::impl::opendir(fname.c_str());
387 if (dir !=
nullptr) {
388 return readDir(fname, dir, result);
391 yCDebug(PROPERTY,
"reading file %s", fname.c_str());
392 FILE* fin = fopen(fname.c_str(),
"r");
393 if (fin ==
nullptr) {
397 while (fgets(buf,
sizeof(buf) - 1, fin) !=
nullptr) {
407 std::string searchPath = env.
check(
"CONFIG_PATH",
409 "path to search for config files")
412 yCDebug(PROPERTY,
"looking for %s, search path: %s", fname.c_str(), searchPath.c_str());
414 std::string pathPrefix;
421 std::string trial = s;
425 yCDebug(PROPERTY,
"looking for %s as %s", fname.c_str(), trial.c_str());
438 size_t index = fname.rfind(
'/');
439 if (index == std::string::npos) {
440 index = fname.rfind(
'\\');
442 if (index != std::string::npos) {
443 path = fname.substr(0, index);
447 yCError(PROPERTY,
"cannot read from %s", fname.c_str());
454 if (searchPath.length() > 0) {
457 searchPath += pathPrefix;
459 envExtended.
put(
"CONFIG_PATH", searchPath);
466 bool fromConfigDir(
const std::string& dirname,
const std::string& section,
bool wipe =
true)
469 if (section.empty()) {
473 yCDebug(PROPERTY,
"looking for %s", dirname.c_str());
475 yarp::os::impl::DIR* dir = yarp::os::impl::opendir(dirname.c_str());
476 if (dir ==
nullptr) {
477 yCError(PROPERTY,
"cannot read from %s", dirname.c_str());
482 if (!
readDir(dirname, dir, txt, section)) {
483 yCError(PROPERTY,
"cannot read from %s", dirname.c_str());
504 bool including =
false;
508 while (good && !BottleImpl::isComplete(buf.c_str())) {
517 if (buf.find(
"//") != std::string::npos || buf.find(
'#') != std::string::npos) {
519 bool prespace =
true;
521 for (
unsigned int i = 0; i < buf.length(); i++) {
530 buf = buf.substr(0, i - 1);
535 if (ch ==
'#' && prespace) {
539 buf = buf.substr(0, i - 1);
544 prespace = (ch ==
' ' || ch ==
'\t');
555 if (buf.length() > 0 && buf[0] ==
'[') {
556 size_t stop = buf.find(
']');
557 if (stop != std::string::npos) {
558 buf = buf.substr(1, stop - 1);
559 size_t space = buf.find(
' ');
560 if (space != std::string::npos) {
563 if (bot.
size() > 1) {
569 if (accum.
size() >= 1) {
583 std::string fname = rf.
findFile(fileName);
584 yCTrace(PROPERTY,
"Importing: %s\n", fname.c_str());
589 yCWarning(PROPERTY,
"Unable to import file: %s from context %s\n", fileName.c_str(), contextName.c_str());
596 if (accum.
size() >= 1) {
601 if (bot.
size() > 2) {
604 if (bot.
size() == 3) {
610 }
else if (bot.
size() == 4) {
617 if (target ==
nullptr) {
627 yCError(PROPERTY,
"bad include");
642 yCTrace(PROPERTY,
">>> tag %s accum %s\n",
646 if (accum.
size() >= 1) {
660 yCTrace(PROPERTY,
"Including %s\n", fname.c_str());
667 if (bot.
size() == 2 && !including) {
671 if (target ==
nullptr) {
688 if (!isTag && !including) {
691 if (bot.
size() >= 1) {
697 for (
size_t i = 0; i < bot.
size(); i++) {
710 if (accum.
size() >= 1) {
723 "MERGE %s, got %s\n",
737 for (
size_t i = 0; i < bot.
size(); i++) {
749 for (
const auto& it :
data) {
761 yCTrace(PROPERTY,
"expanding %s\n", txt);
762 std::string input = txt;
763 if (input.find(
'$') == std::string::npos) {
771 bool varHasParen =
false;
773 for (
size_t i = 0; i <= input.length(); i++) {
775 if (i < input.length()) {
798 if ((isalnum(ch) != 0) || (ch ==
'_')) {
802 if (ch ==
'(' || ch ==
'{') {
803 if (var.length() == 0) {
810 yCTrace(PROPERTY,
"VARIABLE %s\n", var.c_str());
819 if (var ==
"__YARP__") {
823 if (add.find(
'\\') != std::string::npos) {
838 if (varHasParen && (ch ==
'}' || ch ==
')')) {
860 char** szarg =
new char*[128 + 1];
861 char* szcmd =
new char[strlen(command) + 1];
862 strcpy(szcmd, command);
865 szarg[nargs] =
nullptr;
876 char* pNext = azParam;
880 size_t len = strlen(azParam);
883 for (i = 0; i < len; i++) {
884 if ((quoted == 0) && (
'"' == azParam[i])) {
887 }
else if (((quoted) != 0) && (
'"' == azParam[i])) {
890 }
else if (((quoted) != 0) && (
' ' == azParam[i])) {
896 memset(argv, 0x00,
sizeof(
char*) * max_arg);
900 while ((
nullptr != pNext) && (*argc < max_arg)) {
904 if (
nullptr != argv[*argc]) {
909 for (j = 0; j < *argc; j++) {
910 len = strlen(argv[j]);
911 for (i = 0; i < len; i++) {
912 if (
'\1' == argv[j][i]) {
921 char* pTmp = strchr(line,
' ');
922 if (pTmp !=
nullptr) {
925 while (*pTmp ==
' ') {
936Property::Property() :
943#ifndef YARP_NO_DEPRECATED
976 prop.mPriv =
nullptr;
984 for (
const auto& val : values) {
985 put(val.first, val.second);
998 Portable::operator=(
static_cast<const Portable&
>(rhs));
999 mPriv->data = rhs.mPriv->data;
1000 mPriv->owner =
this;
1008 Portable::operator=(std::move(
static_cast<Portable&
>(rhs)));
1009 std::swap(mPriv, rhs.mPriv);
1010 mPriv->owner =
this;
1011 rhs.mPriv->owner = &rhs;
1017 mPriv->put(key, value);
1022 mPriv->put(key, value);
1028 mPriv->put(key, value);
1043 return mPriv->check(key);
1053 return mPriv->get(key);
1065 mPriv->fromString(txt, wipe);
1071 return mPriv->toString();
1080 mPriv->fromCommand(argc, argv, wipe);
1085 fromCommand(argc,
const_cast<char**
>(argv), skipFirst, wipe);
1090 mPriv->fromArguments(arguments, wipe);
1095 return mPriv->fromConfigDir(dirname, section, wipe);
1107 return mPriv->fromConfigFile(fname, env, wipe);
1118 mPriv->fromConfig(txt, env, wipe);
1126 bool ok = b.
read(reader);
1138 return b.
write(writer);
1144 Bottle* result = mPriv->getBottle(key);
1145 if (getMonitor() !=
nullptr) {
1146 SearchReport report;
1148 report.isGroup =
true;
1149 if (result !=
nullptr) {
1150 report.isFound =
true;
1153 reportToMonitor(report);
1154 if (result !=
nullptr) {
1155 std::string context = getMonitorContext();
1158 result->setMonitor(getMonitor(),
1163 if (result !=
nullptr) {
1175 std::string str = url;
1183 for (
char ch : str) {
1188 yCTrace(PROPERTY,
"adding key %s\n", key.c_str());
1189 }
else if (ch ==
'&') {
1190 yCTrace(PROPERTY,
"adding val %s\n", val.c_str());
1193 if (!key.empty() && !val.empty()) {
1197 }
else if (ch ==
'?') {
1202 }
else if (ch ==
'%') {
1207 if (ch >=
'0' && ch <=
'9') {
1210 if (ch >=
'A' && ch <=
'F') {
1211 hex = ch -
'A' + 10;
1213 if (ch >=
'a' && ch <=
'f') {
1214 hex = ch -
'a' + 10;
std::string toString() const
PropertyItem(PropertyItem &&rhs) noexcept=default
PropertyItem & operator=(const PropertyItem &rhs)
PropertyItem & operator=(PropertyItem &&rhs) noexcept=default
PropertyItem(const PropertyItem &rhs)
std::unique_ptr< Property > backing
void unput(const std::string &key)
void fromCommand(int argc, char *argv[], bool wipe=true)
void put(const std::string &key, const Value &bit)
Value & get(const std::string &key) const
Bottle * getBottle(const std::string &key) const
void parseArguments(char *azParam, int *argc, char **argv, int max_arg)
Property & addGroup(const std::string &key)
std::string toString() const
bool check(const std::string &key) const
void put(const std::string &key, const std::string &val)
void fromArguments(const char *command, bool wipe=true)
bool fromConfigDir(const std::string &dirname, const std::string §ion, bool wipe=true)
void fromConfig(const char *txt, Searchable &env, bool wipe=true)
void fromBottle(Bottle &bot, bool wipe=true)
Bottle & putBottle(const char *key)
void fromString(const std::string &txt, bool wipe=true)
std::map< std::string, PropertyItem > data
PropertyItem * getProp(const std::string &key, bool create=true)
bool fromConfigFile(const std::string &fname, Searchable &env, bool wipe=true)
PropertyItem * getPropNoCreate(const std::string &key) const
Bottle & putBottleCompat(const char *key, const Bottle &val)
bool readDir(const std::string &dirname, yarp::os::impl::DIR *&dir, std::string &result, const std::string §ion=std::string())
Bottle & putBottle(const char *key, const Bottle &val)
std::string expand(const char *txt, Searchable &env, Searchable &env2)
void put(const std::string &key, Value *bit)
bool readFile(const std::string &fname, std::string &result, bool allowDir)
void splitArguments(char *line, char **args)
A simple collection of objects that can be described and transmitted in a portable way.
static Bottle & getNullBottle()
A special Bottle with no content.
void add(const Value &value)
Add a Value to the bottle, at the end of the list.
void fromString(const std::string &text)
Initializes bottle from a string.
void append(const Bottle &alt)
Append the content of the given bottle to the current list.
Bottle & addList()
Places an empty nested list in the bottle, at the end of the list.
size_type size() const
Gets the number of elements in the bottle.
bool read(ConnectionReader &reader) override
Set the bottle's value based on input from a network connection.
Value & get(size_type index) const
Reads a Value v from a certain part of the list.
Bottle & findGroup(const std::string &key) const override
Gets a list corresponding to a given keyword.
void copy(const Bottle &alt, size_type first=0, size_type len=npos)
Copy all or part of another Bottle.
Bottle tail() const
Get all but the first element of a bottle.
void clear()
Empties the bottle of any objects it contains.
bool write(ConnectionWriter &writer) const override
Output a representation of the bottle to a network connection.
bool isNull() const override
Checks if the object is invalid.
void addString(const char *str)
Places a string in the bottle, at the end of the list.
std::string toString() const override
Gives a human-readable textual representation of the bottle.
An interface for reading from a network connection.
An interface for writing to a network connection.
This is a base class for objects that can be both read from and be written to the YARP network.
A class for storing options and configuration information.
Value & find(const std::string &key) const override
Gets a value corresponding to a given keyword.
std::string toString() const override
Return a standard text representation of the content of the object.
void fromString(const std::string &txt, bool wipe=true)
Interprets a string as a list of properties.
bool fromConfigFile(const std::string &fname, bool wipe=true)
Interprets a file as a list of properties.
void put(const std::string &key, const std::string &value)
Associate the given key with the given string.
void fromConfig(const char *txt, bool wipe=true)
Parses text in the configuration format described in fromConfigFile().
bool check(const std::string &key) const override
Check if there exists a property of the given name.
Property & operator=(const Property &prop)
Copy assignment operator.
bool write(ConnectionWriter &writer) const override
Write this object to a network connection.
bool read(ConnectionReader &reader) override
Read this object from a network connection.
bool fromConfigDir(const std::string &dirname, const std::string §ion=std::string(), bool wipe=true)
Interprets all files in a directory as lists of properties as described in fromConfigFile().
void clear()
Remove all associations.
void fromArguments(const char *arguments, bool wipe=true)
Interprets a list of command arguments as a list of properties.
~Property() override
Destructor.
Property & addGroup(const std::string &key)
Add a nested group.
Bottle & findGroup(const std::string &key) const override
Gets a list corresponding to a given keyword.
void fromQuery(const char *url, bool wipe=true)
Parses text in a url.
void unput(const std::string &key)
Remove the association from the given key to a value, if present.
void fromCommand(int argc, char *argv[], bool skipFirst=true, bool wipe=true)
Interprets a list of command arguments as a list of properties.
Helper class for finding config files and other external resources.
bool setDefaultContext(const std::string &contextName)
Sets the context for the current ResourceFinder object.
bool configure(int argc, char *argv[], bool skipFirstArgument=true)
Sets up the ResourceFinder.
std::string findFile(const std::string &name)
Find the full path to a file.
bool setDefaultConfigFile(const std::string &fname)
Provide a default value for the configuration file (can be overridden from command line with the –fro...
A base class for nested structures that can be searched.
virtual bool check(const std::string &key) const =0
Check if there exists a property of the given name.
virtual std::string toString() const =0
Return a standard text representation of the content of the object.
virtual Value & find(const std::string &key) const =0
Gets a value corresponding to a given keyword.
Searchable & operator=(const Searchable &rhs)=default
Copy assignment operator.
A single value (typically within a Bottle).
static Value * makeFloat64(yarp::conf::float64_t x)
Create a 64-bit floating point Value.
virtual bool isList() const
Checks if value is a list.
virtual Bottle * asList() const
Get list value.
std::string toString() const override
Return a standard text representation of the content of the object.
static Value * makeInt32(std::int32_t x)
Create a 32-bit integer Value.
virtual std::string asString() const
Get string value.
#define yCError(component,...)
#define yCAssert(component, x)
#define yCTrace(component,...)
#define yCWarning(component,...)
#define yCDebug(component,...)
#define YARP_OS_LOG_COMPONENT(name, name_string)
std::string get_string(const std::string &key, bool *found=nullptr)
Read a string from an environment variable.
ContainerT split(const typename ContainerT::value_type &s, std::basic_regex< typename ContainerT::value_type::value_type > regex)
Utility to split a string by a separator, into a vector of strings.
The components from which ports and connections are built.
An interface to the operating system, including Port based communication.