LibreOffice Module vcl (master)  1
strhelper.cxx
Go to the documentation of this file.
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 <strhelper.hxx>
21 
22 namespace {
23 
24 bool isSpace( sal_Unicode cChar )
25 {
26  return
27  cChar == ' ' || cChar == '\t' ||
28  cChar == '\r' || cChar == '\n' ||
29  cChar == 0x0c || cChar == 0x0b;
30 }
31 
32 bool isProtect( sal_Unicode cChar )
33 {
34  return cChar == '`' || cChar == '\'' || cChar == '"';
35 }
36 
37 void CopyUntil( char*& pTo, const char*& pFrom, char cUntil, bool bIncludeUntil = false )
38 {
39  do
40  {
41  if( *pFrom == '\\' )
42  {
43  pFrom++;
44  if( *pFrom )
45  {
46  *pTo = *pFrom;
47  pTo++;
48  }
49  }
50  else if( bIncludeUntil || ! isProtect( *pFrom ) )
51  {
52  *pTo = *pFrom;
53  pTo++;
54  }
55  pFrom++;
56  } while( *pFrom && *pFrom != cUntil );
57  // copy the terminating character unless zero or protector
58  if( ! isProtect( *pFrom ) || bIncludeUntil )
59  {
60  *pTo = *pFrom;
61  if( *pTo )
62  pTo++;
63  }
64  if( *pFrom )
65  pFrom++;
66 }
67 
68 void CopyUntil( sal_Unicode*& pTo, const sal_Unicode*& pFrom, sal_Unicode cUntil, bool bIncludeUntil = false )
69 {
70  do
71  {
72  if( *pFrom == '\\' )
73  {
74  pFrom++;
75  if( *pFrom )
76  {
77  *pTo = *pFrom;
78  pTo++;
79  }
80  }
81  else if( bIncludeUntil || ! isProtect( *pFrom ) )
82  {
83  *pTo = *pFrom;
84  pTo++;
85  }
86  if( *pFrom )
87  pFrom++;
88  } while( *pFrom && *pFrom != cUntil );
89  // copy the terminating character unless zero or protector
90  if( ! isProtect( *pFrom ) || bIncludeUntil )
91  {
92  *pTo = *pFrom;
93  if( *pTo )
94  pTo++;
95  }
96  if( *pFrom )
97  pFrom++;
98 }
99 
100 }
101 
102 namespace psp {
103 
104 OUString GetCommandLineToken( int nToken, const OUString& rLine )
105 {
106  sal_Int32 nLen = rLine.getLength();
107  if( ! nLen )
108  return OUString();
109 
110  int nActualToken = 0;
111  sal_Unicode* pBuffer = static_cast<sal_Unicode*>(alloca( sizeof(sal_Unicode)*( nLen + 1 ) ));
112  const sal_Unicode* pRun = rLine.getStr();
113  sal_Unicode* pLeap = nullptr;
114 
115  while( *pRun && nActualToken <= nToken )
116  {
117  while( *pRun && isSpace( *pRun ) )
118  pRun++;
119  pLeap = pBuffer;
120  while( *pRun && ! isSpace( *pRun ) )
121  {
122  if( *pRun == '\\' )
123  {
124  // escapement
125  pRun++;
126  *pLeap = *pRun;
127  pLeap++;
128  if( *pRun )
129  pRun++;
130  }
131  else if( *pRun == '`' )
132  CopyUntil( pLeap, pRun, '`' );
133  else if( *pRun == '\'' )
134  CopyUntil( pLeap, pRun, '\'' );
135  else if( *pRun == '"' )
136  CopyUntil( pLeap, pRun, '"' );
137  else
138  {
139  *pLeap = *pRun;
140  pLeap++;
141  pRun++;
142  }
143  }
144  if( nActualToken != nToken )
145  pBuffer[0] = 0;
146  nActualToken++;
147  }
148 
149  *pLeap = 0;
150 
151  return OUString(pBuffer);
152 }
153 
154 OString GetCommandLineToken(int nToken, const OString& rLine)
155 {
156  sal_Int32 nLen = rLine.getLength();
157  if (!nLen)
158  return rLine;
159 
160  int nActualToken = 0;
161  char* pBuffer = static_cast<char*>(alloca( nLen + 1 ));
162  const char* pRun = rLine.getStr();
163  char* pLeap = nullptr;
164 
165  while( *pRun && nActualToken <= nToken )
166  {
167  while( *pRun && isSpace( *pRun ) )
168  pRun++;
169  pLeap = pBuffer;
170  while( *pRun && ! isSpace( *pRun ) )
171  {
172  if( *pRun == '\\' )
173  {
174  // escapement
175  pRun++;
176  *pLeap = *pRun;
177  pLeap++;
178  if( *pRun )
179  pRun++;
180  }
181  else if( *pRun == '`' )
182  CopyUntil( pLeap, pRun, '`' );
183  else if( *pRun == '\'' )
184  CopyUntil( pLeap, pRun, '\'' );
185  else if( *pRun == '"' )
186  CopyUntil( pLeap, pRun, '"' );
187  else
188  {
189  *pLeap = *pRun;
190  pLeap++;
191  pRun++;
192  }
193  }
194  if( nActualToken != nToken )
195  pBuffer[0] = 0;
196  nActualToken++;
197  }
198 
199  *pLeap = 0;
200 
201  return pBuffer;
202 }
203 
204 int GetCommandLineTokenCount(const OUString& rLine)
205 {
206  if (rLine.isEmpty())
207  return 0;
208 
209  int nTokenCount = 0;
210  const sal_Unicode *pRun = rLine.getStr();
211 
212  while( *pRun )
213  {
214  while( *pRun && isSpace( *pRun ) )
215  pRun++;
216  if( ! *pRun )
217  break;
218  while( *pRun && ! isSpace( *pRun ) )
219  {
220  if( *pRun == '\\' )
221  {
222  // escapement
223  pRun++;
224  if( *pRun )
225  pRun++;
226  }
227  else if( *pRun == '`' )
228  {
229  do pRun++; while( *pRun && *pRun != '`' );
230  if( *pRun )
231  pRun++;
232  }
233  else if( *pRun == '\'' )
234  {
235  do pRun++; while( *pRun && *pRun != '\'' );
236  if( *pRun )
237  pRun++;
238  }
239  else if( *pRun == '"' )
240  {
241  do pRun++; while( *pRun && *pRun != '"' );
242  if( *pRun )
243  pRun++;
244  }
245  else
246  pRun++;
247  }
248  nTokenCount++;
249  }
250 
251  return nTokenCount;
252 }
253 
254 OUString WhitespaceToSpace( std::u16string_view rLine, bool bProtect )
255 {
256  size_t nLen = rLine.size();
257  if( ! nLen )
258  return OUString();
259 
260  sal_Unicode *pBuffer = static_cast<sal_Unicode*>(alloca( sizeof(sal_Unicode)*(nLen + 1) ));
261  const sal_Unicode *pRun = rLine.data();
262  const sal_Unicode * const pEnd = rLine.data() + rLine.size();
263  sal_Unicode *pLeap = pBuffer;
264 
265  while( pRun != pEnd )
266  {
267  if( pRun != pEnd && isSpace( *pRun ) )
268  {
269  *pLeap = ' ';
270  pLeap++;
271  pRun++;
272  }
273  while( pRun != pEnd && isSpace( *pRun ) )
274  pRun++;
275  while( pRun != pEnd && ! isSpace( *pRun ) )
276  {
277  if( *pRun == '\\' )
278  {
279  // escapement
280  pRun++;
281  *pLeap = *pRun;
282  pLeap++;
283  if( pRun != pEnd )
284  pRun++;
285  }
286  else if( bProtect && *pRun == '`' )
287  CopyUntil( pLeap, pRun, '`', true );
288  else if( bProtect && *pRun == '\'' )
289  CopyUntil( pLeap, pRun, '\'', true );
290  else if( bProtect && *pRun == '"' )
291  CopyUntil( pLeap, pRun, '"', true );
292  else
293  {
294  *pLeap = *pRun;
295  ++pLeap;
296  ++pRun;
297  }
298  }
299  }
300 
301  *pLeap = 0;
302 
303  // there might be a space at beginning or end
304  if (pLeap > pBuffer)
305  {
306  pLeap--;
307  if( *pLeap == ' ' )
308  *pLeap = 0;
309  }
310 
311  return OUString(*pBuffer == ' ' ? pBuffer+1 : pBuffer);
312 }
313 
314 OString WhitespaceToSpace(std::string_view rLine)
315 {
316  size_t nLen = rLine.size();
317  if (!nLen)
318  return OString();
319 
320  char *pBuffer = static_cast<char*>(alloca( nLen + 1 ));
321  const char *pRun = rLine.data();
322  const char * const pEnd = rLine.data() + rLine.size();
323  char *pLeap = pBuffer;
324 
325  while( pRun != pEnd )
326  {
327  if( pRun != pEnd && isSpace( *pRun ) )
328  {
329  *pLeap = ' ';
330  pLeap++;
331  pRun++;
332  }
333  while( pRun != pEnd && isSpace( *pRun ) )
334  pRun++;
335  while( pRun != pEnd && ! isSpace( *pRun ) )
336  {
337  if( *pRun == '\\' )
338  {
339  // escapement
340  pRun++;
341  *pLeap = *pRun;
342  pLeap++;
343  if( pRun != pEnd )
344  pRun++;
345  }
346  else if( *pRun == '`' )
347  CopyUntil( pLeap, pRun, '`', true );
348  else if( *pRun == '\'' )
349  CopyUntil( pLeap, pRun, '\'', true );
350  else if( *pRun == '"' )
351  CopyUntil( pLeap, pRun, '"', true );
352  else
353  {
354  *pLeap = *pRun;
355  ++pLeap;
356  ++pRun;
357  }
358  }
359  }
360 
361  *pLeap = 0;
362 
363  // there might be a space at beginning or end
364  assert(pLeap > pBuffer);
365  pLeap--;
366 #if defined(__GNUC__) && __GNUC__ == 12
367 #pragma GCC diagnostic push
368 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
369 #endif
370  if( *pLeap == ' ' )
371  *pLeap = 0;
372 #if defined(__GNUC__) && __GNUC__ == 12
373 #pragma GCC diagnostic pop
374 #endif
375  return *pBuffer == ' ' ? pBuffer+1 : pBuffer;
376 }
377 
378 } // namespace
379 
380 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
sal_uInt16 sal_Unicode
int GetCommandLineTokenCount(const OUString &rLine)
Definition: strhelper.cxx:204
OUString WhitespaceToSpace(std::u16string_view rLine, bool bProtect)
Definition: strhelper.cxx:254
OUString GetCommandLineToken(int nToken, const OUString &rLine)
Definition: strhelper.cxx:104