You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

326 lines
10 KiB

  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2004-2020 KiCad Developers, see change_log.txt for contributors.
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public License
  8. * as published by the Free Software Foundation; either version 2
  9. * of the License, or (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, you may find one here:
  18. * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  19. * or you may search the http://www.gnu.org website for the version 2 license,
  20. * or you may write to the Free Software Foundation, Inc.,
  21. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  22. */
  23. /**
  24. * @file kicad_string.h
  25. * @see common.h, string.cpp
  26. */
  27. #ifndef KICAD_STRING_H_
  28. #define KICAD_STRING_H_
  29. #include "config.h"
  30. #include <string>
  31. #include <vector>
  32. #include <wx/string.h>
  33. #include <wx/filename.h>
  34. /**
  35. * Converts curly quotes and em/en dashes to straight quotes and dashes.
  36. *
  37. * @return true if any characters required conversion.
  38. */
  39. bool ConvertSmartQuotesAndDashes( wxString* aString );
  40. /**
  41. * Escape/Unescape routines to safely encode reserved-characters in various contexts.
  42. */
  43. enum ESCAPE_CONTEXT
  44. {
  45. CTX_NETNAME,
  46. CTX_LIBID,
  47. CTX_QUOTED_STR,
  48. CTX_LINE,
  49. CTX_FILENAME
  50. };
  51. wxString EscapeString( const wxString& aSource, ESCAPE_CONTEXT aContext );
  52. wxString UnescapeString( const wxString& aSource );
  53. /**
  54. * Remove markup (such as overbar or subscript) that we can't render to menu items.
  55. */
  56. wxString PrettyPrintForMenu( const wxString& aString );
  57. /**
  58. * Copy bytes from @a aSource delimited string segment to @a aDest buffer.
  59. *
  60. * The extracted string will be null terminated even if truncation is necessary
  61. * because aDestSize was not large enough.
  62. *
  63. * @param aDest is the destination byte buffer.
  64. * @param aSource is the source bytes as a C string.
  65. * @param aDestSize is the size of the destination byte buffer.
  66. * @return the number of bytes read from source, which may be more than the number copied,
  67. * due to escaping of double quotes and the escape byte itself.
  68. * @deprecated should use the one which fetches a wxString, below.
  69. */
  70. int ReadDelimitedText( char* aDest, const char* aSource, int aDestSize );
  71. /**
  72. * Copy bytes from @a aSource delimited string segment to @a aDest wxString.
  73. *
  74. * @param aDest is the destination wxString.
  75. * @param aSource is the source C string holding utf8 encoded bytes.
  76. * @return the number of bytes read from source, which may be more than the number copied,
  77. * due to escaping of double quotes and the escape byte itself.
  78. */
  79. int ReadDelimitedText( wxString* aDest, const char* aSource );
  80. /**
  81. * Return an 8 bit UTF8 string given aString in Unicode form.
  82. *
  83. * Any double quoted or back slashes are prefixed with a '\\' byte and the form
  84. * of this UTF8 byte string is compatible with function ReadDelimitedText().
  85. *
  86. * @param aString is the input string to convert.
  87. * @return the escaped input text, without the wrapping double quotes.
  88. */
  89. std::string EscapedUTF8( wxString aString );
  90. /**
  91. * Return a new wxString escaped for embedding in HTML.
  92. */
  93. wxString EscapeHTML( const wxString& aString );
  94. /**
  95. * Read one line line from \a aFile.
  96. *
  97. * @return a pointer the first useful line read by eliminating blank lines and comments.
  98. */
  99. char* GetLine( FILE* aFile, char* Line, int* LineNum = nullptr, int SizeLine = 255 );
  100. /**
  101. * Return true if the string is empty or contains only whitespace.
  102. */
  103. bool NoPrintableChars( wxString aString );
  104. /**
  105. * Remove leading and training spaces, tabs and end of line chars in \a text
  106. *
  107. * @return a pointer on the first n char in text
  108. */
  109. char* StrPurge( char* text );
  110. /**
  111. * @return a string giving the current date and time.
  112. */
  113. wxString DateAndTime();
  114. /**
  115. * Compare two strings with alphanumerical content.
  116. *
  117. * This function is equivalent to strncmp() or strncasecmp() if \a aIgnoreCase is true
  118. * except that strings containing numbers are compared by their integer value not
  119. * by their ASCII code. In other words U10 would be greater than U2.
  120. *
  121. * @param aString1 A wxString reference to the reference string.
  122. * @param aString2 A wxString reference to the comparison string.
  123. * @param aIgnoreCase Use true to make the comparison case insensitive.
  124. * @return An integer value of -1 if \a aString1 is less than \a aString2, 0 if
  125. * \a aString1 is equal to \a aString2, or 1 if \a aString1 is greater
  126. * than \a aString2.
  127. */
  128. int StrNumCmp( const wxString& aString1, const wxString& aString2, bool aIgnoreCase = false );
  129. /**
  130. * Compare a string against wild card (* and ?) pattern using the usual rules.
  131. *
  132. * @return true if pattern matched otherwise false.
  133. */
  134. bool WildCompareString( const wxString& pattern,
  135. const wxString& string_to_tst,
  136. bool case_sensitive = true );
  137. /**
  138. * Compare strings like the strcmp function but handle numbers and modifiers within the
  139. * string text correctly for sorting. eg. 1mF > 55uF
  140. *
  141. * @return -1 if first string is less than the second, 0 if the strings are equal, or
  142. * 1 if the first string is greater than the second.
  143. */
  144. int ValueStringCompare( wxString strFWord, wxString strSWord );
  145. /**
  146. * Breaks a string into three parts: he alphabetic preamble, the numeric part, and any
  147. * alphabetic ending.
  148. *
  149. * For example C10A is split to C 10 A
  150. */
  151. int SplitString( wxString strToSplit,
  152. wxString* strBeginning,
  153. wxString* strDigits,
  154. wxString* strEnd );
  155. /**
  156. * Gets the trailing int, if any, from a string.
  157. *
  158. * @param aStr the string to check.
  159. * @return the trailing int or 0 if none found.
  160. */
  161. int GetTrailingInt( const wxString& aStr );
  162. /**
  163. * @return a wxString object containing the illegal file name characters for all platforms.
  164. */
  165. wxString GetIllegalFileNameWxChars();
  166. /**
  167. * Checks \a aName for illegal file name characters.
  168. *
  169. * The Windows (DOS) file system forbidden characters already include the forbidden file
  170. * name characters for both Posix and OSX systems. The characters \/?*|"\<\> are illegal
  171. * and are replaced with %xx where xx the hexadecimal equivalent of the replaced character.
  172. * This replacement may not be as elegant as using an underscore ('_') or hyphen ('-') but
  173. * it guarantees that there will be no naming conflicts when fixing footprint library names.
  174. * however, if aReplaceChar is given, it will replace the illegal chars
  175. *
  176. * @param aName is a point to a std::string object containing the footprint name to verify.
  177. * @param aReplaceChar (if not 0) is the replacement char.
  178. * @return true if any characters have been replaced in \a aName.
  179. */
  180. bool ReplaceIllegalFileNameChars( std::string* aName, int aReplaceChar = 0 );
  181. bool ReplaceIllegalFileNameChars( wxString& aName, int aReplaceChar = 0 );
  182. #ifndef HAVE_STRTOKR
  183. // common/strtok_r.c optionally:
  184. extern "C" char* strtok_r( char* str, const char* delim, char** nextp );
  185. #endif
  186. /**
  187. * A helper for sorting strings from the rear.
  188. *
  189. * Useful for things like 3D model names where they tend to be largely repetitious at the front.
  190. */
  191. struct rsort_wxString
  192. {
  193. bool operator() (const wxString& strA, const wxString& strB ) const
  194. {
  195. wxString::const_reverse_iterator sA = strA.rbegin();
  196. wxString::const_reverse_iterator eA = strA.rend();
  197. wxString::const_reverse_iterator sB = strB.rbegin();
  198. wxString::const_reverse_iterator eB = strB.rend();
  199. if( strA.empty() )
  200. {
  201. if( strB.empty() )
  202. return false;
  203. // note: this rule implies that a null string is first in the sort order
  204. return true;
  205. }
  206. if( strB.empty() )
  207. return false;
  208. while( sA != eA && sB != eB )
  209. {
  210. if( (*sA) == (*sB) )
  211. {
  212. ++sA;
  213. ++sB;
  214. continue;
  215. }
  216. if( (*sA) < (*sB) )
  217. return true;
  218. else
  219. return false;
  220. }
  221. if( sB == eB )
  222. return false;
  223. return true;
  224. }
  225. };
  226. /**
  227. * Splits the input string into a vector of output strings
  228. *
  229. * @note Multiple delimiters are considered to be separate records with empty strings
  230. *
  231. * @param aStr Input string with 0 or more delimiters.
  232. * @param aDelim The string of delimiter. Multiple characters here denote alternate delimiters.
  233. * @return a vector of strings
  234. */
  235. static inline std::vector<std::string> split( const std::string& aStr, const std::string& aDelim )
  236. {
  237. size_t pos = 0;
  238. size_t last_pos = 0;
  239. size_t len;
  240. std::vector<std::string> tokens;
  241. while( pos < aStr.size() )
  242. {
  243. pos = aStr.find_first_of( aDelim, last_pos );
  244. if( pos == std::string::npos )
  245. pos = aStr.size();
  246. len = pos - last_pos;
  247. tokens.push_back( aStr.substr( last_pos, len ) );
  248. last_pos = pos + 1;
  249. }
  250. return tokens;
  251. }
  252. /// Utility to build comma separated lists in messages
  253. inline void AccumulateDescription( wxString& aDesc, const wxString& aItem )
  254. {
  255. if( !aDesc.IsEmpty() )
  256. aDesc << wxT( ", " );
  257. aDesc << aItem;
  258. }
  259. /**
  260. * Split \a aString to a string list separated at \a aSplitter.
  261. *
  262. * @param aText is the text to split.
  263. * @param aStrings will contain the split lines.
  264. * @param aSplitter is the 'split' character.
  265. */
  266. void wxStringSplit( const wxString& aText, wxArrayString& aStrings, wxChar aSplitter );
  267. /**
  268. * Remove trailing zeros from a string containing a converted float number.
  269. *
  270. * The trailing zeros are removed if the mantissa has more than \a aTrailingZeroAllowed
  271. * digits and some trailing zeros.
  272. */
  273. void StripTrailingZeros( wxString& aStringValue, unsigned aTrailingZeroAllowed = 1 );
  274. #endif // KICAD_STRING_H_