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    
020    package org.crsh.cli.impl.tokenizer;
021    
022    class 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    }