48 bool inOverbar =
false;
51 if( aOldStr == wxT(
"~" ) )
54 newStr.reserve( aOldStr.length() );
56 for( wxString::const_iterator chIt = aOldStr.begin(); chIt != aOldStr.end(); ++chIt )
60 wxString::const_iterator lookahead = chIt + 1;
62 if( lookahead != aOldStr.end() && *lookahead ==
'~' )
64 if( ++lookahead != aOldStr.end() && *lookahead ==
'{' )
68 newStr << wxT(
"~~{}" );
77 else if( lookahead != aOldStr.end() && *lookahead ==
'{' )
92 newStr << wxT(
"~{" );
99 else if( ( *chIt ==
' ' || *chIt ==
'}' || *chIt ==
')' ) && inOverbar )
102 newStr << wxT(
"}" );
111 newStr << wxT(
"}" );
121 for( wxString::iterator ii = aString->begin(); ii != aString->end(); ++ii )
123 if( *ii == L
'\u00B4' || *ii == L
'\u2018' || *ii == L
'\u2019' )
128 if( *ii == L
'\u201C' || *ii == L
'\u201D' )
133 if( *ii == L
'\u2013' || *ii == L
'\u2014' )
147 std::vector<bool> braceStack;
149 converted.reserve( aSource.length() );
151 for( wxUniChar c: aSource )
156 converted += wxT(
"{slash}" );
157 else if( c ==
'\n' || c ==
'\r' )
158 converted += wxEmptyString;
166 converted += wxT(
"{slash}" );
168 converted += wxT(
"{backslash}" );
170 converted += wxT(
"{lt}" );
172 converted += wxT(
"{gt}" );
174 converted += wxT(
"{colon}" );
176 converted += wxT(
"{dblquote}" );
177 else if( c ==
'\n' || c ==
'\r' )
178 converted += wxEmptyString;
185 converted += wxT(
"{slash}" );
187 converted += wxT(
"{comma}" );
189 converted += wxT(
"{dblquote}" );
196 converted += wxT(
"{dblquote}" );
202 if( c >= 0x7F || c ==
'\'' || c ==
'\\' || c ==
'(' || c ==
')' )
204 unsigned int code = c;
206 snprintf( buffer,
sizeof(buffer),
"\\\\u%4.4X", code );
216 if( c ==
'\n' || c ==
'\r' )
217 converted += wxT(
"{return}" );
224 converted += wxT(
"{slash}" );
226 converted += wxT(
"{backslash}" );
228 converted += wxT(
"{dblquote}" );
230 converted += wxT(
"{lt}" );
232 converted += wxT(
"{gt}" );
234 converted += wxT(
"{bar}" );
236 converted += wxT(
"{colon}" );
238 converted += wxT(
"{tab}" );
239 else if( c ==
'\n' || c ==
'\r' )
240 converted += wxT(
"{return}" );
247 converted += wxT(
"{space}" );
254 converted += wxT(
"{comma}" );
255 else if( c ==
'\n' || c ==
'\r' )
256 converted += wxT(
"{return}" );
272 size_t sourceLen = aSource.length();
281 newbuf.reserve( sourceLen );
286 for(
size_t i = 0; i < sourceLen; ++i )
295 bool terminated =
false;
297 for( i = i + 1; i < sourceLen; ++i )
321 else if( prev ==
'$' || prev ==
'~' || prev ==
'^' || prev ==
'_' )
323 newbuf.append( wxT(
"{" ) +
UnescapeString( token ) + wxT(
"}" ) );
325 else if( token == wxT(
"dblquote" ) ) newbuf.append( wxT(
"\"" ) );
326 else if( token == wxT(
"quote" ) ) newbuf.append( wxT(
"'" ) );
327 else if( token == wxT(
"lt" ) ) newbuf.append( wxT(
"<" ) );
328 else if( token == wxT(
"gt" ) ) newbuf.append( wxT(
">" ) );
329 else if( token == wxT(
"backslash" ) ) newbuf.append( wxT(
"\\" ) );
330 else if( token == wxT(
"slash" ) ) newbuf.append( wxT(
"/" ) );
331 else if( token == wxT(
"bar" ) ) newbuf.append( wxT(
"|" ) );
332 else if( token == wxT(
"comma" ) ) newbuf.append( wxT(
"," ) );
333 else if( token == wxT(
"colon" ) ) newbuf.append( wxT(
":" ) );
334 else if( token == wxT(
"space" ) ) newbuf.append( wxT(
" " ) );
335 else if( token == wxT(
"dollar" ) ) newbuf.append( wxT(
"$" ) );
336 else if( token == wxT(
"tab" ) ) newbuf.append( wxT(
"\t" ) );
337 else if( token == wxT(
"return" ) ) newbuf.append( wxT(
"\n" ) );
338 else if( token == wxT(
"brace" ) ) newbuf.append( wxT(
"{" ) );
341 newbuf.append( wxT(
"{" ) +
UnescapeString( token ) + wxT(
"}" ) );
361 result.reserve( aString.length() );
363 for(
const wxString& word : words )
365 if( !result.IsEmpty() )
366 result += wxT(
" " );
368 result += word.Capitalize();
379 const char* start = aSource;
382 while( (cc = *aSource++) != 0 )
402 if( cc !=
'"' && cc !=
'\\' )
416 return aSource - start;
426 const char* start = aSource;
427 char* limit = aDest + aDestSize - 1;
430 while( (cc = *aSource++) != 0 && aDest < limit )
450 if( cc !=
'"' && cc !=
'\\' )
465 return aSource - start;
471 wxString str = aString;
474 str.Replace( wxT(
"\r\n" ), wxT(
"\r" ) );
475 str.Replace( wxT(
"\n" ), wxT(
"\r" ) );
477 std::string utf8 =
TO_UTF8( aString );
481 ret.reserve( utf8.length() + 2 );
485 for( std::string::const_iterator it = utf8.begin(); it!=utf8.end(); ++it )
493 else if( *it ==
'\\' )
514 converted.reserve( aString.length() );
516 for( wxUniChar c : aString )
519 converted += wxT(
""" );
521 converted += wxT(
"'" );
523 converted += wxT(
"&" );
525 converted += wxT(
"<" );
527 converted += wxT(
">" );
538 wxString tmp = aString;
540 return tmp.Trim(
true ).Trim(
false ).IsEmpty();
551 int overbarDepth = -1;
552 int superSubDepth = -1;
553 int braceNesting = 0;
555 for(
auto chIt = aString.begin(), end = aString.end(); chIt < end; ++chIt )
563 else if( *chIt ==
'^' && superSubDepth == -1 )
565 auto lookahead = chIt;
567 if( ++lookahead != end && *lookahead ==
'{' )
570 superSubDepth = braceNesting;
575 else if( *chIt ==
'_' && superSubDepth == -1 )
577 auto lookahead = chIt;
579 if( ++lookahead != end && *lookahead ==
'{' )
582 superSubDepth = braceNesting;
587 else if( *chIt ==
'~' && overbarDepth == -1 )
589 auto lookahead = chIt;
591 if( ++lookahead != end && *lookahead ==
'{' )
594 overbarDepth = braceNesting;
599 else if( *chIt ==
'{' )
603 else if( *chIt ==
'}' )
605 if( braceNesting > 0 )
608 if( braceNesting == superSubDepth )
614 if( braceNesting == overbarDepth )
630 static const char whitespace[] =
" \t\n\r\f\v";
634 while( *
text && strchr( whitespace, *
text ) )
637 char* cp =
text + strlen(
text ) - 1;
639 while( cp >=
text && strchr( whitespace, *cp ) )
647char*
GetLine( FILE* File,
char* Line,
int* LineNum,
int SizeLine )
650 if( fgets( Line, SizeLine, File ) ==
nullptr )
656 }
while( Line[0] ==
'#' || Line[0] ==
'\n' || Line[0] ==
'\r' || Line[0] == 0 );
658 strtok( Line,
"\n\r" );
665 wxDateTime datetime = wxDateTime::Now();
667 datetime.SetCountry( wxDateTime::Country_Default );
668 return datetime.Format( wxDefaultDateTimeFormat, wxDateTime::Local );
672int StrNumCmp(
const wxString& aString1,
const wxString& aString2,
bool aIgnoreCase )
674 int nb1 = 0, nb2 = 0;
676 auto str1 = aString1.begin();
677 auto str2 = aString2.begin();
679 while( str1 != aString1.end() && str2 != aString2.end() )
681 wxUniChar c1 = *str1;
682 wxUniChar c2 = *str2;
684 if( wxIsdigit( c1 ) && wxIsdigit( c2 ) )
692 nb1 = nb1 * 10 + (int) c1 -
'0';
694 }
while( str1 != aString1.end() && wxIsdigit( *str1 ) );
699 nb2 = nb2 * 10 + (int) c2 -
'0';
701 }
while( str2 != aString2.end() && wxIsdigit( *str2 ) );
709 c1 = ( str1 != aString1.end() ) ? *str1 : wxUniChar( 0 );
710 c2 = ( str2 != aString2.end() ) ? *str2 : wxUniChar( 0 );
716 if( wxToupper( c1 ) < wxToupper( c2 ) )
719 if( wxToupper( c1 ) > wxToupper( c2 ) )
731 if( str1 != aString1.end() )
734 if( str2 != aString2.end() )
738 if( str1 == aString1.end() && str2 != aString2.end() )
742 else if( str1 != aString1.end() && str2 == aString2.end() )
752 bool case_sensitive )
754 const wxChar* cp =
nullptr, * mp =
nullptr;
755 const wxChar* wild, * str;
756 wxString _pattern, _string_to_tst;
760 wild = pattern.GetData();
761 str = string_to_tst.GetData();
766 _pattern.MakeUpper();
767 _string_to_tst = string_to_tst;
768 _string_to_tst.MakeUpper();
769 wild = _pattern.GetData();
770 str = _string_to_tst.GetData();
773 while( ( *str ) && ( *wild !=
'*' ) )
775 if( ( *wild != *str ) && ( *wild !=
'?' ) )
791 else if( ( *wild == *str ) || ( *wild ==
'?' ) )
803 while( *wild ==
'*' )
814 static const wxString modifiers( wxT(
"pnumkKM" ) );
816 if( !aString.length() )
822 if( modifiers.Find( aString[ 0 ] ) >= 0 )
824 modifier = aString[ 0 ];
825 units = aString.Mid( 1 ).Trim();
830 units = aString.Mid( 0 ).Trim();
834 && !units.CmpNoCase( wxT(
"F" ) )
835 && !units.CmpNoCase( wxT(
"hz" ) )
836 && !units.CmpNoCase( wxT(
"W" ) )
837 && !units.CmpNoCase( wxT(
"V" ) )
838 && !units.CmpNoCase( wxT(
"H" ) ) )
841 if( modifier ==
'p' )
843 if( modifier ==
'n' )
845 else if( modifier ==
'u' )
847 else if( modifier ==
'm' )
849 else if( modifier ==
'k' || modifier ==
'K' )
851 else if( modifier ==
'M' )
853 else if( modifier ==
'G' )
867 wxString strFWordBeg, strFWordMid, strFWordEnd;
868 wxString strSWordBeg, strSWordMid, strSWordEnd;
871 SplitString( fWord, &strFWordBeg, &strFWordMid, &strFWordEnd );
872 SplitString( sWord, &strSWordBeg, &strSWordMid, &strSWordEnd );
875 int isEqual = strFWordBeg.CmpNoCase( strSWordBeg );
881 else if( isEqual < 0 )
888 double lFirstNumber = 0;
889 double lSecondNumber = 0;
890 bool endingIsModifier =
false;
892 strFWordMid.ToDouble( &lFirstNumber );
893 strSWordMid.ToDouble( &lSecondNumber );
895 endingIsModifier |=
ApplyModifier( lFirstNumber, strFWordEnd );
896 endingIsModifier |=
ApplyModifier( lSecondNumber, strSWordEnd );
898 if( lFirstNumber > lSecondNumber )
900 else if( lFirstNumber < lSecondNumber )
903 else if( !endingIsModifier )
904 return strFWordEnd.CmpNoCase( strSWordEnd );
913 wxString* strBeginning,
917 static const wxString separators( wxT(
".," ) );
920 strBeginning->Empty();
925 if( strToSplit.length() == 0 )
931 for( ii = (strToSplit.length() - 1); ii >= 0; ii-- )
933 if( wxIsdigit( strToSplit[ii] ) )
940 *strBeginning = strToSplit;
945 *strEnd = strToSplit.substr( ii + 1 );
948 int position = ii + 1;
950 for( ; ii >= 0; ii-- )
952 if( !wxIsdigit( strToSplit[ii] ) && separators.Find( strToSplit[ii] ) < 0 )
958 *strDigits = strToSplit.substr( 0, position );
964 *strDigits = strToSplit.substr( ii + 1, position - ii - 1 );
965 *strBeginning = strToSplit.substr( 0, ii + 1 );
979 int index = aStr.Len() - 1;
983 const char chr = aStr.GetChar( index );
985 if( chr < '0' || chr >
'9' )
988 number += ( chr -
'0' ) * base;
1005 bool changed =
false;
1007 result.reserve( aName->length() );
1009 for( std::string::iterator it = aName->begin(); it != aName->end(); ++it )
1014 StrPrintf( &result,
"%c", aReplaceChar );
1035 bool changed =
false;
1037 result.reserve( aName.Length() );
1040 for( wxString::iterator it = aName.begin(); it != aName.end(); ++it )
1042 if( illWChars.Find( *it ) != wxNOT_FOUND )
1045 result += aReplaceChar;
1047 result += wxString::Format(
"%%%02x", *it );
1064void wxStringSplit(
const wxString& aText, wxArrayString& aStrings, wxChar aSplitter )
1068 for(
unsigned ii = 0; ii < aText.Length(); ii++ )
1070 if( aText[ii] == aSplitter )
1072 aStrings.Add( tmp );
1081 if( !tmp.IsEmpty() )
1082 aStrings.Add( tmp );
1088 struct lconv* lc = localeconv();
1089 char sep = lc->decimal_point[0];
1090 unsigned sep_pos = aStringValue.Find( sep );
1095 unsigned min_len = sep_pos + aTrailingZeroAllowed + 1;
1097 while( aStringValue.Len() > min_len )
1099 if( aStringValue.Last() ==
'0' )
1100 aStringValue.RemoveLast();
1112 if( aValue != 0.0 && std::fabs( aValue ) <= 0.0001 )
1114 buf = fmt::format(
"{:.16f}", aValue );
1117 while( !buf.empty() && buf[buf.size() - 1] ==
'0' )
1124 if( buf[buf.size() - 1] ==
'.' )
1131 buf = fmt::format(
"{:.10g}", aValue );
1143 if( aValue != 0.0 && std::fabs( aValue ) <= 0.0001 )
1147 len = snprintf( buf,
sizeof(buf),
"%.16f", aValue );
1149 while( --len > 0 && buf[len] ==
'0' )
1152 if( buf[len] ==
'.' || buf[len] ==
',' )
1161 len = snprintf( buf,
sizeof(buf),
"%.10g", aValue );
1164 return std::string( buf, len );
This file contains miscellaneous commonly used macros and functions.
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
static wxString FROM_UTF8(const char *cstring)
Convert a UTF8 encoded C string to a wxString for all wxWidgets build modes.
int StrPrintf(std::string *result, const char *format,...)
This is like sprintf() but the output is appended to a std::string instead of to a character array.
int StrNumCmp(const wxString &aString1, const wxString &aString2, bool aIgnoreCase)
Compare two strings with alphanumerical content.
wxString EscapeHTML(const wxString &aString)
Return a new wxString escaped for embedding in HTML.
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.
wxString ConvertToNewOverbarNotation(const wxString &aOldStr)
Convert the old ~...~ overbar notation to the new ~{...} one.
int GetTrailingInt(const wxString &aStr)
Gets the trailing int, if any, from a string.
wxString UnescapeString(const wxString &aSource)
static const char illegalFileNameChars[]
Illegal file name characters used to ensure file names will be valid on all supported platforms.
wxString GetIllegalFileNameWxChars()
bool ConvertSmartQuotesAndDashes(wxString *aString)
Convert curly quotes and em/en dashes to straight quotes and dashes.
void wxStringSplit(const wxString &aText, wxArrayString &aStrings, wxChar aSplitter)
Split aString to a string list separated at aSplitter.
int ReadDelimitedText(wxString *aDest, const char *aSource)
Copy bytes from aSource delimited string segment to aDest wxString.
bool ReplaceIllegalFileNameChars(std::string *aName, int aReplaceChar)
Checks aName for illegal file name characters.
wxString TitleCaps(const wxString &aString)
Capitalize the first letter in each word.
std::string UIDouble2Str(double aValue)
Print a float number without using scientific notation and no trailing 0 We want to avoid scientific ...
std::string FormatDouble2Str(double aValue)
Print a float number without using scientific notation and no trailing 0 This function is intended in...
int PrintableCharCount(const wxString &aString)
Return the number of printable (ie: non-formatting) chars.
std::string EscapedUTF8(const wxString &aString)
Return an 8 bit UTF8 string given aString in Unicode form.
char * GetLine(FILE *File, char *Line, int *LineNum, int SizeLine)
Read one line line from aFile.
bool ApplyModifier(double &value, const wxString &aString)
wxString EscapeString(const wxString &aSource, ESCAPE_CONTEXT aContext)
The Escape/Unescape routines use HTML-entity-reference-style encoding to handle characters which are:...
int ValueStringCompare(const wxString &strFWord, const wxString &strSWord)
Compare strings like the strcmp function but handle numbers and modifiers within the string text corr...
int SplitString(const wxString &strToSplit, wxString *strBeginning, wxString *strDigits, wxString *strEnd)
Break a string into three parts: he alphabetic preamble, the numeric part, and any alphabetic ending.
void StripTrailingZeros(wxString &aStringValue, unsigned aTrailingZeroAllowed)
Remove trailing zeros from a string containing a converted float number.
char * StrPurge(char *text)
Remove leading and training spaces, tabs and end of line chars in text.
bool NoPrintableChars(const wxString &aString)
Return true if the string is empty or contains only whitespace.
ESCAPE_CONTEXT
Escape/Unescape routines to safely encode reserved-characters in various contexts.