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;
165 converted += wxT(
"{backslash}" );
167 converted += wxT(
"{lt}" );
169 converted += wxT(
"{gt}" );
171 converted += wxT(
"{colon}" );
173 converted += wxT(
"{dblquote}" );
174 else if( c ==
'\n' || c ==
'\r' )
175 converted += wxEmptyString;
182 converted += wxT(
"{slash}" );
184 converted += wxT(
"{comma}" );
186 converted += wxT(
"{dblquote}" );
193 converted += wxT(
"{dblquote}" );
199 if( c >= 0x7F || c ==
'\'' || c ==
'\\' )
201 unsigned int code = c;
203 snprintf( buffer,
sizeof(buffer),
"\\\\u%4.4X", code );
213 if( c ==
'\n' || c ==
'\r' )
214 converted += wxT(
"{return}" );
221 converted += wxT(
"{slash}" );
223 converted += wxT(
"{backslash}" );
225 converted += wxT(
"{dblquote}" );
227 converted += wxT(
"{lt}" );
229 converted += wxT(
"{gt}" );
231 converted += wxT(
"{bar}" );
233 converted += wxT(
"{colon}" );
235 converted += wxT(
"{tab}" );
236 else if( c ==
'\n' || c ==
'\r' )
237 converted += wxT(
"{return}" );
244 converted += wxT(
"{space}" );
251 converted += wxT(
"{comma}" );
252 else if( c ==
'\n' || c ==
'\r' )
253 converted += wxT(
"{return}" );
269 size_t sourceLen = aSource.length();
278 newbuf.reserve( sourceLen );
280 for(
size_t i = 0; i < sourceLen; ++i )
282 wxUniChar ch = aSource[i];
284 if( ( ch ==
'$' || ch ==
'~' || ch ==
'^' || ch ==
'_' )
285 && i + 1 < sourceLen && aSource[i+1] ==
'{' )
287 for( ; i < sourceLen; ++i )
301 for( i = i + 1; i < sourceLen; ++i )
315 if( token == wxT(
"dblquote" ) ) newbuf.append( wxT(
"\"" ) );
316 else if( token == wxT(
"quote" ) ) newbuf.append( wxT(
"'" ) );
317 else if( token == wxT(
"lt" ) ) newbuf.append( wxT(
"<" ) );
318 else if( token == wxT(
"gt" ) ) newbuf.append( wxT(
">" ) );
319 else if( token == wxT(
"backslash" ) ) newbuf.append( wxT(
"\\" ) );
320 else if( token == wxT(
"slash" ) ) newbuf.append( wxT(
"/" ) );
321 else if( token == wxT(
"bar" ) ) newbuf.append( wxT(
"|" ) );
322 else if( token == wxT(
"comma" ) ) newbuf.append( wxT(
"," ) );
323 else if( token == wxT(
"colon" ) ) newbuf.append( wxT(
":" ) );
324 else if( token == wxT(
"space" ) ) newbuf.append( wxT(
" " ) );
325 else if( token == wxT(
"dollar" ) ) newbuf.append( wxT(
"$" ) );
326 else if( token == wxT(
"tab" ) ) newbuf.append( wxT(
"\t" ) );
327 else if( token == wxT(
"return" ) ) newbuf.append( wxT(
"\n" ) );
328 else if( token == wxT(
"brace" ) ) newbuf.append( wxT(
"{" ) );
329 else if( token.IsEmpty() ) newbuf.append( wxT(
"{" ) );
332 newbuf.append( wxT(
"{" ) +
UnescapeString( token ) + wxT(
"}" ) );
352 result.reserve( aString.length() );
354 for(
const wxString& word : words )
356 if( !result.IsEmpty() )
357 result += wxT(
" " );
359 result += word.Capitalize();
370 const char* start = aSource;
373 while( (cc = *aSource++) != 0 )
393 if( cc !=
'"' && cc !=
'\\' )
407 return aSource - start;
417 const char* start = aSource;
418 char* limit = aDest + aDestSize - 1;
421 while( (cc = *aSource++) != 0 && aDest < limit )
441 if( cc !=
'"' && cc !=
'\\' )
456 return aSource - start;
462 wxString str = aString;
465 str.Replace( wxT(
"\r\n" ), wxT(
"\r" ) );
466 str.Replace( wxT(
"\n" ), wxT(
"\r" ) );
468 std::string utf8 =
TO_UTF8( aString );
472 ret.reserve( utf8.length() + 2 );
476 for( std::string::const_iterator it = utf8.begin(); it!=utf8.end(); ++it )
484 else if( *it ==
'\\' )
505 converted.reserve( aString.length() );
507 for( wxUniChar c : aString )
510 converted += wxT(
""" );
512 converted += wxT(
"'" );
514 converted += wxT(
"&" );
516 converted += wxT(
"<" );
518 converted += wxT(
">" );
529 wxString tmp = aString;
531 return tmp.Trim(
true ).Trim(
false ).IsEmpty();
542 int overbarDepth = -1;
543 int superSubDepth = -1;
544 int braceNesting = 0;
546 for(
auto chIt = aString.begin(), end = aString.end(); chIt < end; ++chIt )
554 else if( *chIt ==
'^' && superSubDepth == -1 )
556 auto lookahead = chIt;
558 if( ++lookahead != end && *lookahead ==
'{' )
561 superSubDepth = braceNesting;
566 else if( *chIt ==
'_' && superSubDepth == -1 )
568 auto lookahead = chIt;
570 if( ++lookahead != end && *lookahead ==
'{' )
573 superSubDepth = braceNesting;
578 else if( *chIt ==
'~' && overbarDepth == -1 )
580 auto lookahead = chIt;
582 if( ++lookahead != end && *lookahead ==
'{' )
585 overbarDepth = braceNesting;
590 else if( *chIt ==
'{' )
594 else if( *chIt ==
'}' )
596 if( braceNesting > 0 )
599 if( braceNesting == superSubDepth )
605 if( braceNesting == overbarDepth )
621 static const char whitespace[] =
" \t\n\r\f\v";
625 while( *
text && strchr( whitespace, *
text ) )
628 char* cp =
text + strlen(
text ) - 1;
630 while( cp >=
text && strchr( whitespace, *cp ) )
638char*
GetLine( FILE* File,
char* Line,
int* LineNum,
int SizeLine )
641 if( fgets( Line, SizeLine, File ) ==
nullptr )
647 }
while( Line[0] ==
'#' || Line[0] ==
'\n' || Line[0] ==
'\r' || Line[0] == 0 );
649 strtok( Line,
"\n\r" );
656 wxDateTime datetime = wxDateTime::Now();
658 datetime.SetCountry( wxDateTime::Country_Default );
659 return datetime.Format( wxDefaultDateTimeFormat, wxDateTime::Local );
663int StrNumCmp(
const wxString& aString1,
const wxString& aString2,
bool aIgnoreCase )
665 int nb1 = 0, nb2 = 0;
667 auto str1 = aString1.begin();
668 auto str2 = aString2.begin();
670 while( str1 != aString1.end() && str2 != aString2.end() )
672 wxUniChar c1 = *str1;
673 wxUniChar c2 = *str2;
675 if( wxIsdigit( c1 ) && wxIsdigit( c2 ) )
683 nb1 = nb1 * 10 + (int) c1 -
'0';
685 }
while( str1 != aString1.end() && wxIsdigit( *str1 ) );
690 nb2 = nb2 * 10 + (int) c2 -
'0';
692 }
while( str2 != aString2.end() && wxIsdigit( *str2 ) );
700 c1 = ( str1 != aString1.end() ) ? *str1 : wxUniChar( 0 );
701 c2 = ( str2 != aString2.end() ) ? *str2 : wxUniChar( 0 );
707 if( wxToupper( c1 ) < wxToupper( c2 ) )
710 if( wxToupper( c1 ) > wxToupper( c2 ) )
722 if( str1 != aString1.end() )
725 if( str2 != aString2.end() )
729 if( str1 == aString1.end() && str2 != aString2.end() )
733 else if( str1 != aString1.end() && str2 == aString2.end() )
743 bool case_sensitive )
745 const wxChar* cp =
nullptr, * mp =
nullptr;
746 const wxChar* wild, * str;
747 wxString _pattern, _string_to_tst;
751 wild = pattern.GetData();
752 str = string_to_tst.GetData();
757 _pattern.MakeUpper();
758 _string_to_tst = string_to_tst;
759 _string_to_tst.MakeUpper();
760 wild = _pattern.GetData();
761 str = _string_to_tst.GetData();
764 while( ( *str ) && ( *wild !=
'*' ) )
766 if( ( *wild != *str ) && ( *wild !=
'?' ) )
782 else if( ( *wild == *str ) || ( *wild ==
'?' ) )
794 while( *wild ==
'*' )
805 static const wxString modifiers( wxT(
"pnumkKM" ) );
807 if( !aString.length() )
813 if( modifiers.Find( aString[ 0 ] ) >= 0 )
815 modifier = aString[ 0 ];
816 units = aString.Mid( 1 ).Trim();
821 units = aString.Mid( 0 ).Trim();
825 && !units.CmpNoCase( wxT(
"F" ) )
826 && !units.CmpNoCase( wxT(
"hz" ) )
827 && !units.CmpNoCase( wxT(
"W" ) )
828 && !units.CmpNoCase( wxT(
"V" ) )
829 && !units.CmpNoCase( wxT(
"H" ) ) )
832 if( modifier ==
'p' )
834 if( modifier ==
'n' )
836 else if( modifier ==
'u' )
838 else if( modifier ==
'm' )
840 else if( modifier ==
'k' || modifier ==
'K' )
842 else if( modifier ==
'M' )
844 else if( modifier ==
'G' )
858 wxString strFWordBeg, strFWordMid, strFWordEnd;
859 wxString strSWordBeg, strSWordMid, strSWordEnd;
862 SplitString( fWord, &strFWordBeg, &strFWordMid, &strFWordEnd );
863 SplitString( sWord, &strSWordBeg, &strSWordMid, &strSWordEnd );
866 int isEqual = strFWordBeg.CmpNoCase( strSWordBeg );
872 else if( isEqual < 0 )
879 double lFirstNumber = 0;
880 double lSecondNumber = 0;
881 bool endingIsModifier =
false;
883 strFWordMid.ToDouble( &lFirstNumber );
884 strSWordMid.ToDouble( &lSecondNumber );
886 endingIsModifier |=
ApplyModifier( lFirstNumber, strFWordEnd );
887 endingIsModifier |=
ApplyModifier( lSecondNumber, strSWordEnd );
889 if( lFirstNumber > lSecondNumber )
891 else if( lFirstNumber < lSecondNumber )
894 else if( !endingIsModifier )
895 return strFWordEnd.CmpNoCase( strSWordEnd );
904 wxString* strBeginning,
908 static const wxString separators( wxT(
".," ) );
911 strBeginning->Empty();
916 if( strToSplit.length() == 0 )
922 for( ii = (strToSplit.length() - 1); ii >= 0; ii-- )
924 if( wxIsdigit( strToSplit[ii] ) )
931 *strBeginning = strToSplit;
936 *strEnd = strToSplit.substr( ii + 1 );
939 int position = ii + 1;
941 for( ; ii >= 0; ii-- )
943 if( !wxIsdigit( strToSplit[ii] ) && separators.Find( strToSplit[ii] ) < 0 )
949 *strDigits = strToSplit.substr( 0, position );
955 *strDigits = strToSplit.substr( ii + 1, position - ii - 1 );
956 *strBeginning = strToSplit.substr( 0, ii + 1 );
970 int index = aStr.Len() - 1;
974 const char chr = aStr.GetChar( index );
976 if( chr < '0' || chr >
'9' )
979 number += ( chr -
'0' ) * base;
996 bool changed =
false;
998 result.reserve( aName->length() );
1000 for( std::string::iterator it = aName->begin(); it != aName->end(); ++it )
1005 StrPrintf( &result,
"%c", aReplaceChar );
1026 bool changed =
false;
1028 result.reserve( aName.Length() );
1031 for( wxString::iterator it = aName.begin(); it != aName.end(); ++it )
1033 if( illWChars.Find( *it ) != wxNOT_FOUND )
1036 result += aReplaceChar;
1055void wxStringSplit(
const wxString& aText, wxArrayString& aStrings, wxChar aSplitter )
1059 for(
unsigned ii = 0; ii < aText.Length(); ii++ )
1061 if( aText[ii] == aSplitter )
1063 aStrings.Add( tmp );
1072 if( !tmp.IsEmpty() )
1073 aStrings.Add( tmp );
1079 struct lconv* lc = localeconv();
1080 char sep = lc->decimal_point[0];
1081 unsigned sep_pos = aStringValue.Find( sep );
1086 unsigned min_len = sep_pos + aTrailingZeroAllowed + 1;
1088 while( aStringValue.Len() > min_len )
1090 if( aStringValue.Last() ==
'0' )
1091 aStringValue.RemoveLast();
1103 if( aValue != 0.0 && std::fabs( aValue ) <= 0.0001 )
1105 buf = fmt::format(
"{:.16f}", aValue );
1108 while( !buf.empty() && buf[buf.size() - 1] ==
'0' )
1115 if( buf[buf.size() - 1] ==
'.' )
1122 buf = fmt::format(
"{:.10g}", aValue );
1134 if( aValue != 0.0 && std::fabs( aValue ) <= 0.0001 )
1138 len = snprintf( buf,
sizeof(buf),
"%.16f", aValue );
1140 while( --len > 0 && buf[len] ==
'0' )
1143 if( buf[len] ==
'.' || buf[len] ==
',' )
1152 len = snprintf( buf,
sizeof(buf),
"%.10g", aValue );
1155 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.
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
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.