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
isSpace(char cChar)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
isSpace(sal_Unicode cChar)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
isProtect(char cChar)48 inline int isProtect( char cChar )
49 {
50 return cChar == '`' || cChar == '\'' || cChar == '"';
51 }
52
isProtect(sal_Unicode cChar)53 inline int isProtect( sal_Unicode cChar )
54 {
55 return cChar == '`' || cChar == '\'' || cChar == '"';
56 }
57
CopyUntil(char * & pTo,const char * & pFrom,char cUntil,int bIncludeUntil=0)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
CopyUntil(sal_Unicode * & pTo,const sal_Unicode * & pFrom,sal_Unicode cUntil,int bIncludeUntil=0)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
GetCommandLineToken(int nToken,const String & rLine)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
GetCommandLineToken(int nToken,const ByteString & rLine)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
GetCommandLineTokenCount(const String & rLine)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
GetCommandLineTokenCount(const ByteString & rLine)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
WhitespaceToSpace(const String & rLine,sal_Bool bProtect)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
WhitespaceToSpace(const ByteString & rLine,sal_Bool bProtect)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