KiCad PCB EDA Suite
string_utils.cpp File Reference
#include <clocale>
#include <cmath>
#include <macros.h>
#include <richio.h>
#include <string_utils.h>

Go to the source code of this file.

Functions

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 TitleCaps (const wxString &aString)
 Capitalize the first letter in each word. More...
 
int ReadDelimitedText (wxString *aDest, const char *aSource)
 Copy bytes from aSource delimited string segment to aDest wxString. More...
 
int ReadDelimitedText (char *aDest, const char *aSource, int aDestSize)
 Copy bytes from aSource delimited string segment to aDest buffer. 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...
 
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...
 
char * GetLine (FILE *File, char *Line, int *LineNum, int SizeLine)
 Read one line line from aFile. More...
 
wxString DateAndTime ()
 
int StrNumCmp (const wxString &aString1, const wxString &aString2, bool aIgnoreCase)
 Compare two strings with alphanumerical content. More...
 
bool WildCompareString (const wxString &pattern, const wxString &string_to_tst, bool case_sensitive)
 Compare a string against wild card (* and ?) pattern using the usual rules. More...
 
bool ApplyModifier (double &value, const wxString &aString)
 
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)
 Checks aName for illegal file name characters. More...
 
bool ReplaceIllegalFileNameChars (wxString &aName, int aReplaceChar)
 
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)
 Remove trailing zeros from a string containing a converted float number. More...
 
std::string Double2Str (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...
 
wxString AngleToStringDegrees (double aAngle)
 A helper to convert the double aAngle (in internal unit) to a string in degrees. More...
 

Variables

static const char illegalFileNameChars [] = "\\/:\"<>|"
 Illegal file name characters used to ensure file names will be valid on all supported platforms. More...
 

Function Documentation

◆ AngleToStringDegrees()

wxString AngleToStringDegrees ( double  aAngle)

A helper to convert the double aAngle (in internal unit) to a string in degrees.

Definition at line 1108 of file string_utils.cpp.

1109 {
1110  wxString text;
1111 
1112  text.Printf( wxT( "%.3f" ), aAngle / 10.0 );
1113  StripTrailingZeros( text, 1 );
1114 
1115  return text;
1116 }
void StripTrailingZeros(wxString &aStringValue, unsigned aTrailingZeroAllowed)
Remove trailing zeros from a string containing a converted float number.

References StripTrailingZeros(), and text.

Referenced by PANEL_EDIT_OPTIONS::TransferDataToWindow().

◆ ApplyModifier()

bool ApplyModifier ( double &  value,
const wxString &  aString 
)

Definition at line 781 of file string_utils.cpp.

782 {
783  static const wxString modifiers( wxT( "pnumkKM" ) );
784 
785  if( !aString.length() )
786  return false;
787 
788  wxChar modifier;
789  wxString units;
790 
791  if( modifiers.Find( aString[ 0 ] ) >= 0 )
792  {
793  modifier = aString[ 0 ];
794  units = aString.Mid( 1 ).Trim();
795  }
796  else
797  {
798  modifier = ' ';
799  units = aString.Mid( 0 ).Trim();
800  }
801 
802  if( units.length()
803  && !units.CmpNoCase( wxT( "F" ) )
804  && !units.CmpNoCase( wxT( "hz" ) )
805  && !units.CmpNoCase( wxT( "W" ) )
806  && !units.CmpNoCase( wxT( "V" ) )
807  && !units.CmpNoCase( wxT( "H" ) ) )
808  return false;
809 
810  if( modifier == 'p' )
811  value *= 1.0e-12;
812  if( modifier == 'n' )
813  value *= 1.0e-9;
814  else if( modifier == 'u' )
815  value *= 1.0e-6;
816  else if( modifier == 'm' )
817  value *= 1.0e-3;
818  else if( modifier == 'k' || modifier == 'K' )
819  value *= 1.0e3;
820  else if( modifier == 'M' )
821  value *= 1.0e6;
822  else if( modifier == 'G' )
823  value *= 1.0e9;
824 
825  return true;
826 }

Referenced by ValueStringCompare().

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

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

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

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

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(), SCH_SEXPR_PARSER::parseEDA_TEXT(), PCB_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 632 of file string_utils.cpp.

633 {
634  wxDateTime datetime = wxDateTime::Now();
635 
636  datetime.SetCountry( wxDateTime::Country_Default );
637  return datetime.Format( wxDefaultDateTimeFormat, wxDateTime::Local );
638 }

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_ORCADPCB2::WriteNetlist(), NETLIST_EXPORTER_CADSTAR::WriteNetlist(), and DIALOG_ERC::writeReport().

◆ Double2Str()

std::string Double2Str ( 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 1078 of file string_utils.cpp.

1079 {
1080  char buf[50];
1081  int len;
1082 
1083  if( aValue != 0.0 && std::fabs( aValue ) <= 0.0001 )
1084  {
1085  // For these small values, %f works fine,
1086  // and %g gives an exponent
1087  len = sprintf( buf, "%.16f", aValue );
1088 
1089  while( --len > 0 && buf[len] == '0' )
1090  buf[len] = '\0';
1091 
1092  if( buf[len] == '.' )
1093  buf[len] = '\0';
1094  else
1095  ++len;
1096  }
1097  else
1098  {
1099  // For these values, %g works fine, and sometimes %f
1100  // gives a bad value (try aValue = 1.222222222222, with %.16f format!)
1101  len = sprintf( buf, "%.10g", aValue );
1102  }
1103 
1104  return std::string( buf, len );
1105 }

Referenced by PANEL_SETUP_BOARD_STACKUP::createRowData(), GBR_TO_PCB_EXPORTER::export_non_copper_item(), GBR_TO_PCB_EXPORTER::export_via(), PCB_PLUGIN::format(), BOARD_STACKUP::FormatBoardStackup(), DIELECTRIC_SUBSTRATE::FormatEpsilonR(), BOARD_STACKUP_ITEM::FormatEpsilonR(), DIELECTRIC_SUBSTRATE::FormatLossTangent(), BOARD_STACKUP_ITEM::FormatLossTangent(), PCB_PLUGIN::formatSetup(), formatStroke(), NUMERIC_EVALUATOR::parseSetResult(), SCH_SEXPR_PLUGIN::saveJunction(), PANEL_SETUP_BOARD_STACKUP::synchronizeWithBoard(), GBR_TO_PCB_EXPORTER::writeCopperLineItem(), GBR_TO_PCB_EXPORTER::writePcbFilledCircle(), GBR_TO_PCB_EXPORTER::writePcbPolygon(), and GBR_TO_PCB_EXPORTER::writePcbZoneItem().

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

439 {
440  wxString str = aString;
441 
442  // No new-lines allowed in quoted strings
443  str.Replace( wxT( "\r\n" ), wxT( "\r" ) );
444  str.Replace( wxT( "\n" ), wxT( "\r" ) );
445 
446  std::string utf8 = TO_UTF8( aString );
447 
448  std::string ret;
449 
450  ret.reserve( utf8.length() + 2 );
451 
452  ret += '"';
453 
454  for( std::string::const_iterator it = utf8.begin(); it!=utf8.end(); ++it )
455  {
456  // this escaping strategy is designed to be compatible with ReadDelimitedText():
457  if( *it == '"' )
458  {
459  ret += '\\';
460  ret += '"';
461  }
462  else if( *it == '\\' )
463  {
464  ret += '\\'; // double it up
465  ret += '\\';
466  }
467  else
468  {
469  ret += *it;
470  }
471  }
472 
473  ret += '"';
474 
475  return ret;
476 }
#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::saveField(), SCH_LEGACY_PLUGIN_CACHE::saveField(), SCH_SEXPR_PLUGIN::saveSheet(), and SCH_LEGACY_PLUGIN::saveSheet().

◆ EscapeHTML()

wxString EscapeHTML ( const wxString &  aString)

Return a new wxString escaped for embedding in HTML.

Definition at line 479 of file string_utils.cpp.

480 {
481  wxString converted;
482 
483  converted.reserve( aString.length() );
484 
485  for( wxUniChar c : aString )
486  {
487  if( c == '\"' )
488  converted += wxT( "&quot;" );
489  else if( c == '\'' )
490  converted += wxT( "&apos;" );
491  else if( c == '&' )
492  converted += wxT( "&amp;" );
493  else if( c == '<' )
494  converted += wxT( "&lt;" );
495  else if( c == '>' )
496  converted += wxT( "&gt;" );
497  else
498  converted += c;
499  }
500 
501  return converted;
502 }

Referenced by DRC_ENGINE::EvalRules(), FOOTPRINT_INFO_GENERATOR::GenerateHtml(), FOOTPRINT_INFO_GENERATOR::GetHtmlFieldRow(), BOARD_INSPECTION_TOOL::InspectClearance(), BOARD_INSPECTION_TOOL::InspectConstraints(), BOARD_INSPECTION_TOOL::InspectDRCError(), 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 143 of file string_utils.cpp.

144 {
145  wxString converted;
146  std::vector<bool> braceStack; // true == formatting construct
147 
148  auto hasFormattingPrefix =
149  [&]()
150  {
151  static wxString prefixes = wxT( "~_^" );
152  return !converted.IsEmpty() && prefixes.Find( converted.Last() ) >= 0;
153  };
154 
155  converted.reserve( aSource.length() );
156 
157  for( wxUniChar c: aSource )
158  {
159  if( aContext == CTX_NETNAME )
160  {
161  if( c == '/' )
162  converted += wxT( "{slash}" );
163  else if( c == '\n' || c == '\r' )
164  converted += wxEmptyString; // drop
165  else
166  converted += c;
167  }
168  else if( aContext == CTX_LIBID )
169  {
170  if( c == '{' && !hasFormattingPrefix() )
171  converted += wxT( "{brace}" );
172  else if( c == '/' )
173  converted += wxT( "{slash}" );
174  else if( c == '\\' )
175  converted += wxT( "{backslash}" );
176  else if( c == '<' )
177  converted += wxT( "{lt}" );
178  else if( c == '>' )
179  converted += wxT( "{gt}" );
180  else if( c == ':' )
181  converted += wxT( "{colon}" );
182  else if( c == '\"' )
183  converted += wxT( "{dblquote}" );
184  else if( c == '\n' || c == '\r' )
185  converted += wxEmptyString; // drop
186  else
187  converted += c;
188  }
189  else if( aContext == CTX_QUOTED_STR )
190  {
191  if( c == '\"' )
192  converted += wxT( "{dblquote}" );
193  else
194  converted += c;
195  }
196  else if( aContext == CTX_LINE )
197  {
198  if( c == '\n' || c == '\r' )
199  converted += wxT( "{return}" );
200  else
201  converted += c;
202  }
203  else if( aContext == CTX_FILENAME )
204  {
205  if( c == '{' )
206  converted += wxT( "{brace}" );
207  else if( c == '/' )
208  converted += wxT( "{slash}" );
209  else if( c == '\\' )
210  converted += wxT( "{backslash}" );
211  else if( c == '\"' )
212  converted += wxT( "{dblquote}" );
213  else if( c == '<' )
214  converted += wxT( "{lt}" );
215  else if( c == '>' )
216  converted += wxT( "{gt}" );
217  else if( c == '|' )
218  converted += wxT( "{bar}" );
219  else if( c == ':' )
220  converted += wxT( "{colon}" );
221  else if( c == '\t' )
222  converted += wxT( "{tab}" );
223  else if( c == '\n' || c == '\r' )
224  converted += wxT( "{return}" );
225  else
226  converted += c;
227  }
228  else if( aContext == CTX_NO_SPACE )
229  {
230  if( c == ' ' )
231  converted += wxT( "{space}" );
232  else if( c == '{' )
233  converted += wxT( "{brace}" );
234  else
235  converted += c;
236  }
237  else
238  {
239  converted += c;
240  }
241  }
242 
243  return converted;
244 }

References CTX_FILENAME, CTX_LIBID, CTX_LINE, CTX_NETNAME, CTX_NO_SPACE, and CTX_QUOTED_STR.

Referenced by AltiumToKiCadLibID(), SCH_EDIT_TOOL::ChangeTextType(), SYMBOL_VIEWER_FRAME::ClickOnCmpList(), SYMBOL_VIEWER_FRAME::ClickOnLibList(), PANEL_SYM_LIB_TABLE::convertLibrary(), CONNECTION_SUBGRAPH::driverName(), SYMBOL_EDITOR_EDIT_TOOL::editFieldProperties(), CONNECTION_GRAPH::ercCheckBusToNetConflicts(), CONNECTION_GRAPH::ercCheckLabels(), TEXT_BUTTON_SYMBOL_CHOOSER::escapeLibId(), RESCUE_CASE_CANDIDATE::FindRescues(), RESCUE_CACHE_CANDIDATE::FindRescues(), RESCUE_SYMBOL_LIB_TABLE_CANDIDATE::FindRescues(), SYMBOL_VIEWER_FRAME::FinishModal(), 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(), DIALOG_NET_INSPECTOR::onRenameNet(), NET_SETTINGS::ParseBusGroup(), SCH_SEXPR_PLUGIN_CACHE::saveDcmInfoAsFields(), SIM_PLOT_FRAME::saveWorkbook(), LIB_TABLE_GRID::SetValue(), FIELDS_GRID_TABLE< SCH_FIELD >::SetValue(), DIALOG_SHEET_PIN_PROPERTIES::TransferDataFromWindow(), DIALOG_LIB_SYMBOL_PROPERTIES::TransferDataFromWindow(), DIALOG_TEXT_PROPERTIES::TransferDataFromWindow(), DIALOG_TEXT_AND_LABEL_PROPERTIES::TransferDataFromWindow(), DIALOG_LIB_FIELD_PROPERTIES::UpdateField(), and FOOTPRINT_LIST_IMPL::WriteCacheToFile().

◆ GetIllegalFileNameWxChars()

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

Definition at line 966 of file string_utils.cpp.

967 {
969 }
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 616 of file string_utils.cpp.

617 {
618  do {
619  if( fgets( Line, SizeLine, File ) == nullptr )
620  return nullptr;
621 
622  if( LineNum )
623  *LineNum += 1;
624 
625  } while( Line[0] == '#' || Line[0] == '\n' || Line[0] == '\r' || Line[0] == 0 );
626 
627  strtok( Line, "\n\r" );
628  return Line;
629 }

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

943 {
944  int number = 0;
945  int base = 1;
946 
947  // Trim and extract the trailing numeric part
948  int index = aStr.Len() - 1;
949 
950  while( index >= 0 )
951  {
952  const char chr = aStr.GetChar( index );
953 
954  if( chr < '0' || chr > '9' )
955  break;
956 
957  number += ( chr - '0' ) * base;
958  base *= 10;
959  index--;
960  }
961 
962  return number;
963 }

Referenced by BOOST_AUTO_TEST_CASE(), 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 505 of file string_utils.cpp.

506 {
507  wxString tmp = aString;
508 
509  return tmp.Trim( true ).Trim( false ).IsEmpty();
510 }

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

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

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

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

◆ ReadDelimitedText() [1/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 344 of file string_utils.cpp.

345 {
346  std::string utf8; // utf8 but without escapes and quotes.
347  bool inside = false;
348  const char* start = aSource;
349  char cc;
350 
351  while( (cc = *aSource++) != 0 )
352  {
353  if( cc == '"' )
354  {
355  if( inside )
356  break; // 2nd double quote is end of delimited text
357 
358  inside = true; // first delimiter found, make note, do not copy
359  }
360 
361  else if( inside )
362  {
363  if( cc == '\\' )
364  {
365  cc = *aSource++;
366 
367  if( !cc )
368  break;
369 
370  // do no copy the escape byte if it is followed by \ or "
371  if( cc != '"' && cc != '\\' )
372  utf8 += '\\';
373 
374  utf8 += cc;
375  }
376  else
377  {
378  utf8 += cc;
379  }
380  }
381  }
382 
383  *aDest = FROM_UTF8( utf8.c_str() );
384 
385  return aSource - start;
386 }
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

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

◆ ReadDelimitedText() [2/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 389 of file string_utils.cpp.

390 {
391  if( aDestSize <= 0 )
392  return 0;
393 
394  bool inside = false;
395  const char* start = aSource;
396  char* limit = aDest + aDestSize - 1;
397  char cc;
398 
399  while( (cc = *aSource++) != 0 && aDest < limit )
400  {
401  if( cc == '"' )
402  {
403  if( inside )
404  break; // 2nd double quote is end of delimited text
405 
406  inside = true; // first delimiter found, make note, do not copy
407  }
408 
409  else if( inside )
410  {
411  if( cc == '\\' )
412  {
413  cc = *aSource++;
414 
415  if( !cc )
416  break;
417 
418  // do no copy the escape byte if it is followed by \ or "
419  if( cc != '"' && cc != '\\' )
420  *aDest++ = '\\';
421 
422  if( aDest < limit )
423  *aDest++ = cc;
424  }
425  else
426  {
427  *aDest++ = cc;
428  }
429  }
430  }
431 
432  *aDest = 0;
433 
434  return aSource - start;
435 }

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

973 {
974  bool changed = false;
975  std::string result;
976  result.reserve( aName->length() );
977 
978  for( std::string::iterator it = aName->begin(); it != aName->end(); ++it )
979  {
980  if( strchr( illegalFileNameChars, *it ) )
981  {
982  if( aReplaceChar )
983  StrPrintf( &result, "%c", aReplaceChar );
984  else
985  StrPrintf( &result, "%%%02x", *it );
986 
987  changed = true;
988  }
989  else
990  {
991  result += *it;
992  }
993  }
994 
995  if( changed )
996  *aName = result;
997 
998  return changed;
999 }
static const char illegalFileNameChars[]
Illegal file name characters used to ensure file names will be valid on all supported platforms.
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:79

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 
)

Definition at line 1002 of file string_utils.cpp.

1003 {
1004  bool changed = false;
1005  wxString result;
1006  result.reserve( aName.Length() );
1007  wxString illWChars = GetIllegalFileNameWxChars();
1008 
1009  for( wxString::iterator it = aName.begin(); it != aName.end(); ++it )
1010  {
1011  if( illWChars.Find( *it ) != wxNOT_FOUND )
1012  {
1013  if( aReplaceChar )
1014  result += aReplaceChar;
1015  else
1016  result += wxString::Format( "%%%02x", *it );
1017 
1018  changed = true;
1019  }
1020  else
1021  {
1022  result += *it;
1023  }
1024  }
1025 
1026  if( changed )
1027  aName = result;
1028 
1029  return changed;
1030 }
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().

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

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

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

1057 {
1058  struct lconv* lc = localeconv();
1059  char sep = lc->decimal_point[0];
1060  unsigned sep_pos = aStringValue.Find( sep );
1061 
1062  if( sep_pos > 0 )
1063  {
1064  // We want to keep at least aTrailingZeroAllowed digits after the separator
1065  unsigned min_len = sep_pos + aTrailingZeroAllowed + 1;
1066 
1067  while( aStringValue.Len() > min_len )
1068  {
1069  if( aStringValue.Last() == '0' )
1070  aStringValue.RemoveLast();
1071  else
1072  break;
1073  }
1074  }
1075 }

Referenced by AngleToStringDegrees().

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

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

Referenced by REGULATOR_LIST::Add(), LIB_TREE_NODE::AssignIntrinsicRanks(), BOOST_AUTO_TEST_CASE(), ChangeArrayCompare(), FIELDS_EDITOR_GRID_DATA_MODEL::cmp(), SCH_PIN_TABLE_DATA_MODEL::compare(), PIN_TABLE_DATA_MODEL::compare(), SCH_SHEET::ComparePageNum(), SCH_FIELD::DoHypertextMenu(), PLACE_FILE_EXPORTER::GenReportData(), FP_TREE_MODEL_ADAPTER::getFootprints(), LIB_TABLE::GetLogicalLibs(), FIELDS_EDITOR_GRID_DATA_MODEL::GetValue(), NETLIST_EXPORTER_XML::makeListOfNets(), NETLIST_EXPORTER_XML::makeSymbols(), myCompareFunction(), FOOTPRINT::cmp_pads::operator()(), operator<(), BOARD_REANNOTATE_TOOL::ReannotateDuplicates(), NET_SELECTOR_COMBOPOPUP::rebuildList(), SCH_GLOBALLABEL::ResolveTextVar(), SCH_REFERENCE_LIST::sortByReferenceOnly(), sortFPlist(), sortPinsByNum(), sortPinsByNumber(), and FP_TREE_SYNCHRONIZING_ADAPTER::updateLibrary().

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

598 {
599  static const char whitespace[] = " \t\n\r\f\v";
600 
601  if( text )
602  {
603  while( *text && strchr( whitespace, *text ) )
604  ++text;
605 
606  char* cp = text + strlen( text ) - 1;
607 
608  while( cp >= text && strchr( whitespace, *cp ) )
609  *cp-- = '\0';
610  }
611 
612  return text;
613 }

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(), and LEGACY_PLUGIN::loadPAD().

◆ TitleCaps()

wxString TitleCaps ( const wxString &  aString)

Capitalize the first letter in each word.

Definition at line 323 of file string_utils.cpp.

324 {
325  wxArrayString words;
326  wxString result;
327 
328  wxStringSplit( aString, words, ' ' );
329 
330  result.reserve( aString.length() );
331 
332  for( const wxString& word : words )
333  {
334  if( !result.IsEmpty() )
335  result += wxT( " " );
336 
337  result += word.Capitalize();
338  }
339 
340  return result;
341 }
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().

◆ UnescapeString()

wxString UnescapeString ( const wxString &  aSource)

Definition at line 247 of file string_utils.cpp.

248 {
249  size_t sourceLen = aSource.length();
250 
251  // smallest escape string is three characters, shortcut everything else
252  if( sourceLen <= 2 )
253  {
254  return aSource;
255  }
256 
257  wxString newbuf;
258  newbuf.reserve( sourceLen );
259 
260  for( size_t i = 0; i < sourceLen; ++i )
261  {
262  wxUniChar ch = aSource[i];
263  if( ( ch == '$' || ch == '^' || ch == '_' )
264  && i + 1 < sourceLen && aSource[i+1] == '{' )
265  {
266  for( ; i < sourceLen; ++i )
267  {
268  ch = aSource[i];
269  newbuf += ch;
270 
271  if( ch == '}' )
272  break;
273  }
274  }
275  else if( ch == '{' )
276  {
277  wxString token;
278  int depth = 1;
279 
280  for( i = i + 1; i < sourceLen; ++i )
281  {
282  ch = aSource[i];
283  if( ch == '{' )
284  depth++;
285  else if( ch == '}' )
286  depth--;
287 
288  if( depth <= 0 )
289  break;
290  else
291  token.append( ch );
292  }
293 
294  if( token == wxS( "dblquote" ) ) newbuf.append( wxS( "\"" ) );
295  else if( token == wxS( "quote" ) ) newbuf.append( wxS( "'" ) );
296  else if( token == wxS( "lt" ) ) newbuf.append( wxS( "<" ) );
297  else if( token == wxS( "gt" ) ) newbuf.append( wxS( ">" ) );
298  else if( token == wxS( "backslash" ) ) newbuf.append( wxS( "\\" ) );
299  else if( token == wxS( "slash" ) ) newbuf.append( wxS( "/" ) );
300  else if( token == wxS( "bar" ) ) newbuf.append( wxS( "|" ) );
301  else if( token == wxS( "colon" ) ) newbuf.append( wxS( ":" ) );
302  else if( token == wxS( "space" ) ) newbuf.append( wxS( " " ) );
303  else if( token == wxS( "dollar" ) ) newbuf.append( wxS( "$" ) );
304  else if( token == wxS( "tab" ) ) newbuf.append( wxS( "\t" ) );
305  else if( token == wxS( "return" ) ) newbuf.append( wxS( "\n" ) );
306  else if( token == wxS( "brace" ) ) newbuf.append( wxS( "{" ) );
307  else if( token.IsEmpty() ) newbuf.append( wxS( "{" ) );
308  else
309  {
310  newbuf.append( wxT( "{" ) + UnescapeString( token ) + wxT( "}" ) );
311  }
312  }
313  else
314  {
315  newbuf.append( ch );
316  }
317  }
318 
319  return newbuf;
320 }
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(), NETLIST_EXPORTER_PSPICE_SIM::ComponentToVector(), 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(), GRID_CELL_ESCAPED_TEXT_RENDERER::Draw(), KIGFX::SCH_PAINTER::draw(), KIGFX::PCB_PAINTER::draw(), CONNECTION_GRAPH::ercCheckBusToBusEntryConflicts(), CONNECTION_GRAPH::ercCheckHierSheets(), SCH_EDIT_FRAME::ExecuteRemoteCommand(), SYMBOL_EDIT_FRAME::ExportSymbol(), NETLIST_EXPORTER_PSPICE::Format(), DIALOG_NET_INSPECTOR::formatNetName(), GRID_CELL_ESCAPED_TEXT_RENDERER::GetBestSize(), PCB_TEXT::GetMsgPanelInfo(), LIB_TEXT::GetMsgPanelInfo(), ZONE::GetMsgPanelInfo(), LIB_FIELD::GetMsgPanelInfo(), NETINFO_ITEM::GetMsgPanelInfo(), LIB_PIN::GetMsgPanelInfo(), FP_TEXT::GetMsgPanelInfo(), SCH_FIELD::GetMsgPanelInfo(), GERBER_DRAW_ITEM::GetMsgPanelInfo(), SCH_TEXT::GetMsgPanelInfo(), SCH_SYMBOL::GetMsgPanelInfo(), PAD::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(), SYMBOL_TREE_SYNCHRONIZING_ADAPTER::GetValue(), LIB_TABLE_GRID::GetValue(), FIELDS_GRID_TABLE< SCH_FIELD >::GetValue(), LIB_TREE_MODEL_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(), NET_SETTINGS::NET_SETTINGS(), DIALOG_NET_INSPECTOR::netFilterMatches(), TEXT_BUTTON_SYMBOL_CHOOSER::OnButtonClick(), DIALOG_EDIT_SYMBOLS_LIBID::onClickOrphansButton(), 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(), 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_LIB_SYMBOL_PROPERTIES::TransferDataFromWindow(), DIALOG_EDIT_SYMBOLS_LIBID::TransferDataFromWindow(), DIALOG_SIGNAL_LIST::TransferDataToWindow(), DIALOG_SHEET_PIN_PROPERTIES::TransferDataToWindow(), DIALOG_LIB_SYMBOL_PROPERTIES::TransferDataToWindow(), DIALOG_TEXT_PROPERTIES::TransferDataToWindow(), DIALOG_TEXT_AND_LABEL_PROPERTIES::TransferDataToWindow(), DIALOG_SYMBOL_PROPERTIES::TransferDataToWindow(), UnescapeString(), HIGHLIGHT_MENU::update(), SYMBOL_EDIT_FRAME::UpdateAfterSymbolProperties(), BOARD_NETLIST_UPDATER::updateComponentPadConnections(), BOARD_NETLIST_UPDATER::updateCopperZoneNets(), SCH_SYMBOL::UpdateFields(), SCH_EDIT_FRAME::UpdateNetHighlightStatus(), GERBVIEW_FRAME::updateNetnameListSelectBox(), 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 829 of file string_utils.cpp.

830 {
831  // Compare unescaped text
832  wxString fWord = UnescapeString( strFWord );
833  wxString sWord = UnescapeString( strSWord );
834 
835  // The different sections of the two strings
836  wxString strFWordBeg, strFWordMid, strFWordEnd;
837  wxString strSWordBeg, strSWordMid, strSWordEnd;
838 
839  // Split the two strings into separate parts
840  SplitString( fWord, &strFWordBeg, &strFWordMid, &strFWordEnd );
841  SplitString( sWord, &strSWordBeg, &strSWordMid, &strSWordEnd );
842 
843  // Compare the Beginning section of the strings
844  int isEqual = strFWordBeg.CmpNoCase( strSWordBeg );
845 
846  if( isEqual > 0 )
847  {
848  return 1;
849  }
850  else if( isEqual < 0 )
851  {
852  return -1;
853  }
854  else
855  {
856  // If the first sections are equal compare their digits
857  double lFirstNumber = 0;
858  double lSecondNumber = 0;
859  bool endingIsModifier = false;
860 
861  strFWordMid.ToDouble( &lFirstNumber );
862  strSWordMid.ToDouble( &lSecondNumber );
863 
864  endingIsModifier |= ApplyModifier( lFirstNumber, strFWordEnd );
865  endingIsModifier |= ApplyModifier( lSecondNumber, strSWordEnd );
866 
867  if( lFirstNumber > lSecondNumber )
868  return 1;
869  else if( lFirstNumber < lSecondNumber )
870  return -1;
871  // If the first two sections are equal and the endings are modifiers then compare them
872  else if( !endingIsModifier )
873  return strFWordEnd.CmpNoCase( strSWordEnd );
874  // Ran out of things to compare; they must match
875  else
876  return 0;
877  }
878 }
bool ApplyModifier(double &value, const wxString &aString)
wxString UnescapeString(const wxString &aSource)
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 720 of file string_utils.cpp.

722 {
723  const wxChar* cp = nullptr, * mp = nullptr;
724  const wxChar* wild, * str;
725  wxString _pattern, _string_to_tst;
726 
727  if( case_sensitive )
728  {
729  wild = pattern.GetData();
730  str = string_to_tst.GetData();
731  }
732  else
733  {
734  _pattern = pattern;
735  _pattern.MakeUpper();
736  _string_to_tst = string_to_tst;
737  _string_to_tst.MakeUpper();
738  wild = _pattern.GetData();
739  str = _string_to_tst.GetData();
740  }
741 
742  while( ( *str ) && ( *wild != '*' ) )
743  {
744  if( ( *wild != *str ) && ( *wild != '?' ) )
745  return false;
746 
747  wild++;
748  str++;
749  }
750 
751  while( *str )
752  {
753  if( *wild == '*' )
754  {
755  if( !*++wild )
756  return 1;
757  mp = wild;
758  cp = str + 1;
759  }
760  else if( ( *wild == *str ) || ( *wild == '?' ) )
761  {
762  wild++;
763  str++;
764  }
765  else
766  {
767  wild = mp;
768  str = cp++;
769  }
770  }
771 
772  while( *wild == '*' )
773  {
774  wild++;
775  }
776 
777  return !*wild;
778 }

Referenced by FROM_TO_CACHE::cacheFromToPaths(), LIBEVAL::VALUE::EqualTo(), DIALOG_EXCHANGE_FOOTPRINTS::isMatch(), DIALOG_CHANGE_SYMBOLS::isMatch(), 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 1033 of file string_utils.cpp.

1034 {
1035  wxString tmp;
1036 
1037  for( unsigned ii = 0; ii < aText.Length(); ii++ )
1038  {
1039  if( aText[ii] == aSplitter )
1040  {
1041  aStrings.Add( tmp );
1042  tmp.Clear();
1043  }
1044 
1045  else
1046  tmp << aText[ii];
1047  }
1048 
1049  if( !tmp.IsEmpty() )
1050  {
1051  aStrings.Add( tmp );
1052  }
1053 }

Referenced by EDA_TEXT::GetTextBox(), HTML_MESSAGE_BOX::ListSet(), CADSTAR_SCH_ARCHIVE_LOADER::loadSymDefIntoLibrary(), PANEL_SETUP_RULES::OnErrorLinkClicked(), pcbnewGetWizardsBackTrace(), SCH_TEXT::Plot(), BRDITEMS_PLOTTER::PlotPcbText(), EDA_TEXT::Print(), TitleCaps(), and EDA_TEXT::TransformToSegmentList().

Variable Documentation

◆ illegalFileNameChars

const char illegalFileNameChars[] = "\\/:\"<>|"
static

Illegal file name characters used to ensure file names will be valid on all supported platforms.

This is the list of illegal file name characters for Windows which includes the illegal file name characters for Linux and OSX.

Definition at line 41 of file string_utils.cpp.

Referenced by GetIllegalFileNameWxChars(), and ReplaceIllegalFileNameChars().