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