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()

void ConvertMarkdown2Html ( const wxString &  aMarkdownInput,
wxString &  aHtmlOutput 
)

◆ 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 647 of file string_utils.cpp.

648{
649 wxDateTime datetime = wxDateTime::Now();
650
651 datetime.SetCountry( wxDateTime::Country_Default );
652 return datetime.Format( wxDefaultDateTimeFormat, wxDateTime::Local );
653}

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 453 of file string_utils.cpp.

454{
455 wxString str = aString;
456
457 // No new-lines allowed in quoted strings
458 str.Replace( wxT( "\r\n" ), wxT( "\r" ) );
459 str.Replace( wxT( "\n" ), wxT( "\r" ) );
460
461 std::string utf8 = TO_UTF8( aString );
462
463 std::string ret;
464
465 ret.reserve( utf8.length() + 2 );
466
467 ret += '"';
468
469 for( std::string::const_iterator it = utf8.begin(); it!=utf8.end(); ++it )
470 {
471 // this escaping strategy is designed to be compatible with ReadDelimitedText():
472 if( *it == '"' )
473 {
474 ret += '\\';
475 ret += '"';
476 }
477 else if( *it == '\\' )
478 {
479 ret += '\\'; // double it up
480 ret += '\\';
481 }
482 else
483 {
484 ret += *it;
485 }
486 }
487
488 ret += '"';
489
490 return ret;
491}
#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 494 of file string_utils.cpp.

495{
496 wxString converted;
497
498 converted.reserve( aString.length() );
499
500 for( wxUniChar c : aString )
501 {
502 if( c == '\"' )
503 converted += wxT( "&quot;" );
504 else if( c == '\'' )
505 converted += wxT( "&apos;" );
506 else if( c == '&' )
507 converted += wxT( "&amp;" );
508 else if( c == '<' )
509 converted += wxT( "&lt;" );
510 else if( c == '>' )
511 converted += wxT( "&gt;" );
512 else
513 converted += c;
514 }
515
516 return converted;
517}

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 == '\'' )
200 converted += wxT( "{quote}" );
201 else
202 converted += c;
203 }
204 else if( aContext == CTX_LINE )
205 {
206 if( c == '\n' || c == '\r' )
207 converted += wxT( "{return}" );
208 else
209 converted += c;
210 }
211 else if( aContext == CTX_FILENAME )
212 {
213 if( c == '/' )
214 converted += wxT( "{slash}" );
215 else if( c == '\\' )
216 converted += wxT( "{backslash}" );
217 else if( c == '\"' )
218 converted += wxT( "{dblquote}" );
219 else if( c == '<' )
220 converted += wxT( "{lt}" );
221 else if( c == '>' )
222 converted += wxT( "{gt}" );
223 else if( c == '|' )
224 converted += wxT( "{bar}" );
225 else if( c == ':' )
226 converted += wxT( "{colon}" );
227 else if( c == '\t' )
228 converted += wxT( "{tab}" );
229 else if( c == '\n' || c == '\r' )
230 converted += wxT( "{return}" );
231 else
232 converted += c;
233 }
234 else if( aContext == CTX_NO_SPACE )
235 {
236 if( c == ' ' )
237 converted += wxT( "{space}" );
238 else
239 converted += c;
240 }
241 else if( aContext == CTX_CSV )
242 {
243 if( c == ',' )
244 converted += wxT( "{comma}" );
245 else if( c == '\n' || c == '\r' )
246 converted += wxT( "{return}" );
247 else
248 converted += c;
249 }
250 else
251 {
252 converted += c;
253 }
254 }
255
256 return converted;
257}

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_CASE_CANDIDATE::FindRescues(), RESCUE_CACHE_CANDIDATE::FindRescues(), RESCUE_SYMBOL_LIB_TABLE_CANDIDATE::FindRescues(), SYMBOL_VIEWER_FRAME::FinishModal(), 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(), SCH_LEGACY_PLUGIN_CACHE::LoadPart(), 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_SEXPR_PLUGIN_CACHE::saveDcmInfoAsFields(), SIM_PLOT_FRAME::saveWorkbook(), CVPCB_MAINFRAME::SendComponentSelectionToSch(), SCH_EDIT_FRAME::SendSelectItemsToPcb(), FIELDS_GRID_TABLE< T >::SetValue(), LIB_TABLE_GRID::SetValue(), DIALOG_LABEL_PROPERTIES::TransferDataFromWindow(), DIALOG_LIB_SYMBOL_PROPERTIES::TransferDataFromWindow(), DIALOG_SHEET_PIN_PROPERTIES::TransferDataFromWindow(), DIALOG_TEXTBOX_PROPERTIES::TransferDataFromWindow(), DIALOG_LIB_FIELD_PROPERTIES::UpdateField(), 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 1092 of file string_utils.cpp.

1093{
1094 std::string buf;
1095
1096 if( aValue != 0.0 && std::fabs( aValue ) <= 0.0001 )
1097 {
1098 buf = fmt::format( "{:.16f}", aValue );
1099
1100 // remove trailing zeros
1101 while( !buf.empty() && buf[buf.size() - 1] == '0' )
1102 {
1103 buf.pop_back();
1104 }
1105 }
1106 else
1107 {
1108 buf = fmt::format( "{:.10g}", aValue );
1109 }
1110
1111 return buf;
1112}

Referenced by 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 981 of file string_utils.cpp.

982{
984}
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 631 of file string_utils.cpp.

632{
633 do {
634 if( fgets( Line, SizeLine, File ) == nullptr )
635 return nullptr;
636
637 if( LineNum )
638 *LineNum += 1;
639
640 } while( Line[0] == '#' || Line[0] == '\n' || Line[0] == '\r' || Line[0] == 0 );
641
642 strtok( Line, "\n\r" );
643 return Line;
644}

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 957 of file string_utils.cpp.

958{
959 int number = 0;
960 int base = 1;
961
962 // Trim and extract the trailing numeric part
963 int index = aStr.Len() - 1;
964
965 while( index >= 0 )
966 {
967 const char chr = aStr.GetChar( index );
968
969 if( chr < '0' || chr > '9' )
970 break;
971
972 number += ( chr - '0' ) * base;
973 base *= 10;
974 index--;
975 }
976
977 return number;
978}

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 520 of file string_utils.cpp.

521{
522 wxString tmp = aString;
523
524 return tmp.Trim( true ).Trim( false ).IsEmpty();
525}

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 532 of file string_utils.cpp.

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

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 404 of file string_utils.cpp.

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

◆ 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 359 of file string_utils.cpp.

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

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 987 of file string_utils.cpp.

988{
989 bool changed = false;
990 std::string result;
991 result.reserve( aName->length() );
992
993 for( std::string::iterator it = aName->begin(); it != aName->end(); ++it )
994 {
995 if( strchr( illegalFileNameChars, *it ) )
996 {
997 if( aReplaceChar )
998 StrPrintf( &result, "%c", aReplaceChar );
999 else
1000 StrPrintf( &result, "%%%02x", *it );
1001
1002 changed = true;
1003 }
1004 else
1005 {
1006 result += *it;
1007 }
1008 }
1009
1010 if( changed )
1011 *aName = result;
1012
1013 return changed;
1014}
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 1017 of file string_utils.cpp.

1018{
1019 bool changed = false;
1020 wxString result;
1021 result.reserve( aName.Length() );
1022 wxString illWChars = GetIllegalFileNameWxChars();
1023
1024 for( wxString::iterator it = aName.begin(); it != aName.end(); ++it )
1025 {
1026 if( illWChars.Find( *it ) != wxNOT_FOUND )
1027 {
1028 if( aReplaceChar )
1029 result += aReplaceChar;
1030 else
1031 result += wxString::Format( "%%%02x", *it );
1032
1033 changed = true;
1034 }
1035 else
1036 {
1037 result += *it;
1038 }
1039 }
1040
1041 if( changed )
1042 aName = result;
1043
1044 return changed;
1045}
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 896 of file string_utils.cpp.

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

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 1070 of file string_utils.cpp.

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

◆ 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 656 of file string_utils.cpp.

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

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 612 of file string_utils.cpp.

613{
614 static const char whitespace[] = " \t\n\r\f\v";
615
616 if( text )
617 {
618 while( *text && strchr( whitespace, *text ) )
619 ++text;
620
621 char* cp = text + strlen( text ) - 1;
622
623 while( cp >= text && strchr( whitespace, *cp ) )
624 *cp-- = '\0';
625 }
626
627 return text;
628}

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 338 of file string_utils.cpp.

339{
340 wxArrayString words;
341 wxString result;
342
343 wxStringSplit( aString, words, ' ' );
344
345 result.reserve( aString.length() );
346
347 for( const wxString& word : words )
348 {
349 if( !result.IsEmpty() )
350 result += wxT( " " );
351
352 result += word.Capitalize();
353 }
354
355 return result;
356}
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 1115 of file string_utils.cpp.

1116{
1117 char buf[50];
1118 int len;
1119
1120 if( aValue != 0.0 && std::fabs( aValue ) <= 0.0001 )
1121 {
1122 // For these small values, %f works fine,
1123 // and %g gives an exponent
1124 len = sprintf( buf, "%.16f", aValue );
1125
1126 while( --len > 0 && buf[len] == '0' )
1127 buf[len] = '\0';
1128
1129 if( buf[len] == '.' )
1130 buf[len] = '\0';
1131 else
1132 ++len;
1133 }
1134 else
1135 {
1136 // For these values, %g works fine, and sometimes %f
1137 // gives a bad value (try aValue = 1.222222222222, with %.16f format!)
1138 len = sprintf( buf, "%.10g", aValue );
1139 }
1140
1141 return std::string( buf, len );
1142}

Referenced by 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 260 of file string_utils.cpp.

261{
262 size_t sourceLen = aSource.length();
263
264 // smallest escape string is three characters, shortcut everything else
265 if( sourceLen <= 2 )
266 {
267 return aSource;
268 }
269
270 wxString newbuf;
271 newbuf.reserve( sourceLen );
272
273 for( size_t i = 0; i < sourceLen; ++i )
274 {
275 wxUniChar ch = aSource[i];
276
277 if( ( ch == '$' || ch == '~' || ch == '^' || ch == '_' )
278 && i + 1 < sourceLen && aSource[i+1] == '{' )
279 {
280 for( ; i < sourceLen; ++i )
281 {
282 ch = aSource[i];
283 newbuf += ch;
284
285 if( ch == '}' )
286 break;
287 }
288 }
289 else if( ch == '{' )
290 {
291 wxString token;
292 int depth = 1;
293
294 for( i = i + 1; i < sourceLen; ++i )
295 {
296 ch = aSource[i];
297 if( ch == '{' )
298 depth++;
299 else if( ch == '}' )
300 depth--;
301
302 if( depth <= 0 )
303 break;
304 else
305 token.append( ch );
306 }
307
308 if( token == wxT( "dblquote" ) ) newbuf.append( wxT( "\"" ) );
309 else if( token == wxT( "quote" ) ) newbuf.append( wxT( "'" ) );
310 else if( token == wxT( "lt" ) ) newbuf.append( wxT( "<" ) );
311 else if( token == wxT( "gt" ) ) newbuf.append( wxT( ">" ) );
312 else if( token == wxT( "backslash" ) ) newbuf.append( wxT( "\\" ) );
313 else if( token == wxT( "slash" ) ) newbuf.append( wxT( "/" ) );
314 else if( token == wxT( "bar" ) ) newbuf.append( wxT( "|" ) );
315 else if( token == wxT( "comma" ) ) newbuf.append( wxT( "," ) );
316 else if( token == wxT( "colon" ) ) newbuf.append( wxT( ":" ) );
317 else if( token == wxT( "space" ) ) newbuf.append( wxT( " " ) );
318 else if( token == wxT( "dollar" ) ) newbuf.append( wxT( "$" ) );
319 else if( token == wxT( "tab" ) ) newbuf.append( wxT( "\t" ) );
320 else if( token == wxT( "return" ) ) newbuf.append( wxT( "\n" ) );
321 else if( token == wxT( "brace" ) ) newbuf.append( wxT( "{" ) );
322 else if( token.IsEmpty() ) newbuf.append( wxT( "{" ) );
323 else
324 {
325 newbuf.append( wxT( "{" ) + UnescapeString( token ) + wxT( "}" ) );
326 }
327 }
328 else
329 {
330 newbuf.append( ch );
331 }
332 }
333
334 return newbuf;
335}
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(), 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(), GRID_CELL_ESCAPED_TEXT_RENDERER::GetBestSize(), 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(), SYMBOL_LIBRARY_MANAGER::LIB_BUFFER::GetRootSymbolNames(), LIB_PIN::GetSelectMenuText(), SCH_SYMBOL::GetSelectMenuText(), 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_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(), APPEARANCE_CONTROLS::rebuildNets(), 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(), 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(), ROUTER_TOOL::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(), 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 844 of file string_utils.cpp.

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

737{
738 const wxChar* cp = nullptr, * mp = nullptr;
739 const wxChar* wild, * str;
740 wxString _pattern, _string_to_tst;
741
742 if( case_sensitive )
743 {
744 wild = pattern.GetData();
745 str = string_to_tst.GetData();
746 }
747 else
748 {
749 _pattern = pattern;
750 _pattern.MakeUpper();
751 _string_to_tst = string_to_tst;
752 _string_to_tst.MakeUpper();
753 wild = _pattern.GetData();
754 str = _string_to_tst.GetData();
755 }
756
757 while( ( *str ) && ( *wild != '*' ) )
758 {
759 if( ( *wild != *str ) && ( *wild != '?' ) )
760 return false;
761
762 wild++;
763 str++;
764 }
765
766 while( *str )
767 {
768 if( *wild == '*' )
769 {
770 if( !*++wild )
771 return 1;
772 mp = wild;
773 cp = str + 1;
774 }
775 else if( ( *wild == *str ) || ( *wild == '?' ) )
776 {
777 wild++;
778 str++;
779 }
780 else
781 {
782 wild = mp;
783 str = cp++;
784 }
785 }
786
787 while( *wild == '*' )
788 {
789 wild++;
790 }
791
792 return !*wild;
793}

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 1048 of file string_utils.cpp.

1049{
1050 wxString tmp;
1051
1052 for( unsigned ii = 0; ii < aText.Length(); ii++ )
1053 {
1054 if( aText[ii] == aSplitter )
1055 {
1056 aStrings.Add( tmp );
1057 tmp.Clear();
1058 }
1059 else
1060 {
1061 tmp << aText[ii];
1062 }
1063 }
1064
1065 if( !tmp.IsEmpty() )
1066 aStrings.Add( tmp );
1067}

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