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

1079 {
1080  wxString text;
1081 
1082  text.Printf( wxT( "%.3f" ), aAngle / 10.0 );
1083  StripTrailingZeros( text, 1 );
1084 
1085  return text;
1086 }
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 751 of file string_utils.cpp.

752 {
753  static const wxString modifiers( wxT( "pnumkKM" ) );
754 
755  if( !aString.length() )
756  return false;
757 
758  wxChar modifier;
759  wxString units;
760 
761  if( modifiers.Find( aString[ 0 ] ) >= 0 )
762  {
763  modifier = aString[ 0 ];
764  units = aString.Mid( 1 ).Trim();
765  }
766  else
767  {
768  modifier = ' ';
769  units = aString.Mid( 0 ).Trim();
770  }
771 
772  if( units.length()
773  && !units.CmpNoCase( wxT( "F" ) )
774  && !units.CmpNoCase( wxT( "hz" ) )
775  && !units.CmpNoCase( wxT( "W" ) )
776  && !units.CmpNoCase( wxT( "V" ) )
777  && !units.CmpNoCase( wxT( "H" ) ) )
778  return false;
779 
780  if( modifier == 'p' )
781  value *= 1.0e-12;
782  if( modifier == 'n' )
783  value *= 1.0e-9;
784  else if( modifier == 'u' )
785  value *= 1.0e-6;
786  else if( modifier == 'm' )
787  value *= 1.0e-3;
788  else if( modifier == 'k' || modifier == 'K' )
789  value *= 1.0e3;
790  else if( modifier == 'M' )
791  value *= 1.0e6;
792  else if( modifier == 'G' )
793  value *= 1.0e9;
794 
795  return true;
796 }

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

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

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

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

603 {
604  wxDateTime datetime = wxDateTime::Now();
605 
606  datetime.SetCountry( wxDateTime::Country_Default );
607  return datetime.Format( wxDefaultDateTimeFormat, wxDateTime::Local );
608 }

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

1049 {
1050  char buf[50];
1051  int len;
1052 
1053  if( aValue != 0.0 && std::fabs( aValue ) <= 0.0001 )
1054  {
1055  // For these small values, %f works fine,
1056  // and %g gives an exponent
1057  len = sprintf( buf, "%.16f", aValue );
1058 
1059  while( --len > 0 && buf[len] == '0' )
1060  buf[len] = '\0';
1061 
1062  if( buf[len] == '.' )
1063  buf[len] = '\0';
1064  else
1065  ++len;
1066  }
1067  else
1068  {
1069  // For these values, %g works fine, and sometimes %f
1070  // gives a bad value (try aValue = 1.222222222222, with %.16f format!)
1071  len = sprintf( buf, "%.10g", aValue );
1072  }
1073 
1074  return std::string( buf, len );
1075 }

Referenced by PANEL_SETUP_BOARD_STACKUP::createRowData(), GBR_TO_PCB_EXPORTER::export_non_copper_item(), GBR_TO_PCB_EXPORTER::export_via(), PCB_IO::format(), BOARD_STACKUP::FormatBoardStackup(), DIELECTRIC_SUBSTRATE::FormatEpsilonR(), BOARD_STACKUP_ITEM::FormatEpsilonR(), DIELECTRIC_SUBSTRATE::FormatLossTangent(), BOARD_STACKUP_ITEM::FormatLossTangent(), PCB_IO::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 412 of file string_utils.cpp.

413 {
414  wxString str = aString;
415 
416  // No new-lines allowed in quoted strings
417  str.Replace( "\r\n", "\r" );
418  str.Replace( "\n", "\r" );
419 
420  std::string utf8 = TO_UTF8( aString );
421 
422  std::string ret;
423 
424  ret += '"';
425 
426  for( std::string::const_iterator it = utf8.begin(); it!=utf8.end(); ++it )
427  {
428  // this escaping strategy is designed to be compatible with ReadDelimitedText():
429  if( *it == '"' )
430  {
431  ret += '\\';
432  ret += '"';
433  }
434  else if( *it == '\\' )
435  {
436  ret += '\\'; // double it up
437  ret += '\\';
438  }
439  else
440  {
441  ret += *it;
442  }
443  }
444 
445  ret += '"';
446 
447  return ret;
448 }
#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 451 of file string_utils.cpp.

452 {
453  wxString converted;
454 
455  for( wxUniChar c : aString )
456  {
457  if( c == '\"' )
458  converted += "&quot;";
459  else if( c == '\'' )
460  converted += "&apos;";
461  else if( c == '&' )
462  converted += "&amp;";
463  else if( c == '<' )
464  converted += "&lt;";
465  else if( c == '>' )
466  converted += "&gt;";
467  else
468  converted += c;
469  }
470 
471  return converted;
472 }

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(), and FOOTPRINT_INFO_GENERATOR::SetHtmlName().

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

142 {
143  wxString converted;
144 
145  for( wxUniChar c: aSource )
146  {
147  if( aContext == CTX_NETNAME )
148  {
149  if( c == '/' )
150  converted += "{slash}";
151  else if( c == '\n' || c == '\r' )
152  converted += ""; // drop
153  else
154  converted += c;
155  }
156  else if( aContext == CTX_LIBID )
157  {
158  if( c == '{' )
159  converted += "{brace}";
160  else if( c == '/' )
161  converted += "{slash}";
162  else if( c == '\\' )
163  converted += "{backslash}";
164  else if( c == '<' )
165  converted += "{lt}";
166  else if( c == '>' )
167  converted += "{gt}";
168  else if( c == ':' )
169  converted += "{colon}";
170  else if( c == '\n' || c == '\r' )
171  converted += ""; // drop
172  else
173  converted += c;
174  }
175  else if( aContext == CTX_QUOTED_STR )
176  {
177  if( c == '\"' )
178  converted += "{dblquote}";
179  else
180  converted += c;
181  }
182  else if( aContext == CTX_LINE )
183  {
184  if( c == '\n' || c == '\r' )
185  converted += "{return}";
186  else
187  converted += c;
188  }
189  else if( aContext == CTX_FILENAME )
190  {
191  if( c == '{' )
192  converted += "{brace}";
193  else if( c == '/' )
194  converted += "{slash}";
195  else if( c == '\\' )
196  converted += "{backslash}";
197  else if( c == '\"' )
198  converted += "{dblquote}";
199  else if( c == '<' )
200  converted += "{lt}";
201  else if( c == '>' )
202  converted += "{gt}";
203  else if( c == '|' )
204  converted += "{bar}";
205  else if( c == ':' )
206  converted += "{colon}";
207  else if( c == '\t' )
208  converted += "{tab}";
209  else if( c == '\n' || c == '\r' )
210  converted += "{return}";
211  else
212  converted += c;
213  }
214  else if( aContext == CTX_NO_SPACE )
215  {
216  if( c == ' ' )
217  converted += "{space}";
218  else if( c == '{' )
219  converted += "{brace}";
220  else
221  converted += c;
222  }
223  else
224  converted += c;
225  }
226 
227  return converted;
228 }

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(), SYMBOL_VIEWER_FRAME::FinishModal(), getLibIdValue(), DIALOG_LIB_NEW_SYMBOL::GetName(), DIALOG_LIB_NEW_SYMBOL::GetParentSymbolName(), SCH_EAGLE_PLUGIN::loadInstance(), SCH_EAGLE_PLUGIN::loadLibrary(), 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 936 of file string_utils.cpp.

937 {
939 }
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 586 of file string_utils.cpp.

587 {
588  do {
589  if( fgets( Line, SizeLine, File ) == nullptr )
590  return nullptr;
591 
592  if( LineNum )
593  *LineNum += 1;
594 
595  } while( Line[0] == '#' || Line[0] == '\n' || Line[0] == '\r' || Line[0] == 0 );
596 
597  strtok( Line, "\n\r" );
598  return Line;
599 }

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

913 {
914  int number = 0;
915  int base = 1;
916 
917  // Trim and extract the trailing numeric part
918  int index = aStr.Len() - 1;
919 
920  while( index >= 0 )
921  {
922  const char chr = aStr.GetChar( index );
923 
924  if( chr < '0' || chr > '9' )
925  break;
926 
927  number += ( chr - '0' ) * base;
928  base *= 10;
929  index--;
930  }
931 
932  return number;
933 }

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

476 {
477  wxString tmp = aString;
478 
479  return tmp.Trim( true ).Trim( false ).IsEmpty();
480 }

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

488 {
489  int char_count = 0;
490  int overbarDepth = -1;
491  int superSubDepth = -1;
492  int braceNesting = 0;
493 
494  for( auto chIt = aString.begin(), end = aString.end(); chIt < end; ++chIt )
495  {
496  if( *chIt == '\t' )
497  {
498  // We don't format tabs in bitmap text (where this is currently used), so just
499  // drop them from the count.
500  continue;
501  }
502  else if( *chIt == '^' && superSubDepth == -1 )
503  {
504  auto lookahead = chIt;
505 
506  if( ++lookahead != end && *lookahead == '{' )
507  {
508  chIt = lookahead;
509  superSubDepth = braceNesting;
510  braceNesting++;
511  continue;
512  }
513  }
514  else if( *chIt == '_' && superSubDepth == -1 )
515  {
516  auto lookahead = chIt;
517 
518  if( ++lookahead != end && *lookahead == '{' )
519  {
520  chIt = lookahead;
521  superSubDepth = braceNesting;
522  braceNesting++;
523  continue;
524  }
525  }
526  else if( *chIt == '~' && overbarDepth == -1 )
527  {
528  auto lookahead = chIt;
529 
530  if( ++lookahead != end && *lookahead == '{' )
531  {
532  chIt = lookahead;
533  overbarDepth = braceNesting;
534  braceNesting++;
535  continue;
536  }
537  }
538  else if( *chIt == '{' )
539  {
540  braceNesting++;
541  }
542  else if( *chIt == '}' )
543  {
544  if( braceNesting > 0 )
545  braceNesting--;
546 
547  if( braceNesting == superSubDepth )
548  {
549  superSubDepth = -1;
550  continue;
551  }
552 
553  if( braceNesting == overbarDepth )
554  {
555  overbarDepth = -1;
556  continue;
557  }
558  }
559 
560  char_count++;
561  }
562 
563  return char_count;
564 }

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

319 {
320  std::string utf8; // utf8 but without escapes and quotes.
321  bool inside = false;
322  const char* start = aSource;
323  char cc;
324 
325  while( (cc = *aSource++) != 0 )
326  {
327  if( cc == '"' )
328  {
329  if( inside )
330  break; // 2nd double quote is end of delimited text
331 
332  inside = true; // first delimiter found, make note, do not copy
333  }
334 
335  else if( inside )
336  {
337  if( cc == '\\' )
338  {
339  cc = *aSource++;
340 
341  if( !cc )
342  break;
343 
344  // do no copy the escape byte if it is followed by \ or "
345  if( cc != '"' && cc != '\\' )
346  utf8 += '\\';
347 
348  utf8 += cc;
349  }
350  else
351  {
352  utf8 += cc;
353  }
354  }
355  }
356 
357  *aDest = FROM_UTF8( utf8.c_str() );
358 
359  return aSource - start;
360 }
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 363 of file string_utils.cpp.

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

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

943 {
944  bool changed = false;
945  std::string result;
946  result.reserve( aName->length() );
947 
948  for( std::string::iterator it = aName->begin(); it != aName->end(); ++it )
949  {
950  if( strchr( illegalFileNameChars, *it ) )
951  {
952  if( aReplaceChar )
953  StrPrintf( &result, "%c", aReplaceChar );
954  else
955  StrPrintf( &result, "%%%02x", *it );
956 
957  changed = true;
958  }
959  else
960  {
961  result += *it;
962  }
963  }
964 
965  if( changed )
966  *aName = result;
967 
968  return changed;
969 }
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:78

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

973 {
974  bool changed = false;
975  wxString result;
976  result.reserve( aName.Length() );
977  wxString illWChars = GetIllegalFileNameWxChars();
978 
979  for( wxString::iterator it = aName.begin(); it != aName.end(); ++it )
980  {
981  if( illWChars.Find( *it ) != wxNOT_FOUND )
982  {
983  if( aReplaceChar )
984  result += aReplaceChar;
985  else
986  result += wxString::Format( "%%%02x", *it );
987 
988  changed = true;
989  }
990  else
991  {
992  result += *it;
993  }
994  }
995 
996  if( changed )
997  aName = result;
998 
999  return changed;
1000 }
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 851 of file string_utils.cpp.

855 {
856  static const wxString separators( wxT( ".," ) );
857 
858  // Clear all the return strings
859  strBeginning->Empty();
860  strDigits->Empty();
861  strEnd->Empty();
862 
863  // There no need to do anything if the string is empty
864  if( strToSplit.length() == 0 )
865  return 0;
866 
867  // Starting at the end of the string look for the first digit
868  int ii;
869 
870  for( ii = (strToSplit.length() - 1); ii >= 0; ii-- )
871  {
872  if( wxIsdigit( strToSplit[ii] ) )
873  break;
874  }
875 
876  // If there were no digits then just set the single string
877  if( ii < 0 )
878  {
879  *strBeginning = strToSplit;
880  }
881  else
882  {
883  // Since there is at least one digit this is the trailing string
884  *strEnd = strToSplit.substr( ii + 1 );
885 
886  // Go to the end of the digits
887  int position = ii + 1;
888 
889  for( ; ii >= 0; ii-- )
890  {
891  if( !wxIsdigit( strToSplit[ii] ) && separators.Find( strToSplit[ii] ) < 0 )
892  break;
893  }
894 
895  // If all that was left was digits, then just set the digits string
896  if( ii < 0 )
897  *strDigits = strToSplit.substr( 0, position );
898 
899  /* We were only looking for the last set of digits everything else is
900  * part of the preamble */
901  else
902  {
903  *strDigits = strToSplit.substr( ii + 1, position - ii - 1 );
904  *strBeginning = strToSplit.substr( 0, ii + 1 );
905  }
906  }
907 
908  return 0;
909 }

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

1027 {
1028  struct lconv* lc = localeconv();
1029  char sep = lc->decimal_point[0];
1030  unsigned sep_pos = aStringValue.Find( sep );
1031 
1032  if( sep_pos > 0 )
1033  {
1034  // We want to keep at least aTrailingZeroAllowed digits after the separator
1035  unsigned min_len = sep_pos + aTrailingZeroAllowed + 1;
1036 
1037  while( aStringValue.Len() > min_len )
1038  {
1039  if( aStringValue.Last() == '0' )
1040  aStringValue.RemoveLast();
1041  else
1042  break;
1043  }
1044  }
1045 }

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

612 {
613  int nb1 = 0, nb2 = 0;
614 
615  auto str1 = aString1.begin();
616  auto str2 = aString2.begin();
617 
618  while( str1 != aString1.end() && str2 != aString2.end() )
619  {
620  wxUniChar c1 = *str1;
621  wxUniChar c2 = *str2;
622 
623  if( wxIsdigit( c1 ) && wxIsdigit( c2 ) ) // Both characters are digits, do numeric compare.
624  {
625  nb1 = 0;
626  nb2 = 0;
627 
628  do
629  {
630  c1 = *str1;
631  nb1 = nb1 * 10 + (int) c1 - '0';
632  ++str1;
633  } while( str1 != aString1.end() && wxIsdigit( *str1 ) );
634 
635  do
636  {
637  c2 = *str2;
638  nb2 = nb2 * 10 + (int) c2 - '0';
639  ++str2;
640  } while( str2 != aString2.end() && wxIsdigit( *str2 ) );
641 
642  if( nb1 < nb2 )
643  return -1;
644 
645  if( nb1 > nb2 )
646  return 1;
647 
648  c1 = ( str1 != aString1.end() ) ? *str1 : wxUniChar( 0 );
649  c2 = ( str2 != aString2.end() ) ? *str2 : wxUniChar( 0 );
650  }
651 
652  // Any numerical comparisons to here are identical.
653  if( aIgnoreCase )
654  {
655  if( wxToupper( c1 ) < wxToupper( c2 ) )
656  return -1;
657 
658  if( wxToupper( c1 ) > wxToupper( c2 ) )
659  return 1;
660  }
661  else
662  {
663  if( c1 < c2 )
664  return -1;
665 
666  if( c1 > c2 )
667  return 1;
668  }
669 
670  if( str1 != aString1.end() )
671  ++str1;
672 
673  if( str2 != aString2.end() )
674  ++str2;
675  }
676 
677  if( str1 == aString1.end() && str2 != aString2.end() )
678  {
679  return -1; // Identical to here but aString1 is longer.
680  }
681  else if( str1 != aString1.end() && str2 == aString2.end() )
682  {
683  return 1; // Identical to here but aString2 is longer.
684  }
685 
686  return 0;
687 }

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(), PLACE_FILE_EXPORTER::GenReportData(), FP_TREE_MODEL_ADAPTER::getFootprints(), FIELDS_EDITOR_GRID_DATA_MODEL::GetValue(), NETLIST_EXPORTER_XML::makeListOfNets(), NETLIST_EXPORTER_XML::makeSymbols(), myCompareFunction(), FOOTPRINT::cmp_pads::operator()(), operator<(), BOARD_REANNOTATE_TOOL::ReannotateDuplicatesInSelection(), 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 567 of file string_utils.cpp.

568 {
569  static const char whitespace[] = " \t\n\r\f\v";
570 
571  if( text )
572  {
573  while( *text && strchr( whitespace, *text ) )
574  ++text;
575 
576  char* cp = text + strlen( text ) - 1;
577 
578  while( cp >= text && strchr( whitespace, *cp ) )
579  *cp-- = '\0';
580  }
581 
582  return text;
583 }

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

300 {
301  wxArrayString words;
302  wxString result;
303 
304  wxStringSplit( aString, words, ' ' );
305 
306  for( const wxString& word : words )
307  {
308  if( !result.IsEmpty() )
309  result += wxT( " " );
310 
311  result += word.Capitalize();
312  }
313 
314  return result;
315 }
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 231 of file string_utils.cpp.

232 {
233  wxString newbuf;
234  size_t sourceLen = aSource.length();
235 
236  for( size_t i = 0; i < sourceLen; ++i )
237  {
238  wxUniChar ch = aSource[i];
239  if( ( ch == '$' || ch == '^' || ch == '_' )
240  && i + 1 < sourceLen && aSource[i+1] == '{' )
241  {
242  for( ; i < sourceLen; ++i )
243  {
244  ch = aSource[i];
245  newbuf += ch;
246 
247  if( ch == '}' )
248  break;
249  }
250  }
251  else if( ch == '{' )
252  {
253  wxString token;
254  int depth = 1;
255 
256  for( i = i + 1; i < sourceLen; ++i )
257  {
258  ch = aSource[i];
259  if( ch == '{' )
260  depth++;
261  else if( ch == '}' )
262  depth--;
263 
264  if( depth <= 0 )
265  break;
266  else
267  token.append( ch );
268  }
269 
270  if( token == wxS( "dblquote" ) ) newbuf.append( wxS( "\"" ) );
271  else if( token == wxS( "quote" ) ) newbuf.append( wxS( "'" ) );
272  else if( token == wxS( "lt" ) ) newbuf.append( wxS( "<" ) );
273  else if( token == wxS( "gt" ) ) newbuf.append( wxS( ">" ) );
274  else if( token == wxS( "backslash" ) ) newbuf.append( wxS( "\\" ) );
275  else if( token == wxS( "slash" ) ) newbuf.append( wxS( "/" ) );
276  else if( token == wxS( "bar" ) ) newbuf.append( wxS( "|" ) );
277  else if( token == wxS( "colon" ) ) newbuf.append( wxS( ":" ) );
278  else if( token == wxS( "space" ) ) newbuf.append( wxS( " " ) );
279  else if( token == wxS( "dollar" ) ) newbuf.append( wxS( "$" ) );
280  else if( token == wxS( "tab" ) ) newbuf.append( wxS( "\t" ) );
281  else if( token == wxS( "return" ) ) newbuf.append( wxS( "\n" ) );
282  else if( token == wxS( "brace" ) ) newbuf.append( wxS( "{" ) );
283  else if( token.IsEmpty() ) newbuf.append( wxS( "{" ) );
284  else
285  {
286  newbuf.append( "{" + UnescapeString( token ) + "}" );
287  }
288  }
289  else
290  {
291  newbuf.append( ch );
292  }
293  }
294 
295  return newbuf;
296 }
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(), ZONE::GetMsgPanelInfo(), NETINFO_ITEM::GetMsgPanelInfo(), LIB_PIN::GetMsgPanelInfo(), FP_TEXT::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(), 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_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 799 of file string_utils.cpp.

800 {
801  // Compare unescaped text
802  wxString fWord = UnescapeString( strFWord );
803  wxString sWord = UnescapeString( strSWord );
804 
805  // The different sections of the two strings
806  wxString strFWordBeg, strFWordMid, strFWordEnd;
807  wxString strSWordBeg, strSWordMid, strSWordEnd;
808 
809  // Split the two strings into separate parts
810  SplitString( fWord, &strFWordBeg, &strFWordMid, &strFWordEnd );
811  SplitString( sWord, &strSWordBeg, &strSWordMid, &strSWordEnd );
812 
813  // Compare the Beginning section of the strings
814  int isEqual = strFWordBeg.CmpNoCase( strSWordBeg );
815 
816  if( isEqual > 0 )
817  {
818  return 1;
819  }
820  else if( isEqual < 0 )
821  {
822  return -1;
823  }
824  else
825  {
826  // If the first sections are equal compare their digits
827  double lFirstNumber = 0;
828  double lSecondNumber = 0;
829  bool endingIsModifier = false;
830 
831  strFWordMid.ToDouble( &lFirstNumber );
832  strSWordMid.ToDouble( &lSecondNumber );
833 
834  endingIsModifier |= ApplyModifier( lFirstNumber, strFWordEnd );
835  endingIsModifier |= ApplyModifier( lSecondNumber, strSWordEnd );
836 
837  if( lFirstNumber > lSecondNumber )
838  return 1;
839  else if( lFirstNumber < lSecondNumber )
840  return -1;
841  // If the first two sections are equal and the endings are modifiers then compare them
842  else if( !endingIsModifier )
843  return strFWordEnd.CmpNoCase( strSWordEnd );
844  // Ran out of things to compare; they must match
845  else
846  return 0;
847  }
848 }
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 690 of file string_utils.cpp.

692 {
693  const wxChar* cp = nullptr, * mp = nullptr;
694  const wxChar* wild, * str;
695  wxString _pattern, _string_to_tst;
696 
697  if( case_sensitive )
698  {
699  wild = pattern.GetData();
700  str = string_to_tst.GetData();
701  }
702  else
703  {
704  _pattern = pattern;
705  _pattern.MakeUpper();
706  _string_to_tst = string_to_tst;
707  _string_to_tst.MakeUpper();
708  wild = _pattern.GetData();
709  str = _string_to_tst.GetData();
710  }
711 
712  while( ( *str ) && ( *wild != '*' ) )
713  {
714  if( ( *wild != *str ) && ( *wild != '?' ) )
715  return false;
716 
717  wild++;
718  str++;
719  }
720 
721  while( *str )
722  {
723  if( *wild == '*' )
724  {
725  if( !*++wild )
726  return 1;
727  mp = wild;
728  cp = str + 1;
729  }
730  else if( ( *wild == *str ) || ( *wild == '?' ) )
731  {
732  wild++;
733  str++;
734  }
735  else
736  {
737  wild = mp;
738  str = cp++;
739  }
740  }
741 
742  while( *wild == '*' )
743  {
744  wild++;
745  }
746 
747  return !*wild;
748 }

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

1004 {
1005  wxString tmp;
1006 
1007  for( unsigned ii = 0; ii < aText.Length(); ii++ )
1008  {
1009  if( aText[ii] == aSplitter )
1010  {
1011  aStrings.Add( tmp );
1012  tmp.Clear();
1013  }
1014 
1015  else
1016  tmp << aText[ii];
1017  }
1018 
1019  if( !tmp.IsEmpty() )
1020  {
1021  aStrings.Add( tmp );
1022  }
1023 }

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