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.

368 lines
12 KiB

3 years ago
  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2004-2021 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. #ifndef STRING_UTILS_H
  24. #define STRING_UTILS_H
  25. #include "config.h"
  26. #include <string>
  27. #include <vector>
  28. #include <wx/string.h>
  29. #include <wx/filename.h>
  30. void ConvertMarkdown2Html( const wxString& aMarkdownInput, wxString& aHtmlOutput );
  31. /**
  32. * Convert the old `~...~` overbar notation to the new `~{...}` one.
  33. */
  34. wxString ConvertToNewOverbarNotation( const wxString& aOldStr );
  35. /**
  36. * Convert curly quotes and em/en dashes to straight quotes and dashes.
  37. *
  38. * @return true if any characters required conversion.
  39. */
  40. bool ConvertSmartQuotesAndDashes( wxString* aString );
  41. /**
  42. * Escape/Unescape routines to safely encode reserved-characters in various contexts.
  43. */
  44. enum ESCAPE_CONTEXT
  45. {
  46. CTX_NETNAME,
  47. CTX_LIBID,
  48. CTX_IPC,
  49. CTX_QUOTED_STR,
  50. CTX_JS_STR,
  51. CTX_LINE,
  52. CTX_CSV,
  53. CTX_FILENAME,
  54. CTX_NO_SPACE // to replace spaces in names that do not accept spaces
  55. };
  56. /**
  57. * The Escape/Unescape routines use HTML-entity-reference-style encoding to handle
  58. * characters which are:
  59. * (a) not legal in filenames
  60. * (b) used as control characters in LIB_IDs
  61. * (c) used to delineate hierarchical paths
  62. */
  63. wxString EscapeString( const wxString& aSource, ESCAPE_CONTEXT aContext );
  64. wxString UnescapeString( const wxString& aSource );
  65. /**
  66. * Remove markup (such as overbar or subscript) that we can't render to menu items.
  67. */
  68. wxString PrettyPrintForMenu( const wxString& aString );
  69. /**
  70. * Capitalize the first letter in each word.
  71. */
  72. wxString TitleCaps( const wxString& aString );
  73. /**
  74. * Copy bytes from @a aSource delimited string segment to @a aDest buffer.
  75. *
  76. * The extracted string will be null terminated even if truncation is necessary
  77. * because aDestSize was not large enough.
  78. *
  79. * @param aDest is the destination byte buffer.
  80. * @param aSource is the source bytes as a C string.
  81. * @param aDestSize is the size of the destination byte buffer.
  82. * @return the number of bytes read from source, which may be more than the number copied,
  83. * due to escaping of double quotes and the escape byte itself.
  84. * @deprecated should use the one which fetches a wxString, below.
  85. */
  86. int ReadDelimitedText( char* aDest, const char* aSource, int aDestSize );
  87. /**
  88. * Copy bytes from @a aSource delimited string segment to @a aDest wxString.
  89. *
  90. * @param aDest is the destination wxString.
  91. * @param aSource is the source C string holding utf8 encoded bytes.
  92. * @return the number of bytes read from source, which may be more than the number copied,
  93. * due to escaping of double quotes and the escape byte itself.
  94. */
  95. int ReadDelimitedText( wxString* aDest, const char* aSource );
  96. /**
  97. * Return an 8 bit UTF8 string given aString in Unicode form.
  98. *
  99. * Any double quoted or back slashes are prefixed with a '\\' byte and the form
  100. * of this UTF8 byte string is compatible with function ReadDelimitedText().
  101. *
  102. * @param aString is the input string to convert.
  103. * @return the escaped input text, without the wrapping double quotes.
  104. */
  105. std::string EscapedUTF8( const wxString& aString );
  106. /**
  107. * Return a new wxString escaped for embedding in HTML.
  108. */
  109. wxString EscapeHTML( const wxString& aString );
  110. /**
  111. * Read one line line from \a aFile.
  112. *
  113. * @return a pointer the first useful line read by eliminating blank lines and comments.
  114. */
  115. char* GetLine( FILE* aFile, char* Line, int* LineNum = nullptr, int SizeLine = 255 );
  116. /**
  117. * Return true if the string is empty or contains only whitespace.
  118. */
  119. bool NoPrintableChars( const wxString& aString );
  120. /**
  121. * Return the number of printable (ie: non-formatting) chars. Used to approximate rendered
  122. * text size when speed is more important than accuracy.
  123. */
  124. int PrintableCharCount( const wxString& aString );
  125. /**
  126. * Remove leading and training spaces, tabs and end of line chars in \a text
  127. *
  128. * @return a pointer on the first n char in text
  129. */
  130. char* StrPurge( char* text );
  131. /**
  132. * @return a string giving the current date and time.
  133. */
  134. wxString DateAndTime();
  135. /**
  136. * Compare two strings with alphanumerical content.
  137. *
  138. * This function is equivalent to strncmp() or strncasecmp() if \a aIgnoreCase is true
  139. * except that strings containing numbers are compared by their integer value not
  140. * by their ASCII code. In other words U10 would be greater than U2.
  141. *
  142. * @param aString1 A wxString reference to the reference string.
  143. * @param aString2 A wxString reference to the comparison string.
  144. * @param aIgnoreCase Use true to make the comparison case insensitive.
  145. * @return An integer value of -1 if \a aString1 is less than \a aString2, 0 if
  146. * \a aString1 is equal to \a aString2, or 1 if \a aString1 is greater
  147. * than \a aString2.
  148. */
  149. int StrNumCmp( const wxString& aString1, const wxString& aString2, bool aIgnoreCase = false );
  150. /**
  151. * Compare a string against wild card (* and ?) pattern using the usual rules.
  152. *
  153. * @return true if pattern matched otherwise false.
  154. */
  155. bool WildCompareString( const wxString& pattern,
  156. const wxString& string_to_tst,
  157. bool case_sensitive = true );
  158. /**
  159. * Compare strings like the strcmp function but handle numbers and modifiers within the
  160. * string text correctly for sorting. eg. 1mF > 55uF
  161. *
  162. * @return -1 if first string is less than the second, 0 if the strings are equal, or
  163. * 1 if the first string is greater than the second.
  164. */
  165. int ValueStringCompare( const wxString& strFWord, const wxString& strSWord );
  166. /**
  167. * Break a string into three parts: he alphabetic preamble, the numeric part, and any
  168. * alphabetic ending.
  169. *
  170. * For example C10A is split to C 10 A
  171. */
  172. int SplitString( const wxString& strToSplit,
  173. wxString* strBeginning,
  174. wxString* strDigits,
  175. wxString* strEnd );
  176. /**
  177. * Gets the trailing int, if any, from a string.
  178. *
  179. * @param aStr the string to check.
  180. * @return the trailing int or 0 if none found.
  181. */
  182. int GetTrailingInt( const wxString& aStr );
  183. /**
  184. * @return a wxString object containing the illegal file name characters for all platforms.
  185. */
  186. wxString GetIllegalFileNameWxChars();
  187. /**
  188. * Checks \a aName for illegal file name characters.
  189. *
  190. * The Windows (DOS) file system forbidden characters already include the forbidden file
  191. * name characters for both Posix and OSX systems. The characters \/?*|"\<\> are illegal
  192. * and are replaced with %xx where xx the hexadecimal equivalent of the replaced character.
  193. * This replacement may not be as elegant as using an underscore ('_') or hyphen ('-') but
  194. * it guarantees that there will be no naming conflicts when fixing footprint library names.
  195. * however, if aReplaceChar is given, it will replace the illegal chars
  196. *
  197. * @param aName is a point to a std::string object containing the footprint name to verify.
  198. * @param aReplaceChar (if not 0) is the replacement char.
  199. * @return true if any characters have been replaced in \a aName.
  200. */
  201. bool ReplaceIllegalFileNameChars( std::string* aName, int aReplaceChar = 0 );
  202. bool ReplaceIllegalFileNameChars( wxString& aName, int aReplaceChar = 0 );
  203. #ifndef HAVE_STRTOKR
  204. // common/strtok_r.c optionally:
  205. extern "C" char* strtok_r( char* str, const char* delim, char** nextp );
  206. #endif
  207. /**
  208. * A helper for sorting strings from the rear.
  209. *
  210. * Useful for things like 3D model names where they tend to be largely repetitious at the front.
  211. */
  212. struct rsort_wxString
  213. {
  214. bool operator() ( const wxString& strA, const wxString& strB ) const
  215. {
  216. wxString::const_reverse_iterator sA = strA.rbegin();
  217. wxString::const_reverse_iterator eA = strA.rend();
  218. wxString::const_reverse_iterator sB = strB.rbegin();
  219. wxString::const_reverse_iterator eB = strB.rend();
  220. if( strA.empty() )
  221. {
  222. if( strB.empty() )
  223. return false;
  224. // note: this rule implies that a null string is first in the sort order
  225. return true;
  226. }
  227. if( strB.empty() )
  228. return false;
  229. while( sA != eA && sB != eB )
  230. {
  231. if( ( *sA ) == ( *sB ) )
  232. {
  233. ++sA;
  234. ++sB;
  235. continue;
  236. }
  237. if( ( *sA ) < ( *sB ) )
  238. return true;
  239. else
  240. return false;
  241. }
  242. if( sB == eB )
  243. return false;
  244. return true;
  245. }
  246. };
  247. /**
  248. * Split the input string into a vector of output strings
  249. *
  250. * @note Multiple delimiters are considered to be separate records with empty strings
  251. *
  252. * @param aStr Input string with 0 or more delimiters.
  253. * @param aDelim The string of delimiter. Multiple characters here denote alternate delimiters.
  254. * @return a vector of strings
  255. */
  256. static inline std::vector<std::string> split( const std::string& aStr, const std::string& aDelim )
  257. {
  258. size_t pos = 0;
  259. size_t last_pos = 0;
  260. size_t len;
  261. std::vector<std::string> tokens;
  262. while( pos < aStr.size() )
  263. {
  264. pos = aStr.find_first_of( aDelim, last_pos );
  265. if( pos == std::string::npos )
  266. pos = aStr.size();
  267. len = pos - last_pos;
  268. tokens.push_back( aStr.substr( last_pos, len ) );
  269. last_pos = pos + 1;
  270. }
  271. return tokens;
  272. }
  273. /// Utility to build comma separated lists in messages
  274. inline void AccumulateDescription( wxString& aDesc, const wxString& aItem )
  275. {
  276. if( !aDesc.IsEmpty() )
  277. aDesc << wxT( ", " );
  278. aDesc << aItem;
  279. }
  280. /**
  281. * Split \a aString to a string list separated at \a aSplitter.
  282. *
  283. * @param aText is the text to split.
  284. * @param aStrings will contain the split lines.
  285. * @param aSplitter is the 'split' character.
  286. */
  287. void wxStringSplit( const wxString& aText, wxArrayString& aStrings, wxChar aSplitter );
  288. /**
  289. * Remove trailing zeros from a string containing a converted float number.
  290. *
  291. * The trailing zeros are removed if the mantissa has more than \a aTrailingZeroAllowed
  292. * digits and some trailing zeros.
  293. */
  294. void StripTrailingZeros( wxString& aStringValue, unsigned aTrailingZeroAllowed = 1 );
  295. /**
  296. * Print a float number without using scientific notation and no trailing 0
  297. * We want to avoid scientific notation in S-expr files (not easy to read)
  298. * for floating numbers.
  299. *
  300. * We cannot always just use the %g or the %f format to print a fp number
  301. * this helper function uses the %f format when needed, or %g when %f is
  302. * not well working and then removes trailing 0
  303. */
  304. std::string UIDouble2Str( double aValue );
  305. /**
  306. * Print a float number without using scientific notation and no trailing 0
  307. * This function is intended in uses to write to file, it ignores locale
  308. *
  309. * We cannot always just use the %g or the %f format to print a fp number
  310. * this helper function uses the %f format when needed, or %g when %f is
  311. * not well working and then removes trailing 0
  312. */
  313. std::string FormatDouble2Str( double aValue );
  314. #endif // STRING_UTILS_H