nux-1.16.0
|
00001 /* 00002 * Copyright 2010 Inalogic® Inc. 00003 * 00004 * This program is free software: you can redistribute it and/or modify it 00005 * under the terms of the GNU Lesser General Public License, as 00006 * published by the Free Software Foundation; either version 2.1 or 3.0 00007 * of the License. 00008 * 00009 * This program is distributed in the hope that it will be useful, but 00010 * WITHOUT ANY WARRANTY; without even the implied warranties of 00011 * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR 00012 * PURPOSE. See the applicable version of the GNU Lesser General Public 00013 * License for more details. 00014 * 00015 * You should have received a copy of both the GNU Lesser General Public 00016 * License along with this program. If not, see <http://www.gnu.org/licenses/> 00017 * 00018 * Authored by: Jay Taoko <jaytaoko@inalogic.com> 00019 * 00020 */ 00021 00022 00023 #include "NuxCore.h" 00024 #include "Parsing.h" 00025 00026 #define CHAR_TAB TEXT('\t') 00027 #define CHAR_CR TEXT('\r') 00028 #define CHAR_FF TEXT('\f') 00029 #define CHAR_NEW_LINE TEXT('\n') 00030 #define CHAR_QUOTE TEXT('\"') 00031 00032 namespace nux 00033 { 00034 00035 bool ParseCommand (const TCHAR **Stream, const TCHAR *Match) 00036 { 00037 while ( (**Stream == TEXT (' ') ) || (**Stream == CHAR_TAB) ) 00038 (*Stream) ++; 00039 00040 if (TCharStringNICompare (*Stream, Match, StringLength (Match) ) == 0) 00041 { 00042 *Stream += StringLength (Match); 00043 00044 if (!IsAlphanumericChar (**Stream) ) 00045 { 00046 while ( (**Stream == TEXT (' ') ) || (**Stream == CHAR_TAB) ) 00047 (*Stream) ++; 00048 00049 return true; // Success. 00050 } 00051 else 00052 { 00053 *Stream -= StringLength (Match); 00054 return false; // Only found partial match. 00055 } 00056 } 00057 else return false; // No match. 00058 } 00059 00060 bool Parse_tchar (const TCHAR *Stream, const TCHAR *Match, TCHAR *Value, t_int Size, t_int MaxLen) 00061 { 00062 const TCHAR *Found = Strfind (Stream, Match); 00063 const TCHAR *Start; 00064 00065 if (Found) 00066 { 00067 Start = Found + StringLength (Match); 00068 00069 if (*Start == '\x22') // Character '"' 00070 { 00071 // The value begins with the quotation mark character: ". We skip it. 00072 Strncpy (Value, Size, Start + 1, MaxLen); 00073 Value[MaxLen - 1] = 0; 00074 TCHAR *Temp = Strstr (Value, TEXT ("\x22") ); 00075 00076 if (Temp != NULL) 00077 { 00078 // We read in the termination quotation mark. Set it t0 0 to null terminate the Value buffer. 00079 *Temp = 0; 00080 } 00081 } 00082 else 00083 { 00084 // Non-quoted string without spaces. 00085 Strncpy (Value, Size, Start, MaxLen); 00086 Value[MaxLen - 1] = 0; 00087 TCHAR *Temp; 00088 Temp = Strstr (Value, TEXT (" ") ); 00089 00090 if (Temp) *Temp = 0; 00091 00092 Temp = Strstr (Value, TEXT ("\r") ); 00093 00094 if (Temp) *Temp = 0; 00095 00096 Temp = Strstr (Value, TEXT ("\n") ); 00097 00098 if (Temp) *Temp = 0; 00099 00100 Temp = Strstr (Value, TEXT ("\t") ); 00101 00102 if (Temp) *Temp = 0; 00103 00104 Temp = Strstr (Value, TEXT (",") ); 00105 00106 if (Temp) *Temp = 0; 00107 } 00108 00109 return true; 00110 } 00111 else 00112 return false; 00113 } 00114 00115 bool ParseParam (const TCHAR *Stream, const TCHAR *Param) 00116 { 00117 const TCHAR *Start = Stream; 00118 00119 if (*Stream) 00120 { 00121 while ( (Start = Strfind (Start + 1, Param) ) != NULL) 00122 { 00123 if (Start > Stream && ( (Start[-1] == TEXT ('-') ) || (Start[-1] == TEXT ('/') ) ) ) 00124 { 00125 const TCHAR *End = Start + StringLength (Param); 00126 00127 if (End == NULL || *End == 0 || IsWhitespaceChar (*End) ) 00128 return true; 00129 } 00130 } 00131 } 00132 00133 return false; 00134 } 00135 00136 bool Parse_string (const TCHAR *Stream, const TCHAR *Match, NString &Value) 00137 { 00138 TCHAR Temp[4096] = TEXT (""); 00139 00140 if (Parse_tchar (Stream, Match, Temp, NUX_ARRAY_COUNT (Temp), NUX_ARRAY_COUNT (Temp) ) ) 00141 { 00142 Value = Temp; 00143 return true; 00144 } 00145 else return false; 00146 } 00147 00148 bool Parse_u64 (const TCHAR *Stream, const TCHAR *Match, QWORD &Value) 00149 { 00150 return Parse_s64 (Stream, Match, * (SQWORD *) &Value); 00151 } 00152 00153 bool Parse_s64 (const TCHAR *Stream, const TCHAR *Match, SQWORD &Value) 00154 { 00155 TCHAR Temp[4096] = TEXT (""), *Ptr = Temp; 00156 00157 if (Parse_tchar (Stream, Match, Temp, NUX_ARRAY_COUNT (Temp), NUX_ARRAY_COUNT (Temp) ) ) 00158 { 00159 Value = 0; 00160 bool Negative = (*Ptr == TEXT ('-') ); 00161 Ptr += Negative; 00162 00163 while ( (*Ptr >= TEXT ('0') ) && (*Ptr <= TEXT ('9') ) ) 00164 Value = Value * 10 + *Ptr++ - TEXT ('0'); 00165 00166 if (Negative) 00167 Value = -Value; 00168 00169 return true; 00170 } 00171 else 00172 return false; 00173 } 00174 00175 bool Parse_u32 (const TCHAR *Stream, const TCHAR *Match, DWORD &Value) 00176 { 00177 const TCHAR *Temp = Strfind (Stream, Match); 00178 TCHAR *End; 00179 00180 if (Temp == NULL) 00181 return false; 00182 00183 Value = Strtoi (Temp + StringLength (Match), &End, 10); 00184 00185 return true; 00186 } 00187 00188 bool Parse_u8 (const TCHAR *Stream, const TCHAR *Match, BYTE &Value) 00189 { 00190 const TCHAR *Temp = Strfind (Stream, Match); 00191 00192 if (Temp == NULL) 00193 return false; 00194 00195 Temp += StringLength (Match); 00196 Value = (BYTE) CharToInteger (Temp); 00197 return (Value != 0) || IsDigitChar (Temp[0]); 00198 } 00199 00200 bool Parse_s8 (const TCHAR *Stream, const TCHAR *Match, SBYTE &Value) 00201 { 00202 const TCHAR *Temp = Strfind (Stream, Match); 00203 00204 if (Temp == NULL) 00205 return false; 00206 00207 Temp += StringLength (Match); 00208 Value = CharToInteger (Temp); 00209 return Value != 0 || IsDigitChar (Temp[0]); 00210 } 00211 00212 bool Parse_u16 (const TCHAR *Stream, const TCHAR *Match, WORD &Value) 00213 { 00214 const TCHAR *Temp = Strfind (Stream, Match); 00215 00216 if (Temp == NULL) 00217 return false; 00218 00219 Temp += StringLength (Match); 00220 Value = (t_u16) CharToInteger (Temp); 00221 return Value != 0 || IsDigitChar (Temp[0]); 00222 } 00223 00224 bool Parse_s16 (const TCHAR *Stream, const TCHAR *Match, SWORD &Value) 00225 { 00226 const TCHAR *Temp = Strfind (Stream, Match); 00227 00228 if (Temp == NULL) 00229 return false; 00230 00231 Temp += StringLength (Match); 00232 Value = (t_s16) CharToInteger (Temp); 00233 return Value != 0 || IsDigitChar (Temp[0]); 00234 } 00235 00236 bool Parse_float (const TCHAR *Stream, const TCHAR *Match, float &Value) 00237 { 00238 const TCHAR *Temp = Strfind (Stream, Match); 00239 00240 if (Temp == NULL) 00241 return false; 00242 00243 Value = CharToDouble (Temp + StringLength (Match) ); 00244 return true; 00245 } 00246 00247 bool Parse_int (const TCHAR *Stream, const TCHAR *Match, t_int &Value) 00248 { 00249 const TCHAR *Temp = Strfind (Stream, Match); 00250 00251 if (Temp == NULL) 00252 return false; 00253 00254 Value = CharToInteger (Temp + StringLength (Match) ); 00255 return true; 00256 } 00257 00258 bool Parse_bool (const TCHAR *Stream, const TCHAR *Match, bool &OnOff) 00259 { 00260 TCHAR TempStr[16]; 00261 00262 if (Parse_tchar (Stream, Match, TempStr, NUX_ARRAY_COUNT (TempStr), NUX_ARRAY_COUNT (TempStr) - 1) ) 00263 { 00264 OnOff = !Stricmp (TempStr, TEXT ("On") ) || !Stricmp (TempStr, TEXT ("True") ) || !Stricmp (TempStr, TEXT ("1") ); 00265 return true; 00266 } 00267 else 00268 return false; 00269 } 00270 00271 void ParseToNextLine (const TCHAR **Stream, TCHAR CommentChar) 00272 { 00273 // Skip over spaces, tabs, cr's, and linefeeds. 00274 00275 while (1) 00276 { 00277 while ( (**Stream == TEXT (' ') ) || (**Stream == CHAR_TAB) || (**Stream == CHAR_CR) || (**Stream == CHAR_NEW_LINE) || (**Stream == CHAR_FF) ) 00278 { 00279 // Skip tabs, cr, new line, form feed 00280 ++*Stream; 00281 } 00282 00283 if (**Stream == CommentChar) 00284 { 00285 // Start of a comment 00286 while ( (**Stream != 0) && (**Stream != CHAR_NEW_LINE) && (**Stream != CHAR_CR) ) 00287 { 00288 // Advance to a new line 00289 ++*Stream; 00290 } 00291 } 00292 else 00293 { 00294 break; 00295 } 00296 } 00297 } 00298 00299 bool ParseToken (const TCHAR *Str, TCHAR *TokenBuffer, t_int BufferSize) 00300 { 00301 t_int sz = 0; 00302 00303 while ( (*Str == TEXT (' ') ) || (*Str == CHAR_TAB) ) 00304 { 00305 // Skip spaces and tabs. 00306 Str++; 00307 } 00308 00309 if (*Str == CHAR_QUOTE) 00310 { 00311 // Get quoted string. 00312 Str++; 00313 00314 while (*Str && (*Str != CHAR_QUOTE) && (sz + 1 < BufferSize) ) 00315 { 00316 TCHAR c = *Str++; 00317 00318 if (sz + 1 < BufferSize) 00319 TokenBuffer[sz++] = c; 00320 } 00321 00322 if (*Str == CHAR_QUOTE) 00323 Str++; 00324 } 00325 else 00326 { 00327 // Get unquoted string. 00328 for (; *Str && (*Str != TEXT (' ') ) && (*Str != CHAR_TAB); Str++) 00329 { 00330 if (sz + 1 < BufferSize) 00331 TokenBuffer[sz++] = *Str; 00332 } 00333 } 00334 00335 TokenBuffer[sz] = 0; 00336 return sz != 0; 00337 } 00338 00339 bool ParseToken (const TCHAR *Str, NString &TokenString) 00340 { 00341 TokenString.Clear(); 00342 00343 // Skip spaces and tabs. 00344 while (IsWhitespaceChar (*Str) ) 00345 Str++; 00346 00347 if (*Str == CHAR_QUOTE) 00348 { 00349 // Get quoted string. 00350 Str++; 00351 00352 while (*Str && *Str != CHAR_QUOTE) 00353 { 00354 TCHAR c = *Str++; 00355 TokenString += c; 00356 } 00357 00358 if (*Str == CHAR_QUOTE) 00359 Str++; 00360 } 00361 else 00362 { 00363 // Get unquoted string. 00364 for (; *Str && !IsWhitespaceChar (*Str); Str++) 00365 { 00366 TokenString += *Str; 00367 } 00368 } 00369 00370 return TokenString.Length() > 0; 00371 } 00372 00373 NString ParseToken (const TCHAR *Str, bool UseEscape) 00374 { 00375 TCHAR Buffer[1024]; 00376 00377 if (ParseToken (Str, Buffer, NUX_ARRAY_COUNT (Buffer) ) ) 00378 return Buffer; 00379 else 00380 return TEXT (""); 00381 } 00382 00383 // 00384 // Get a line of Stream (everything up to, but not including, CR/LF. 00385 // Returns 0 if ok, nonzero if at end of stream and returned 0-length string. 00386 // 00387 bool ParseLine (const TCHAR **Stream, TCHAR *LineBuffer, t_int BufferSize) 00388 { 00389 TCHAR *tmp = LineBuffer; 00390 *tmp = 0; 00391 00392 while ( (**Stream != 0) && (**Stream != CHAR_NEW_LINE) && (**Stream != CHAR_CR) && (**Stream != CHAR_FF) && (--BufferSize > 0) ) 00393 { 00394 * (tmp++) = * ( (*Stream) ++); 00395 } 00396 00397 *tmp = 0; 00398 return LineBuffer[0] != 0; 00399 } 00400 00401 bool ParseLine (const TCHAR **Stream, NString &LineString) 00402 { 00403 LineString.Clear(); 00404 00405 while ( (**Stream != 0) && (**Stream != CHAR_NEW_LINE) && (**Stream != CHAR_CR) && (**Stream != CHAR_FF) ) 00406 { 00407 LineString += **Stream++; 00408 } 00409 00410 return LineString.Size() > 0; 00411 } 00412 00413 }