001/*
002 * Copyright (C) 2012 eXo Platform SAS.
003 *
004 * This is free software; you can redistribute it and/or modify it
005 * under the terms of the GNU Lesser General Public License as
006 * published by the Free Software Foundation; either version 2.1 of
007 * the License, or (at your option) any later version.
008 *
009 * This software is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Lesser General Public License for more details.
013 *
014 * You should have received a copy of the GNU Lesser General Public
015 * License along with this software; if not, write to the Free
016 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
017 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
018 */
019
020package org.crsh.cli.impl.tokenizer;
021
022class State {
023
024  /** . */
025  StringBuilder buffer;
026
027  /** . */
028  Escape escape;
029
030  /** . */
031  Status status;
032
033  public State() {
034    this.buffer = new StringBuilder();
035    this.status = Status.INIT;
036    this.escape = Escape.NONE;
037  }
038
039  void push(char c) {
040
041    //
042    switch (escape) {
043      case NONE:
044        if (c == '"') {
045          escape = Escape.DOUBLE;
046          return;
047        } else if (c == '\\') {
048          escape = Escape.BACKSLASH;
049          return;
050        } else if (c == '\'') {
051          escape = Escape.SINGLE;
052          return;
053        } else {
054          // Do nothing
055          break;
056        }
057      case DOUBLE:
058        if (c == '"') {
059          escape = Escape.NONE;
060          return;
061        } else {
062          // Do nothing
063          break;
064        }
065      case SINGLE:
066        if (c == '\'') {
067          escape = Escape.NONE;
068          return;
069        } else {
070          // Do nothing
071          break;
072        }
073      case BACKSLASH:
074        escape = Escape.NONE;
075        break;
076      default:
077        throw new AssertionError(escape);
078    }
079
080    switch (status) {
081      case INIT: {
082        if (c == '-') {
083          buffer.append(c);
084          status = Status.SHORT_OPTION;
085          return;
086        } else {
087          buffer.append(c);
088          status = Status.WORD;
089          return;
090        }
091      }
092      case WORD: {
093        buffer.append(c);
094        status = Status.WORD;
095        return;
096      }
097      case SHORT_OPTION: {
098        if (Character.isLetter(c)) {
099          buffer.append(c);
100          return;
101        } else if (c == '-') {
102          buffer.append('-');
103          status = Status.LONG_OPTION;
104          return;
105        } else {
106          buffer.append(c);
107          status = Status.WORD;
108          return;
109        }
110      }
111      case LONG_OPTION: {
112        if (Character.isLetter(c) || (buffer.length() > 0 && c == '-')) {
113          buffer.append(c);
114          return;
115        } else {
116          buffer.append(c);
117          status = Status.WORD;
118          return;
119        }
120      }
121      default:
122        throw new AssertionError(escape);
123    }
124  }
125}