KiCad PCB EDA Suite
string.cpp
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2004-2019 KiCad Developers, see AUTHORS.txt for contributors.
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, you may find one here:
18  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19  * or you may search the http://www.gnu.org website for the version 2 license,
20  * or you may write to the Free Software Foundation, Inc.,
21  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22  */
23 
29 #include <clocale>
30 #include <macros.h>
31 #include <richio.h> // StrPrintf
32 #include <kicad_string.h>
33 
34 
40 static const char illegalFileNameChars[] = "\\/:\"<>|";
41 
42 
43 bool ConvertSmartQuotesAndDashes( wxString* aString )
44 {
45  bool retVal = false;
46 
47  for( wxString::iterator ii = aString->begin(); ii != aString->end(); ++ii )
48  {
49  if( *ii == L'\u00B4' || *ii == L'\u2018' || *ii == L'\u2019' )
50  {
51  *ii = '\'';
52  retVal = true;
53  }
54  if( *ii == L'\u201C' || *ii == L'\u201D' )
55  {
56  *ii = '"';
57  retVal = true;
58  }
59  if( *ii == L'\u2013' || *ii == L'\u2014' )
60  {
61  *ii = '-';
62  retVal = true;
63  }
64  }
65 
66  return retVal;
67 }
68 
69 
77 wxString EscapeString( const wxString& aSource, ESCAPE_CONTEXT aContext )
78 {
79  wxString converted;
80 
81  for( wxUniChar c: aSource )
82  {
83  if( aContext == CTX_NETNAME )
84  {
85  if( c == '/' )
86  converted += "{slash}";
87  else if( c == '\n' || c == '\r' )
88  converted += ""; // drop
89  else
90  converted += c;
91  }
92  else if( aContext == CTX_LIBID )
93  {
94  if( c == '{' )
95  converted += "{brace}";
96  else if( c == ':' )
97  converted += "{colon}";
98  else if( c == '\n' || c == '\r' )
99  converted += ""; // drop
100  else
101  converted += c;
102  }
103  else if( aContext == CTX_QUOTED_STR )
104  {
105  if( c == '{' )
106  converted += "{brace}";
107  else if( c == '\"' )
108  converted += "{dblquote}";
109  else
110  converted += c;
111  }
112  else if( aContext == CTX_LINE )
113  {
114  if( c == '\n' || c == '\r' )
115  converted += "{return}";
116  else
117  converted += c;
118  }
119  else if( aContext == CTX_FILENAME )
120  {
121  if( c == '{' )
122  converted += "{brace}";
123  else if( c == '/' )
124  converted += "{slash}";
125  else if( c == '\\' )
126  converted += "{backslash}";
127  else if( c == '\"' )
128  converted += "{dblquote}";
129  else if( c == '<' )
130  converted += "{lt}";
131  else if( c == '>' )
132  converted += "{gt}";
133  else if( c == '|' )
134  converted += "{bar}";
135  else if( c == ':' )
136  converted += "{colon}";
137  else if( c == '\t' )
138  converted += "{tab}";
139  else if( c == '\n' || c == '\r' )
140  converted += "{return}";
141  else
142  converted += c;
143  }
144  else
145  converted += c;
146  }
147 
148  return converted;
149 }
150 
151 
152 wxString UnescapeString( const wxString& aSource )
153 {
154  wxString newbuf;
155  size_t sourceLen = aSource.length();
156 
157  for( size_t i = 0; i < sourceLen; ++i )
158  {
159  if( ( aSource[i] == '$' || aSource[i] == '^' || aSource[i] == '_' )
160  && i + 1 < sourceLen && aSource[i+1] == '{' )
161  {
162  for( ; i < sourceLen; ++i )
163  {
164  newbuf += aSource[i];
165 
166  if( aSource[i] == '}' )
167  break;
168  }
169  }
170  else if( aSource[i] == '{' )
171  {
172  wxString token;
173 
174  for( i = i + 1; i < sourceLen; ++i )
175  {
176  if( aSource[i] == '}' )
177  break;
178  else
179  token.append( aSource[i] );
180  }
181 
182  if( token == wxS( "dblquote" ) ) newbuf.append( wxS( "\"" ) );
183  else if( token == wxS( "quote" ) ) newbuf.append( wxS( "'" ) );
184  else if( token == wxS( "lt" ) ) newbuf.append( wxS( "<" ) );
185  else if( token == wxS( "gt" ) ) newbuf.append( wxS( ">" ) );
186  else if( token == wxS( "backslash" ) ) newbuf.append( wxS( "\\" ) );
187  else if( token == wxS( "slash" ) ) newbuf.append( wxS( "/" ) );
188  else if( token == wxS( "bar" ) ) newbuf.append( wxS( "|" ) );
189  else if( token == wxS( "colon" ) ) newbuf.append( wxS( ":" ) );
190  else if( token == wxS( "space" ) ) newbuf.append( wxS( " " ) );
191  else if( token == wxS( "dollar" ) ) newbuf.append( wxS( "$" ) );
192  else if( token == wxS( "tab" ) ) newbuf.append( wxS( "\t" ) );
193  else if( token == wxS( "return" ) ) newbuf.append( wxS( "\n" ) );
194  else if( token == wxS( "brace" ) ) newbuf.append( wxS( "{" ) );
195  else
196  {
197  newbuf.append( "{" + token + "}" );
198  }
199  }
200  else
201  {
202  newbuf.append( aSource[i] );
203  }
204  }
205 
206  return newbuf;
207 }
208 
209 
210 int ReadDelimitedText( wxString* aDest, const char* aSource )
211 {
212  std::string utf8; // utf8 but without escapes and quotes.
213  bool inside = false;
214  const char* start = aSource;
215  char cc;
216 
217  while( (cc = *aSource++) != 0 )
218  {
219  if( cc == '"' )
220  {
221  if( inside )
222  break; // 2nd double quote is end of delimited text
223 
224  inside = true; // first delimiter found, make note, do not copy
225  }
226 
227  else if( inside )
228  {
229  if( cc == '\\' )
230  {
231  cc = *aSource++;
232 
233  if( !cc )
234  break;
235 
236  // do no copy the escape byte if it is followed by \ or "
237  if( cc != '"' && cc != '\\' )
238  utf8 += '\\';
239 
240  utf8 += cc;
241  }
242  else
243  {
244  utf8 += cc;
245  }
246  }
247  }
248 
249  *aDest = FROM_UTF8( utf8.c_str() );
250 
251  return aSource - start;
252 }
253 
254 
255 int ReadDelimitedText( char* aDest, const char* aSource, int aDestSize )
256 {
257  if( aDestSize <= 0 )
258  return 0;
259 
260  bool inside = false;
261  const char* start = aSource;
262  char* limit = aDest + aDestSize - 1;
263  char cc;
264 
265  while( (cc = *aSource++) != 0 && aDest < limit )
266  {
267  if( cc == '"' )
268  {
269  if( inside )
270  break; // 2nd double quote is end of delimited text
271 
272  inside = true; // first delimiter found, make note, do not copy
273  }
274 
275  else if( inside )
276  {
277  if( cc == '\\' )
278  {
279  cc = *aSource++;
280 
281  if( !cc )
282  break;
283 
284  // do no copy the escape byte if it is followed by \ or "
285  if( cc != '"' && cc != '\\' )
286  *aDest++ = '\\';
287 
288  if( aDest < limit )
289  *aDest++ = cc;
290  }
291  else
292  {
293  *aDest++ = cc;
294  }
295  }
296  }
297 
298  *aDest = 0;
299 
300  return aSource - start;
301 }
302 
303 
304 std::string EscapedUTF8( wxString aString )
305 {
306  // No new-lines allowed in quoted strings
307  aString.Replace( "\r\n", "\r" );
308  aString.Replace( "\n", "\r" );
309 
310  std::string utf8 = TO_UTF8( aString );
311 
312  std::string ret;
313 
314  ret += '"';
315 
316  for( std::string::const_iterator it = utf8.begin(); it!=utf8.end(); ++it )
317  {
318  // this escaping strategy is designed to be compatible with ReadDelimitedText():
319  if( *it == '"' )
320  {
321  ret += '\\';
322  ret += '"';
323  }
324  else if( *it == '\\' )
325  {
326  ret += '\\'; // double it up
327  ret += '\\';
328  }
329  else
330  {
331  ret += *it;
332  }
333  }
334 
335  ret += '"';
336 
337  return ret;
338 }
339 
340 
341 wxString EscapeHTML( const wxString& aString )
342 {
343  wxString converted;
344 
345  for( wxUniChar c: aString )
346  {
347  if( c == '\"' )
348  converted += "&quot;";
349  else if( c == '\'' )
350  converted += "&apos;";
351  else if( c == '&' )
352  converted += "&amp;";
353  else if( c == '<' )
354  converted += "&lt;";
355  else if( c == '>' )
356  converted += "&gt;";
357  else
358  converted += c;
359  }
360 
361  return converted;
362 }
363 
364 
365 bool NoPrintableChars( wxString aString )
366 {
367  return aString.Trim( true ).Trim( false ).IsEmpty();
368 }
369 
370 
371 char* StrPurge( char* text )
372 {
373  static const char whitespace[] = " \t\n\r\f\v";
374 
375  if( text )
376  {
377  while( *text && strchr( whitespace, *text ) )
378  ++text;
379 
380  char* cp = text + strlen( text ) - 1;
381 
382  while( cp >= text && strchr( whitespace, *cp ) )
383  *cp-- = '\0';
384  }
385 
386  return text;
387 }
388 
389 
390 char* GetLine( FILE* File, char* Line, int* LineNum, int SizeLine )
391 {
392  do {
393  if( fgets( Line, SizeLine, File ) == NULL )
394  return NULL;
395 
396  if( LineNum )
397  *LineNum += 1;
398 
399  } while( Line[0] == '#' || Line[0] == '\n' || Line[0] == '\r' || Line[0] == 0 );
400 
401  strtok( Line, "\n\r" );
402  return Line;
403 }
404 
405 
406 wxString DateAndTime()
407 {
408  wxDateTime datetime = wxDateTime::Now();
409 
410  datetime.SetCountry( wxDateTime::Country_Default );
411  return datetime.Format( wxDefaultDateTimeFormat, wxDateTime::Local );
412 }
413 
414 
415 int StrNumCmp( const wxString& aString1, const wxString& aString2, bool aIgnoreCase )
416 {
417  int nb1 = 0, nb2 = 0;
418 
419  auto str1 = aString1.begin();
420  auto str2 = aString2.begin();
421 
422  while( str1 != aString1.end() && str2 != aString2.end() )
423  {
424  wxUniChar c1 = *str1;
425  wxUniChar c2 = *str2;
426 
427  if( wxIsdigit( c1 ) && wxIsdigit( c2 ) ) // Both characters are digits, do numeric compare.
428  {
429  nb1 = 0;
430  nb2 = 0;
431 
432  do
433  {
434  c1 = *str1;
435  nb1 = nb1 * 10 + (int) c1 - '0';
436  ++str1;
437  } while( str1 != aString1.end() && wxIsdigit( *str1 ) );
438 
439  do
440  {
441  c2 = *str2;
442  nb2 = nb2 * 10 + (int) c2 - '0';
443  ++str2;
444  } while( str2 != aString2.end() && wxIsdigit( *str2 ) );
445 
446  if( nb1 < nb2 )
447  return -1;
448 
449  if( nb1 > nb2 )
450  return 1;
451 
452  c1 = ( str1 != aString1.end() ) ? *str1 : wxUniChar( 0 );
453  c2 = ( str2 != aString2.end() ) ? *str2 : wxUniChar( 0 );
454  }
455 
456  // Any numerical comparisons to here are identical.
457  if( aIgnoreCase )
458  {
459  if( wxToupper( c1 ) < wxToupper( c2 ) )
460  return -1;
461 
462  if( wxToupper( c1 ) > wxToupper( c2 ) )
463  return 1;
464  }
465  else
466  {
467  if( c1 < c2 )
468  return -1;
469 
470  if( c1 > c2 )
471  return 1;
472  }
473 
474  if( str1 != aString1.end() )
475  ++str1;
476 
477  if( str2 != aString2.end() )
478  ++str2;
479  }
480 
481  if( str1 == aString1.end() && str2 != aString2.end() )
482  {
483  return -1; // Identical to here but aString1 is longer.
484  }
485  else if( str1 != aString1.end() && str2 == aString2.end() )
486  {
487  return 1; // Identical to here but aString2 is longer.
488  }
489 
490  return 0;
491 }
492 
493 
494 bool WildCompareString( const wxString& pattern, const wxString& string_to_tst,
495  bool case_sensitive )
496 {
497  const wxChar* cp = NULL, * mp = NULL;
498  const wxChar* wild, * string;
499  wxString _pattern, _string_to_tst;
500 
501  if( case_sensitive )
502  {
503  wild = pattern.GetData();
504  string = string_to_tst.GetData();
505  }
506  else
507  {
508  _pattern = pattern;
509  _pattern.MakeUpper();
510  _string_to_tst = string_to_tst;
511  _string_to_tst.MakeUpper();
512  wild = _pattern.GetData();
513  string = _string_to_tst.GetData();
514  }
515 
516  while( ( *string ) && ( *wild != '*' ) )
517  {
518  if( ( *wild != *string ) && ( *wild != '?' ) )
519  return false;
520 
521  wild++; string++;
522  }
523 
524  while( *string )
525  {
526  if( *wild == '*' )
527  {
528  if( !*++wild )
529  return 1;
530  mp = wild;
531  cp = string + 1;
532  }
533  else if( ( *wild == *string ) || ( *wild == '?' ) )
534  {
535  wild++;
536  string++;
537  }
538  else
539  {
540  wild = mp;
541  string = cp++;
542  }
543  }
544 
545  while( *wild == '*' )
546  {
547  wild++;
548  }
549 
550  return !*wild;
551 }
552 
553 
554 bool ApplyModifier( double& value, const wxString& aString )
555 {
556  static const wxString modifiers( wxT( "pnumkKM" ) );
557 
558  if( !aString.length() )
559  return false;
560 
561  wxChar modifier;
562  wxString units;
563 
564  if( modifiers.Find( aString[ 0 ] ) >= 0 )
565  {
566  modifier = aString[ 0 ];
567  units = aString.Mid( 1 ).Trim();
568  }
569  else
570  {
571  modifier = ' ';
572  units = aString.Mid( 0 ).Trim();
573  }
574 
575  if( units.length()
576  && !units.CmpNoCase( wxT( "F" ) )
577  && !units.CmpNoCase( wxT( "hz" ) )
578  && !units.CmpNoCase( wxT( "W" ) )
579  && !units.CmpNoCase( wxT( "V" ) )
580  && !units.CmpNoCase( wxT( "H" ) ) )
581  return false;
582 
583  if( modifier == 'p' )
584  value *= 1.0e-12;
585  if( modifier == 'n' )
586  value *= 1.0e-9;
587  else if( modifier == 'u' )
588  value *= 1.0e-6;
589  else if( modifier == 'm' )
590  value *= 1.0e-3;
591  else if( modifier == 'k' || modifier == 'K' )
592  value *= 1.0e3;
593  else if( modifier == 'M' )
594  value *= 1.0e6;
595  else if( modifier == 'G' )
596  value *= 1.0e9;
597 
598  return true;
599 }
600 
601 
602 int ValueStringCompare( wxString strFWord, wxString strSWord )
603 {
604  // Compare unescaped text
605  strFWord = UnescapeString( strFWord );
606  strSWord = UnescapeString( strSWord );
607 
608  // The different sections of the two strings
609  wxString strFWordBeg, strFWordMid, strFWordEnd;
610  wxString strSWordBeg, strSWordMid, strSWordEnd;
611 
612  // Split the two strings into separate parts
613  SplitString( strFWord, &strFWordBeg, &strFWordMid, &strFWordEnd );
614  SplitString( strSWord, &strSWordBeg, &strSWordMid, &strSWordEnd );
615 
616  // Compare the Beginning section of the strings
617  int isEqual = strFWordBeg.CmpNoCase( strSWordBeg );
618 
619  if( isEqual > 0 )
620  return 1;
621  else if( isEqual < 0 )
622  return -1;
623  else
624  {
625  // If the first sections are equal compare their digits
626  double lFirstNumber = 0;
627  double lSecondNumber = 0;
628  bool endingIsModifier = false;
629 
630  strFWordMid.ToDouble( &lFirstNumber );
631  strSWordMid.ToDouble( &lSecondNumber );
632 
633  endingIsModifier |= ApplyModifier( lFirstNumber, strFWordEnd );
634  endingIsModifier |= ApplyModifier( lSecondNumber, strSWordEnd );
635 
636  if( lFirstNumber > lSecondNumber )
637  return 1;
638  else if( lFirstNumber < lSecondNumber )
639  return -1;
640  // If the first two sections are equal and the endings are modifiers then compare them
641  else if( !endingIsModifier )
642  return strFWordEnd.CmpNoCase( strSWordEnd );
643  // Ran out of things to compare; they must match
644  else
645  return 0;
646  }
647 }
648 
649 
650 int SplitString( wxString strToSplit,
651  wxString* strBeginning,
652  wxString* strDigits,
653  wxString* strEnd )
654 {
655  static const wxString separators( wxT( ".," ) );
656 
657  // Clear all the return strings
658  strBeginning->Empty();
659  strDigits->Empty();
660  strEnd->Empty();
661 
662  // There no need to do anything if the string is empty
663  if( strToSplit.length() == 0 )
664  return 0;
665 
666  // Starting at the end of the string look for the first digit
667  int ii;
668 
669  for( ii = (strToSplit.length() - 1); ii >= 0; ii-- )
670  {
671  if( wxIsdigit( strToSplit[ii] ) )
672  break;
673  }
674 
675  // If there were no digits then just set the single string
676  if( ii < 0 )
677  {
678  *strBeginning = strToSplit;
679  }
680  else
681  {
682  // Since there is at least one digit this is the trailing string
683  *strEnd = strToSplit.substr( ii + 1 );
684 
685  // Go to the end of the digits
686  int position = ii + 1;
687 
688  for( ; ii >= 0; ii-- )
689  {
690  if( !wxIsdigit( strToSplit[ii] ) && separators.Find( strToSplit[ii] ) < 0 )
691  break;
692  }
693 
694  // If all that was left was digits, then just set the digits string
695  if( ii < 0 )
696  *strDigits = strToSplit.substr( 0, position );
697 
698  /* We were only looking for the last set of digits everything else is
699  * part of the preamble */
700  else
701  {
702  *strDigits = strToSplit.substr( ii + 1, position - ii - 1 );
703  *strBeginning = strToSplit.substr( 0, ii + 1 );
704  }
705  }
706 
707  return 0;
708 }
709 
710 
711 int GetTrailingInt( const wxString& aStr )
712 {
713  int number = 0;
714  int base = 1;
715 
716  // Trim and extract the trailing numeric part
717  int index = aStr.Len() - 1;
718 
719  while( index >= 0 )
720  {
721  const char chr = aStr.GetChar( index );
722 
723  if( chr < '0' || chr > '9' )
724  break;
725 
726  number += ( chr - '0' ) * base;
727  base *= 10;
728  index--;
729  }
730 
731  return number;
732 }
733 
734 
736 {
738 }
739 
740 
741 bool ReplaceIllegalFileNameChars( std::string* aName, int aReplaceChar )
742 {
743  bool changed = false;
744  std::string result;
745  result.reserve( aName->length() );
746 
747  for( std::string::iterator it = aName->begin(); it != aName->end(); ++it )
748  {
749  if( strchr( illegalFileNameChars, *it ) )
750  {
751  if( aReplaceChar )
752  StrPrintf( &result, "%c", aReplaceChar );
753  else
754  StrPrintf( &result, "%%%02x", *it );
755 
756  changed = true;
757  }
758  else
759  {
760  result += *it;
761  }
762  }
763 
764  if( changed )
765  *aName = result;
766 
767  return changed;
768 }
769 
770 
771 bool ReplaceIllegalFileNameChars( wxString& aName, int aReplaceChar )
772 {
773  bool changed = false;
774  wxString result;
775  result.reserve( aName.Length() );
776  wxString illWChars = GetIllegalFileNameWxChars();
777 
778  for( wxString::iterator it = aName.begin(); it != aName.end(); ++it )
779  {
780  if( illWChars.Find( *it ) != wxNOT_FOUND )
781  {
782  if( aReplaceChar )
783  result += aReplaceChar;
784  else
785  result += wxString::Format( "%%%02x", *it );
786 
787  changed = true;
788  }
789  else
790  {
791  result += *it;
792  }
793  }
794 
795  if( changed )
796  aName = result;
797 
798  return changed;
799 }
800 
801 
802 void wxStringSplit( const wxString& aText, wxArrayString& aStrings, wxChar aSplitter )
803 {
804  wxString tmp;
805 
806  for( unsigned ii = 0; ii < aText.Length(); ii++ )
807  {
808  if( aText[ii] == aSplitter )
809  {
810  aStrings.Add( tmp );
811  tmp.Clear();
812  }
813 
814  else
815  tmp << aText[ii];
816  }
817 
818  if( !tmp.IsEmpty() )
819  {
820  aStrings.Add( tmp );
821  }
822 }
823 
824 
825 void StripTrailingZeros( wxString& aStringValue, unsigned aTrailingZeroAllowed )
826 {
827  struct lconv* lc = localeconv();
828  char sep = lc->decimal_point[0];
829  unsigned sep_pos = aStringValue.Find( sep );
830 
831  if( sep_pos > 0 )
832  {
833  // We want to keep at least aTrailingZeroAllowed digits after the separator
834  unsigned min_len = sep_pos + aTrailingZeroAllowed + 1;
835 
836  while( aStringValue.Len() > min_len )
837  {
838  if( aStringValue.Last() == '0' )
839  aStringValue.RemoveLast();
840  else
841  break;
842  }
843  }
844 }
static const char illegalFileNameChars[]
Illegal file name characters used to insure file names will be valid on all supported platforms.
Definition: string.cpp:40
ESCAPE_CONTEXT
Escape/Unescape routines to safely encode reserved-characters in various contexts.
Definition: kicad_string.h:52
int SplitString(wxString strToSplit, wxString *strBeginning, wxString *strDigits, wxString *strEnd)
Breaks a string into three parts: he alphabetic preamble, the numeric part, and any alphabetic ending...
Definition: string.cpp:650
int StrNumCmp(const wxString &aString1, const wxString &aString2, bool aIgnoreCase)
Compare two strings with alphanumerical content.
Definition: string.cpp:415
static wxString FROM_UTF8(const char *cstring)
function FROM_UTF8 converts a UTF8 encoded C string to a wxString for all wxWidgets build modes.
Definition: macros.h:109
char * StrPurge(char *text)
Remove leading and training spaces, tabs and end of line chars in text.
Definition: string.cpp:371
bool ReplaceIllegalFileNameChars(std::string *aName, int aReplaceChar)
Checks aName for illegal file name characters.
Definition: string.cpp:741
void StripTrailingZeros(wxString &aStringValue, unsigned aTrailingZeroAllowed)
Function StripTrailingZeros Remove trailing 0 from a string containing a converted float number.
Definition: string.cpp:825
This file contains miscellaneous commonly used macros and functions.
std::string EscapedUTF8(wxString aString)
Function EscapedUTF8 returns an 8 bit UTF8 string given aString in unicode form.
Definition: string.cpp:304
int StrPrintf(std::string *result, const char *format,...)
Function StrPrintf is like sprintf() but the output is appended to a std::string instead of to a char...
Definition: richio.cpp:78
#define TO_UTF8(wxstring)
Macro TO_UTF8 converts a wxString to a UTF8 encoded C string for all wxWidgets build modes.
Definition: macros.h:95
#define NULL
int ValueStringCompare(wxString strFWord, wxString strSWord)
Compare strings like the strcmp function but handle numbers and modifiers within the string text corr...
Definition: string.cpp:602
bool WildCompareString(const wxString &pattern, const wxString &string_to_tst, bool case_sensitive)
Compare a string against wild card (* and ?) pattern using the usual rules.
Definition: string.cpp:494
wxString GetIllegalFileNameWxChars()
Definition: string.cpp:735
void wxStringSplit(const wxString &aText, wxArrayString &aStrings, wxChar aSplitter)
Split aString to a string list separated at aSplitter.
Definition: string.cpp:802
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
char * GetLine(FILE *File, char *Line, int *LineNum, int SizeLine)
Read one line line from aFile.
Definition: string.cpp:390
wxString UnescapeString(const wxString &aSource)
Definition: string.cpp:152
wxString EscapeString(const wxString &aSource, ESCAPE_CONTEXT aContext)
These Escape/Unescape routines use HTML-entity-reference-style encoding to handle characters which ar...
Definition: string.cpp:77
int GetTrailingInt(const wxString &aStr)
Gets the trailing int, if any, from a string.
Definition: string.cpp:711
int ReadDelimitedText(wxString *aDest, const char *aSource)
Copy bytes from aSource delimited string segment to aDest wxString.
Definition: string.cpp:210
bool NoPrintableChars(wxString aString)
Return true if the string is empty or contains only whitespace.
Definition: string.cpp:365
wxString EscapeHTML(const wxString &aString)
Return a new wxString escaped for embedding in HTML.
Definition: string.cpp:341
bool ApplyModifier(double &value, const wxString &aString)
Definition: string.cpp:554
bool ConvertSmartQuotesAndDashes(wxString *aString)
Converts curly quotes and em/en dashes to straight quotes and dashes.
Definition: string.cpp:43
wxString DateAndTime()
Definition: string.cpp:406