KiCad PCB EDA Suite
string.cpp File Reference

Some useful functions to handle strings. More...

#include <clocale>
#include <macros.h>
#include <richio.h>
#include <kicad_string.h>

Go to the source code of this file.

Functions

bool ConvertSmartQuotesAndDashes (wxString *aString)
 Converts curly quotes and em/en dashes to straight quotes and dashes. More...
 
wxString EscapeString (const wxString &aSource, ESCAPE_CONTEXT aContext)
 These 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)
 
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 (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 (wxString aString)
 Return true if the string is empty or contains only whitespace. 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 (wxString strFWord, wxString strSWord)
 Compare strings like the strcmp function but handle numbers and modifiers within the string text correctly for sorting. More...
 
int SplitString (wxString strToSplit, wxString *strBeginning, wxString *strDigits, wxString *strEnd)
 Breaks 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...
 

Variables

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

Detailed Description

Some useful functions to handle strings.

Definition in file string.cpp.

Function Documentation

◆ ApplyModifier()

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

Definition at line 559 of file string.cpp.

560 {
561  static const wxString modifiers( wxT( "pnumkKM" ) );
562 
563  if( !aString.length() )
564  return false;
565 
566  wxChar modifier;
567  wxString units;
568 
569  if( modifiers.Find( aString[ 0 ] ) >= 0 )
570  {
571  modifier = aString[ 0 ];
572  units = aString.Mid( 1 ).Trim();
573  }
574  else
575  {
576  modifier = ' ';
577  units = aString.Mid( 0 ).Trim();
578  }
579 
580  if( units.length()
581  && !units.CmpNoCase( wxT( "F" ) )
582  && !units.CmpNoCase( wxT( "hz" ) )
583  && !units.CmpNoCase( wxT( "W" ) )
584  && !units.CmpNoCase( wxT( "V" ) )
585  && !units.CmpNoCase( wxT( "H" ) ) )
586  return false;
587 
588  if( modifier == 'p' )
589  value *= 1.0e-12;
590  if( modifier == 'n' )
591  value *= 1.0e-9;
592  else if( modifier == 'u' )
593  value *= 1.0e-6;
594  else if( modifier == 'm' )
595  value *= 1.0e-3;
596  else if( modifier == 'k' || modifier == 'K' )
597  value *= 1.0e3;
598  else if( modifier == 'M' )
599  value *= 1.0e6;
600  else if( modifier == 'G' )
601  value *= 1.0e9;
602 
603  return true;
604 }

Referenced by ValueStringCompare().

◆ ConvertSmartQuotesAndDashes()

bool ConvertSmartQuotesAndDashes ( wxString *  aString)

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

Returns
true if any characters required conversion.

Definition at line 43 of file string.cpp.

44 {
45  bool retVal = false;
46 
47  for( wxString::iterator ii = aString->begin(); ii != aString->end(); ++ii )
48  {
49  if( *ii == L'\u00B4' || *ii == L'\u2018' || *ii == L'\u2019' )
50  {
51  *ii = '\'';
52  retVal = true;
53  }
54  if( *ii == L'\u201C' || *ii == L'\u201D' )
55  {
56  *ii = '"';
57  retVal = true;
58  }
59  if( *ii == L'\u2013' || *ii == L'\u2014' )
60  {
61  *ii = '-';
62  retVal = true;
63  }
64  }
65 
66  return retVal;
67 }

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

◆ DateAndTime()

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

Definition at line 411 of file string.cpp.

412 {
413  wxDateTime datetime = wxDateTime::Now();
414 
415  datetime.SetCountry( wxDateTime::Country_Default );
416  return datetime.Format( wxDefaultDateTimeFormat, wxDateTime::Local );
417 }

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

◆ EscapedUTF8()

std::string EscapedUTF8 ( 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 309 of file string.cpp.

310 {
311  // No new-lines allowed in quoted strings
312  aString.Replace( "\r\n", "\r" );
313  aString.Replace( "\n", "\r" );
314 
315  std::string utf8 = TO_UTF8( aString );
316 
317  std::string ret;
318 
319  ret += '"';
320 
321  for( std::string::const_iterator it = utf8.begin(); it!=utf8.end(); ++it )
322  {
323  // this escaping strategy is designed to be compatible with ReadDelimitedText():
324  if( *it == '"' )
325  {
326  ret += '\\';
327  ret += '"';
328  }
329  else if( *it == '\\' )
330  {
331  ret += '\\'; // double it up
332  ret += '\\';
333  }
334  else
335  {
336  ret += *it;
337  }
338  }
339 
340  ret += '"';
341 
342  return ret;
343 }
#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 346 of file string.cpp.

347 {
348  wxString converted;
349 
350  for( wxUniChar c: aString )
351  {
352  if( c == '\"' )
353  converted += "&quot;";
354  else if( c == '\'' )
355  converted += "&apos;";
356  else if( c == '&' )
357  converted += "&amp;";
358  else if( c == '<' )
359  converted += "&lt;";
360  else if( c == '>' )
361  converted += "&gt;";
362  else
363  converted += c;
364  }
365 
366  return converted;
367 }

Referenced by DRC_ENGINE::EvalRules(), FOOTPRINT_INFO_GENERATOR::GenerateHtml(), FOOTPRINT_INFO_GENERATOR::GetHtmlFieldRow(), BOARD_INSPECTION_TOOL::InspectClearance(), BOARD_INSPECTION_TOOL::InspectConstraints(), 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 
)

These 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 77 of file string.cpp.

78 {
79  wxString converted;
80 
81  for( wxUniChar c: aSource )
82  {
83  if( aContext == CTX_NETNAME )
84  {
85  if( c == '/' )
86  converted += "{slash}";
87  else if( c == '\n' || c == '\r' )
88  converted += ""; // drop
89  else
90  converted += c;
91  }
92  else if( aContext == CTX_LIBID )
93  {
94  if( c == '{' )
95  converted += "{brace}";
96  else if( c == ':' )
97  converted += "{colon}";
98  else if( c == '\n' || c == '\r' )
99  converted += ""; // drop
100  else
101  converted += c;
102  }
103  else if( aContext == CTX_QUOTED_STR )
104  {
105  if( c == '\"' )
106  converted += "{dblquote}";
107  else
108  converted += c;
109  }
110  else if( aContext == CTX_LINE )
111  {
112  if( c == '\n' || c == '\r' )
113  converted += "{return}";
114  else
115  converted += c;
116  }
117  else if( aContext == CTX_FILENAME )
118  {
119  if( c == '{' )
120  converted += "{brace}";
121  else if( c == '/' )
122  converted += "{slash}";
123  else if( c == '\\' )
124  converted += "{backslash}";
125  else if( c == '\"' )
126  converted += "{dblquote}";
127  else if( c == '<' )
128  converted += "{lt}";
129  else if( c == '>' )
130  converted += "{gt}";
131  else if( c == '|' )
132  converted += "{bar}";
133  else if( c == ':' )
134  converted += "{colon}";
135  else if( c == '\t' )
136  converted += "{tab}";
137  else if( c == '\n' || c == '\r' )
138  converted += "{return}";
139  else
140  converted += c;
141  }
142  else
143  converted += c;
144  }
145 
146  return converted;
147 }

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

Referenced by SCH_EDIT_TOOL::ChangeTextType(), CONNECTION_SUBGRAPH::driverName(), CONNECTION_GRAPH::ercCheckBusToNetConflicts(), CONNECTION_GRAPH::ercCheckLabels(), DIALOG_NET_INSPECTOR::onRenameNet(), NET_SETTINGS::ParseBusGroup(), DIALOG_SHEET_PIN_PROPERTIES::TransferDataFromWindow(), DIALOG_TEXT_PROPERTIES::TransferDataFromWindow(), DIALOG_LABEL_EDITOR::TransferDataFromWindow(), and FOOTPRINT_LIST_IMPL::WriteCacheToFile().

◆ GetIllegalFileNameWxChars()

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

Definition at line 740 of file string.cpp.

741 {
743 }
static const char illegalFileNameChars[]
Illegal file name characters used to insure file names will be valid on all supported platforms.
Definition: string.cpp:40
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(), 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 395 of file string.cpp.

396 {
397  do {
398  if( fgets( Line, SizeLine, File ) == NULL )
399  return NULL;
400 
401  if( LineNum )
402  *LineNum += 1;
403 
404  } while( Line[0] == '#' || Line[0] == '\n' || Line[0] == '\r' || Line[0] == 0 );
405 
406  strtok( Line, "\n\r" );
407  return Line;
408 }
#define NULL

References NULL.

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 716 of file string.cpp.

717 {
718  int number = 0;
719  int base = 1;
720 
721  // Trim and extract the trailing numeric part
722  int index = aStr.Len() - 1;
723 
724  while( index >= 0 )
725  {
726  const char chr = aStr.GetChar( index );
727 
728  if( chr < '0' || chr > '9' )
729  break;
730 
731  number += ( chr - '0' ) * base;
732  base *= 10;
733  index--;
734  }
735 
736  return number;
737 }

Referenced by BOOST_AUTO_TEST_CASE(), FOOTPRINT::GetNextPadName(), and FOOTPRINT::IncrementReference().

◆ NoPrintableChars()

bool NoPrintableChars ( wxString  aString)

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

Definition at line 370 of file string.cpp.

371 {
372  return aString.Trim( true ).Trim( false ).IsEmpty();
373 }

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

◆ 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 215 of file string.cpp.

216 {
217  std::string utf8; // utf8 but without escapes and quotes.
218  bool inside = false;
219  const char* start = aSource;
220  char cc;
221 
222  while( (cc = *aSource++) != 0 )
223  {
224  if( cc == '"' )
225  {
226  if( inside )
227  break; // 2nd double quote is end of delimited text
228 
229  inside = true; // first delimiter found, make note, do not copy
230  }
231 
232  else if( inside )
233  {
234  if( cc == '\\' )
235  {
236  cc = *aSource++;
237 
238  if( !cc )
239  break;
240 
241  // do no copy the escape byte if it is followed by \ or "
242  if( cc != '"' && cc != '\\' )
243  utf8 += '\\';
244 
245  utf8 += cc;
246  }
247  else
248  {
249  utf8 += cc;
250  }
251  }
252  }
253 
254  *aDest = FROM_UTF8( utf8.c_str() );
255 
256  return aSource - start;
257 }
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 260 of file string.cpp.

261 {
262  if( aDestSize <= 0 )
263  return 0;
264 
265  bool inside = false;
266  const char* start = aSource;
267  char* limit = aDest + aDestSize - 1;
268  char cc;
269 
270  while( (cc = *aSource++) != 0 && aDest < limit )
271  {
272  if( cc == '"' )
273  {
274  if( inside )
275  break; // 2nd double quote is end of delimited text
276 
277  inside = true; // first delimiter found, make note, do not copy
278  }
279 
280  else if( inside )
281  {
282  if( cc == '\\' )
283  {
284  cc = *aSource++;
285 
286  if( !cc )
287  break;
288 
289  // do no copy the escape byte if it is followed by \ or "
290  if( cc != '"' && cc != '\\' )
291  *aDest++ = '\\';
292 
293  if( aDest < limit )
294  *aDest++ = cc;
295  }
296  else
297  {
298  *aDest++ = cc;
299  }
300  }
301  }
302 
303  *aDest = 0;
304 
305  return aSource - start;
306 }

◆ 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 746 of file string.cpp.

747 {
748  bool changed = false;
749  std::string result;
750  result.reserve( aName->length() );
751 
752  for( std::string::iterator it = aName->begin(); it != aName->end(); ++it )
753  {
754  if( strchr( illegalFileNameChars, *it ) )
755  {
756  if( aReplaceChar )
757  StrPrintf( &result, "%c", aReplaceChar );
758  else
759  StrPrintf( &result, "%%%02x", *it );
760 
761  changed = true;
762  }
763  else
764  {
765  result += *it;
766  }
767  }
768 
769  if( changed )
770  *aName = result;
771 
772  return changed;
773 }
static const char illegalFileNameChars[]
Illegal file name characters used to insure file names will be valid on all supported platforms.
Definition: string.cpp:40
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 AltiumToKiCadLibID(), 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 776 of file string.cpp.

777 {
778  bool changed = false;
779  wxString result;
780  result.reserve( aName.Length() );
781  wxString illWChars = GetIllegalFileNameWxChars();
782 
783  for( wxString::iterator it = aName.begin(); it != aName.end(); ++it )
784  {
785  if( illWChars.Find( *it ) != wxNOT_FOUND )
786  {
787  if( aReplaceChar )
788  result += aReplaceChar;
789  else
790  result += wxString::Format( "%%%02x", *it );
791 
792  changed = true;
793  }
794  else
795  {
796  result += *it;
797  }
798  }
799 
800  if( changed )
801  aName = result;
802 
803  return changed;
804 }
wxString GetIllegalFileNameWxChars()
Definition: string.cpp:740
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

References Format(), and GetIllegalFileNameWxChars().

◆ SplitString()

int SplitString ( wxString  strToSplit,
wxString *  strBeginning,
wxString *  strDigits,
wxString *  strEnd 
)

Breaks 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 655 of file string.cpp.

659 {
660  static const wxString separators( wxT( ".," ) );
661 
662  // Clear all the return strings
663  strBeginning->Empty();
664  strDigits->Empty();
665  strEnd->Empty();
666 
667  // There no need to do anything if the string is empty
668  if( strToSplit.length() == 0 )
669  return 0;
670 
671  // Starting at the end of the string look for the first digit
672  int ii;
673 
674  for( ii = (strToSplit.length() - 1); ii >= 0; ii-- )
675  {
676  if( wxIsdigit( strToSplit[ii] ) )
677  break;
678  }
679 
680  // If there were no digits then just set the single string
681  if( ii < 0 )
682  {
683  *strBeginning = strToSplit;
684  }
685  else
686  {
687  // Since there is at least one digit this is the trailing string
688  *strEnd = strToSplit.substr( ii + 1 );
689 
690  // Go to the end of the digits
691  int position = ii + 1;
692 
693  for( ; ii >= 0; ii-- )
694  {
695  if( !wxIsdigit( strToSplit[ii] ) && separators.Find( strToSplit[ii] ) < 0 )
696  break;
697  }
698 
699  // If all that was left was digits, then just set the digits string
700  if( ii < 0 )
701  *strDigits = strToSplit.substr( 0, position );
702 
703  /* We were only looking for the last set of digits everything else is
704  * part of the preamble */
705  else
706  {
707  *strDigits = strToSplit.substr( ii + 1, position - ii - 1 );
708  *strBeginning = strToSplit.substr( 0, ii + 1 );
709  }
710  }
711 
712  return 0;
713 }

Referenced by UTIL::RefDesStringCompare(), and 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 830 of file string.cpp.

831 {
832  struct lconv* lc = localeconv();
833  char sep = lc->decimal_point[0];
834  unsigned sep_pos = aStringValue.Find( sep );
835 
836  if( sep_pos > 0 )
837  {
838  // We want to keep at least aTrailingZeroAllowed digits after the separator
839  unsigned min_len = sep_pos + aTrailingZeroAllowed + 1;
840 
841  while( aStringValue.Len() > min_len )
842  {
843  if( aStringValue.Last() == '0' )
844  aStringValue.RemoveLast();
845  else
846  break;
847  }
848  }
849 }

Referenced by AngleToStringDegrees(), and StringFromValue().

◆ 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 420 of file string.cpp.

421 {
422  int nb1 = 0, nb2 = 0;
423 
424  auto str1 = aString1.begin();
425  auto str2 = aString2.begin();
426 
427  while( str1 != aString1.end() && str2 != aString2.end() )
428  {
429  wxUniChar c1 = *str1;
430  wxUniChar c2 = *str2;
431 
432  if( wxIsdigit( c1 ) && wxIsdigit( c2 ) ) // Both characters are digits, do numeric compare.
433  {
434  nb1 = 0;
435  nb2 = 0;
436 
437  do
438  {
439  c1 = *str1;
440  nb1 = nb1 * 10 + (int) c1 - '0';
441  ++str1;
442  } while( str1 != aString1.end() && wxIsdigit( *str1 ) );
443 
444  do
445  {
446  c2 = *str2;
447  nb2 = nb2 * 10 + (int) c2 - '0';
448  ++str2;
449  } while( str2 != aString2.end() && wxIsdigit( *str2 ) );
450 
451  if( nb1 < nb2 )
452  return -1;
453 
454  if( nb1 > nb2 )
455  return 1;
456 
457  c1 = ( str1 != aString1.end() ) ? *str1 : wxUniChar( 0 );
458  c2 = ( str2 != aString2.end() ) ? *str2 : wxUniChar( 0 );
459  }
460 
461  // Any numerical comparisons to here are identical.
462  if( aIgnoreCase )
463  {
464  if( wxToupper( c1 ) < wxToupper( c2 ) )
465  return -1;
466 
467  if( wxToupper( c1 ) > wxToupper( c2 ) )
468  return 1;
469  }
470  else
471  {
472  if( c1 < c2 )
473  return -1;
474 
475  if( c1 > c2 )
476  return 1;
477  }
478 
479  if( str1 != aString1.end() )
480  ++str1;
481 
482  if( str2 != aString2.end() )
483  ++str2;
484  }
485 
486  if( str1 == aString1.end() && str2 != aString2.end() )
487  {
488  return -1; // Identical to here but aString1 is longer.
489  }
490  else if( str1 != aString1.end() && str2 == aString2.end() )
491  {
492  return 1; // Identical to here but aString2 is longer.
493  }
494 
495  return 0;
496 }

Referenced by LIB_TREE_NODE::AssignIntrinsicRanks(), BOOST_AUTO_TEST_CASE(), SCH_PIN_TABLE_DATA_MODEL::compare(), PIN_TABLE_DATA_MODEL::compare(), PLACE_FILE_EXPORTER::GenReportData(), FP_TREE_MODEL_ADAPTER::getFootprints(), NETLIST_EXPORTER_XML::makeListOfNets(), myCompareFunction(), FOOTPRINT::cmp_pads::operator()(), operator<(), sortFPlist(), 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 376 of file string.cpp.

377 {
378  static const char whitespace[] = " \t\n\r\f\v";
379 
380  if( text )
381  {
382  while( *text && strchr( whitespace, *text ) )
383  ++text;
384 
385  char* cp = text + strlen( text ) - 1;
386 
387  while( cp >= text && strchr( whitespace, *cp ) )
388  *cp-- = '\0';
389  }
390 
391  return text;
392 }

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

◆ UnescapeString()

wxString UnescapeString ( const wxString &  aSource)

Definition at line 150 of file string.cpp.

151 {
152  wxString newbuf;
153  size_t sourceLen = aSource.length();
154 
155  for( size_t i = 0; i < sourceLen; ++i )
156  {
157  if( ( aSource[i] == '$' || aSource[i] == '^' || aSource[i] == '_' )
158  && i + 1 < sourceLen && aSource[i+1] == '{' )
159  {
160  for( ; i < sourceLen; ++i )
161  {
162  newbuf += aSource[i];
163 
164  if( aSource[i] == '}' )
165  break;
166  }
167  }
168  else if( aSource[i] == '{' )
169  {
170  wxString token;
171  int depth = 1;
172 
173  for( i = i + 1; i < sourceLen; ++i )
174  {
175  if( aSource[i] == '{' )
176  depth++;
177  else if( aSource[i] == '}' )
178  depth--;
179 
180  if( depth <= 0 )
181  break;
182  else
183  token.append( aSource[i] );
184  }
185 
186  if( token == wxS( "dblquote" ) ) newbuf.append( wxS( "\"" ) );
187  else if( token == wxS( "quote" ) ) newbuf.append( wxS( "'" ) );
188  else if( token == wxS( "lt" ) ) newbuf.append( wxS( "<" ) );
189  else if( token == wxS( "gt" ) ) newbuf.append( wxS( ">" ) );
190  else if( token == wxS( "backslash" ) ) newbuf.append( wxS( "\\" ) );
191  else if( token == wxS( "slash" ) ) newbuf.append( wxS( "/" ) );
192  else if( token == wxS( "bar" ) ) newbuf.append( wxS( "|" ) );
193  else if( token == wxS( "colon" ) ) newbuf.append( wxS( ":" ) );
194  else if( token == wxS( "space" ) ) newbuf.append( wxS( " " ) );
195  else if( token == wxS( "dollar" ) ) newbuf.append( wxS( "$" ) );
196  else if( token == wxS( "tab" ) ) newbuf.append( wxS( "\t" ) );
197  else if( token == wxS( "return" ) ) newbuf.append( wxS( "\n" ) );
198  else if( token == wxS( "brace" ) ) newbuf.append( wxS( "{" ) );
199  else if( token.IsEmpty() ) newbuf.append( wxS( "{" ) );
200  else
201  {
202  newbuf.append( "{" + UnescapeString( token ) + "}" );
203  }
204  }
205  else
206  {
207  newbuf.append( aSource[i] );
208  }
209  }
210 
211  return newbuf;
212 }
wxString UnescapeString(const wxString &aSource)
Definition: string.cpp:150

References UnescapeString().

Referenced by NET_SELECTOR_COMBOPOPUP::Accept(), SCH_CONNECTION::AppendInfoToMsgPanel(), SCH_EDIT_TOOL::ChangeTextType(), NETLIST_EXPORTER_PSPICE_SIM::ComponentToVector(), SCH_CONNECTION::ConfigureFromLabel(), BOARD_NETLIST_UPDATER::deleteSinglePadNets(), GRID_CELL_ESCAPED_TEXT_RENDERER::Draw(), KIGFX::PCB_PAINTER::draw(), EDA_TEXT::EDA_TEXT(), CONNECTION_GRAPH::ercCheckBusToBusEntryConflicts(), CONNECTION_GRAPH::ercCheckHierSheets(), SCH_EDIT_FRAME::ExecuteRemoteCommand(), NETLIST_EXPORTER_PSPICE::Format(), DIALOG_NET_INSPECTOR::formatNetName(), GRID_CELL_ESCAPED_TEXT_RENDERER::GetBestSize(), PCB_TEXT::GetMsgPanelInfo(), ZONE::GetMsgPanelInfo(), NETINFO_ITEM::GetMsgPanelInfo(), FP_TEXT::GetMsgPanelInfo(), GERBER_DRAW_ITEM::GetMsgPanelInfo(), SCH_TEXT::GetMsgPanelInfo(), PAD::GetMsgPanelInfo(), TRACK::GetMsgPanelInfoBase_Common(), BOARD_CONNECTED_ITEM::GetNetnameMsg(), GERBVIEW_CONTROL::HighlightControl(), SCH_CONNECTION::IsBusLabel(), DIALOG_NET_INSPECTOR::LIST_ITEM::LIST_ITEM(), SCH_CONNECTION::MightBeBusLabel(), DIALOG_NET_INSPECTOR::netFilterMatches(), DIALOG_NET_INSPECTOR::onRenameNet(), FOOTPRINT_LIST_IMPL::ReadCacheFromFile(), NET_SELECTOR_COMBOPOPUP::rebuildList(), UTIL::RefDesStringCompare(), EDA_TEXT::Replace(), NET_SETTINGS::ResolveNetClassAssignments(), NET_SELECTOR::SetSelectedNet(), NET_SELECTOR::SetSelectedNetcode(), EDA_TEXT::SetText(), BOARD::SortedNetnamesList(), DIALOG_SIGNAL_LIST::TransferDataToWindow(), DIALOG_SHEET_PIN_PROPERTIES::TransferDataToWindow(), DIALOG_LABEL_EDITOR::TransferDataToWindow(), UnescapeString(), HIGHLIGHT_MENU::update(), BOARD_NETLIST_UPDATER::updateComponentPadConnections(), BOARD_NETLIST_UPDATER::updateCopperZoneNets(), SCH_EDIT_FRAME::UpdateNetHighlightStatus(), GERBVIEW_FRAME::updateNetnameListSelectBox(), and ValueStringCompare().

◆ ValueStringCompare()

int ValueStringCompare ( wxString  strFWord,
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 607 of file string.cpp.

608 {
609  // Compare unescaped text
610  strFWord = UnescapeString( strFWord );
611  strSWord = UnescapeString( strSWord );
612 
613  // The different sections of the two strings
614  wxString strFWordBeg, strFWordMid, strFWordEnd;
615  wxString strSWordBeg, strSWordMid, strSWordEnd;
616 
617  // Split the two strings into separate parts
618  SplitString( strFWord, &strFWordBeg, &strFWordMid, &strFWordEnd );
619  SplitString( strSWord, &strSWordBeg, &strSWordMid, &strSWordEnd );
620 
621  // Compare the Beginning section of the strings
622  int isEqual = strFWordBeg.CmpNoCase( strSWordBeg );
623 
624  if( isEqual > 0 )
625  return 1;
626  else if( isEqual < 0 )
627  return -1;
628  else
629  {
630  // If the first sections are equal compare their digits
631  double lFirstNumber = 0;
632  double lSecondNumber = 0;
633  bool endingIsModifier = false;
634 
635  strFWordMid.ToDouble( &lFirstNumber );
636  strSWordMid.ToDouble( &lSecondNumber );
637 
638  endingIsModifier |= ApplyModifier( lFirstNumber, strFWordEnd );
639  endingIsModifier |= ApplyModifier( lSecondNumber, strSWordEnd );
640 
641  if( lFirstNumber > lSecondNumber )
642  return 1;
643  else if( lFirstNumber < lSecondNumber )
644  return -1;
645  // If the first two sections are equal and the endings are modifiers then compare them
646  else if( !endingIsModifier )
647  return strFWordEnd.CmpNoCase( strSWordEnd );
648  // Ran out of things to compare; they must match
649  else
650  return 0;
651  }
652 }
int SplitString(wxString strToSplit, wxString *strBeginning, wxString *strDigits, wxString *strEnd)
Breaks a string into three parts: he alphabetic preamble, the numeric part, and any alphabetic ending...
Definition: string.cpp:655
wxString UnescapeString(const wxString &aSource)
Definition: string.cpp:150
bool ApplyModifier(double &value, const wxString &aString)
Definition: string.cpp:559

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 499 of file string.cpp.

501 {
502  const wxChar* cp = NULL, * mp = NULL;
503  const wxChar* wild, * string;
504  wxString _pattern, _string_to_tst;
505 
506  if( case_sensitive )
507  {
508  wild = pattern.GetData();
509  string = string_to_tst.GetData();
510  }
511  else
512  {
513  _pattern = pattern;
514  _pattern.MakeUpper();
515  _string_to_tst = string_to_tst;
516  _string_to_tst.MakeUpper();
517  wild = _pattern.GetData();
518  string = _string_to_tst.GetData();
519  }
520 
521  while( ( *string ) && ( *wild != '*' ) )
522  {
523  if( ( *wild != *string ) && ( *wild != '?' ) )
524  return false;
525 
526  wild++; string++;
527  }
528 
529  while( *string )
530  {
531  if( *wild == '*' )
532  {
533  if( !*++wild )
534  return 1;
535  mp = wild;
536  cp = string + 1;
537  }
538  else if( ( *wild == *string ) || ( *wild == '?' ) )
539  {
540  wild++;
541  string++;
542  }
543  else
544  {
545  wild = mp;
546  string = cp++;
547  }
548  }
549 
550  while( *wild == '*' )
551  {
552  wild++;
553  }
554 
555  return !*wild;
556 }
#define NULL

References NULL.

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 807 of file string.cpp.

808 {
809  wxString tmp;
810 
811  for( unsigned ii = 0; ii < aText.Length(); ii++ )
812  {
813  if( aText[ii] == aSplitter )
814  {
815  aStrings.Add( tmp );
816  tmp.Clear();
817  }
818 
819  else
820  tmp << aText[ii];
821  }
822 
823  if( !tmp.IsEmpty() )
824  {
825  aStrings.Add( tmp );
826  }
827 }

Referenced by BOARD_ADAPTER::addShapeWithClearance(), export_vrml_pcbtext(), EDA_TEXT::GetTextBox(), HTML_MESSAGE_BOX::ListSet(), PANEL_SETUP_RULES::OnErrorLinkClicked(), pcbnewGetWizardsBackTrace(), SCH_TEXT::Plot(), BRDITEMS_PLOTTER::PlotPcbText(), EDA_TEXT::Print(), PCB_TEXT::TransformTextShapeWithClearanceToPolygon(), and EDA_TEXT::TransformToSegmentList().

Variable Documentation

◆ illegalFileNameChars

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

Illegal file name characters used to insure 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 40 of file string.cpp.

Referenced by GetIllegalFileNameWxChars(), and ReplaceIllegalFileNameChars().