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

Go to the source code of this file.

Classes

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

Enumerations

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

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 PrettyPrintForMenu (const wxString &aString)
 Remove markup (such as overbar or subscript) that we can't render to menu items. More...
 
wxString TitleCaps (const wxString &aString)
 Capitalize the first letter in each word. More...
 
int ReadDelimitedText (char *aDest, const char *aSource, int aDestSize)
 Copy bytes from aSource delimited string segment to aDest buffer. More...
 
int ReadDelimitedText (wxString *aDest, const char *aSource)
 Copy bytes from aSource delimited string segment to aDest wxString. More...
 
std::string EscapedUTF8 (const wxString &aString)
 Return an 8 bit UTF8 string given aString in Unicode form. More...
 
wxString EscapeHTML (const wxString &aString)
 Return a new wxString escaped for embedding in HTML. More...
 
char * GetLine (FILE *aFile, char *Line, int *LineNum=nullptr, int SizeLine=255)
 Read one line line from aFile. More...
 
bool NoPrintableChars (const wxString &aString)
 Return true if the string is empty or contains only whitespace. More...
 
char * StrPurge (char *text)
 Remove leading and training spaces, tabs and end of line chars in text. More...
 
wxString DateAndTime ()
 
int StrNumCmp (const wxString &aString1, const wxString &aString2, bool aIgnoreCase=false)
 Compare two strings with alphanumerical content. More...
 
bool WildCompareString (const wxString &pattern, const wxString &string_to_tst, bool case_sensitive=true)
 Compare a string against wild card (* and ?) pattern using the usual rules. More...
 
int ValueStringCompare (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 (const wxString &strToSplit, wxString *strBeginning, wxString *strDigits, wxString *strEnd)
 Break a string into three parts: he alphabetic preamble, the numeric part, and any alphabetic ending. More...
 
int GetTrailingInt (const wxString &aStr)
 Gets the trailing int, if any, from a string. More...
 
wxString GetIllegalFileNameWxChars ()
 
bool ReplaceIllegalFileNameChars (std::string *aName, int aReplaceChar=0)
 Checks aName for illegal file name characters. More...
 
bool ReplaceIllegalFileNameChars (wxString &aName, int aReplaceChar=0)
 
char * strtok_r (char *str, const char *delim, char **nextp)
 
static std::vector< std::string > split (const std::string &aStr, const std::string &aDelim)
 Split the input string into a vector of output strings. More...
 
void AccumulateDescription (wxString &aDesc, const wxString &aItem)
 Utility to build comma separated lists in messages. More...
 
void wxStringSplit (const wxString &aText, wxArrayString &aStrings, wxChar aSplitter)
 Split aString to a string list separated at aSplitter. More...
 
void StripTrailingZeros (wxString &aStringValue, unsigned aTrailingZeroAllowed=1)
 Remove trailing zeros from a string containing a converted float number. More...
 
std::string 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...
 

Detailed Description

See also
common.h, string.cpp

Definition in file kicad_string.h.

Enumeration Type Documentation

◆ ESCAPE_CONTEXT

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

Enumerator
CTX_NETNAME 
CTX_LIBID 
CTX_QUOTED_STR 
CTX_LINE 
CTX_FILENAME 

Definition at line 56 of file kicad_string.h.

Function Documentation

◆ AccumulateDescription()

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

Utility to build comma separated lists in messages.

Definition at line 316 of file kicad_string.h.

317 {
318  if( !aDesc.IsEmpty() )
319  aDesc << wxT( ", " );
320 
321  aDesc << aItem;
322 }

Referenced by ZONE::GetMsgPanelInfo().

◆ AngleToStringDegrees()

wxString AngleToStringDegrees ( double  aAngle)

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

Definition at line 964 of file string.cpp.

965 {
966  wxString text;
967 
968  text.Printf( wxT( "%.3f" ), aAngle / 10.0 );
969  StripTrailingZeros( text, 1 );
970 
971  return text;
972 }
void StripTrailingZeros(wxString &aStringValue, unsigned aTrailingZeroAllowed)
Remove trailing zeros from a string containing a converted float number.
Definition: string.cpp:912

References StripTrailingZeros(), and text.

Referenced by PANEL_EDIT_OPTIONS::TransferDataToWindow().

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

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

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.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;
58 
59  if( ++lookahead != aOldStr.end() && *lookahead == '~' )
60  {
61  if( ++lookahead != aOldStr.end() && *lookahead == '{' )
62  {
63  // This way the subseqent 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
75  {
76  if( inOverbar )
77  {
78  newStr << "}";
79  inOverbar = false;
80  }
81  else
82  {
83  newStr << "~{";
84  inOverbar = true;
85  }
86 
87  continue;
88  }
89  }
90  else if( ( *chIt == ' ' || *chIt == '}' || *chIt == ')' ) && inOverbar )
91  {
92  // Spaces were used to terminate overbar as well
93  newStr << "}";
94  inOverbar = false;
95  }
96 
97  newStr << *chIt;
98  }
99 
100  // Explicitly end the overbar even if there was no terminating '~' in the aOldStr.
101  if( inOverbar )
102  newStr << "}";
103 
104  return newStr;
105 }

Referenced by LEGACY_PLUGIN::loadMODULE_TEXT(), LEGACY_PLUGIN::loadNETCLASS(), LEGACY_PLUGIN::loadNETINFO_ITEM(), LEGACY_PLUGIN::loadPAD(), LEGACY_PLUGIN::loadPCB_TEXT(), NET_SETTINGS::migrateSchema0to1(), SCH_SEXPR_PARSER::parseEDA_TEXT(), PCB_PARSER::parseEDA_TEXT(), PCB_PARSER::parseNETCLASS(), PCB_PARSER::parseNETINFO_ITEM(), PCB_PARSER::parsePAD(), and DRAWING_SHEET_READER_PARSER::parseText().

◆ DateAndTime()

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

Definition at line 492 of file string.cpp.

493 {
494  wxDateTime datetime = wxDateTime::Now();
495 
496  datetime.SetCountry( wxDateTime::Country_Default );
497  return datetime.Format( wxDefaultDateTimeFormat, wxDateTime::Local );
498 }

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

935 {
936  char buf[50];
937  int len;
938 
939  if( aValue != 0.0 && std::fabs( aValue ) <= 0.0001 )
940  {
941  // For these small values, %f works fine,
942  // and %g gives an exponent
943  len = sprintf( buf, "%.16f", aValue );
944 
945  while( --len > 0 && buf[len] == '0' )
946  buf[len] = '\0';
947 
948  if( buf[len] == '.' )
949  buf[len] = '\0';
950  else
951  ++len;
952  }
953  else
954  {
955  // For these values, %g works fine, and sometimes %f
956  // gives a bad value (try aValue = 1.222222222222, with %.16f format!)
957  len = sprintf( buf, "%.10g", aValue );
958  }
959 
960  return std::string( buf, len );
961 }

Referenced by GBR_TO_PCB_EXPORTER::export_non_copper_item(), GBR_TO_PCB_EXPORTER::export_via(), PCB_IO::format(), BOARD_STACKUP::FormatBoardStackup(), PCB_IO::formatSetup(), formatStroke(), NUMERIC_EVALUATOR::parseSetResult(), SCH_SEXPR_PLUGIN::saveJunction(), GBR_TO_PCB_EXPORTER::writeCopperLineItem(), GBR_TO_PCB_EXPORTER::writePcbFilledCircle(), GBR_TO_PCB_EXPORTER::writePcbPolygon(), and GBR_TO_PCB_EXPORTER::writePcbZoneItem().

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

387 {
388  wxString str = aString;
389 
390  // No new-lines allowed in quoted strings
391  str.Replace( "\r\n", "\r" );
392  str.Replace( "\n", "\r" );
393 
394  std::string utf8 = TO_UTF8( aString );
395 
396  std::string ret;
397 
398  ret += '"';
399 
400  for( std::string::const_iterator it = utf8.begin(); it!=utf8.end(); ++it )
401  {
402  // this escaping strategy is designed to be compatible with ReadDelimitedText():
403  if( *it == '"' )
404  {
405  ret += '\\';
406  ret += '"';
407  }
408  else if( *it == '\\' )
409  {
410  ret += '\\'; // double it up
411  ret += '\\';
412  }
413  else
414  {
415  ret += *it;
416  }
417  }
418 
419  ret += '"';
420 
421  return ret;
422 }
#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 425 of file string.cpp.

426 {
427  wxString converted;
428 
429  for( wxUniChar c: aString )
430  {
431  if( c == '\"' )
432  converted += "&quot;";
433  else if( c == '\'' )
434  converted += "&apos;";
435  else if( c == '&' )
436  converted += "&amp;";
437  else if( c == '<' )
438  converted += "&lt;";
439  else if( c == '>' )
440  converted += "&gt;";
441  else
442  converted += c;
443  }
444 
445  return converted;
446 }

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

136 {
137  wxString converted;
138 
139  for( wxUniChar c: aSource )
140  {
141  if( aContext == CTX_NETNAME )
142  {
143  if( c == '/' )
144  converted += "{slash}";
145  else if( c == '\n' || c == '\r' )
146  converted += ""; // drop
147  else
148  converted += c;
149  }
150  else if( aContext == CTX_LIBID )
151  {
152  if( c == '{' )
153  converted += "{brace}";
154  else if( c == ':' )
155  converted += "{colon}";
156  else if( c == '\n' || c == '\r' )
157  converted += ""; // drop
158  else
159  converted += c;
160  }
161  else if( aContext == CTX_QUOTED_STR )
162  {
163  if( c == '\"' )
164  converted += "{dblquote}";
165  else
166  converted += c;
167  }
168  else if( aContext == CTX_LINE )
169  {
170  if( c == '\n' || c == '\r' )
171  converted += "{return}";
172  else
173  converted += c;
174  }
175  else if( aContext == CTX_FILENAME )
176  {
177  if( c == '{' )
178  converted += "{brace}";
179  else if( c == '/' )
180  converted += "{slash}";
181  else if( c == '\\' )
182  converted += "{backslash}";
183  else if( c == '\"' )
184  converted += "{dblquote}";
185  else if( c == '<' )
186  converted += "{lt}";
187  else if( c == '>' )
188  converted += "{gt}";
189  else if( c == '|' )
190  converted += "{bar}";
191  else if( c == ':' )
192  converted += "{colon}";
193  else if( c == '\t' )
194  converted += "{tab}";
195  else if( c == '\n' || c == '\r' )
196  converted += "{return}";
197  else
198  converted += c;
199  }
200  else
201  converted += c;
202  }
203 
204  return converted;
205 }

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_LABEL_EDITOR::TransferDataFromWindow(), DIALOG_TEXT_PROPERTIES::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 822 of file string.cpp.

823 {
825 }
static const char illegalFileNameChars[]
Illegal file name characters used to ensure file names will be valid on all supported platforms.
Definition: string.cpp:41
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 476 of file string.cpp.

477 {
478  do {
479  if( fgets( Line, SizeLine, File ) == NULL )
480  return NULL;
481 
482  if( LineNum )
483  *LineNum += 1;
484 
485  } while( Line[0] == '#' || Line[0] == '\n' || Line[0] == '\r' || Line[0] == 0 );
486 
487  strtok( Line, "\n\r" );
488  return Line;
489 }
#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 798 of file string.cpp.

799 {
800  int number = 0;
801  int base = 1;
802 
803  // Trim and extract the trailing numeric part
804  int index = aStr.Len() - 1;
805 
806  while( index >= 0 )
807  {
808  const char chr = aStr.GetChar( index );
809 
810  if( chr < '0' || chr > '9' )
811  break;
812 
813  number += ( chr - '0' ) * base;
814  base *= 10;
815  index--;
816  }
817 
818  return number;
819 }

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

◆ NoPrintableChars()

bool NoPrintableChars ( const wxString &  aString)

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

Definition at line 449 of file string.cpp.

450 {
451  wxString tmp = aString;
452 
453  return tmp.Trim( true ).Trim( false ).IsEmpty();
454 }

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

◆ PrettyPrintForMenu()

wxString PrettyPrintForMenu ( const wxString &  aString)

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

◆ ReadDelimitedText() [1/2]

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

Copy bytes from aSource delimited string segment to aDest buffer.

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

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

Definition at line 337 of file string.cpp.

338 {
339  if( aDestSize <= 0 )
340  return 0;
341 
342  bool inside = false;
343  const char* start = aSource;
344  char* limit = aDest + aDestSize - 1;
345  char cc;
346 
347  while( (cc = *aSource++) != 0 && aDest < limit )
348  {
349  if( cc == '"' )
350  {
351  if( inside )
352  break; // 2nd double quote is end of delimited text
353 
354  inside = true; // first delimiter found, make note, do not copy
355  }
356 
357  else if( inside )
358  {
359  if( cc == '\\' )
360  {
361  cc = *aSource++;
362 
363  if( !cc )
364  break;
365 
366  // do no copy the escape byte if it is followed by \ or "
367  if( cc != '"' && cc != '\\' )
368  *aDest++ = '\\';
369 
370  if( aDest < limit )
371  *aDest++ = cc;
372  }
373  else
374  {
375  *aDest++ = cc;
376  }
377  }
378  }
379 
380  *aDest = 0;
381 
382  return aSource - start;
383 }

◆ ReadDelimitedText() [2/2]

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

Copy bytes from aSource delimited string segment to aDest wxString.

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

Definition at line 292 of file string.cpp.

293 {
294  std::string utf8; // utf8 but without escapes and quotes.
295  bool inside = false;
296  const char* start = aSource;
297  char cc;
298 
299  while( (cc = *aSource++) != 0 )
300  {
301  if( cc == '"' )
302  {
303  if( inside )
304  break; // 2nd double quote is end of delimited text
305 
306  inside = true; // first delimiter found, make note, do not copy
307  }
308 
309  else if( inside )
310  {
311  if( cc == '\\' )
312  {
313  cc = *aSource++;
314 
315  if( !cc )
316  break;
317 
318  // do no copy the escape byte if it is followed by \ or "
319  if( cc != '"' && cc != '\\' )
320  utf8 += '\\';
321 
322  utf8 += cc;
323  }
324  else
325  {
326  utf8 += cc;
327  }
328  }
329  }
330 
331  *aDest = FROM_UTF8( utf8.c_str() );
332 
333  return aSource - start;
334 }
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().

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

829 {
830  bool changed = false;
831  std::string result;
832  result.reserve( aName->length() );
833 
834  for( std::string::iterator it = aName->begin(); it != aName->end(); ++it )
835  {
836  if( strchr( illegalFileNameChars, *it ) )
837  {
838  if( aReplaceChar )
839  StrPrintf( &result, "%c", aReplaceChar );
840  else
841  StrPrintf( &result, "%%%02x", *it );
842 
843  changed = true;
844  }
845  else
846  {
847  result += *it;
848  }
849  }
850 
851  if( changed )
852  *aName = result;
853 
854  return changed;
855 }
static const char illegalFileNameChars[]
Illegal file name characters used to ensure file names will be valid on all supported platforms.
Definition: string.cpp:41
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 = 0 
)

Definition at line 858 of file string.cpp.

859 {
860  bool changed = false;
861  wxString result;
862  result.reserve( aName.Length() );
863  wxString illWChars = GetIllegalFileNameWxChars();
864 
865  for( wxString::iterator it = aName.begin(); it != aName.end(); ++it )
866  {
867  if( illWChars.Find( *it ) != wxNOT_FOUND )
868  {
869  if( aReplaceChar )
870  result += aReplaceChar;
871  else
872  result += wxString::Format( "%%%02x", *it );
873 
874  changed = true;
875  }
876  else
877  {
878  result += *it;
879  }
880  }
881 
882  if( changed )
883  aName = result;
884 
885  return changed;
886 }
wxString GetIllegalFileNameWxChars()
Definition: string.cpp:822
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().

◆ split()

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

Split the input string into a vector of output strings.

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

Definition at line 290 of file kicad_string.h.

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

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

◆ SplitString()

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

Break a string into three parts: he alphabetic preamble, the numeric part, and any alphabetic ending.

For example C10A is split to C 10 A

Definition at line 737 of file string.cpp.

741 {
742  static const wxString separators( wxT( ".," ) );
743 
744  // Clear all the return strings
745  strBeginning->Empty();
746  strDigits->Empty();
747  strEnd->Empty();
748 
749  // There no need to do anything if the string is empty
750  if( strToSplit.length() == 0 )
751  return 0;
752 
753  // Starting at the end of the string look for the first digit
754  int ii;
755 
756  for( ii = (strToSplit.length() - 1); ii >= 0; ii-- )
757  {
758  if( wxIsdigit( strToSplit[ii] ) )
759  break;
760  }
761 
762  // If there were no digits then just set the single string
763  if( ii < 0 )
764  {
765  *strBeginning = strToSplit;
766  }
767  else
768  {
769  // Since there is at least one digit this is the trailing string
770  *strEnd = strToSplit.substr( ii + 1 );
771 
772  // Go to the end of the digits
773  int position = ii + 1;
774 
775  for( ; ii >= 0; ii-- )
776  {
777  if( !wxIsdigit( strToSplit[ii] ) && separators.Find( strToSplit[ii] ) < 0 )
778  break;
779  }
780 
781  // If all that was left was digits, then just set the digits string
782  if( ii < 0 )
783  *strDigits = strToSplit.substr( 0, position );
784 
785  /* We were only looking for the last set of digits everything else is
786  * part of the preamble */
787  else
788  {
789  *strDigits = strToSplit.substr( ii + 1, position - ii - 1 );
790  *strBeginning = strToSplit.substr( 0, ii + 1 );
791  }
792  }
793 
794  return 0;
795 }

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

913 {
914  struct lconv* lc = localeconv();
915  char sep = lc->decimal_point[0];
916  unsigned sep_pos = aStringValue.Find( sep );
917 
918  if( sep_pos > 0 )
919  {
920  // We want to keep at least aTrailingZeroAllowed digits after the separator
921  unsigned min_len = sep_pos + aTrailingZeroAllowed + 1;
922 
923  while( aStringValue.Len() > min_len )
924  {
925  if( aStringValue.Last() == '0' )
926  aStringValue.RemoveLast();
927  else
928  break;
929  }
930  }
931 }

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

502 {
503  int nb1 = 0, nb2 = 0;
504 
505  auto str1 = aString1.begin();
506  auto str2 = aString2.begin();
507 
508  while( str1 != aString1.end() && str2 != aString2.end() )
509  {
510  wxUniChar c1 = *str1;
511  wxUniChar c2 = *str2;
512 
513  if( wxIsdigit( c1 ) && wxIsdigit( c2 ) ) // Both characters are digits, do numeric compare.
514  {
515  nb1 = 0;
516  nb2 = 0;
517 
518  do
519  {
520  c1 = *str1;
521  nb1 = nb1 * 10 + (int) c1 - '0';
522  ++str1;
523  } while( str1 != aString1.end() && wxIsdigit( *str1 ) );
524 
525  do
526  {
527  c2 = *str2;
528  nb2 = nb2 * 10 + (int) c2 - '0';
529  ++str2;
530  } while( str2 != aString2.end() && wxIsdigit( *str2 ) );
531 
532  if( nb1 < nb2 )
533  return -1;
534 
535  if( nb1 > nb2 )
536  return 1;
537 
538  c1 = ( str1 != aString1.end() ) ? *str1 : wxUniChar( 0 );
539  c2 = ( str2 != aString2.end() ) ? *str2 : wxUniChar( 0 );
540  }
541 
542  // Any numerical comparisons to here are identical.
543  if( aIgnoreCase )
544  {
545  if( wxToupper( c1 ) < wxToupper( c2 ) )
546  return -1;
547 
548  if( wxToupper( c1 ) > wxToupper( c2 ) )
549  return 1;
550  }
551  else
552  {
553  if( c1 < c2 )
554  return -1;
555 
556  if( c1 > c2 )
557  return 1;
558  }
559 
560  if( str1 != aString1.end() )
561  ++str1;
562 
563  if( str2 != aString2.end() )
564  ++str2;
565  }
566 
567  if( str1 == aString1.end() && str2 != aString2.end() )
568  {
569  return -1; // Identical to here but aString1 is longer.
570  }
571  else if( str1 != aString1.end() && str2 == aString2.end() )
572  {
573  return 1; // Identical to here but aString2 is longer.
574  }
575 
576  return 0;
577 }

Referenced by LIB_TREE_NODE::AssignIntrinsicRanks(), BOOST_AUTO_TEST_CASE(), ChangeArrayCompare(), 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 457 of file string.cpp.

458 {
459  static const char whitespace[] = " \t\n\r\f\v";
460 
461  if( text )
462  {
463  while( *text && strchr( whitespace, *text ) )
464  ++text;
465 
466  char* cp = text + strlen( text ) - 1;
467 
468  while( cp >= text && strchr( whitespace, *cp ) )
469  *cp-- = '\0';
470  }
471 
472  return text;
473 }

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

◆ strtok_r()

◆ TitleCaps()

wxString TitleCaps ( const wxString &  aString)

Capitalize the first letter in each word.

Definition at line 273 of file string.cpp.

274 {
275  wxArrayString words;
276  wxString result;
277 
278  wxStringSplit( aString, words, ' ' );
279 
280  for( const wxString& word : words )
281  {
282  if( !result.IsEmpty() )
283  result += wxT( " " );
284 
285  result += word.Capitalize();
286  }
287 
288  return result;
289 }
void wxStringSplit(const wxString &aText, wxArrayString &aStrings, wxChar aSplitter)
Split aString to a string list separated at aSplitter.
Definition: string.cpp:889

References wxStringSplit().

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

◆ UnescapeString()

wxString UnescapeString ( const wxString &  aSource)

Definition at line 208 of file string.cpp.

209 {
210  wxString newbuf;
211  size_t sourceLen = aSource.length();
212 
213  for( size_t i = 0; i < sourceLen; ++i )
214  {
215  if( ( aSource[i] == '$' || aSource[i] == '^' || aSource[i] == '_' )
216  && i + 1 < sourceLen && aSource[i+1] == '{' )
217  {
218  for( ; i < sourceLen; ++i )
219  {
220  newbuf += aSource[i];
221 
222  if( aSource[i] == '}' )
223  break;
224  }
225  }
226  else if( aSource[i] == '{' )
227  {
228  wxString token;
229  int depth = 1;
230 
231  for( i = i + 1; i < sourceLen; ++i )
232  {
233  if( aSource[i] == '{' )
234  depth++;
235  else if( aSource[i] == '}' )
236  depth--;
237 
238  if( depth <= 0 )
239  break;
240  else
241  token.append( aSource[i] );
242  }
243 
244  if( token == wxS( "dblquote" ) ) newbuf.append( wxS( "\"" ) );
245  else if( token == wxS( "quote" ) ) newbuf.append( wxS( "'" ) );
246  else if( token == wxS( "lt" ) ) newbuf.append( wxS( "<" ) );
247  else if( token == wxS( "gt" ) ) newbuf.append( wxS( ">" ) );
248  else if( token == wxS( "backslash" ) ) newbuf.append( wxS( "\\" ) );
249  else if( token == wxS( "slash" ) ) newbuf.append( wxS( "/" ) );
250  else if( token == wxS( "bar" ) ) newbuf.append( wxS( "|" ) );
251  else if( token == wxS( "colon" ) ) newbuf.append( wxS( ":" ) );
252  else if( token == wxS( "space" ) ) newbuf.append( wxS( " " ) );
253  else if( token == wxS( "dollar" ) ) newbuf.append( wxS( "$" ) );
254  else if( token == wxS( "tab" ) ) newbuf.append( wxS( "\t" ) );
255  else if( token == wxS( "return" ) ) newbuf.append( wxS( "\n" ) );
256  else if( token == wxS( "brace" ) ) newbuf.append( wxS( "{" ) );
257  else if( token.IsEmpty() ) newbuf.append( wxS( "{" ) );
258  else
259  {
260  newbuf.append( "{" + UnescapeString( token ) + "}" );
261  }
262  }
263  else
264  {
265  newbuf.append( aSource[i] );
266  }
267  }
268 
269  return newbuf;
270 }
wxString UnescapeString(const wxString &aSource)
Definition: string.cpp:208

References UnescapeString().

Referenced by NET_SELECTOR_COMBOPOPUP::Accept(), SCH_CONNECTION::AppendInfoToMsgPanel(), EDA_TEXT::cacheShownText(), 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(), 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(), PCB_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(), NET_SETTINGS::ResolveNetClassAssignments(), NET_SELECTOR::SetSelectedNet(), NET_SELECTOR::SetSelectedNetcode(), 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 689 of file string.cpp.

690 {
691  // Compare unescaped text
692  strFWord = UnescapeString( strFWord );
693  strSWord = UnescapeString( strSWord );
694 
695  // The different sections of the two strings
696  wxString strFWordBeg, strFWordMid, strFWordEnd;
697  wxString strSWordBeg, strSWordMid, strSWordEnd;
698 
699  // Split the two strings into separate parts
700  SplitString( strFWord, &strFWordBeg, &strFWordMid, &strFWordEnd );
701  SplitString( strSWord, &strSWordBeg, &strSWordMid, &strSWordEnd );
702 
703  // Compare the Beginning section of the strings
704  int isEqual = strFWordBeg.CmpNoCase( strSWordBeg );
705 
706  if( isEqual > 0 )
707  return 1;
708  else if( isEqual < 0 )
709  return -1;
710  else
711  {
712  // If the first sections are equal compare their digits
713  double lFirstNumber = 0;
714  double lSecondNumber = 0;
715  bool endingIsModifier = false;
716 
717  strFWordMid.ToDouble( &lFirstNumber );
718  strSWordMid.ToDouble( &lSecondNumber );
719 
720  endingIsModifier |= ApplyModifier( lFirstNumber, strFWordEnd );
721  endingIsModifier |= ApplyModifier( lSecondNumber, strSWordEnd );
722 
723  if( lFirstNumber > lSecondNumber )
724  return 1;
725  else if( lFirstNumber < lSecondNumber )
726  return -1;
727  // If the first two sections are equal and the endings are modifiers then compare them
728  else if( !endingIsModifier )
729  return strFWordEnd.CmpNoCase( strSWordEnd );
730  // Ran out of things to compare; they must match
731  else
732  return 0;
733  }
734 }
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.
Definition: string.cpp:737
wxString UnescapeString(const wxString &aSource)
Definition: string.cpp:208
bool ApplyModifier(double &value, const wxString &aString)
Definition: string.cpp:641

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

582 {
583  const wxChar* cp = NULL, * mp = NULL;
584  const wxChar* wild, * str;
585  wxString _pattern, _string_to_tst;
586 
587  if( case_sensitive )
588  {
589  wild = pattern.GetData();
590  str = string_to_tst.GetData();
591  }
592  else
593  {
594  _pattern = pattern;
595  _pattern.MakeUpper();
596  _string_to_tst = string_to_tst;
597  _string_to_tst.MakeUpper();
598  wild = _pattern.GetData();
599  str = _string_to_tst.GetData();
600  }
601 
602  while( ( *str ) && ( *wild != '*' ) )
603  {
604  if( ( *wild != *str ) && ( *wild != '?' ) )
605  return false;
606 
607  wild++;
608  str++;
609  }
610 
611  while( *str )
612  {
613  if( *wild == '*' )
614  {
615  if( !*++wild )
616  return 1;
617  mp = wild;
618  cp = str + 1;
619  }
620  else if( ( *wild == *str ) || ( *wild == '?' ) )
621  {
622  wild++;
623  str++;
624  }
625  else
626  {
627  wild = mp;
628  str = cp++;
629  }
630  }
631 
632  while( *wild == '*' )
633  {
634  wild++;
635  }
636 
637  return !*wild;
638 }
#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 889 of file string.cpp.

890 {
891  wxString tmp;
892 
893  for( unsigned ii = 0; ii < aText.Length(); ii++ )
894  {
895  if( aText[ii] == aSplitter )
896  {
897  aStrings.Add( tmp );
898  tmp.Clear();
899  }
900 
901  else
902  tmp << aText[ii];
903  }
904 
905  if( !tmp.IsEmpty() )
906  {
907  aStrings.Add( tmp );
908  }
909 }

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