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 import org.crsh.cli.impl.Delimiter; 023 024 public class TokenizerImpl extends Tokenizer { 025 026 /** . */ 027 private final CharSequence s; 028 029 /** . */ 030 private int index; 031 032 /** . */ 033 private Delimiter delimiter; 034 035 public TokenizerImpl(CharSequence s) { 036 this.s = s; 037 this.index = 0; 038 this.delimiter = null; 039 } 040 041 protected Token parse() { 042 Token token = null; 043 if (index < s.length()) { 044 char c = s.charAt(index); 045 int from = index; 046 while (true) { 047 if (Character.isWhitespace(c)) { 048 index++; 049 if (index < s.length()) { 050 c = s.charAt(index); 051 } else { 052 break; 053 } 054 } else { 055 break; 056 } 057 } 058 if (index > from) { 059 token = new Token.Whitespace(from, s.subSequence(from, index).toString()); 060 } else { 061 State state = new State(); 062 while (true) { 063 if (Character.isWhitespace(c) && state.escape == Escape.NONE) { 064 break; 065 } else { 066 index++; 067 state.push(c); 068 if (index < s.length()) { 069 c = s.charAt(index); 070 } else { 071 break; 072 } 073 } 074 } 075 if (index > from) { 076 switch (state.status) { 077 case INIT: { 078 token = new Token.Literal.Word(from, s.subSequence(from, index).toString(), state.buffer.toString()); 079 break; 080 } 081 case WORD: { 082 token = new Token.Literal.Word(from, s.subSequence(from, index).toString(), state.buffer.toString()); 083 break; 084 } 085 case SHORT_OPTION: { 086 token = new Token.Literal.Option.Short(from, s.subSequence(from, index).toString(), state.buffer.toString()); 087 break; 088 } 089 case LONG_OPTION: { 090 token = new Token.Literal.Option.Long(from, s.subSequence(from, index).toString(), state.buffer.toString()); 091 break; 092 } 093 default: 094 throw new AssertionError(state.status); 095 } 096 delimiter = state.escape.delimiter; 097 return token; 098 } 099 } 100 } 101 return token; 102 } 103 104 public Delimiter getDelimiter() { 105 return delimiter; 106 } 107 }