78 std::map<std::string, PropertyItem>
data;
85 auto it = data.find(key);
93 auto entry = data.find(key);
94 if (entry == data.end()) {
99 entry = data.find(key);
102 return &(entry->second);
105 void put(
const std::string& key,
const std::string& val) {
114 void put(
const std::string& key,
const Value& bit) {
150 void unput(
const std::string& key) {
154 bool check(
const std::string& key)
const {
156 if (owner.getMonitor()!=
nullptr) {
159 report.isFound = (p!=
nullptr);
160 owner.reportToMonitor(report);
165 Value&
get(
const std::string& key)
const {
170 if (owner.getMonitor()!=
nullptr) {
173 report.isFound =
true;
175 owner.reportToMonitor(report);
179 if (owner.getMonitor()!=
nullptr) {
182 owner.reportToMonitor(report);
192 return putBottle(key, b);
194 return putBottle(key, val);
231 fromBottle(bot, wipe);
238 bool qualified =
false;
239 for (
int i=0; i<argc; i++) {
240 std::string work = argv[i];
242 if (work.length()>=2) {
243 if (work[0]==
'-'&&work[1]==
'-') {
244 work = work.substr(2, work.length()-2);
246 if (work.find(
"::")!=std::string::npos) {
258 if (work.find(
'\\')!=std::string::npos) {
263 for (
char i : work) {
278 fromBottle(total, wipe);
285 for (
size_t i=0; i<total.
size(); i++) {
290 std::string base = key;
291 while (key.length()>0) {
293 size_t at = key.find(
"::");
294 if (at != std::string::npos) {
295 base = key.substr(0, at);
296 key = key.substr(at+2);
303 cursor = &putBottle((base).c_str());
319 bool readDir(
const std::string& dirname, yarp::os::impl::DIR *&dir, std::string& result,
const std::string& section=std::string()) {
322 std::string(
"reading directory ") + dirname);
324 yarp::os::impl::dirent **namelist;
325 yarp::os::impl::closedir(dir);
327 int n = yarp::os::impl::scandir(dirname.c_str(), &namelist,
nullptr, yarp::os::impl::alphasort);
331 for (
int i=0; i<n; i++) {
332 std::string name = namelist[i]->d_name;
334 int len = (int)name.length();
336 if (name.substr(len-4)!=
".ini")
continue;
337 std::string fname = std::string(dirname) +
"/" + name;
338 std::replace(fname.begin(), fname.end(),
'\\',
'/');
339 if (section.empty()) {
340 ok = ok && readFile(fname, result,
false);
343 result.append(
"[include ").append(section).append(
" \"").append(fname).append(
"\" \"").append(fname).append(
"\"]\n");
350 bool readFile(
const std::string& fname, std::string& result,
bool allowDir) {
352 yarp::os::impl::DIR *dir = yarp::os::impl::opendir(fname.c_str());
353 if (dir)
return readDir(fname, dir, result);
356 std::string(
"reading file ") + fname);
357 FILE *fin = fopen(fname.c_str(),
"r");
362 while(fgets(buf,
sizeof(buf)-1, fin) !=
nullptr) {
371 std::string searchPath =
372 env.
check(
"CONFIG_PATH",
374 "path to search for config files").toString();
377 std::string(
"looking for ") + fname +
", search path: " +
380 std::string pathPrefix;
384 if (!readFile(fname, txt,
true)) {
387 for (
int i=0; i<ss.size(); i++) {
388 std::string trial = ss.
get(i);
393 std::string(
"looking for ").append(fname).append(
" as ").append(trial));
396 if (readFile(trial, txt,
true)) {
398 pathPrefix = ss.get(i);
406 size_t index = fname.rfind(
'/');
407 if (index==std::string::npos) {
408 index = fname.rfind(
'\\');
410 if (index!=std::string::npos) {
411 path = fname.substr(0, index);
423 if (searchPath.length()>0) {
426 searchPath += pathPrefix;
428 envExtended.
put(
"CONFIG_PATH", searchPath);
431 fromConfig(txt.c_str(), envExtended, wipe);
435 bool fromConfigDir(
const std::string& dirname,
const std::string& section,
bool wipe=
true) {
437 if (section.empty()) {
438 return fromConfigFile(dirname, p, wipe);
443 yarp::os::impl::DIR *dir = yarp::os::impl::opendir(dirname.c_str());
450 if (!readDir(dirname, dir, txt, section)) {
455 fromConfig(txt.c_str(), p, wipe);
471 bool including =
false;
484 if (buf.find(
"//")!=std::string::npos||buf.find(
'#')!=std::string::npos) {
486 bool prespace =
true;
488 for (
unsigned int i=0; i<buf.length(); i++) {
490 if (ch==
'\"') { quoted = !quoted; }
495 buf = buf.substr(0, i-1);
500 if (ch==
'#'&&prespace) {
504 buf = buf.substr(0, i-1);
509 prespace = (ch==
' '||ch==
'\t');
518 buf = expand(buf.c_str(), env, owner);
520 if (buf.length()>0 && buf[0]==
'[') {
521 size_t stop = buf.find(
']');
522 if (stop!=std::string::npos) {
523 buf = buf.substr(1, stop-1);
524 size_t space = buf.find(
' ');
525 if (space!=std::string::npos) {
534 if (accum.
size()>=1) {
535 putBottleCompat(tag.c_str(),
542 std::string subName, fname;
549 }
else if (bot.
size()==4) {
555 Bottle *target = getBottle(key);
556 if (target==
nullptr) {
560 putBottleCompat(key.c_str(),
567 std::string(
"bad include"));
573 if (getBottle(subName)!=
nullptr) {
585 if (accum.
size()>=1) {
591 putBottleCompat(tag.c_str(),
601 fromConfigFile(fname, env,
false);
607 if (bot.
size()==2 && !including) {
610 Bottle *target = getBottle(key);
611 if (target==
nullptr) {
615 putBottleCompat(key.c_str(), init);
628 if (!isTag && !including) {
633 putBottleCompat(bot.
get(0).
toString().c_str(), bot);
637 for (
size_t i=0; i<bot.
size(); i++) {
650 if (accum.
size()>=1) {
651 putBottleCompat(tag.c_str(), accum);
659 if (getBottle(tag)!=
nullptr) {
661 accum.
append(getBottle(tag)->tail());
674 for (
size_t i=0; i<bot.
size(); i++) {
685 for (
const auto& it : data) {
697 std::string input = txt;
698 if (input.find(
'$')==std::string::npos) {
706 bool varHasParen =
false;
708 for (
int i=0; i<=(int)input.length(); i++) {
710 if (i<(
int)input.length()) {
734 if (isalnum(ch)||(ch==
'_')) {
738 if (ch==
'('||ch==
'{') {
739 if (var.length()==0) {
755 if (var==
"__YARP__") {
759 if (add.find(
'\\')!=std::string::npos) {
774 if (varHasParen && (ch==
'}'||ch==
')')) {
797 char** szarg =
new char*[128 + 1];
798 char* szcmd =
new char[strlen(command)+1];
799 strcpy(szcmd, command);
802 szarg[nargs]=
nullptr;
803 fromCommand(nargs, szarg, wipe);
812 char *pNext = azParam;
816 size_t len = strlen(azParam);
819 for(i = 0; i < len; i++) {
820 if ((!quoted) && (
'"' == azParam [i])) {
823 }
else if ((quoted) && (
'"' == azParam [i])) {
826 }
else if ((quoted) && (
' ' == azParam [i])) {
832 memset(argv, 0x00,
sizeof(
char*) * max_arg);
836 while ((
nullptr != pNext) && (*argc < max_arg)) {
837 splitArguments(pNext, &(argv[*argc]));
840 if (
nullptr != argv[*argc]) {
845 for(j = 0; j < *argc; j++) {
846 len = strlen(argv[j]);
847 for(i = 0; i < len; i++) {
848 if (
'\1' == argv[j][i]) {
856 char *pTmp = strchr(line,
' ');
860 while ((*pTmp) && (*pTmp ==
' ')) {
875 #define HELPER(x) (*((PropertyHelper*)(x))) 879 this->hash_size = hash_size;
954 if (!
check())
return false;
984 if (!
check())
return {};
1000 fromCommand(argc, (
char **)argv, skipFirst, wipe);
1040 bool ok = b.
read(reader);
1051 return b.
write(writer);
1058 if (getMonitor()!=
nullptr) {
1059 SearchReport report;
1061 report.isGroup =
true;
1062 if (result !=
nullptr) {
1063 report.isFound =
true;
1066 reportToMonitor(report);
1067 if (result !=
nullptr) {
1068 std::string context = getMonitorContext();
1071 result->setMonitor(getMonitor(),
1076 if (result!=((
Bottle*)
nullptr)) {
return *result; }
1086 std::string str = url;
1094 for (
char ch : str) {
1100 }
else if (ch==
'&') {
1104 if (key!=
"" && val!=
"") {
1108 }
else if (ch==
'?') {
1113 }
else if (ch==
'%') {
1118 if (ch>=
'0'&&ch<=
'9') { hex = ch-
'0'; }
1119 if (ch>=
'A'&&ch<=
'F') { hex = ch-
'A'+10; }
1120 if (ch>=
'a'&&ch<=
'f') { hex = ch-
'a'+10; }
const Property & operator=(const Property &prop)
Assignment operator.
std::string expand(const char *txt, Searchable &env, Searchable &env2)
void fromString(const std::string &text)
Initializes bottle from a string.
void splitArguments(char *line, char **args)
void append(const Bottle &alt)
Append the content of the given bottle to the current list.
void unput(const std::string &key)
bool fromConfigFile(const std::string &fname, Searchable &env, bool wipe=true)
void put(const std::string &key, const Value &bit)
std::string toString() const override
Return a standard text representation of the content of the object.
Bottle & putBottle(const char *key)
#define YARP_DEBUG(log, x)
void parseArguments(char *azParam, int *argc, char **argv, int max_arg)
A class for storing options and configuration information.
Bottle & putBottle(const char *key, const Bottle &val)
static Value & getNullValue()
Return an invalid, "null" Value.
PropertyItem * getPropNoCreate(const std::string &key) const
A base class for nested structures that can be searched.
This is a base class for objects that can be both read from and be written to the YARP network...
Property & addGroup(const std::string &key)
void addString(const char *str)
Places a string in the bottle, at the end of the list.
void parseArguments(char *io_pLine, int *o_pArgc, char **o_pArgv)
Breaks up a line into multiple arguments.
bool readFile(const std::string &fname, std::string &result, bool allowDir)
void add(const Value &value)
Add a Value to the bottle, at the end of the list.
std::string toString() const override
Return a standard text representation of the content of the object.
virtual bool check(const std::string &key) const =0
Check if there exists a property of the given name.
void copy(const Bottle &alt, int first=0, int len=-1)
Copy all or part of another Bottle.
virtual std::string toString() const =0
Return a standard text representation of the content of the object.
virtual std::string asString() const
Get string value.
void put(const std::string &key, const std::string &val)
Bottle & findGroup(const std::string &key) const override
Gets a list corresponding to a given keyword.
void fromConfig(const char *txt, bool wipe=true)
Parses text in the configuration format described in fromConfigFile().
Bottle & putBottleCompat(const char *key, const Bottle &val)
Bottle * getBottle(const std::string &key) const
An interface for writing to a network connection.
void clear()
Empties the bottle of any objects it contains.
static Value * makeInt32(std::int32_t x)
Create a 32-bit integer Value.
Value & find(const std::string &key) const override
Gets a value corresponding to a given keyword.
void fromArguments(const char *command, bool wipe=true)
virtual Bottle * asList() const
Get list value.
std::string toString() const
Split a string into pieces.
void fromBottle(Bottle &bot, bool wipe=true)
bool write(ConnectionWriter &writer) const override
Output a representation of the bottle to a network connection.
static std::string getEnvironment(const char *key, bool *found=nullptr)
Read a variable from the environment.
A simple collection of objects that can be described and transmitted in a portable way...
void unput(const std::string &key)
Remove the association from the given key to a value, if present.
Bottle & findGroup(const std::string &key) const override
Gets a list corresponding to a given keyword.
#define YARP_ERROR(log, x)
Bottle tail() const
Get all but the first element of a bottle.
std::map< std::string, PropertyItem > data
bool readDir(const std::string &dirname, yarp::os::impl::DIR *&dir, std::string &result, const std::string §ion=std::string())
Bottle & addList()
Places an empty nested list in the bottle, at the end of the list.
static Value * makeFloat64(yarp::conf::float64_t x)
Create a 64-bit floating point Value.
An interface for reading from a network connection.
static bool isComplete(const char *txt)
virtual ~Property()
Destructor.
void fromCommand(int argc, char *argv[], bool wipe=true)
virtual Value & find(const std::string &key) const =0
Gets a value corresponding to a given keyword.
void fromQuery(const char *url, bool wipe=true)
Parses text in a url.
PropertyHelper(Property &owner, int hash_size)
bool fromConfigDir(const std::string &dirname, const std::string §ion, bool wipe=true)
std::string toString() const override
Gives a human-readable textual representation of the bottle.
A single value (typically within a Bottle).
static Bottle & getNullBottle()
A special Bottle with no content.
RandScalar * implementation(void *t)
bool read(ConnectionReader &reader) override
Set the bottle's value based on input from a network connection.
PropertyItem * getProp(const std::string &key, bool create=true)
void fromString(const std::string &txt, bool wipe=true)
Interprets a string as a list of properties.
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.
bool check(const std::string &key, Value *&output) const
std::string toString() const
const char * get(int idx)
void put(const std::string &key, Value *bit)
static Value * makeValue(const std::string &txt)
Create a Value from a text description.
An interface to the operating system, including Port based communication.
bool isNull() const override
Checks if the object is invalid.
bool write(ConnectionWriter &writer) const override
Write this object to a network connection.
void fromString(const std::string &txt, bool wipe=true)
virtual bool isList() const
Checks if value is a list.
void fromConfig(const char *txt, Searchable &env, bool wipe=true)
Property & addGroup(const std::string &key)
Add a nested group.
bool read(ConnectionReader &reader) override
Read this object from a network connection.
std::string toString(const T &value)
convert an arbitrary type to string.
The components from which ports and connections are built.
void fromArguments(const char *arguments, bool wipe=true)
Interprets a list of command arguments as a list of properties.
Property(int hash_size=0)
Constructor.
bool fromConfigFile(const std::string &fname, bool wipe=true)
Interprets a file as a list of properties.
size_t size() const
Gets the number of elements in the bottle.
void put(const std::string &key, const std::string &value)
Associate the given key with the given string.
bool check(const std::string &key) const
void fromCommand(int argc, char *argv[], bool skipFirst=true, bool wipe=true)
Interprets a list of command arguments as a list of properties.
Value & get(size_t index) const
Reads a Value v from a certain part of the list.