KiCad PCB EDA Suite
string_utils.h File Reference
#include "config.h"
#include <string>
#include <vector>
#include <wx/string.h>
#include <wx/filename.h>

Go to the source code of this file.

Classes

struct  rsort_wxString
 A helper for sorting strings from the rear. More...
 

Enumerations

enum  ESCAPE_CONTEXT {
  CTX_NETNAME , CTX_LIBID , CTX_IPC , CTX_QUOTED_STR ,
  CTX_JS_STR , CTX_LINE , CTX_CSV , CTX_FILENAME ,
  CTX_NO_SPACE
}
 Escape/Unescape routines to safely encode reserved-characters in various contexts. More...
 

Functions

void ConvertMarkdown2Html (const wxString &aMarkdownInput, wxString &aHtmlOutput)
 
wxString ConvertToNewOverbarNotation (const wxString &aOldStr)
 Convert the old ~...~ overbar notation to the new ~{...} one. More...
 
bool ConvertSmartQuotesAndDashes (wxString *aString)
 Convert curly quotes and em/en dashes to straight quotes and dashes. More...
 
wxString EscapeString (const wxString &aSource, ESCAPE_CONTEXT aContext)
 The Escape/Unescape routines use HTML-entity-reference-style encoding to handle characters which are: (a) not legal in filenames (b) used as control characters in LIB_IDs (c) used to delineate hierarchical paths. More...
 
wxString UnescapeString (const wxString &aSource)
 
wxString PrettyPrintForMenu (const wxString &aString)
 Remove markup (such as overbar or subscript) that we can't render to menu items. More...
 
wxString TitleCaps (const wxString &aString)
 Capitalize the first letter in each word. More...
 
int ReadDelimitedText (char *aDest, const char *aSource, int aDestSize)
 Copy bytes from aSource delimited string segment to aDest buffer. More...
 
int ReadDelimitedText (wxString *aDest, const char *aSource)
 Copy bytes from aSource delimited string segment to aDest wxString. More...
 
std::string EscapedUTF8 (const wxString &aString)
 Return an 8 bit UTF8 string given aString in Unicode form. More...
 
wxString EscapeHTML (const wxString &aString)
 Return a new wxString escaped for embedding in HTML. More...
 
char * GetLine (FILE *aFile, char *Line, int *LineNum=nullptr, int SizeLine=255)
 Read one line line from aFile. More...
 
bool NoPrintableChars (const wxString &aString)
 Return true if the string is empty or contains only whitespace. More...
 
int PrintableCharCount (const wxString &aString)
 Return the number of printable (ie: non-formatting) chars. More...
 
char * StrPurge (char *text)
 Remove leading and training spaces, tabs and end of line chars in text. More...
 
wxString DateAndTime ()
 
int StrNumCmp (const wxString &aString1, const wxString &aString2, bool aIgnoreCase=false)
 Compare two strings with alphanumerical content. More...
 
bool WildCompareString (const wxString &pattern, const wxString &string_to_tst, bool case_sensitive=true)
 Compare a string against wild card (* and ?) pattern using the usual rules. More...
 
int ValueStringCompare (const wxString &strFWord, const wxString &strSWord)
 Compare strings like the strcmp function but handle numbers and modifiers within the string text correctly for sorting. More...
 
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. More...
 
int GetTrailingInt (const wxString &aStr)
 Gets the trailing int, if any, from a string. More...
 
wxString GetIllegalFileNameWxChars ()
 
bool ReplaceIllegalFileNameChars (std::string *aName, int aReplaceChar=0)
 Checks aName for illegal file name characters. More...
 
bool ReplaceIllegalFileNameChars (wxString &aName, int aReplaceChar=0)
 
char * strtok_r (char *str, const char *delim, char **nextp)
 
static std::vector< std::string > split (const std::string &aStr, const std::string &aDelim)
 Split the input string into a vector of output strings. More...
 
void AccumulateDescription (wxString &aDesc, const wxString &aItem)
 Utility to build comma separated lists in messages. More...
 
void wxStringSplit (const wxString &aText, wxArrayString &aStrings, wxChar aSplitter)
 Split aString to a string list separated at aSplitter. More...
 
void StripTrailingZeros (wxString &aStringValue, unsigned aTrailingZeroAllowed=1)
 Remove trailing zeros from a string containing a converted float number. More...
 
std::string UIDouble2Str (double aValue)
 Print a float number without using scientific notation and no trailing 0 We want to avoid scientific notation in S-expr files (not easy to read) for floating numbers. More...
 
std::string FormatDouble2Str (double aValue)
 Print a float number without using scientific notation and no trailing 0 This function is intended in uses to write to file, it ignores locale. More...
 

Enumeration Type Documentation

◆ ESCAPE_CONTEXT

Escape/Unescape routines to safely encode reserved-characters in various contexts.

Enumerator
CTX_NETNAME 
CTX_LIBID 
CTX_IPC 
CTX_QUOTED_STR 
CTX_JS_STR 
CTX_LINE 
CTX_CSV 
CTX_FILENAME 
CTX_NO_SPACE 

Definition at line 52 of file string_utils.h.

53{
56 CTX_IPC,
60 CTX_CSV,
62 CTX_NO_SPACE // to replace spaces in names that do not accept spaces
63};
@ CTX_FILENAME
Definition: string_utils.h:61
@ CTX_QUOTED_STR
Definition: string_utils.h:57
@ CTX_LINE
Definition: string_utils.h:59
@ CTX_NO_SPACE
Definition: string_utils.h:62
@ CTX_LIBID
Definition: string_utils.h:55
@ CTX_NETNAME
Definition: string_utils.h:54
@ CTX_CSV
Definition: string_utils.h:60
@ CTX_IPC
Definition: string_utils.h:56
@ CTX_JS_STR
Definition: string_utils.h:58

Function Documentation

◆ AccumulateDescription()

void AccumulateDescription ( wxString &  aDesc,
const wxString &  aItem 
)
inline

Utility to build comma separated lists in messages.

Definition at line 322 of file string_utils.h.

323{
324 if( !aDesc.IsEmpty() )
325 aDesc << wxT( ", " );
326
327 aDesc << aItem;
328}

Referenced by ZONE::GetMsgPanelInfo().

◆ ConvertMarkdown2Html()

◆ ConvertSmartQuotesAndDashes()

bool ConvertSmartQuotesAndDashes ( wxString *  aString)

Convert curly quotes and em/en dashes to straight quotes and dashes.

Returns
true if any characters required conversion.

Definition at line 117 of file string_utils.cpp.

118{
119 bool retVal = false;
120
121 for( wxString::iterator ii = aString->begin(); ii != aString->end(); ++ii )
122 {
123 if( *ii == L'\u00B4' || *ii == L'\u2018' || *ii == L'\u2019' )
124 {
125 *ii = '\'';
126 retVal = true;
127 }
128 if( *ii == L'\u201C' || *ii == L'\u201D' )
129 {
130 *ii = '"';
131 retVal = true;
132 }
133 if( *ii == L'\u2013' || *ii == L'\u2014' )
134 {
135 *ii = '-';
136 retVal = true;
137 }
138 }
139
140 return retVal;
141}

Referenced by WX_HTML_REPORT_PANEL::onBtnSaveToFile(), SCINTILLA_TRICKS::onCharHook(), and PANEL_SETUP_RULES::TransferDataToWindow().

◆ ConvertToNewOverbarNotation()

wxString ConvertToNewOverbarNotation ( const wxString &  aOldStr)

Convert the old ~...~ overbar notation to the new ~{...} one.

Definition at line 45 of file string_utils.cpp.

46{
47 wxString newStr;
48 bool inOverbar = false;
49
50 // Don't get tripped up by the legacy empty-string token.
51 if( aOldStr == wxT( "~" ) )
52 return aOldStr;
53
54 newStr.reserve( aOldStr.length() );
55
56 for( wxString::const_iterator chIt = aOldStr.begin(); chIt != aOldStr.end(); ++chIt )
57 {
58 if( *chIt == '~' )
59 {
60 wxString::const_iterator lookahead = chIt + 1;
61
62 if( lookahead != aOldStr.end() && *lookahead == '~' )
63 {
64 if( ++lookahead != aOldStr.end() && *lookahead == '{' )
65 {
66 // This way the subsequent opening curly brace will not start an
67 // overbar.
68 newStr << wxT( "~~{}" );
69 continue;
70 }
71
72 // Two subsequent tildes mean a tilde.
73 newStr << wxT( "~" );
74 ++chIt;
75 continue;
76 }
77 else if( lookahead != aOldStr.end() && *lookahead == '{' )
78 {
79 // Could mean the user wants "{" with an overbar, but more likely this
80 // is a case of double notation conversion. Bail out.
81 return aOldStr;
82 }
83 else
84 {
85 if( inOverbar )
86 {
87 newStr << wxT( "}" );
88 inOverbar = false;
89 }
90 else
91 {
92 newStr << wxT( "~{" );
93 inOverbar = true;
94 }
95
96 continue;
97 }
98 }
99 else if( ( *chIt == ' ' || *chIt == '}' || *chIt == ')' ) && inOverbar )
100 {
101 // Spaces were used to terminate overbar as well
102 newStr << wxT( "}" );
103 inOverbar = false;
104 }
105
106 newStr << *chIt;
107 }
108
109 // Explicitly end the overbar even if there was no terminating '~' in the aOldStr.
110 if( inOverbar )
111 newStr << wxT( "}" );
112
113 return newStr;
114}

Referenced by escapeName(), CADSTAR_ARCHIVE_PARSER::HandleTextOverbar(), SCH_LEGACY_PLUGIN_CACHE::loadField(), LEGACY_PLUGIN::loadMODULE_TEXT(), LEGACY_PLUGIN::loadNETCLASS(), LEGACY_PLUGIN::loadNETINFO_ITEM(), LEGACY_PLUGIN::loadPAD(), LEGACY_PLUGIN::loadPCB_TEXT(), SCH_LEGACY_PLUGIN_CACHE::loadPin(), SCH_LEGACY_PLUGIN::loadSheet(), SCH_LEGACY_PLUGIN::loadText(), SCH_LEGACY_PLUGIN_CACHE::loadText(), NET_SETTINGS::migrateSchema0to1(), SCH_SEXPR_PARSER::parseBusAlias(), PCB_PARSER::parseEDA_TEXT(), SCH_SEXPR_PARSER::parseEDA_TEXT(), PCB_PARSER::parseNETCLASS(), PCB_PARSER::parseNETINFO_ITEM(), PCB_PARSER::parsePAD(), SCH_SEXPR_PARSER::parsePin(), and DRAWING_SHEET_PARSER::parseText().

◆ DateAndTime()

wxString DateAndTime ( )
Returns
a string giving the current date and time.

Definition at line 654 of file string_utils.cpp.

655{
656 wxDateTime datetime = wxDateTime::Now();
657
658 datetime.SetCountry( wxDateTime::Country_Default );
659 return datetime.Format( wxDefaultDateTimeFormat, wxDateTime::Local );
660}

Referenced by GENDRILL_WRITER_BASE::GenDrillReportFile(), PLACE_FILE_EXPORTER::GenPositionData(), PLACE_FILE_EXPORTER::GenReportData(), NETLIST_EXPORTER_XML::makeDesignHeader(), RecreateCmpFile(), EXCELLON_WRITER::writeEXCELLONHeader(), PCB_CALCULATOR_DATAFILE::WriteHeader(), NETLIST_EXPORTER_CADSTAR::WriteNetlist(), NETLIST_EXPORTER_ORCADPCB2::WriteNetlist(), and DIALOG_ERC::writeReport().

◆ EscapedUTF8()

std::string EscapedUTF8 ( const wxString &  aString)

Return an 8 bit UTF8 string given aString in Unicode form.

Any double quoted or back slashes are prefixed with a '\' byte and the form of this UTF8 byte string is compatible with function ReadDelimitedText().

Parameters
aStringis the input string to convert.
Returns
the escaped input text, without the wrapping double quotes.

Definition at line 460 of file string_utils.cpp.

461{
462 wxString str = aString;
463
464 // No new-lines allowed in quoted strings
465 str.Replace( wxT( "\r\n" ), wxT( "\r" ) );
466 str.Replace( wxT( "\n" ), wxT( "\r" ) );
467
468 std::string utf8 = TO_UTF8( aString );
469
470 std::string ret;
471
472 ret.reserve( utf8.length() + 2 );
473
474 ret += '"';
475
476 for( std::string::const_iterator it = utf8.begin(); it!=utf8.end(); ++it )
477 {
478 // this escaping strategy is designed to be compatible with ReadDelimitedText():
479 if( *it == '"' )
480 {
481 ret += '\\';
482 ret += '"';
483 }
484 else if( *it == '\\' )
485 {
486 ret += '\\'; // double it up
487 ret += '\\';
488 }
489 else
490 {
491 ret += *it;
492 }
493 }
494
495 ret += '"';
496
497 return ret;
498}
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
Definition: macros.h:96

References TO_UTF8.

Referenced by SCH_LEGACY_PLUGIN::Format(), PLACE_FILE_EXPORTER::GenReportData(), SCH_LEGACY_PLUGIN_CACHE::saveField(), SCH_LEGACY_PLUGIN::saveField(), SCH_LEGACY_PLUGIN::saveSheet(), and SCH_SEXPR_PLUGIN::saveSheet().

◆ EscapeHTML()

wxString EscapeHTML ( const wxString &  aString)

Return a new wxString escaped for embedding in HTML.

Definition at line 501 of file string_utils.cpp.

502{
503 wxString converted;
504
505 converted.reserve( aString.length() );
506
507 for( wxUniChar c : aString )
508 {
509 if( c == '\"' )
510 converted += wxT( "&quot;" );
511 else if( c == '\'' )
512 converted += wxT( "&apos;" );
513 else if( c == '&' )
514 converted += wxT( "&amp;" );
515 else if( c == '<' )
516 converted += wxT( "&lt;" );
517 else if( c == '>' )
518 converted += wxT( "&gt;" );
519 else
520 converted += c;
521 }
522
523 return converted;
524}

Referenced by DRC_ENGINE::EvalRules(), DRC_ENGINE::EvalZoneConnection(), FOOTPRINT_INFO_GENERATOR::GenerateHtml(), FOOTPRINT_INFO_GENERATOR::GetHtmlFieldRow(), BOARD_INSPECTION_TOOL::InspectClearance(), DRC_ENGINE::ProcessAssertions(), BOARD_INSPECTION_TOOL::reportHeader(), FOOTPRINT_INFO_GENERATOR::SetHtmlAliasOf(), FOOTPRINT_INFO_GENERATOR::SetHtmlDesc(), FOOTPRINT_INFO_GENERATOR::SetHtmlKeywords(), FOOTPRINT_INFO_GENERATOR::SetHtmlName(), and PANEL_PACKAGES_VIEW::setPackageDetails().

◆ EscapeString()

wxString EscapeString ( const wxString &  aSource,
ESCAPE_CONTEXT  aContext 
)

The Escape/Unescape routines use HTML-entity-reference-style encoding to handle characters which are: (a) not legal in filenames (b) used as control characters in LIB_IDs (c) used to delineate hierarchical paths.

Definition at line 144 of file string_utils.cpp.

145{
146 wxString converted;
147 std::vector<bool> braceStack; // true == formatting construct
148
149 converted.reserve( aSource.length() );
150
151 for( wxUniChar c: aSource )
152 {
153 if( aContext == CTX_NETNAME )
154 {
155 if( c == '/' )
156 converted += wxT( "{slash}" );
157 else if( c == '\n' || c == '\r' )
158 converted += wxEmptyString; // drop
159 else
160 converted += c;
161 }
162 else if( aContext == CTX_LIBID )
163 {
164 if( c == '\\' )
165 converted += wxT( "{backslash}" );
166 else if( c == '<' )
167 converted += wxT( "{lt}" );
168 else if( c == '>' )
169 converted += wxT( "{gt}" );
170 else if( c == ':' )
171 converted += wxT( "{colon}" );
172 else if( c == '\"' )
173 converted += wxT( "{dblquote}" );
174 else if( c == '\n' || c == '\r' )
175 converted += wxEmptyString; // drop
176 else
177 converted += c;
178 }
179 else if( aContext == CTX_IPC )
180 {
181 if( c == '/' )
182 converted += wxT( "{slash}" );
183 else if( c == ',' )
184 converted += wxT( "{comma}" );
185 else if( c == '\"' )
186 converted += wxT( "{dblquote}" );
187 else
188 converted += c;
189 }
190 else if( aContext == CTX_QUOTED_STR )
191 {
192 if( c == '\"' )
193 converted += wxT( "{dblquote}" );
194 else
195 converted += c;
196 }
197 else if( aContext == CTX_JS_STR )
198 {
199 if( c >= 0x7F || c == '\'' || c == '\\' )
200 {
201 unsigned int code = c;
202 char buffer[16];
203 snprintf( buffer, sizeof(buffer), "\\\\u%4.4X", code );
204 converted += buffer;
205 }
206 else
207 {
208 converted += c;
209 }
210 }
211 else if( aContext == CTX_LINE )
212 {
213 if( c == '\n' || c == '\r' )
214 converted += wxT( "{return}" );
215 else
216 converted += c;
217 }
218 else if( aContext == CTX_FILENAME )
219 {
220 if( c == '/' )
221 converted += wxT( "{slash}" );
222 else if( c == '\\' )
223 converted += wxT( "{backslash}" );
224 else if( c == '\"' )
225 converted += wxT( "{dblquote}" );
226 else if( c == '<' )
227 converted += wxT( "{lt}" );
228 else if( c == '>' )
229 converted += wxT( "{gt}" );
230 else if( c == '|' )
231 converted += wxT( "{bar}" );
232 else if( c == ':' )
233 converted += wxT( "{colon}" );
234 else if( c == '\t' )
235 converted += wxT( "{tab}" );
236 else if( c == '\n' || c == '\r' )
237 converted += wxT( "{return}" );
238 else
239 converted += c;
240 }
241 else if( aContext == CTX_NO_SPACE )
242 {
243 if( c == ' ' )
244 converted += wxT( "{space}" );
245 else
246 converted += c;
247 }
248 else if( aContext == CTX_CSV )
249 {
250 if( c == ',' )
251 converted += wxT( "{comma}" );
252 else if( c == '\n' || c == '\r' )
253 converted += wxT( "{return}" );
254 else
255 converted += c;
256 }
257 else
258 {
259 converted += c;
260 }
261 }
262
263 return converted;
264}

References CTX_CSV, CTX_FILENAME, CTX_IPC, CTX_JS_STR, CTX_LIBID, CTX_LINE, CTX_NETNAME, CTX_NO_SPACE, and CTX_QUOTED_STR.

Referenced by AltiumToKiCadLibID(), SCH_EDIT_TOOL::ChangeTextType(), SYMBOL_VIEWER_FRAME::ClickOnLibList(), SYMBOL_VIEWER_FRAME::ClickOnSymbolList(), collectItemsForSyncParts(), PANEL_SYM_LIB_TABLE::convertLibrary(), CONNECTION_SUBGRAPH::driverName(), SYMBOL_EDITOR_EDIT_TOOL::editFieldProperties(), PDF_PLOTTER::EndPlot(), CONNECTION_GRAPH::ercCheckBusToNetConflicts(), TEXT_BUTTON_SYMBOL_CHOOSER::escapeLibId(), PCB_EDIT_FRAME::FindItemsFromSyncSelection(), RESCUE_SYMBOL_LIB_TABLE_CANDIDATE::FindRescues(), PCB_PLUGIN::format(), SCH_PIN::GetDefaultNetName(), getLibIdValue(), DIALOG_LIB_NEW_SYMBOL::GetName(), DIALOG_LIB_NEW_SYMBOL::GetParentSymbolName(), SYMBOL_EDIT_FRAME::ImportSymbol(), SCH_LEGACY_PLUGIN_CACHE::loadField(), SCH_EAGLE_PLUGIN::loadInstance(), SCH_EAGLE_PLUGIN::loadLibrary(), CADSTAR_SCH_ARCHIVE_LOADER::loadPartsLibrary(), CADSTAR_SCH_ARCHIVE_LOADER::loadSchematicSymbolInstances(), SCH_EAGLE_PLUGIN::loadSegments(), netList(), DIALOG_NET_INSPECTOR::onRenameNet(), NET_SETTINGS::ParseBusGroup(), SYMBOL_EDITOR_CONTROL::RenameSymbol(), SCH_LABEL_BASE::Replace(), SCH_SEXPR_PLUGIN_CACHE::saveDcmInfoAsFields(), SIM_PLOT_FRAME::saveWorkbook(), CVPCB_MAINFRAME::SendComponentSelectionToSch(), SCH_EDIT_FRAME::SendSelectItemsToPcb(), FIELDS_GRID_TABLE< T >::SetValue(), LIB_TABLE_GRID::SetValue(), PGPROPERTY_STRING::StringToValue(), DIALOG_LABEL_PROPERTIES::TransferDataFromWindow(), DIALOG_LIB_SYMBOL_PROPERTIES::TransferDataFromWindow(), DIALOG_SHEET_PIN_PROPERTIES::TransferDataFromWindow(), DIALOG_TEXTBOX_PROPERTIES::TransferDataFromWindow(), and FOOTPRINT_LIST_IMPL::WriteCacheToFile().

◆ FormatDouble2Str()

std::string FormatDouble2Str ( double  aValue)

Print a float number without using scientific notation and no trailing 0 This function is intended in uses to write to file, it ignores locale.

We cannot always just use the g or the f format to print a fp number this helper function uses the f format when needed, or g when f is not well working and then removes trailing 0

Definition at line 1099 of file string_utils.cpp.

1100{
1101 std::string buf;
1102
1103 if( aValue != 0.0 && std::fabs( aValue ) <= 0.0001 )
1104 {
1105 buf = fmt::format( "{:.16f}", aValue );
1106
1107 // remove trailing zeros (and the decimal marker if needed)
1108 while( !buf.empty() && buf[buf.size() - 1] == '0' )
1109 {
1110 buf.pop_back();
1111 }
1112
1113 // if the value was really small
1114 // we may have just stripped all the zeros after the decimal
1115 if( buf[buf.size() - 1] == '.' )
1116 {
1117 buf.pop_back();
1118 }
1119 }
1120 else
1121 {
1122 buf = fmt::format( "{:.10g}", aValue );
1123 }
1124
1125 return buf;
1126}

Referenced by BOOST_AUTO_TEST_CASE(), GBR_TO_PCB_EXPORTER::export_non_copper_item(), GBR_TO_PCB_EXPORTER::export_via(), PCB_PLUGIN::format(), DS_DATA_MODEL_IO::format(), DS_DATA_MODEL_IO::Format(), EDA_TEXT::Format(), STROKE_PARAMS::Format(), BOARD_STACKUP::FormatBoardStackup(), DS_DATA_MODEL_IO::formatCoordinate(), formatFill(), DS_DATA_MODEL_IO::formatRepeatParameters(), PCB_PLUGIN::formatSetup(), SCH_SEXPR_PLUGIN::saveJunction(), GBR_TO_PCB_EXPORTER::writeCopperLineItem(), GBR_TO_PCB_EXPORTER::writePcbFilledCircle(), GBR_TO_PCB_EXPORTER::writePcbPolygon(), and GBR_TO_PCB_EXPORTER::writePcbZoneItem().

◆ GetIllegalFileNameWxChars()

wxString GetIllegalFileNameWxChars ( )
Returns
a wxString object containing the illegal file name characters for all platforms.

Definition at line 988 of file string_utils.cpp.

989{
991}
static wxString FROM_UTF8(const char *cstring)
Convert a UTF8 encoded C string to a wxString for all wxWidgets build modes.
Definition: macros.h:110
static const char illegalFileNameChars[]
Illegal file name characters used to ensure file names will be valid on all supported platforms.

References FROM_UTF8(), and illegalFileNameChars.

Referenced by ReplaceIllegalFileNameChars().

◆ GetLine()

char * GetLine ( FILE *  aFile,
char *  Line,
int *  LineNum = nullptr,
int  SizeLine = 255 
)

Read one line line from aFile.

Returns
a pointer the first useful line read by eliminating blank lines and comments.

Definition at line 638 of file string_utils.cpp.

639{
640 do {
641 if( fgets( Line, SizeLine, File ) == nullptr )
642 return nullptr;
643
644 if( LineNum )
645 *LineNum += 1;
646
647 } while( Line[0] == '#' || Line[0] == '\n' || Line[0] == '\r' || Line[0] == 0 );
648
649 strtok( Line, "\n\r" );
650 return Line;
651}

Referenced by CVPCB_MAINFRAME::buildEquivalenceList().

◆ GetTrailingInt()

int GetTrailingInt ( const wxString &  aStr)

Gets the trailing int, if any, from a string.

Parameters
aStrthe string to check.
Returns
the trailing int or 0 if none found.

Definition at line 964 of file string_utils.cpp.

965{
966 int number = 0;
967 int base = 1;
968
969 // Trim and extract the trailing numeric part
970 int index = aStr.Len() - 1;
971
972 while( index >= 0 )
973 {
974 const char chr = aStr.GetChar( index );
975
976 if( chr < '0' || chr > '9' )
977 break;
978
979 number += ( chr - '0' ) * base;
980 base *= 10;
981 index--;
982 }
983
984 return number;
985}

Referenced by BOOST_AUTO_TEST_CASE(), compareFootprintsbyRef(), FOOTPRINT::GetNextPadNumber(), and FOOTPRINT::IncrementReference().

◆ NoPrintableChars()

bool NoPrintableChars ( const wxString &  aString)

Return true if the string is empty or contains only whitespace.

Definition at line 527 of file string_utils.cpp.

528{
529 wxString tmp = aString;
530
531 return tmp.Trim( true ).Trim( false ).IsEmpty();
532}

Referenced by SCH_DRAWING_TOOLS::createNewText(), SCH_DRAWING_TOOLS::createSheetPin(), DRAWING_TOOL::PlaceText(), and SYMBOL_EDITOR_DRAWING_TOOLS::TwoClickPlace().

◆ PrettyPrintForMenu()

wxString PrettyPrintForMenu ( const wxString &  aString)

Remove markup (such as overbar or subscript) that we can't render to menu items.

◆ PrintableCharCount()

int PrintableCharCount ( const wxString &  aString)

Return the number of printable (ie: non-formatting) chars.

Used to approximate rendered text size when speed is more important than accuracy.

Definition at line 539 of file string_utils.cpp.

540{
541 int char_count = 0;
542 int overbarDepth = -1;
543 int superSubDepth = -1;
544 int braceNesting = 0;
545
546 for( auto chIt = aString.begin(), end = aString.end(); chIt < end; ++chIt )
547 {
548 if( *chIt == '\t' )
549 {
550 // We don't format tabs in bitmap text (where this is currently used), so just
551 // drop them from the count.
552 continue;
553 }
554 else if( *chIt == '^' && superSubDepth == -1 )
555 {
556 auto lookahead = chIt;
557
558 if( ++lookahead != end && *lookahead == '{' )
559 {
560 chIt = lookahead;
561 superSubDepth = braceNesting;
562 braceNesting++;
563 continue;
564 }
565 }
566 else if( *chIt == '_' && superSubDepth == -1 )
567 {
568 auto lookahead = chIt;
569
570 if( ++lookahead != end && *lookahead == '{' )
571 {
572 chIt = lookahead;
573 superSubDepth = braceNesting;
574 braceNesting++;
575 continue;
576 }
577 }
578 else if( *chIt == '~' && overbarDepth == -1 )
579 {
580 auto lookahead = chIt;
581
582 if( ++lookahead != end && *lookahead == '{' )
583 {
584 chIt = lookahead;
585 overbarDepth = braceNesting;
586 braceNesting++;
587 continue;
588 }
589 }
590 else if( *chIt == '{' )
591 {
592 braceNesting++;
593 }
594 else if( *chIt == '}' )
595 {
596 if( braceNesting > 0 )
597 braceNesting--;
598
599 if( braceNesting == superSubDepth )
600 {
601 superSubDepth = -1;
602 continue;
603 }
604
605 if( braceNesting == overbarDepth )
606 {
607 overbarDepth = -1;
608 continue;
609 }
610 }
611
612 char_count++;
613 }
614
615 return char_count;
616}

Referenced by KIGFX::PCB_PAINTER::draw().

◆ ReadDelimitedText() [1/2]

int ReadDelimitedText ( char *  aDest,
const char *  aSource,
int  aDestSize 
)

Copy bytes from aSource delimited string segment to aDest buffer.

The extracted string will be null terminated even if truncation is necessary because aDestSize was not large enough.

Parameters
aDestis the destination byte buffer.
aSourceis the source bytes as a C string.
aDestSizeis the size of the destination byte buffer.
Returns
the number of bytes read from source, which may be more than the number copied, due to escaping of double quotes and the escape byte itself.
Deprecated:
should use the one which fetches a wxString, below.

Definition at line 411 of file string_utils.cpp.

412{
413 if( aDestSize <= 0 )
414 return 0;
415
416 bool inside = false;
417 const char* start = aSource;
418 char* limit = aDest + aDestSize - 1;
419 char cc;
420
421 while( (cc = *aSource++) != 0 && aDest < limit )
422 {
423 if( cc == '"' )
424 {
425 if( inside )
426 break; // 2nd double quote is end of delimited text
427
428 inside = true; // first delimiter found, make note, do not copy
429 }
430
431 else if( inside )
432 {
433 if( cc == '\\' )
434 {
435 cc = *aSource++;
436
437 if( !cc )
438 break;
439
440 // do no copy the escape byte if it is followed by \ or "
441 if( cc != '"' && cc != '\\' )
442 *aDest++ = '\\';
443
444 if( aDest < limit )
445 *aDest++ = cc;
446 }
447 else
448 {
449 *aDest++ = cc;
450 }
451 }
452 }
453
454 *aDest = 0;
455
456 return aSource - start;
457}

◆ ReadDelimitedText() [2/2]

int ReadDelimitedText ( wxString *  aDest,
const char *  aSource 
)

Copy bytes from aSource delimited string segment to aDest wxString.

Parameters
aDestis the destination wxString.
aSourceis the source C string holding utf8 encoded bytes.
Returns
the number of bytes read from source, which may be more than the number copied, due to escaping of double quotes and the escape byte itself.

Definition at line 366 of file string_utils.cpp.

367{
368 std::string utf8; // utf8 but without escapes and quotes.
369 bool inside = false;
370 const char* start = aSource;
371 char cc;
372
373 while( (cc = *aSource++) != 0 )
374 {
375 if( cc == '"' )
376 {
377 if( inside )
378 break; // 2nd double quote is end of delimited text
379
380 inside = true; // first delimiter found, make note, do not copy
381 }
382
383 else if( inside )
384 {
385 if( cc == '\\' )
386 {
387 cc = *aSource++;
388
389 if( !cc )
390 break;
391
392 // do no copy the escape byte if it is followed by \ or "
393 if( cc != '"' && cc != '\\' )
394 utf8 += '\\';
395
396 utf8 += cc;
397 }
398 else
399 {
400 utf8 += cc;
401 }
402 }
403 }
404
405 *aDest = FROM_UTF8( utf8.c_str() );
406
407 return aSource - start;
408}

References FROM_UTF8().

Referenced by LEGACY_PLUGIN::load3D(), LEGACY_PLUGIN::loadDIMENSION(), LEGACY_PLUGIN::loadMODULE_TEXT(), LEGACY_PLUGIN::loadNETCLASS(), LEGACY_PLUGIN::loadNETINFO_ITEM(), LEGACY_PLUGIN::loadPAD(), LEGACY_PLUGIN::loadPCB_TEXT(), LEGACY_PLUGIN::loadSHEET(), and LEGACY_PLUGIN::loadZONE_CONTAINER().

◆ ReplaceIllegalFileNameChars() [1/2]

bool ReplaceIllegalFileNameChars ( std::string *  aName,
int  aReplaceChar = 0 
)

Checks aName for illegal file name characters.

The Windows (DOS) file system forbidden characters already include the forbidden file name characters for both Posix and OSX systems. The characters \/?*|"<> are illegal and are replaced with xx where xx the hexadecimal equivalent of the replaced character. This replacement may not be as elegant as using an underscore ('_') or hyphen ('-') but it guarantees that there will be no naming conflicts when fixing footprint library names. however, if aReplaceChar is given, it will replace the illegal chars

Parameters
aNameis a point to a std::string object containing the footprint name to verify.
aReplaceChar(if not 0) is the replacement char.
Returns
true if any characters have been replaced in aName.

Definition at line 994 of file string_utils.cpp.

995{
996 bool changed = false;
997 std::string result;
998 result.reserve( aName->length() );
999
1000 for( std::string::iterator it = aName->begin(); it != aName->end(); ++it )
1001 {
1002 if( strchr( illegalFileNameChars, *it ) )
1003 {
1004 if( aReplaceChar )
1005 StrPrintf( &result, "%c", aReplaceChar );
1006 else
1007 StrPrintf( &result, "%%%02x", *it );
1008
1009 changed = true;
1010 }
1011 else
1012 {
1013 result += *it;
1014 }
1015 }
1016
1017 if( changed )
1018 *aName = result;
1019
1020 return changed;
1021}
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.
Definition: richio.cpp:84

References illegalFileNameChars, and StrPrintf().

Referenced by EDEVICE::EDEVICE(), EELEMENT::EELEMENT(), LEGACY_PLUGIN::loadAllSections(), FABMASTER::loadFootprints(), EAGLE_PLUGIN::loadLibrary(), LP_CACHE::LoadModules(), SCH_EAGLE_PLUGIN::loadSheet(), CADSTAR_SCH_ARCHIVE_LOADER::loadSheetAndChildSheets(), and CADSTAR_SCH_ARCHIVE_LOADER::loadSheets().

◆ ReplaceIllegalFileNameChars() [2/2]

bool ReplaceIllegalFileNameChars ( wxString &  aName,
int  aReplaceChar = 0 
)

Definition at line 1024 of file string_utils.cpp.

1025{
1026 bool changed = false;
1027 wxString result;
1028 result.reserve( aName.Length() );
1029 wxString illWChars = GetIllegalFileNameWxChars();
1030
1031 for( wxString::iterator it = aName.begin(); it != aName.end(); ++it )
1032 {
1033 if( illWChars.Find( *it ) != wxNOT_FOUND )
1034 {
1035 if( aReplaceChar )
1036 result += aReplaceChar;
1037 else
1038 result += wxString::Format( "%%%02x", *it );
1039
1040 changed = true;
1041 }
1042 else
1043 {
1044 result += *it;
1045 }
1046 }
1047
1048 if( changed )
1049 aName = result;
1050
1051 return changed;
1052}
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
wxString GetIllegalFileNameWxChars()

References Format(), and GetIllegalFileNameWxChars().

◆ split()

static std::vector< std::string > split ( const std::string &  aStr,
const std::string &  aDelim 
)
inlinestatic

Split the input string into a vector of output strings.

Note
Multiple delimiters are considered to be separate records with empty strings
Parameters
aStrInput string with 0 or more delimiters.
aDelimThe string of delimiter. Multiple characters here denote alternate delimiters.
Returns
a vector of strings

Definition at line 296 of file string_utils.h.

297{
298 size_t pos = 0;
299 size_t last_pos = 0;
300 size_t len;
301
302 std::vector<std::string> tokens;
303
304 while( pos < aStr.size() )
305 {
306 pos = aStr.find_first_of( aDelim, last_pos );
307
308 if( pos == std::string::npos )
309 pos = aStr.size();
310
311 len = pos - last_pos;
312
313 tokens.push_back( aStr.substr( last_pos, len ) );
314
315 last_pos = pos + 1;
316 }
317
318 return tokens;
319}

Referenced by CompareToBucket::CompareToBucket(), HLBVH_SAH_Evaluator::HLBVH_SAH_Evaluator(), SCH_EDIT_FRAME::KiwayMailIn(), PCB_EDIT_FRAME::KiwayMailIn(), FOOTPRINT_VIEWER_FRAME::KiwayMailIn(), FABMASTER::processText(), and PNS::NODE::rebuildJoint().

◆ SplitString()

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.

For example C10A is split to C 10 A

Definition at line 903 of file string_utils.cpp.

907{
908 static const wxString separators( wxT( ".," ) );
909
910 // Clear all the return strings
911 strBeginning->Empty();
912 strDigits->Empty();
913 strEnd->Empty();
914
915 // There no need to do anything if the string is empty
916 if( strToSplit.length() == 0 )
917 return 0;
918
919 // Starting at the end of the string look for the first digit
920 int ii;
921
922 for( ii = (strToSplit.length() - 1); ii >= 0; ii-- )
923 {
924 if( wxIsdigit( strToSplit[ii] ) )
925 break;
926 }
927
928 // If there were no digits then just set the single string
929 if( ii < 0 )
930 {
931 *strBeginning = strToSplit;
932 }
933 else
934 {
935 // Since there is at least one digit this is the trailing string
936 *strEnd = strToSplit.substr( ii + 1 );
937
938 // Go to the end of the digits
939 int position = ii + 1;
940
941 for( ; ii >= 0; ii-- )
942 {
943 if( !wxIsdigit( strToSplit[ii] ) && separators.Find( strToSplit[ii] ) < 0 )
944 break;
945 }
946
947 // If all that was left was digits, then just set the digits string
948 if( ii < 0 )
949 *strDigits = strToSplit.substr( 0, position );
950
951 /* We were only looking for the last set of digits everything else is
952 * part of the preamble */
953 else
954 {
955 *strDigits = strToSplit.substr( ii + 1, position - ii - 1 );
956 *strBeginning = strToSplit.substr( 0, ii + 1 );
957 }
958 }
959
960 return 0;
961}

Referenced by ValueStringCompare().

◆ StripTrailingZeros()

void StripTrailingZeros ( wxString &  aStringValue,
unsigned  aTrailingZeroAllowed = 1 
)

Remove trailing zeros from a string containing a converted float number.

The trailing zeros are removed if the mantissa has more than aTrailingZeroAllowed digits and some trailing zeros.

Definition at line 1077 of file string_utils.cpp.

1078{
1079 struct lconv* lc = localeconv();
1080 char sep = lc->decimal_point[0];
1081 unsigned sep_pos = aStringValue.Find( sep );
1082
1083 if( sep_pos > 0 )
1084 {
1085 // We want to keep at least aTrailingZeroAllowed digits after the separator
1086 unsigned min_len = sep_pos + aTrailingZeroAllowed + 1;
1087
1088 while( aStringValue.Len() > min_len )
1089 {
1090 if( aStringValue.Last() == '0' )
1091 aStringValue.RemoveLast();
1092 else
1093 break;
1094 }
1095 }
1096}

◆ StrNumCmp()

int StrNumCmp ( const wxString &  aString1,
const wxString &  aString2,
bool  aIgnoreCase = false 
)

Compare two strings with alphanumerical content.

This function is equivalent to strncmp() or strncasecmp() if aIgnoreCase is true except that strings containing numbers are compared by their integer value not by their ASCII code. In other words U10 would be greater than U2.

Parameters
aString1A wxString reference to the reference string.
aString2A wxString reference to the comparison string.
aIgnoreCaseUse true to make the comparison case insensitive.
Returns
An integer value of -1 if aString1 is less than aString2, 0 if aString1 is equal to aString2, or 1 if aString1 is greater than aString2.

Definition at line 663 of file string_utils.cpp.

664{
665 int nb1 = 0, nb2 = 0;
666
667 auto str1 = aString1.begin();
668 auto str2 = aString2.begin();
669
670 while( str1 != aString1.end() && str2 != aString2.end() )
671 {
672 wxUniChar c1 = *str1;
673 wxUniChar c2 = *str2;
674
675 if( wxIsdigit( c1 ) && wxIsdigit( c2 ) ) // Both characters are digits, do numeric compare.
676 {
677 nb1 = 0;
678 nb2 = 0;
679
680 do
681 {
682 c1 = *str1;
683 nb1 = nb1 * 10 + (int) c1 - '0';
684 ++str1;
685 } while( str1 != aString1.end() && wxIsdigit( *str1 ) );
686
687 do
688 {
689 c2 = *str2;
690 nb2 = nb2 * 10 + (int) c2 - '0';
691 ++str2;
692 } while( str2 != aString2.end() && wxIsdigit( *str2 ) );
693
694 if( nb1 < nb2 )
695 return -1;
696
697 if( nb1 > nb2 )
698 return 1;
699
700 c1 = ( str1 != aString1.end() ) ? *str1 : wxUniChar( 0 );
701 c2 = ( str2 != aString2.end() ) ? *str2 : wxUniChar( 0 );
702 }
703
704 // Any numerical comparisons to here are identical.
705 if( aIgnoreCase )
706 {
707 if( wxToupper( c1 ) < wxToupper( c2 ) )
708 return -1;
709
710 if( wxToupper( c1 ) > wxToupper( c2 ) )
711 return 1;
712 }
713 else
714 {
715 if( c1 < c2 )
716 return -1;
717
718 if( c1 > c2 )
719 return 1;
720 }
721
722 if( str1 != aString1.end() )
723 ++str1;
724
725 if( str2 != aString2.end() )
726 ++str2;
727 }
728
729 if( str1 == aString1.end() && str2 != aString2.end() )
730 {
731 return -1; // Identical to here but aString1 is longer.
732 }
733 else if( str1 != aString1.end() && str2 == aString2.end() )
734 {
735 return 1; // Identical to here but aString2 is longer.
736 }
737
738 return 0;
739}

Referenced by REGULATOR_LIST::Add(), BOOST_AUTO_TEST_CASE(), ChangeArrayCompare(), FIELDS_EDITOR_GRID_DATA_MODEL::cmp(), PIN_TABLE_DATA_MODEL::compare(), SCH_PIN_TABLE_DATA_MODEL::compare(), SCH_SHEET::ComparePageNum(), FP_TREE_MODEL_ADAPTER::getFootprints(), NETLIST_EXPORTER_XML::makeSymbols(), myCompareFunction(), FOOTPRINT::cmp_pads::operator()(), operator<(), SCH_REFERENCE_LIST::sortByReferenceOnly(), sortFPlist(), and sortPinsByNumber().

◆ StrPurge()

char * StrPurge ( char *  text)

Remove leading and training spaces, tabs and end of line chars in text.

Returns
a pointer on the first n char in text

Definition at line 619 of file string_utils.cpp.

620{
621 static const char whitespace[] = " \t\n\r\f\v";
622
623 if( text )
624 {
625 while( *text && strchr( whitespace, *text ) )
626 ++text;
627
628 char* cp = text + strlen( text ) - 1;
629
630 while( cp >= text && strchr( whitespace, *cp ) )
631 *cp-- = '\0';
632 }
633
634 return text;
635}

References text.

Referenced by detect_file_type(), LEGACY_PLUGIN::loadAllSections(), EXCELLON_IMAGE::LoadFile(), LEGACY_PLUGIN::loadFOOTPRINT(), GERBER_FILE_IMAGE::LoadGerberFile(), LP_CACHE::LoadModules(), LEGACY_NETLIST_READER::LoadNetlist(), LEGACY_PLUGIN::loadPAD(), EXCELLON_IMAGE::TestFileIsExcellon(), and GERBER_FILE_IMAGE::TestFileIsRS274().

◆ strtok_r()

◆ TitleCaps()

wxString TitleCaps ( const wxString &  aString)

Capitalize the first letter in each word.

Definition at line 345 of file string_utils.cpp.

346{
347 wxArrayString words;
348 wxString result;
349
350 wxStringSplit( aString, words, ' ' );
351
352 result.reserve( aString.length() );
353
354 for( const wxString& word : words )
355 {
356 if( !result.IsEmpty() )
357 result += wxT( " " );
358
359 result += word.Capitalize();
360 }
361
362 return result;
363}
void wxStringSplit(const wxString &aText, wxArrayString &aStrings, wxChar aSplitter)
Split aString to a string list separated at aSplitter.

References wxStringSplit().

Referenced by SYMBOL_EDITOR_EDIT_TOOL::editFieldProperties(), and SCH_EDIT_TOOL::editFieldText().

◆ UIDouble2Str()

std::string UIDouble2Str ( double  aValue)

Print a float number without using scientific notation and no trailing 0 We want to avoid scientific notation in S-expr files (not easy to read) for floating numbers.

We cannot always just use the g or the f format to print a fp number this helper function uses the f format when needed, or g when f is not well working and then removes trailing 0

Definition at line 1129 of file string_utils.cpp.

1130{
1131 char buf[50];
1132 int len;
1133
1134 if( aValue != 0.0 && std::fabs( aValue ) <= 0.0001 )
1135 {
1136 // For these small values, %f works fine,
1137 // and %g gives an exponent
1138 len = snprintf( buf, sizeof(buf), "%.16f", aValue );
1139
1140 while( --len > 0 && buf[len] == '0' )
1141 buf[len] = '\0';
1142
1143 if( buf[len] == '.' || buf[len] == ',' )
1144 buf[len] = '\0';
1145 else
1146 ++len;
1147 }
1148 else
1149 {
1150 // For these values, %g works fine, and sometimes %f
1151 // gives a bad value (try aValue = 1.222222222222, with %.16f format!)
1152 len = snprintf( buf, sizeof(buf), "%.10g", aValue );
1153 }
1154
1155 return std::string( buf, len );
1156}

Referenced by BOOST_AUTO_TEST_CASE(), PANEL_SETUP_BOARD_STACKUP::createRowData(), DIELECTRIC_SUBSTRATE::FormatEpsilonR(), BOARD_STACKUP_ITEM::FormatEpsilonR(), DIELECTRIC_SUBSTRATE::FormatLossTangent(), BOARD_STACKUP_ITEM::FormatLossTangent(), NUMERIC_EVALUATOR::parseSetResult(), and PANEL_SETUP_BOARD_STACKUP::synchronizeWithBoard().

◆ UnescapeString()

wxString UnescapeString ( const wxString &  aSource)

Definition at line 267 of file string_utils.cpp.

268{
269 size_t sourceLen = aSource.length();
270
271 // smallest escape string is three characters, shortcut everything else
272 if( sourceLen <= 2 )
273 {
274 return aSource;
275 }
276
277 wxString newbuf;
278 newbuf.reserve( sourceLen );
279
280 for( size_t i = 0; i < sourceLen; ++i )
281 {
282 wxUniChar ch = aSource[i];
283
284 if( ( ch == '$' || ch == '~' || ch == '^' || ch == '_' )
285 && i + 1 < sourceLen && aSource[i+1] == '{' )
286 {
287 for( ; i < sourceLen; ++i )
288 {
289 ch = aSource[i];
290 newbuf += ch;
291
292 if( ch == '}' )
293 break;
294 }
295 }
296 else if( ch == '{' )
297 {
298 wxString token;
299 int depth = 1;
300
301 for( i = i + 1; i < sourceLen; ++i )
302 {
303 ch = aSource[i];
304 if( ch == '{' )
305 depth++;
306 else if( ch == '}' )
307 depth--;
308
309 if( depth <= 0 )
310 break;
311 else
312 token.append( ch );
313 }
314
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( "{" ) );
330 else
331 {
332 newbuf.append( wxT( "{" ) + UnescapeString( token ) + wxT( "}" ) );
333 }
334 }
335 else
336 {
337 newbuf.append( ch );
338 }
339 }
340
341 return newbuf;
342}
wxString UnescapeString(const wxString &aSource)

References UnescapeString().

Referenced by NET_SELECTOR_COMBOPOPUP::Accept(), DIALOG_EDIT_SYMBOLS_LIBID::AddRowToGrid(), NETLIST_EXPORTER_XML::addSymbolFields(), SCH_CONNECTION::AppendInfoToMsgPanel(), APPEARANCE_CONTROLS::buildNetClassMenu(), EDA_TEXT::cacheShownText(), SCH_EDIT_TOOL::ChangeTextType(), SCH_CONNECTION::ConfigureFromLabel(), DIALOG_CHANGE_SYMBOLS::DIALOG_CHANGE_SYMBOLS(), DIALOG_LIB_FIELD_PROPERTIES::DIALOG_LIB_FIELD_PROPERTIES(), DIALOG_LIB_NEW_SYMBOL::DIALOG_LIB_NEW_SYMBOL(), DIALOG_UPDATE_SYMBOL_FIELDS::DIALOG_UPDATE_SYMBOL_FIELDS(), KIGFX::SCH_PAINTER::draw(), KIGFX::PCB_PAINTER::draw(), GRID_CELL_ESCAPED_TEXT_RENDERER::Draw(), KIUI::EllipsizeMenuText(), KIUI::EllipsizeStatusText(), CONNECTION_GRAPH::ercCheckBusToBusEntryConflicts(), CONNECTION_GRAPH::ercCheckHierSheets(), SCH_EDIT_FRAME::ExecuteRemoteCommand(), SYMBOL_EDIT_FRAME::ExportSymbol(), findItemsFromSyncSelection(), PCB_EDIT_FRAME::FindItemsFromSyncSelection(), DIALOG_NET_INSPECTOR::formatNetName(), NETLIST_EXPORTER_SPICE::GenerateItemPinNetName(), RESCUE_SYMBOL_LIB_TABLE_CANDIDATE::GetActionDescription(), GRID_CELL_ESCAPED_TEXT_RENDERER::GetBestSize(), LIB_PIN::GetItemDescription(), SCH_SYMBOL::GetItemDescription(), LIB_FIELD::GetMsgPanelInfo(), LIB_PIN::GetMsgPanelInfo(), LIB_TEXT::GetMsgPanelInfo(), SCH_FIELD::GetMsgPanelInfo(), SCH_LABEL_BASE::GetMsgPanelInfo(), SCH_LINE::GetMsgPanelInfo(), SCH_SYMBOL::GetMsgPanelInfo(), GERBER_DRAW_ITEM::GetMsgPanelInfo(), FP_TEXT::GetMsgPanelInfo(), FP_TEXTBOX::GetMsgPanelInfo(), NETINFO_ITEM::GetMsgPanelInfo(), PAD::GetMsgPanelInfo(), ZONE::GetMsgPanelInfo(), PCB_TRACK::GetMsgPanelInfoBase_Common(), BOARD_CONNECTED_ITEM::GetNetnameMsg(), FOOTPRINT_SEARCH_HANDLER::GetResultCell(), ZONE_SEARCH_HANDLER::GetResultCell(), TEXT_SEARCH_HANDLER::GetResultCell(), NETS_SEARCH_HANDLER::GetResultCell(), SYMBOL_LIBRARY_MANAGER::LIB_BUFFER::GetRootSymbolNames(), DIALOG_COPPER_ZONE::getUnescapedNetName(), FIELDS_GRID_TABLE< T >::GetValue(), LIB_TABLE_GRID::GetValue(), LIB_TREE_MODEL_ADAPTER::GetValue(), SYMBOL_TREE_SYNCHRONIZING_ADAPTER::GetValue(), GERBVIEW_CONTROL::HighlightControl(), SCH_CONNECTION::IsBusLabel(), SYMBOL_EDIT_FRAME::KiwayMailIn(), DIALOG_CHANGE_SYMBOLS::launchMatchIdSymbolBrowser(), DIALOG_CHANGE_SYMBOLS::launchNewIdSymbolBrowser(), DIALOG_NET_INSPECTOR::LIST_ITEM::LIST_ITEM(), SCH_EAGLE_PLUGIN::loadInstance(), SCH_LEGACY_PLUGIN_CACHE::LoadPart(), SIM_PLOT_FRAME::loadWorkbook(), SCH_LABEL_BASE::Matches(), SCH_CONNECTION::MightBeBusLabel(), DIALOG_NET_INSPECTOR::netFilterMatches(), TEXT_BUTTON_SYMBOL_CHOOSER::OnButtonClick(), DIALOG_EDIT_SYMBOLS_LIBID::onClickOrphansButton(), APPEARANCE_CONTROLS::OnNetGridRightClick(), DIALOG_NET_INSPECTOR::onRenameNet(), SCH_SEXPR_PARSER::parseProperty(), DIALOG_CHANGE_SYMBOLS::processSymbol(), FOOTPRINT_LIST_IMPL::ReadCacheFromFile(), NET_SELECTOR_COMBOPOPUP::rebuildList(), SYMBOL_VIEWER_FRAME::ReCreateLibList(), SYMBOL_VIEWER_FRAME::ReCreateSymbolList(), FOOTPRINT_EDITOR_CONTROL::RenameFootprint(), SYMBOL_EDITOR_CONTROL::RenameSymbol(), SYMBOL_LIBRARY_MANAGER::LIB_BUFFER::SaveBuffer(), SYMBOL_EDIT_FRAME::SetCurSymbol(), FOOTPRINT_INFO_GENERATOR::SetHtmlAliasOf(), FOOTPRINT_INFO_GENERATOR::SetHtmlName(), DIALOG_EDIT_SYMBOLS_LIBID::setLibIdByBrowser(), DIALOG_LIB_NEW_SYMBOL::SetName(), NETINFO_ITEM::SetNetname(), SYMBOL_VIEWER_FRAME::SetSelectedLibrary(), NET_SELECTOR::SetSelectedNet(), NET_SELECTOR::SetSelectedNetcode(), SYMBOL_VIEWER_FRAME::SetSelectedSymbol(), SYMBOL_VIEWER_FRAME::ShowModal(), ERC_TESTER::TestLibSymbolIssues(), DIALOG_EDIT_SYMBOLS_LIBID::TransferDataFromWindow(), DIALOG_LIB_SYMBOL_PROPERTIES::TransferDataFromWindow(), DIALOG_LABEL_PROPERTIES::TransferDataToWindow(), DIALOG_LIB_SYMBOL_PROPERTIES::TransferDataToWindow(), DIALOG_SHEET_PIN_PROPERTIES::TransferDataToWindow(), DIALOG_SIGNAL_LIST::TransferDataToWindow(), DIALOG_SYMBOL_PROPERTIES::TransferDataToWindow(), DIALOG_TEXTBOX_PROPERTIES::TransferDataToWindow(), UnescapeString(), HIGHLIGHT_MENU::update(), SYMBOL_EDIT_FRAME::UpdateAfterSymbolProperties(), BOARD_NETLIST_UPDATER::updateComponentPadConnections(), BOARD_NETLIST_UPDATER::updateCopperZoneNets(), SCH_SYMBOL::UpdateFields(), PCB_PROPERTIES_PANEL::updateLists(), ROUTER_TOOL::UpdateMessagePanel(), PCB_CONTROL::UpdateMessagePanel(), SCH_EDIT_FRAME::UpdateNetHighlightStatus(), GERBVIEW_FRAME::updateNetnameListSelectBox(), SCH_EDITOR_CONTROL::updatePastedSymbol(), SYMBOL_VIEWER_FRAME::updatePreviewSymbol(), LIB_TREE_NODE_LIB_ID::UpdateScore(), SCH_SCREEN::UpdateSymbolLinks(), SYMBOL_EDIT_FRAME::UpdateSymbolMsgPanelInfo(), SYMBOL_EDIT_FRAME::updateTitle(), ValueStringCompare(), PGPROPERTY_STRING::ValueToString(), and DIALOG_GLOBAL_EDIT_TEXT_AND_GRAPHICS::visitItem().

◆ ValueStringCompare()

int ValueStringCompare ( const wxString &  strFWord,
const wxString &  strSWord 
)

Compare strings like the strcmp function but handle numbers and modifiers within the string text correctly for sorting.

eg. 1mF > 55uF

Returns
-1 if first string is less than the second, 0 if the strings are equal, or 1 if the first string is greater than the second.

Definition at line 851 of file string_utils.cpp.

852{
853 // Compare unescaped text
854 wxString fWord = UnescapeString( strFWord );
855 wxString sWord = UnescapeString( strSWord );
856
857 // The different sections of the two strings
858 wxString strFWordBeg, strFWordMid, strFWordEnd;
859 wxString strSWordBeg, strSWordMid, strSWordEnd;
860
861 // Split the two strings into separate parts
862 SplitString( fWord, &strFWordBeg, &strFWordMid, &strFWordEnd );
863 SplitString( sWord, &strSWordBeg, &strSWordMid, &strSWordEnd );
864
865 // Compare the Beginning section of the strings
866 int isEqual = strFWordBeg.CmpNoCase( strSWordBeg );
867
868 if( isEqual > 0 )
869 {
870 return 1;
871 }
872 else if( isEqual < 0 )
873 {
874 return -1;
875 }
876 else
877 {
878 // If the first sections are equal compare their digits
879 double lFirstNumber = 0;
880 double lSecondNumber = 0;
881 bool endingIsModifier = false;
882
883 strFWordMid.ToDouble( &lFirstNumber );
884 strSWordMid.ToDouble( &lSecondNumber );
885
886 endingIsModifier |= ApplyModifier( lFirstNumber, strFWordEnd );
887 endingIsModifier |= ApplyModifier( lSecondNumber, strSWordEnd );
888
889 if( lFirstNumber > lSecondNumber )
890 return 1;
891 else if( lFirstNumber < lSecondNumber )
892 return -1;
893 // If the first two sections are equal and the endings are modifiers then compare them
894 else if( !endingIsModifier )
895 return strFWordEnd.CmpNoCase( strSWordEnd );
896 // Ran out of things to compare; they must match
897 else
898 return 0;
899 }
900}
bool ApplyModifier(double &value, const wxString &aString)
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.

References ApplyModifier(), SplitString(), and UnescapeString().

Referenced by FIELDS_EDITOR_GRID_DATA_MODEL::cmp().

◆ WildCompareString()

bool WildCompareString ( const wxString &  pattern,
const wxString &  string_to_tst,
bool  case_sensitive = true 
)

Compare a string against wild card (* and ?) pattern using the usual rules.

Returns
true if pattern matched otherwise false.

Definition at line 742 of file string_utils.cpp.

744{
745 const wxChar* cp = nullptr, * mp = nullptr;
746 const wxChar* wild, * str;
747 wxString _pattern, _string_to_tst;
748
749 if( case_sensitive )
750 {
751 wild = pattern.GetData();
752 str = string_to_tst.GetData();
753 }
754 else
755 {
756 _pattern = pattern;
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();
762 }
763
764 while( ( *str ) && ( *wild != '*' ) )
765 {
766 if( ( *wild != *str ) && ( *wild != '?' ) )
767 return false;
768
769 wild++;
770 str++;
771 }
772
773 while( *str )
774 {
775 if( *wild == '*' )
776 {
777 if( !*++wild )
778 return 1;
779 mp = wild;
780 cp = str + 1;
781 }
782 else if( ( *wild == *str ) || ( *wild == '?' ) )
783 {
784 wild++;
785 str++;
786 }
787 else
788 {
789 wild = mp;
790 str = cp++;
791 }
792 }
793
794 while( *wild == '*' )
795 {
796 wild++;
797 }
798
799 return !*wild;
800}

Referenced by FROM_TO_CACHE::cacheFromToPaths(), LIBEVAL::VALUE::EqualTo(), DIALOG_EXCHANGE_FOOTPRINTS::isMatch(), DIALOG_CHANGE_SYMBOLS::isMatch(), FIELDS_EDITOR_GRID_DATA_MODEL::RebuildRows(), and DIALOG_GLOBAL_EDIT_TEXT_AND_GRAPHICS::visitItem().

◆ wxStringSplit()

void wxStringSplit ( const wxString &  aText,
wxArrayString &  aStrings,
wxChar  aSplitter 
)

Split aString to a string list separated at aSplitter.

Parameters
aTextis the text to split.
aStringswill contain the split lines.
aSplitteris the 'split' character.

Definition at line 1055 of file string_utils.cpp.

1056{
1057 wxString tmp;
1058
1059 for( unsigned ii = 0; ii < aText.Length(); ii++ )
1060 {
1061 if( aText[ii] == aSplitter )
1062 {
1063 aStrings.Add( tmp );
1064 tmp.Clear();
1065 }
1066 else
1067 {
1068 tmp << aText[ii];
1069 }
1070 }
1071
1072 if( !tmp.IsEmpty() )
1073 aStrings.Add( tmp );
1074}

Referenced by KIFONT::FONT::getLinePositions(), EDA_TEXT::GetTextBox(), KIFONT::FONT::LinebreakText(), HTML_MESSAGE_BOX::ListSet(), CADSTAR_SCH_ARCHIVE_LOADER::loadSymDefIntoLibrary(), SIM_MODEL::MigrateSimModel(), PANEL_SETUP_RULES::OnErrorLinkClicked(), pcbnewGetWizardsBackTrace(), SCH_TEXT::Plot(), SCH_TEXTBOX::Plot(), LIB_TEXTBOX::Plot(), BRDITEMS_PLOTTER::PlotPcbText(), EDA_TEXT::Print(), TitleCaps(), and wordbreakMarkup().