--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tool/NumberListParser.cpp Wed Feb 24 16:27:11 2010 +0100
@@ -0,0 +1,230 @@
+/*****************************************************************************
+ *
+ * $Id$
+ *
+ * Copyright (C) 2006-2009 Florian Pose, Ingenieurgemeinschaft IgH
+ *
+ * This file is part of the IgH EtherCAT Master.
+ *
+ * The IgH EtherCAT Master is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version 2, as
+ * published by the Free Software Foundation.
+ *
+ * The IgH EtherCAT Master is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+ * Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with the IgH EtherCAT Master; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * ---
+ *
+ * The license mentioned above concerns the source code only. Using the
+ * EtherCAT technology and brand is only permitted in compliance with the
+ * industrial property and similar rights of Beckhoff Automation GmbH.
+ *
+ ****************************************************************************/
+
+#include <cstring>
+#include <sstream>
+#include <stdexcept>
+using namespace std;
+
+#include "NumberListParser.h"
+
+/*****************************************************************************/
+
+NumberListParser::NumberListParser():
+ max(0U),
+ hasMax(false)
+{
+}
+
+/*****************************************************************************/
+
+NumberListParser::~NumberListParser()
+{
+}
+
+/*****************************************************************************/
+
+NumberListParser::NumberList NumberListParser::parse(const char *data)
+{
+ NumberList ret;
+ unsigned int i = 0, size = strlen(data), firstNum = 0U, secondNum = 0U;
+ typedef enum {
+ SectionStart,
+ FirstNumber,
+ Range,
+ SecondNumber,
+ Finished
+ } State;
+ State state = SectionStart;
+
+ while (state != Finished) {
+ switch (state) {
+ case SectionStart:
+ if (i >= size) {
+ state = Finished;
+ } else if (isNumeric(data[i])) {
+ firstNum = parseNumber(data, &i, size);
+ state = FirstNumber;
+ } else if (data[i] == '-') {
+ firstNum = 0U;
+ i++;
+ state = Range;
+ } else if (data[i] == ',') {
+ i++;
+ } else {
+ stringstream err;
+ err << "Invalid character " << data[i]
+ << " at position " << i << "in state "
+ << state << "." << endl;
+ throw runtime_error(err.str());
+ }
+ break;
+
+ case FirstNumber:
+ if (i >= size) {
+ ret.push_back(firstNum);
+ state = Finished;
+ } else if (data[i] == '-') {
+ i++;
+ state = Range;
+ } else if (data[i] == ',') {
+ i++;
+ ret.push_back(firstNum);
+ state = SectionStart;
+ } else {
+ stringstream err;
+ err << "Invalid character " << data[i]
+ << " at position " << i << "in state "
+ << state << "." << endl;
+ throw runtime_error(err.str());
+ }
+ break;
+
+ case Range:
+ if (i >= size) {
+ secondNum = maximum();
+ NumberList r = range(firstNum, secondNum);
+ ret.splice(ret.end(), r);
+ state = Finished;
+ } else if (isNumeric(data[i])) {
+ secondNum = parseNumber(data, &i, size);
+ state = SecondNumber;
+ } else if (data[i] == ',') {
+ i++;
+ secondNum = maximum();
+ NumberList r = range(firstNum, secondNum);
+ ret.splice(ret.end(), r);
+ state = SectionStart;
+ } else {
+ stringstream err;
+ err << "Invalid character " << data[i]
+ << " at position " << i << "in state "
+ << state << "." << endl;
+ throw runtime_error(err.str());
+ }
+ break;
+
+ case SecondNumber:
+ if (i >= size) {
+ NumberList r = range(firstNum, secondNum);
+ ret.splice(ret.end(), r);
+ state = Finished;
+ } else if (data[i] == ',') {
+ i++;
+ NumberList r = range(firstNum, secondNum);
+ ret.splice(ret.end(), r);
+ state = SectionStart;
+ } else {
+ stringstream err;
+ err << "Invalid character " << data[i]
+ << " at position " << i << "in state "
+ << state << "." << endl;
+ throw runtime_error(err.str());
+ }
+ break;
+
+ default:
+ {
+ stringstream err;
+ err << "Invalid state " << state << ".";
+ throw runtime_error(err.str());
+ }
+ }
+ }
+
+ return ret;
+}
+
+/*****************************************************************************/
+
+unsigned int NumberListParser::maximum()
+{
+ if (!hasMax) {
+ max = getMax();
+ }
+
+ return max;
+}
+
+/*****************************************************************************/
+
+bool NumberListParser::isNumeric(char c)
+{
+ return c >= '0' && c <= '9';
+}
+
+/*****************************************************************************/
+
+unsigned int NumberListParser::parseNumber(
+ const char *data,
+ unsigned int *i,
+ unsigned int size
+ )
+{
+ unsigned int numSize = 0U, ret;
+
+ while (*i + numSize < size && isNumeric(data[*i + numSize])) {
+ numSize++;
+ }
+
+ if (numSize) {
+ stringstream str;
+ str << string(data + *i, numSize);
+ str >> ret;
+ } else {
+ throw runtime_error("EOF");
+ }
+
+ *i = *i + numSize;
+ return ret;
+}
+
+/****************************************************************************/
+
+NumberListParser::NumberList NumberListParser::range(
+ unsigned int i,
+ unsigned int j
+ )
+{
+ NumberList ret;
+
+ if (i <= j) {
+ for (; i <= j; i++) {
+ ret.push_back(i);
+ }
+ } else {
+ for (; i >= j; i--) {
+ ret.push_back(i);
+ }
+ }
+
+ return ret;
+}
+
+/****************************************************************************/