Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include "vcl/strhelper.hxx"
21 : #include "sal/alloca.h"
22 :
23 : namespace psp {
24 :
25 2448307 : inline bool isSpace( sal_Unicode cChar )
26 : {
27 : return
28 2193784 : cChar == ' ' || cChar == '\t' ||
29 2193784 : cChar == '\r' || cChar == '\n' ||
30 4642091 : cChar == 0x0c || cChar == 0x0b;
31 : }
32 :
33 26149 : inline bool isProtect( sal_Unicode cChar )
34 : {
35 26149 : return cChar == '`' || cChar == '\'' || cChar == '"';
36 : }
37 :
38 715898 : inline void CopyUntil( char*& pTo, const char*& pFrom, char cUntil, bool bIncludeUntil = false )
39 : {
40 715898 : do
41 : {
42 715898 : if( *pFrom == '\\' )
43 : {
44 158 : pFrom++;
45 158 : if( *pFrom )
46 : {
47 158 : *pTo = *pFrom;
48 158 : pTo++;
49 : }
50 : }
51 715740 : else if( bIncludeUntil || ! isProtect( *pFrom ) )
52 : {
53 715740 : *pTo = *pFrom;
54 715740 : pTo++;
55 : }
56 715898 : pFrom++;
57 715898 : } while( *pFrom && *pFrom != cUntil );
58 : // copy the terminating character unless zero or protector
59 26149 : if( ! isProtect( *pFrom ) || bIncludeUntil )
60 : {
61 26149 : *pTo = *pFrom;
62 26149 : if( *pTo )
63 26149 : pTo++;
64 : }
65 26149 : if( *pFrom )
66 26149 : pFrom++;
67 26149 : }
68 :
69 0 : inline void CopyUntil( sal_Unicode*& pTo, const sal_Unicode*& pFrom, sal_Unicode cUntil, bool bIncludeUntil = false )
70 : {
71 0 : do
72 : {
73 0 : if( *pFrom == '\\' )
74 : {
75 0 : pFrom++;
76 0 : if( *pFrom )
77 : {
78 0 : *pTo = *pFrom;
79 0 : pTo++;
80 : }
81 : }
82 0 : else if( bIncludeUntil || ! isProtect( *pFrom ) )
83 : {
84 0 : *pTo = *pFrom;
85 0 : pTo++;
86 : }
87 0 : pFrom++;
88 0 : } while( *pFrom && *pFrom != cUntil );
89 : // copy the terminating character unless zero or protector
90 0 : if( ! isProtect( *pFrom ) || bIncludeUntil )
91 : {
92 0 : *pTo = *pFrom;
93 0 : if( *pTo )
94 0 : pTo++;
95 : }
96 0 : if( *pFrom )
97 0 : pFrom++;
98 0 : }
99 :
100 32047 : OUString GetCommandLineToken( int nToken, const OUString& rLine )
101 : {
102 32047 : sal_Int32 nLen = rLine.getLength();
103 32047 : if( ! nLen )
104 0 : return OUString();
105 :
106 32047 : int nActualToken = 0;
107 32047 : sal_Unicode* pBuffer = static_cast<sal_Unicode*>(alloca( sizeof(sal_Unicode)*( nLen + 1 ) ));
108 32047 : const sal_Unicode* pRun = rLine.getStr();
109 32047 : sal_Unicode* pLeap = NULL;
110 :
111 122953 : while( *pRun && nActualToken <= nToken )
112 : {
113 144530 : while( *pRun && isSpace( *pRun ) )
114 26812 : pRun++;
115 58859 : pLeap = pBuffer;
116 797699 : while( *pRun && ! isSpace( *pRun ) )
117 : {
118 679981 : if( *pRun == '\\' )
119 : {
120 : // escapement
121 0 : pRun++;
122 0 : *pLeap = *pRun;
123 0 : pLeap++;
124 0 : if( *pRun )
125 0 : pRun++;
126 : }
127 679981 : else if( *pRun == '`' )
128 0 : CopyUntil( pLeap, pRun, '`' );
129 679981 : else if( *pRun == '\'' )
130 0 : CopyUntil( pLeap, pRun, '\'' );
131 679981 : else if( *pRun == '"' )
132 0 : CopyUntil( pLeap, pRun, '"' );
133 : else
134 : {
135 679981 : *pLeap = *pRun;
136 679981 : pLeap++;
137 679981 : pRun++;
138 : }
139 : }
140 58859 : if( nActualToken != nToken )
141 31552 : pBuffer[0] = 0;
142 58859 : nActualToken++;
143 : }
144 :
145 32047 : *pLeap = 0;
146 :
147 32047 : return OUString(pBuffer);
148 : }
149 :
150 31047 : OString GetCommandLineToken(int nToken, const OString& rLine)
151 : {
152 31047 : sal_Int32 nLen = rLine.getLength();
153 31047 : if (!nLen)
154 0 : return rLine;
155 :
156 31047 : int nActualToken = 0;
157 31047 : char* pBuffer = static_cast<char*>(alloca( nLen + 1 ));
158 31047 : const char* pRun = rLine.getStr();
159 31047 : char* pLeap = NULL;
160 :
161 94405 : while( *pRun && nActualToken <= nToken )
162 : {
163 66834 : while( *pRun && isSpace( *pRun ) )
164 2212 : pRun++;
165 32311 : pLeap = pBuffer;
166 464125 : while( *pRun && ! isSpace( *pRun ) )
167 : {
168 399503 : if( *pRun == '\\' )
169 : {
170 : // escapement
171 0 : pRun++;
172 0 : *pLeap = *pRun;
173 0 : pLeap++;
174 0 : if( *pRun )
175 0 : pRun++;
176 : }
177 399503 : else if( *pRun == '`' )
178 0 : CopyUntil( pLeap, pRun, '`' );
179 399503 : else if( *pRun == '\'' )
180 0 : CopyUntil( pLeap, pRun, '\'' );
181 399503 : else if( *pRun == '"' )
182 0 : CopyUntil( pLeap, pRun, '"' );
183 : else
184 : {
185 399503 : *pLeap = *pRun;
186 399503 : pLeap++;
187 399503 : pRun++;
188 : }
189 : }
190 32311 : if( nActualToken != nToken )
191 1264 : pBuffer[0] = 0;
192 32311 : nActualToken++;
193 : }
194 :
195 31047 : *pLeap = 0;
196 :
197 31047 : return OString(pBuffer);
198 : }
199 :
200 0 : int GetCommandLineTokenCount(const OUString& rLine)
201 : {
202 0 : if (rLine.isEmpty())
203 0 : return 0;
204 :
205 0 : int nTokenCount = 0;
206 0 : const sal_Unicode *pRun = rLine.getStr();
207 :
208 0 : while( *pRun )
209 : {
210 0 : while( *pRun && isSpace( *pRun ) )
211 0 : pRun++;
212 0 : if( ! *pRun )
213 0 : break;
214 0 : while( *pRun && ! isSpace( *pRun ) )
215 : {
216 0 : if( *pRun == '\\' )
217 : {
218 : // escapement
219 0 : pRun++;
220 0 : if( *pRun )
221 0 : pRun++;
222 : }
223 0 : else if( *pRun == '`' )
224 : {
225 0 : do pRun++; while( *pRun && *pRun != '`' );
226 0 : if( *pRun )
227 0 : pRun++;
228 : }
229 0 : else if( *pRun == '\'' )
230 : {
231 0 : do pRun++; while( *pRun && *pRun != '\'' );
232 0 : if( *pRun )
233 0 : pRun++;
234 : }
235 0 : else if( *pRun == '"' )
236 : {
237 0 : do pRun++; while( *pRun && *pRun != '"' );
238 0 : if( *pRun )
239 0 : pRun++;
240 : }
241 : else
242 0 : pRun++;
243 : }
244 0 : nTokenCount++;
245 : }
246 :
247 0 : return nTokenCount;
248 : }
249 :
250 3654 : OUString WhitespaceToSpace( const OUString& rLine, bool bProtect )
251 : {
252 3654 : sal_Int32 nLen = rLine.getLength();
253 3654 : if( ! nLen )
254 232 : return OUString();
255 :
256 3422 : sal_Unicode *pBuffer = static_cast<sal_Unicode*>(alloca( sizeof(sal_Unicode)*(nLen + 1) ));
257 3422 : const sal_Unicode *pRun = rLine.getStr();
258 3422 : sal_Unicode *pLeap = pBuffer;
259 :
260 11890 : while( *pRun )
261 : {
262 5046 : if( *pRun && isSpace( *pRun ) )
263 : {
264 5046 : *pLeap = ' ';
265 5046 : pLeap++;
266 5046 : pRun++;
267 : }
268 10092 : while( *pRun && isSpace( *pRun ) )
269 0 : pRun++;
270 38048 : while( *pRun && ! isSpace( *pRun ) )
271 : {
272 27956 : if( *pRun == '\\' )
273 : {
274 : // escapement
275 0 : pRun++;
276 0 : *pLeap = *pRun;
277 0 : pLeap++;
278 0 : if( *pRun )
279 0 : pRun++;
280 : }
281 27956 : else if( bProtect && *pRun == '`' )
282 0 : CopyUntil( pLeap, pRun, '`', true );
283 27956 : else if( bProtect && *pRun == '\'' )
284 0 : CopyUntil( pLeap, pRun, '\'', true );
285 27956 : else if( bProtect && *pRun == '"' )
286 0 : CopyUntil( pLeap, pRun, '"', true );
287 : else
288 : {
289 27956 : *pLeap = *pRun;
290 27956 : ++pLeap;
291 27956 : ++pRun;
292 : }
293 : }
294 : }
295 :
296 3422 : *pLeap = 0;
297 :
298 : // there might be a space at beginning or end
299 3422 : pLeap--;
300 3422 : if( *pLeap == ' ' )
301 58 : *pLeap = 0;
302 :
303 3422 : return OUString(*pBuffer == ' ' ? pBuffer+1 : pBuffer);
304 : }
305 :
306 55537 : OString WhitespaceToSpace(const OString& rLine, bool bProtect)
307 : {
308 55537 : sal_Int32 nLen = rLine.getLength();
309 55537 : if (!nLen)
310 0 : return rLine;
311 :
312 55537 : char *pBuffer = static_cast<char*>(alloca( nLen + 1 ));
313 55537 : const char *pRun = rLine.getStr();
314 55537 : char *pLeap = pBuffer;
315 :
316 229574 : while( *pRun )
317 : {
318 118500 : if( *pRun && isSpace( *pRun ) )
319 : {
320 91245 : *pLeap = ' ';
321 91245 : pLeap++;
322 91245 : pRun++;
323 : }
324 237000 : while( *pRun && isSpace( *pRun ) )
325 0 : pRun++;
326 1081431 : while( *pRun && ! isSpace( *pRun ) )
327 : {
328 844431 : if( *pRun == '\\' )
329 : {
330 : // escapement
331 0 : pRun++;
332 0 : *pLeap = *pRun;
333 0 : pLeap++;
334 0 : if( *pRun )
335 0 : pRun++;
336 : }
337 844431 : else if( bProtect && *pRun == '`' )
338 0 : CopyUntil( pLeap, pRun, '`', true );
339 844431 : else if( bProtect && *pRun == '\'' )
340 0 : CopyUntil( pLeap, pRun, '\'', true );
341 844431 : else if( bProtect && *pRun == '"' )
342 26149 : CopyUntil( pLeap, pRun, '"', true );
343 : else
344 : {
345 818282 : *pLeap = *pRun;
346 818282 : ++pLeap;
347 818282 : ++pRun;
348 : }
349 : }
350 : }
351 :
352 55537 : *pLeap = 0;
353 :
354 : // there might be a space at beginning or end
355 55537 : pLeap--;
356 55537 : if( *pLeap == ' ' )
357 0 : *pLeap = 0;
358 :
359 55537 : return OString(*pBuffer == ' ' ? pBuffer+1 : pBuffer);
360 : }
361 :
362 : } // namespace
363 :
364 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|