xref: /aoo41x/main/vcl/source/helper/strhelper.cxx (revision cdf0e10c)
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