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