1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_vcl.hxx" 30 31 #include "vcl/strhelper.hxx" 32 #include "sal/alloca.h" 33 34 namespace psp { 35 36 inline int isSpace( char cChar ) 37 { 38 return 39 cChar == ' ' || cChar == '\t' || 40 cChar == '\r' || cChar == '\n' || 41 cChar == 0x0c || cChar == 0x0b; 42 } 43 44 inline int isSpace( sal_Unicode cChar ) 45 { 46 return 47 cChar == ' ' || cChar == '\t' || 48 cChar == '\r' || cChar == '\n' || 49 cChar == 0x0c || cChar == 0x0b; 50 } 51 52 inline int isProtect( char cChar ) 53 { 54 return cChar == '`' || cChar == '\'' || cChar == '"'; 55 } 56 57 inline int isProtect( sal_Unicode cChar ) 58 { 59 return cChar == '`' || cChar == '\'' || cChar == '"'; 60 } 61 62 inline void CopyUntil( char*& pTo, const char*& pFrom, char cUntil, int bIncludeUntil = 0 ) 63 { 64 do 65 { 66 if( *pFrom == '\\' ) 67 { 68 pFrom++; 69 if( *pFrom ) 70 { 71 *pTo = *pFrom; 72 pTo++; 73 } 74 } 75 else if( bIncludeUntil || ! isProtect( *pFrom ) ) 76 { 77 *pTo = *pFrom; 78 pTo++; 79 } 80 pFrom++; 81 } while( *pFrom && *pFrom != cUntil ); 82 // copy the terminating character unless zero or protector 83 if( ! isProtect( *pFrom ) || bIncludeUntil ) 84 { 85 *pTo = *pFrom; 86 if( *pTo ) 87 pTo++; 88 } 89 if( *pFrom ) 90 pFrom++; 91 } 92 93 inline void CopyUntil( sal_Unicode*& pTo, const sal_Unicode*& pFrom, sal_Unicode cUntil, int bIncludeUntil = 0 ) 94 { 95 do 96 { 97 if( *pFrom == '\\' ) 98 { 99 pFrom++; 100 if( *pFrom ) 101 { 102 *pTo = *pFrom; 103 pTo++; 104 } 105 } 106 else if( bIncludeUntil || ! isProtect( *pFrom ) ) 107 { 108 *pTo = *pFrom; 109 pTo++; 110 } 111 pFrom++; 112 } while( *pFrom && *pFrom != cUntil ); 113 // copy the terminating character unless zero or protector 114 if( ! isProtect( *pFrom ) || bIncludeUntil ) 115 { 116 *pTo = *pFrom; 117 if( *pTo ) 118 pTo++; 119 } 120 if( *pFrom ) 121 pFrom++; 122 } 123 124 String GetCommandLineToken( int nToken, const String& rLine ) 125 { 126 int nLen = rLine.Len(); 127 if( ! nLen ) 128 return String(); 129 130 int nActualToken = 0; 131 sal_Unicode* pBuffer = (sal_Unicode*)alloca( sizeof(sal_Unicode)*( nLen + 1 ) ); 132 const sal_Unicode* pRun = rLine.GetBuffer(); 133 sal_Unicode* pLeap = NULL; 134 135 while( *pRun && nActualToken <= nToken ) 136 { 137 while( *pRun && isSpace( *pRun ) ) 138 pRun++; 139 pLeap = pBuffer; 140 while( *pRun && ! isSpace( *pRun ) ) 141 { 142 if( *pRun == '\\' ) 143 { 144 // escapement 145 pRun++; 146 *pLeap = *pRun; 147 pLeap++; 148 if( *pRun ) 149 pRun++; 150 } 151 else if( *pRun == '`' ) 152 CopyUntil( pLeap, pRun, '`' ); 153 else if( *pRun == '\'' ) 154 CopyUntil( pLeap, pRun, '\'' ); 155 else if( *pRun == '"' ) 156 CopyUntil( pLeap, pRun, '"' ); 157 else 158 { 159 *pLeap = *pRun; 160 pLeap++; 161 pRun++; 162 } 163 } 164 if( nActualToken != nToken ) 165 pBuffer[0] = 0; 166 nActualToken++; 167 } 168 169 *pLeap = 0; 170 171 String aRet( pBuffer ); 172 return aRet; 173 } 174 175 ByteString GetCommandLineToken( int nToken, const ByteString& rLine ) 176 { 177 int nLen = rLine.Len(); 178 if( ! nLen ) 179 return ByteString(); 180 181 int nActualToken = 0; 182 char* pBuffer = (char*)alloca( nLen + 1 ); 183 const char* pRun = rLine.GetBuffer(); 184 char* pLeap = NULL; 185 186 while( *pRun && nActualToken <= nToken ) 187 { 188 while( *pRun && isSpace( *pRun ) ) 189 pRun++; 190 pLeap = pBuffer; 191 while( *pRun && ! isSpace( *pRun ) ) 192 { 193 if( *pRun == '\\' ) 194 { 195 // escapement 196 pRun++; 197 *pLeap = *pRun; 198 pLeap++; 199 if( *pRun ) 200 pRun++; 201 } 202 else if( *pRun == '`' ) 203 CopyUntil( pLeap, pRun, '`' ); 204 else if( *pRun == '\'' ) 205 CopyUntil( pLeap, pRun, '\'' ); 206 else if( *pRun == '"' ) 207 CopyUntil( pLeap, pRun, '"' ); 208 else 209 { 210 *pLeap = *pRun; 211 pLeap++; 212 pRun++; 213 } 214 } 215 if( nActualToken != nToken ) 216 pBuffer[0] = 0; 217 nActualToken++; 218 } 219 220 *pLeap = 0; 221 222 ByteString aRet( pBuffer ); 223 return aRet; 224 } 225 226 int GetCommandLineTokenCount( const String& rLine ) 227 { 228 if( ! rLine.Len() ) 229 return 0; 230 231 int nTokenCount = 0; 232 const sal_Unicode *pRun = rLine.GetBuffer(); 233 234 235 while( *pRun ) 236 { 237 while( *pRun && isSpace( *pRun ) ) 238 pRun++; 239 if( ! *pRun ) 240 break; 241 while( *pRun && ! isSpace( *pRun ) ) 242 { 243 if( *pRun == '\\' ) 244 { 245 // escapement 246 pRun++; 247 if( *pRun ) 248 pRun++; 249 } 250 else if( *pRun == '`' ) 251 { 252 do pRun++; while( *pRun && *pRun != '`' ); 253 if( *pRun ) 254 pRun++; 255 } 256 else if( *pRun == '\'' ) 257 { 258 do pRun++; while( *pRun && *pRun != '\'' ); 259 if( *pRun ) 260 pRun++; 261 } 262 else if( *pRun == '"' ) 263 { 264 do pRun++; while( *pRun && *pRun != '"' ); 265 if( *pRun ) 266 pRun++; 267 } 268 else 269 pRun++; 270 } 271 nTokenCount++; 272 } 273 274 return nTokenCount; 275 } 276 277 int GetCommandLineTokenCount( const ByteString& rLine ) 278 { 279 if( ! rLine.Len() ) 280 return 0; 281 282 int nTokenCount = 0; 283 const char *pRun = rLine.GetBuffer(); 284 285 286 while( *pRun ) 287 { 288 while( *pRun && isSpace( *pRun ) ) 289 pRun++; 290 if( ! *pRun ) 291 break; 292 while( *pRun && ! isSpace( *pRun ) ) 293 { 294 if( *pRun == '\\' ) 295 { 296 // escapement 297 pRun++; 298 if( *pRun ) 299 pRun++; 300 } 301 else if( *pRun == '`' ) 302 { 303 do pRun++; while( *pRun && *pRun != '`' ); 304 if( *pRun ) 305 pRun++; 306 } 307 else if( *pRun == '\'' ) 308 { 309 do pRun++; while( *pRun && *pRun != '\'' ); 310 if( *pRun ) 311 pRun++; 312 } 313 else if( *pRun == '"' ) 314 { 315 do pRun++; while( *pRun && *pRun != '"' ); 316 if( *pRun ) 317 pRun++; 318 } 319 else 320 pRun++; 321 } 322 nTokenCount++; 323 } 324 325 return nTokenCount; 326 } 327 328 String WhitespaceToSpace( const String& rLine, sal_Bool bProtect ) 329 { 330 int nLen = rLine.Len(); 331 if( ! nLen ) 332 return String(); 333 334 sal_Unicode *pBuffer = (sal_Unicode*)alloca( sizeof(sal_Unicode)*(nLen + 1) ); 335 const sal_Unicode *pRun = rLine.GetBuffer(); 336 sal_Unicode *pLeap = pBuffer; 337 338 while( *pRun ) 339 { 340 if( *pRun && isSpace( *pRun ) ) 341 { 342 *pLeap = ' '; 343 pLeap++; 344 pRun++; 345 } 346 while( *pRun && isSpace( *pRun ) ) 347 pRun++; 348 while( *pRun && ! isSpace( *pRun ) ) 349 { 350 if( *pRun == '\\' ) 351 { 352 // escapement 353 pRun++; 354 *pLeap = *pRun; 355 pLeap++; 356 if( *pRun ) 357 pRun++; 358 } 359 else if( bProtect && *pRun == '`' ) 360 CopyUntil( pLeap, pRun, '`', sal_True ); 361 else if( bProtect && *pRun == '\'' ) 362 CopyUntil( pLeap, pRun, '\'', sal_True ); 363 else if( bProtect && *pRun == '"' ) 364 CopyUntil( pLeap, pRun, '"', sal_True ); 365 else 366 { 367 *pLeap = *pRun; 368 ++pLeap; 369 ++pRun; 370 } 371 } 372 } 373 374 *pLeap = 0; 375 376 // there might be a space at beginning or end 377 pLeap--; 378 if( *pLeap == ' ' ) 379 *pLeap = 0; 380 381 String aRet( *pBuffer == ' ' ? pBuffer+1 : pBuffer ); 382 return aRet; 383 } 384 385 ByteString WhitespaceToSpace( const ByteString& rLine, sal_Bool bProtect ) 386 { 387 int nLen = rLine.Len(); 388 if( ! nLen ) 389 return ByteString(); 390 391 char *pBuffer = (char*)alloca( nLen + 1 ); 392 const char *pRun = rLine.GetBuffer(); 393 char *pLeap = pBuffer; 394 395 while( *pRun ) 396 { 397 if( *pRun && isSpace( *pRun ) ) 398 { 399 *pLeap = ' '; 400 pLeap++; 401 pRun++; 402 } 403 while( *pRun && isSpace( *pRun ) ) 404 pRun++; 405 while( *pRun && ! isSpace( *pRun ) ) 406 { 407 if( *pRun == '\\' ) 408 { 409 // escapement 410 pRun++; 411 *pLeap = *pRun; 412 pLeap++; 413 if( *pRun ) 414 pRun++; 415 } 416 else if( bProtect && *pRun == '`' ) 417 CopyUntil( pLeap, pRun, '`', sal_True ); 418 else if( bProtect && *pRun == '\'' ) 419 CopyUntil( pLeap, pRun, '\'', sal_True ); 420 else if( bProtect && *pRun == '"' ) 421 CopyUntil( pLeap, pRun, '"', sal_True ); 422 else 423 { 424 *pLeap = *pRun; 425 ++pLeap; 426 ++pRun; 427 } 428 } 429 } 430 431 *pLeap = 0; 432 433 // there might be a space at beginning or end 434 pLeap--; 435 if( *pLeap == ' ' ) 436 *pLeap = 0; 437 438 ByteString aRet( *pBuffer == ' ' ? pBuffer+1 : pBuffer ); 439 return aRet; 440 } 441 442 } // namespace 443