Пример #1
0
char * construct_next_attribute( char * (*get_attribute)(char *, unsigned int ) )
{
	unsigned int start_position = eat_whitespaces( current_position );
	if ( start_position == strlen( attributes_line ) ) return NULL;
	current_position = eat_not_whitespaces( start_position );

	return get_attribute( attributes_line + start_position, current_position - start_position );
}
Пример #2
0
// Try to consume characters from the input stream and match the
// pattern string. Leading whitespaces from the input are ignored if
// ignore_ws is true.
bool match(const std::string& pattern, std::istream& input,
           bool ignore_ws) {
    if (ignore_ws) {
        eat_whitespaces(input);
    }
    std::string::const_iterator cur(pattern.begin());
    char ch(0);
    while(input && !input.eof() && cur != pattern.end()) {
        input.get(ch);
        if (ch != *cur) {
            input.putback(ch);
            return false;
        } else {
            cur++;
        }
    }
    return cur == pattern.end();
}
Пример #3
0
bool parse_number(std::istream& input, long* value) {
    eat_whitespaces(input);
    char ch;
    std::string value_str;
    std::string exp_str; // whole exp part
    std::string exp_value_str; // value of exp part
    int sign = 1;
    int e_sign = 1;
    bool correct = true;
    long e_value;

    enum {
      p_number,
      p_e,
      p_enumber
    } p_state = p_number;

    if (match("-", input)) {
        sign = -1;
    } else {
        match("+", input);
    }

    while(input && !input.eof()) {
      input.get(ch);
      switch (p_state) {
      case p_number: {
	// DBG("st = p_number, ch=%c\n",ch);
	if (ch == 'E' || ch == 'e') {
	  exp_str.push_back(ch);
	  p_state = p_e;
	  continue;
	}
	if (!isdigit(ch)) {
	  input.putback(ch);
	  correct = false;
	  break;
	}
	value_str.push_back(ch);
      } break;

      case p_e: {
	// DBG("st = p_e, ch=%c\n",ch);

	if (ch == '+') {
	  exp_str.push_back(ch);
	  p_state = p_enumber;
	} else if (ch == '-') {
	  e_sign = -1;
	  exp_str.push_back(ch);
	  p_state = p_enumber;
	} else if (isdigit(ch)) {
	  exp_value_str.push_back(ch);
	  exp_str.push_back(ch);
	  p_state = p_enumber;
	} else {
	  input.putback(ch);
	  correct = false;
	}
      } break;

      case p_enumber: {
	// DBG("st = p_enumber, ch=%c\n",ch);

	if (isdigit(ch)) {
	  exp_value_str.push_back(ch);
	  exp_str.push_back(ch);
	} else {
	  input.putback(ch);
	  correct = false;
	}
      } break;

      }

      if (!correct)
	break;
    }

    if (p_state == p_e) { 
      // todo: check also some other error states
      for (std::string::reverse_iterator r_it=
    	     exp_str.rbegin(); r_it != exp_str.rend(); r_it++)
    	input.putback(*r_it);
      for (std::string::reverse_iterator r_it=
    	     value_str.rbegin(); r_it != value_str.rend(); r_it++)
    	input.putback(*r_it);
      return false;
    }
    
    if (value_str.size() > 0) {
        std::istringstream(value_str) >> *value;
	*value*=sign;

	if (exp_value_str.size()) {	  
	  std::istringstream(exp_value_str) >> e_value;

	  if (e_value && e_sign==-1) {
	    // should have been catched by parse_float
	    for (std::string::reverse_iterator r_it=
		   exp_str.rbegin(); r_it != exp_str.rend(); r_it++)
	      input.putback(*r_it);
	    for (std::string::reverse_iterator r_it=
		   value_str.rbegin(); r_it != value_str.rend(); r_it++)
	      input.putback(*r_it);
	    
	    return false;  
	  }
	  *value *= pow(10, e_value);
	}