Esempio n. 1
0
/**
 * Look for sections set up to inherit from a base section
 * and copy the missing parameters
 *
 *   [sub/seciton]
 *   inherit = base/section
 */
void config::copy_inherited() {
  for (auto&& section : m_sections) {
    for (auto&& param : section.second) {
      if (param.first.find("inherit") == 0) {
        // Get name of base section
        auto inherit = param.second;
        if ((inherit = dereference<string>(section.first, param.first, inherit, inherit)).empty()) {
          throw value_error("Invalid section \"\" defined for \"" + section.first + ".inherit\"");
        }

        // Find and validate base section
        auto base_section = m_sections.find(inherit);
        if (base_section == m_sections.end()) {
          throw value_error("Invalid section \"" + inherit + "\" defined for \"" + section.first + ".inherit\"");
        }

        m_log.trace("config: Copying missing params (sub=\"%s\", base=\"%s\")", section.first, inherit);

        // Iterate the base and copy the parameters
        // that hasn't been defined for the sub-section
        for (auto&& base_param : base_section->second) {
          section.second.insert(make_pair(base_param.first, base_param.second));
        }
      }
    }
  }
}
Esempio n. 2
0
value value_tail(value op)
{
	if (op.type == VALUE_ARY) {
		size_t length = value_length(op);
		if (length == 0) {
			value_error(1, "Error: cannot find tail() of an empty array.");
			return value_init_error();
		}
		
		value array[length - 1];
		size_t i;
		for (i = 0; i < length-1; ++i)
			array[i] = op.core.u_a.a[i+1];
		
		value res = value_set_ary(array, length-1);
		
		return res;
		
	} else if (op.type == VALUE_LST) {		
		return value_set(op.core.u_l[1]);
		
	} else if (op.type == VALUE_PAR) {
		return value_set(op.core.u_p->tail);
	} else {
		value_error(1, "Type Error: tail() is undefined where op is %ts (array or list expected).", op);
		return value_init_error();
	}

}
Esempio n. 3
0
value value_cons(value op1, value op2)
{
	value res = value_init_nil();
	if (op2.type == VALUE_NIL) {
		res = value_init(VALUE_PAR);
		res.core.u_p->head = value_set(op1);
	} else if (op2.type == VALUE_ARY) {
		size_t length = value_length(op2) + 1;
		value array[length];
		array[0] = op1;
		size_t i;
		for (i = 1; i < length; ++i)
			array[i] = op2.core.u_a.a[i-1];
		res = value_set_ary(array, length);
	} else if (op2.type == VALUE_LST) {
		res = value_init(VALUE_LST);
		res.core.u_l[0] = value_set(op1);
		res.core.u_l[1] = value_set(op2);
	} else if (op2.type == VALUE_PAR) {
		res = value_init(VALUE_PAR);
		res.core.u_l[0] = value_set(op1);
		res.core.u_l[1] = value_set(op2);
	} else {
		value_error(1, "Type Error: cons() is undefined where op2 is %ts (nil, array or list expected).", op2);
		res = value_init_error();
	}
	
	return res;
}
Esempio n. 4
0
    /**
     *  @brief Deserialize the integer value from the specified input stream.
     *  @param __s  Reference to the input stream.
     */
    void
    load(std::basic_istream<CharT, Traits> &__s)
    {
        // We must ensure that subsequent actions will be performed
        // for very likely integer value, otherwise and exception
        // should be raised.
        if (__s.peek() != basic_value_type::integer_token) {
            throw type_error(
                "bencode::integer::load the specified stream does "
                "not contain interpretable bencode integer value\n");
        }

        // Read the leading "i" symbol from the provided stream.
        __s.get();

        // Define the integer symbol representation placeholder.
        std::basic_stringstream<CharT, Traits> __i;

        // Define the input stream iterator of the provided stream to
        // be able to read the integer value symbol by symbol.
        auto __si = std::istream_iterator<CharT, CharT, Traits>(__s);

        // Define the output stream to as a buffer for the integer
        // value, which will be later converted.
        auto __ival = std::ostream_iterator<CharT, CharT, Traits>(__i);

        // Copy the values from the input stream into the integer
        // placeholder string stream.
        auto __result = copy_until(__si, __ival,
            [&__s](const CharT& __ch) {

            // Additionally, check that we did not exceed the
            // length of the stream to prevent hangs.
            return !__s.eof() && __ch != basic_value_type::end_token;
        }, basic_value_type::integer_length);

        // Covert the value from the string into the integer.
        __i >> _M_value;

        // The "e" symbol should be already extracted at this moment,
        // so validate that the iterator pointing right to it.
        if (*__result != basic_value_type::end_token) {
            std::ostringstream __error;

            __error << "bencode::integer::load the end of the integer "
                "`e` expected, but `" << CharT(*__result) << "` found\n";
            throw encoding_error(__error.str());
        }

        // Validate that decoded value is an actual integer.
        if (!_M_value && __i.str() != std::basic_string<
                CharT, Traits>(1, CharT('0'))) {
            std::ostringstream __error;

            __error << "bencode::integer::load the specified "
                "value is not a number\n";
            throw value_error(__error.str());
        }
    }
Esempio n. 5
0
value value_head(value op)
{
	if (op.type == VALUE_ARY) {
		if (value_length(op) == 0) {
			value_error(1, "Error: cannot find head() of an empty array.");
			return value_init_error();
		}

		return value_set(op.core.u_a.a[0]);
	} else if (op.type == VALUE_LST) {
		return value_set(op.core.u_l[0]);
	} else if (op.type == VALUE_PAR) {
		return value_set(op.core.u_p->head);
	} else {
		value_error(1, "Type Error: head() is undefined where op is %ts (array or list expected).", op);
		return value_init_error();
	}
}
Esempio n. 6
0
Dict::Dict( xmmsv_t* val ) : value_( 0 )
{
    if( xmmsv_is_error( val ) ) {
        const char *buf;
        xmmsv_get_error( val, &buf );
        throw value_error( buf );
    }
    else if( xmmsv_get_type( val ) != XMMSV_TYPE_DICT ) {
        throw not_dict_error( "Value is not a dict" );
    }
    setValue( val );
}
Esempio n. 7
0
value value_tail_now(value *op)
{
	if (op->type == VALUE_NIL) {
		value_error(1, "Error: cannot find tail!() of an empty list.");
		return value_init_error();
	} else if (op->type == VALUE_ARY) {
		size_t i, length = value_length(*op);
		if (length == 0) {
			value_error(1, "Error: cannot find tail!() of an empty array.");
			return value_init_error();
		}
		
		value_clear(&op->core.u_a.a[0]);
		for (i = 0; i < length-1; ++i)
			op->core.u_a.a[i] = op->core.u_a.a[i+1];
		
		--op->core.u_a.length;
	} else if (op->type == VALUE_LST) {
		if (value_empty_p(*op)) {
			value_error(1, "Error: cannot find tail!() of an empty list.");
			return value_init_error();
		} else {
			value_clear(&op->core.u_l[0]);
			value_free(op->core.u_l);
			*op = op->core.u_l[1];
		}
	} else if (op->type == VALUE_PAR) {
		value tmp = op->core.u_p->tail;
		value_clear(&op->core.u_p->head);
		value_free(op->core.u_p);
		*op = tmp;
	} else {
		value_error(1, "Type Error: tail!() is undefined where op is %ts (array or list expected).", *op);
		return value_init_error();
	}

	
	return value_init_nil();
}
output_formatter *formatter_factory::output(const string &name)
{
    if(name == "simple")
        return new simple_output_formatter();
    else if(name == "csv")
        return new csv_output_formatter();
    else if(name == "keyvalue")
        return new key_value_output_formatter();
    else if(name == "xml")
        return new xml_output_formatter();
    else
        throw value_error(EXCEPTION_RECORD,
                "Unknown output formatter ["+name+"]!");
}
Esempio n. 9
0
/*
** Store the string on top of the stack on the attributes structure.
** Increment the bvals counter.
*/
static BerValue *A_setbval (lua_State *L, attrs_data *a, const char *n) {
	BerValue *ret = &(a->bvals[a->bi]);
	if (a->bi >= LUALDAP_MAX_VALUES) {
		luaL_error (L, LUALDAP_PREFIX"too many values");
		return NULL;
	} else if (!lua_isstring (L, -1)) {
		value_error (L, n);
		return NULL;
	}
	a->bvals[a->bi].bv_len = lua_strlen (L, -1);
	a->bvals[a->bi].bv_val = (char *)lua_tostring (L, -1);
	a->bi++;
	return ret;
}
Esempio n. 10
0
void command_line_parser::parse_parameters(void)
{
	for (const auto& parameter : m_params)
	{
		const char* token = m_command_line.read();
		if (!token)
		{
			if (parameter.is_required())
				throw value_error(parameter.name());
			else
				return;
		}
		parameter.read(token);
	}
}
Esempio n. 11
0
/// Sets the value of a leaf addressed by its key from a string value.
///
/// This respects the native types of all the nodes that have been predefined.
/// For new nodes under a dynamic subtree, this has no mechanism of determining
/// what type they need to have, so they are created as plain string nodes.
///
/// \param dotted_key The key to be registered in dotted representation.
/// \param raw_value The string representation of the value to set the node to.
///
/// \throw invalid_key_error If the provided key has an invalid format.
/// \throw unknown_key_error If the provided key is unknown.
/// \throw value_error If the value mismatches the node type.
void
config::tree::set_string(const std::string& dotted_key,
                         const std::string& raw_value)
{
    const detail::tree_key key = detail::parse_key(dotted_key);
    detail::base_node* raw_node = _root->lookup_rw(
                                      key, 0, detail::new_node< string_node >);
    try {
        leaf_node& child = dynamic_cast< leaf_node& >(*raw_node);
        child.set_string(raw_value);
    } catch (const std::bad_cast& unused_error) {
        throw value_error(F("Invalid value for key '%s'") %
                          detail::flatten_key(key));
    }
}
Esempio n. 12
0
value value_cons_now2(value *op1, value *op2)
{
	if (op2->type == VALUE_NIL) {
		op2->type = VALUE_PAR;
		value_malloc(op2, 2);
		if (op2->type == VALUE_ERROR) return;
		op2->core.u_p->head = *op1;
		op2->core.u_p->tail = value_init_nil();
		
	} else if (op2->type == VALUE_ARY) {
		value res;
		res.type = VALUE_ARY;
		size_t i, length = value_length(*op2);
		if (resize_p(length+1)) {
			value_realloc(op1, next_size(length+1) + 1);
			if (op1->type == VALUE_ERROR)
				return value_init_error();
		}
		for (i = 1; i < length; ++i)
			res.core.u_a.a[i+1] = op2->core.u_a.a[i];
		res.core.u_a.a[0] = *op1;
		res.core.u_a.length = op2->core.u_a.length + 1;
		*op2 = res;
	} else if (op2->type == VALUE_LST) {
		value res;
		res.type = VALUE_LST;
		value_malloc(&res, 2);
		if (res.type == VALUE_ERROR) {
			return value_init_error();
		}
		res.core.u_l[0] = *op1;
		res.core.u_l[1] = *op2;
		*op2 = res;		
	} else if (op2->type == VALUE_PAR) {
		value res;
		res.type = VALUE_PAR;
		value_malloc(&res, 2);
		return_if_error(res);
		res.core.u_l[0] = *op1;
		res.core.u_l[1] = *op2;
		*op2 = res;		
	} else {
		value_error(1, "Type Error: cons() is undefined where op2 is %ts (nil, array or list expected).", *op2);
		return value_init_error();
	}
	
	return value_init_nil();
}
Esempio n. 13
0
value value_drop(value op, value n)
{
	if (op.type == VALUE_NIL) {
		return value_init_nil();
	} else if (op.type == VALUE_ARY) {
		if (n.type == VALUE_MPZ) {
			value length = value_set_long(op.core.u_a.length);
			value res = value_range(op, n, length);
			value_clear(&length);
			return res;
		}
	} else if (op.type == VALUE_LST) {
		if (n.type == VALUE_MPZ) {
			if (value_lt(n, value_zero)) {
				value_error(1, "Domain Error: drop() is undefined where n is %s (>= 0 expected).", n);
				return value_init_error();
			} else if (value_gt(n, value_int_max)) {
				value_error(1, "Domain Error: drop() is undefined where n is %s (<= %s expected).", n, value_int_max);
				return value_init_error();				
			}
			size_t i, max = value_get_long(n);
			value ptr = op;
			for (i = 0; i < max && ptr.type == VALUE_LST; ++i) {
				ptr = ptr.core.u_l[1];
			}
			
			return value_set(ptr);
		}
	} else if (op.type == VALUE_PAR) {
		if (n.type == VALUE_MPZ) {
			if (value_lt(n, value_zero)) {
				value_error(1, "Domain Error: drop() is undefined where n is %s (>= 0 expected).", n);
				return value_init_error();
			} else if (value_gt(n, value_int_max)) {
				value_error(1, "Domain Error: drop() is undefined where n is %s (<= %s expected).", n, value_int_max);
				return value_init_error();				
			}
			size_t i, max = value_get_long(n);
			value ptr = op;
			for (i = 0; i < max && ptr.type == VALUE_PAR; ++i) {
				ptr = ptr.core.u_p->tail;
			}
			
			return value_set(ptr);
		}
	} else {
		value_error(1, "Type Error: drop() is undefined where op1 is %ts (array or list expected).", op);
		if (n.type == VALUE_MPZ)
			return value_init_error();
	}
	
	value_error(1, "Type Error: drop() is undefined where op2 is %ts (integer expected).", n);
	return value_init_error();
}
Esempio n. 14
0
/// Converts the tree to a collection of key/value string pairs.
///
/// \param dotted_key Subtree from which to start the export.
/// \param strip_key If true, remove the dotted_key prefix from the resulting
///     properties.
///
/// \return A map of keys to values in their textual representation.
///
/// \throw invalid_key_error If the provided key has an invalid format.
/// \throw unknown_key_error If the provided key is unknown.
/// \throw value_error If the provided key points to a leaf.
config::properties_map
config::tree::all_properties(const std::string& dotted_key,
                             const bool strip_key) const
{
    PRE(!strip_key || !dotted_key.empty());

    properties_map properties;

    detail::tree_key key;
    const detail::base_node* raw_node;
    if (dotted_key.empty()) {
        raw_node = _root.get();
    } else {
        key = detail::parse_key(dotted_key);
        raw_node = _root->lookup_ro(key, 0);
    }
    try {
        const detail::inner_node& child =
            dynamic_cast< const detail::inner_node& >(*raw_node);
        child.all_properties(properties, key);
    } catch (const std::bad_cast& unused_error) {
        INV(!dotted_key.empty());
        throw value_error(F("Cannot export properties from a leaf node; "
                            "'%s' given") % dotted_key);
    }

    if (strip_key) {
        properties_map stripped;
        for (properties_map::const_iterator iter = properties.begin();
                iter != properties.end(); ++iter) {
            stripped[(*iter).first.substr(dotted_key.length() + 1)] =
                (*iter).second;
        }
        properties = stripped;
    }

    return properties;
}
Esempio n. 15
0
    /**
     *  @brief Deserialize the string value from the specified input stream.
     *  @param __s  Reference to the input stream.
     */
    void
    load(std::basic_istream<CharT, Traits>& __s)
    {
        // Define the integer symbol representation placeholder.
        std::basic_stringstream<CharT, Traits> __i;

        // Define the input stream iterator of the provided stream to
        // be able to read the string length value symbol by symbol.
        auto __si = std::istream_iterator<CharT, CharT, Traits>(__s);

        // Define the output stream to as a buffer for the integer
        // value, which will be later converted.
        auto __ival = std::ostream_iterator<CharT, CharT, Traits>(__i);

        // Copy the symbols from the input stream to the integer
        // placeholder until the ":" delimiter value.
        auto __result = copy_until(__si, __ival,
            [&__s](const CharT& __ch) {

            // Additionally, check that we did not exceed the
            // length of the stream to prevent hangs.
            return !__s.eof() && __ch != basic_value_type::delimiter_token;
        }, basic_value_type::integer_length);

        if (*__result != basic_value_type::delimiter_token) {
            std::ostringstream __error;

            __error << "bencode::string::load the delimiter `:` "
                "expected, but `" << CharT(*__result) << "` found\n";
            throw encoding_error(__error.str());
        }

        // Save the length of the string.
        int64_t __count;
        __i >> __count;

        if (!__count && __i.str() != std::basic_string<
                CharT, Traits>(1, CharT('0'))) {
            std::ostringstream __error;

            __error << "bencode::string::load the specified string "
                "length is not a number\n";
            throw value_error(__error.str());
        }

        // Ensure that the string length is a non-negative value.
        if (__count < 0) {
            std::ostringstream __error;

            __error << "bencode::string::load the length of the string "
                "value must be a positive integer: `" << __count << "`\n";
            throw value_error(__error.str());
        }

        // Allocate the list of symbols of the specified string length.
        std::unique_ptr<CharT[]> __str(new CharT[__count+1]);

        // Read the string value into the symbol list.
        __s.get(__str.get(), std::streamsize(__count+1));
        auto __strval = string_type(__str.get());

        // Ensure that valid count of the symbols was extracted from
        // the provided input stream.
        if (int64_t(__strval.length()) != __count) {
            std::ostringstream __error;

            __error << "bencode::string::load the specified string "
                "decoded length is not equal to the real one: `" << __count
                << "` != `" << __strval.length() << "`\n";
            throw value_error(__error.str());
        }

        // Initialize the internal value with a new string.
        _M_value = __strval;
    }
Esempio n. 16
0
static bool handle_configitem(const char keyword[], const char *value)
{
  const struct option keyopt = { keyword, 0, 0, 0, 0 };
  const struct option *const opt =
    bsearch(&keyopt,
	options,
	sizeof(options)/sizeof(*options),
	sizeof(*options),
	optcmp);

  if (!opt) return value_error(keyword, "unknown configuration item");

  long long numarg = 0;
  size_t arglen = 0;
  if (value) arglen = strlen(value);

  const char *err = NULL;
  if (value) switch (opt->argtype)
  {
  case at_none:
    err = "does not take an argument";
    break;
  case at_num:
    if (!*value) err = "requires a numeric argument";
    else
    {
      char *endptr;
      numarg = strtoll(value, &endptr, 0);

      if (*endptr) switch (tolower(*endptr++))
      {
      case 'k': numarg *= KILO; break;
      case 'm': numarg *= MEGA; break;
      case 'g': numarg *= GIGA; break;
      case 't': numarg *= TERA; break;
      default: err = "invalid unit letter";
      }

      if (*endptr) err = "invalid numeric argument";
      else if (numarg < opt->min) switch (opt->min)
      {
      case 0:	err = "argument may not be negative";		break;
      case 1:	err = "argument must be greater than zero";	break;
      default:	err = "given value too small";			break;
      }
      else if (numarg > opt->max) err = "given value too large";
    }
    break;
  case at_str:
    if (arglen > opt->max) err = "string too long";
    break;
  }
  else if (opt->argtype == at_num || (opt->argtype == at_str && opt->min))
  {
    err = "requires an argument";
  }
  if (err) return value_error(keyword, err);

  char *const strdest = opt->setter(numarg);
  if (strdest && value) strcpy(strdest, value);

  return true;
}
Esempio n. 17
0
/**
 * Parse key/value pairs from the configuration file
 */
void config::parse_file() {
  vector<pair<int, string>> lines;
  vector<string> files{m_file};

  std::function<void(int, string&&)> pushline = [&](int lineno, string&& line) {
    // Ignore empty lines and comments
    if (line.empty() || line[0] == ';' || line[0] == '#') {
      return;
    }

    string key, value;
    string::size_type pos;

    // Filter lines by:
    // - key/value pairs
    // - section headers
    if ((pos = line.find('=')) != string::npos) {
      key = forward<string>(string_util::trim(forward<string>(line.substr(0, pos))));
      value = forward<string>(string_util::trim(line.substr(pos + 1)));
    } else if (line[0] != '[' || line[line.length() - 1] != ']') {
      return;
    }

    if (key == "include-file") {
      auto file_path = file_util::expand(value);
      if (file_path.empty() || !file_util::exists(file_path)) {
        throw value_error("Invalid include file \"" + file_path + "\" defined on line " + to_string(lineno));
      }
      if (std::find(files.begin(), files.end(), file_path) != files.end()) {
        throw value_error("Recursive include file \"" + file_path + "\"");
      }
      files.push_back(file_util::expand(file_path));
      m_log.trace("config: Including file \"%s\"", file_path);
      for (auto&& l : string_util::split(file_util::contents(file_path), '\n')) {
        pushline(lineno, forward<string>(l));
      }
      files.pop_back();
    } else {
      lines.emplace_back(make_pair(lineno, line));
    }
  };

  int lineno{0};
  string line;
  std::ifstream in(m_file);
  while (std::getline(in, line)) {
    pushline(++lineno, string_util::replace_all(line, "\t", ""));
  }

  string section;
  for (auto&& l : lines) {
    auto& lineno = l.first;
    auto& line = l.second;

    // New section
    if (line[0] == '[' && line[line.length() - 1] == ']') {
      section = line.substr(1, line.length() - 2);
      continue;
    } else if (section.empty()) {
      continue;
    }

    size_t equal_pos;

    // Check for key-value pair equal sign
    if ((equal_pos = line.find('=')) == string::npos) {
      continue;
    }

    string key{forward<string>(string_util::trim(forward<string>(line.substr(0, equal_pos))))};
    string value;

    auto it = m_sections[section].find(key);
    if (it != m_sections[section].end()) {
      throw key_error("Duplicate key name \"" + key + "\" defined on line " + to_string(lineno));
    }

    if (equal_pos + 1 < line.size()) {
      value = forward<string>(string_util::trim(line.substr(equal_pos + 1)));
      size_t len{value.size()};
      if (len > 2 && value[0] == '"' && value[len - 1] == '"') {
        value.erase(len - 1, 1).erase(0, 1);
      }
    }

#if WITH_XRM
    // Initialize the xresource manage if there are any xrdb refs
    // present in the configuration
    if (!m_xrm && value.find("${xrdb") != string::npos) {
      m_xrm.reset(new xresource_manager{connection::make()});
    }
#endif

    m_sections[section].emplace_hint(it, move(key), move(value));
  }
}
Esempio n. 18
0
 void assert_check() const
 {
     if (pos_ == end_)
     throw value_error("Attempt to read past end of value list.");
 }
Esempio n. 19
0
 void finish() const
 {
     if (pos_ != end_)
     throw value_error("Not all values handled.");
 }
Esempio n. 20
0
 void assert_check(value::tag_type t) const
 {
     assert_check();
     if (t != pos_->get_tag())
     throw value_error("Incorrect value tag.");
 }
Esempio n. 21
0
value value_take(value op, value n)
{
	if (op.type == VALUE_NIL) {
		return value_init_nil();
	} else if (op.type == VALUE_ARY) {
		if (n.type == VALUE_MPZ) {
			value start = value_set_long(0);
			value res = value_range(op, start, n);
			value_clear(&start);
			return res;
		}
	} else if (op.type == VALUE_LST) {
		if (n.type == VALUE_MPZ) {
			if (value_lt(n, value_zero)) {
				value_error(1, "Domain Error: drop() is undefined where n is %s (>= 0 expected).", n);
				return value_init_error();
			} else if (value_gt(n, value_int_max)) {
				value_error(1, "Domain Error: drop() is undefined where n is %s (<= %s expected).", n, value_int_max);
				return value_init_error();				
			}
			
			value res = value_init_nil();
			size_t i, max = value_get_long(n);
			value ptr = op;
			for (i = 0; i < max && ptr.type == VALUE_LST; ++i) {
				value_cons_now(ptr.core.u_l[0], &res);
				ptr = ptr.core.u_l[1];
			}
			
			value_reverse_now(&res);
			
			return res;
		}
	} else if (op.type == VALUE_PAR) {
		if (n.type == VALUE_MPZ) {
			if (value_lt(n, value_zero)) {
				value_error(1, "Domain Error: drop() is undefined where n is %s (>= 0 expected).", n);
				return value_init_error();
			} else if (value_gt(n, value_int_max)) {
				value_error(1, "Domain Error: drop() is undefined where n is %s (<= %s expected).", n, value_int_max);
				return value_init_error();				
			}
			
			value res = value_init_nil();
			size_t i, max = value_get_long(n);
			value ptr = op;
			for (i = 0; i < max && ptr.type == VALUE_PAR; ++i) {
				value_cons_now(ptr.core.u_p->tail, &res);
				ptr = ptr.core.u_p->tail;
			}
			
			value_reverse_now(&res);
			
			return res;
		}
	} else {
		value_error(1, "Type Error: take() is undefined where op is %ts (array or list expected).", op);
		if (n.type == VALUE_MPZ)
			return value_init_error();
	}
	
	value_error(1, "Type Error: drop() is undefined where n is %ts (integer expected).", n);
	return value_init_error();

}
Esempio n. 22
0
void command_line_parser::parse_options(void)
{
	while(const char* token = m_command_line.peek())
	{
		if (*token != '-')
			break;
		std::string param(m_command_line.read());
		logger().trace(corecpp::concat<std::string>({"parsing ", param}), __FILE__, __LINE__);
		if (param.substr(0,2) == "--")
		{
			std::string value = "";
			auto pos = param.find('=');
			if(pos == std::string::npos)
			{
				//param with no value => value is let to an empty string
				param = param.substr(2);
			}
			else
			{
				value = param.substr(pos);
				param = param.substr(2, param.length() - 2 - pos);
			}
			auto option = get_option(param);
			if (option == m_options.end())
				throw std::invalid_argument(param);
			if (option->require_value() && (pos == std::string::npos))
				throw value_error(param);
			option->read(value);
		}
		else if (param[0] == '-')
		{
			param = param.substr(1);
			const char* value = m_command_line.peek();
			if(value && *value == '-') //another option
				value = nullptr;
			//for loop because we can have multiple params
			for(auto iter = param.begin(); iter != param.end(); )
			{
				char shortname = *iter;
				auto option = get_option(shortname);
				if(option == m_options.end())
					throw std::invalid_argument(std::string(1, shortname));

				if (++iter == param.end())//last option => must give the value to it
				{
					if (!value && option->require_value())
						throw value_error(param);
					if (option->require_value())
					{
						value = m_command_line.read(); //consume the parameter
						option->read(value);
					}
					else
						option->read("");
				}
				else //not the last parameter => should not need a value
				{
					if (option->require_value())
						throw value_error(param);
					option->read("");
				}
			}
		}
	}
}
Esempio n. 23
0
File: Value.c Progetto: dhaley/dcp
Value pow(Value & v1,Value & v2)
{
  Value val;
  if ((v1.code == ISERROR) || (v2.code == ISERROR)) return val;
  switch(v1.code)
    {
    case ISINT:
      {
	switch(v2.code)
	  {
	  case ISINT:
	    val.code = ISINT;
	    if (((v1.i < 0)&&(v2.i <= 0)) || ((v1.i < 0)&&(v2.IsInt())))
	      {
		return value_error(" illegal exponentiation");
	      }
	    else
	      {
		val.i = (int)pow((double)v1.i,v2.i);
		return val;
	      }
	  default:
	    val.code = ISFLOAT;
	    if (((v1.i < 0)&&(v2.f <= 0)) || ((v1.i < 0)&&(v2.IsInt())))
	      {
		return value_error(" illegal exponentiation");
	      }
	    else
	      {
		val.f = pow((double)(v1.i),v2.f);
		return val;
	      }
	  }
      }
    default:
      switch(v2.code)
	{
	case ISINT:
	  val.code = ISFLOAT;
	  if (((v1.f < 0)&&(v2.i <= 0)) || ((v1.f < 0)&&(v2.IsInt())))
	    {
	      return value_error(" illegal exponentiation");
	    }
	  else
	    {
	      val.f = pow(v1.f,(double)(v2.i));
	      return val;
	    }
	default:
	  val.code = ISFLOAT;
	  if (((v1.f < 0)&&(v2.f <= 0)) || ((v1.f <  0)&&(v2.IsInt())))
	    {
	      return value_error(" illegal exponentiation");
	    }
	  else
	    {
	      val.f = pow(v1.f,v2.f);
	      return val;
	    }
	}
    }
}
Esempio n. 24
0
File: Value.c Progetto: dhaley/dcp
Value operator/(Value & v1,Value & v2)
{
  Value val;
  if ((v1.code == ISERROR) || (v2.code == ISERROR)) return val;
  switch(v1.code)
    {
    case ISINT:
      {
	switch(v2.code)
	  {
	  case ISINT:
	    val.code = ISINT;
	    if (v2.i == 0)
	      {
		value_error(" divide by 0");
		val.i = 0;
	      }
	    else
	      {
		val.i = (v1.i) / (v2.i);
	      }
	    return val;
	  default:
	    val.code = ISFLOAT;
	    if (v2.f == 0)
	      {
		value_error(" divide by 0");
		val.f = 0;
	      }
	    else
	      {
		val.f = (double)(v1.i) / (v2.f);
	      }
	    return val;
	  }
      }
    default:
      {
	switch(v2.code)
	  {
	  case ISINT:
	    val.code = ISFLOAT;
	    if (v2.i == 0)
	      {
		value_error(" divide by 0");
		val.f = 0;
	      }
	    else
	      {
		val.f = (v1.f) / (double)(v2.i);
	      }
	    return val;
	  default:
	    val.code = ISFLOAT;
	    if (v2.f == 0)
	      {
		value_error(" divide by 0");
		val.f = 0;
	      }
	    else
	      {
		val.f = (v1.f) / (v2.f);
	      }
	    return val;
	  }
      }
      
    }
}