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.

456 lines
15 KiB

3 years ago
  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright The KiCad Developers, see AUTHORS.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 <string>
  26. #include <vector>
  27. #include <wx/string.h>
  28. #include <wx/filename.h>
  29. #include <kicommon.h>
  30. void ConvertMarkdown2Html( const wxString& aMarkdownInput, wxString& aHtmlOutput );
  31. /**
  32. * Convert the old `~...~` overbar notation to the new `~{...}` one.
  33. */
  34. KICOMMON_API 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. KICOMMON_API 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_LEGACY_LIBID,
  49. CTX_IPC,
  50. CTX_QUOTED_STR,
  51. CTX_JS_STR,
  52. CTX_LINE,
  53. CTX_CSV,
  54. CTX_FILENAME,
  55. CTX_NO_SPACE // to replace spaces in names that do not accept spaces
  56. };
  57. /**
  58. * The Escape/Unescape routines use HTML-entity-reference-style encoding to handle
  59. * characters which are:
  60. * (a) not legal in filenames
  61. * (b) used as control characters in LIB_IDs
  62. * (c) used to delineate hierarchical paths
  63. */
  64. KICOMMON_API wxString EscapeString( const wxString& aSource, ESCAPE_CONTEXT aContext );
  65. KICOMMON_API wxString UnescapeString( const wxString& aSource );
  66. /**
  67. * Remove markup (such as overbar or subscript) that we can't render to menu items.
  68. */
  69. KICOMMON_API wxString PrettyPrintForMenu( const wxString& aString );
  70. /**
  71. * Capitalize the first letter in each word.
  72. */
  73. KICOMMON_API wxString TitleCaps( const wxString& aString );
  74. /**
  75. * Capitalize only the first word.
  76. */
  77. KICOMMON_API wxString InitialCaps( const wxString& aString );
  78. /**
  79. * Copy bytes from @a aSource delimited string segment to @a aDest buffer.
  80. *
  81. * The extracted string will be null terminated even if truncation is necessary
  82. * because aDestSize was not large enough.
  83. *
  84. * @param aDest is the destination byte buffer.
  85. * @param aSource is the source bytes as a C string.
  86. * @param aDestSize is the size of the destination byte buffer.
  87. * @return the number of bytes read from source, which may be more than the number copied,
  88. * due to escaping of double quotes and the escape byte itself.
  89. * @deprecated should use the one which fetches a wxString, below.
  90. */
  91. KICOMMON_API int ReadDelimitedText( char* aDest, const char* aSource, int aDestSize );
  92. /**
  93. * Copy bytes from @a aSource delimited string segment to @a aDest wxString.
  94. *
  95. * @param aDest is the destination wxString.
  96. * @param aSource is the source C string holding utf8 encoded bytes.
  97. * @return the number of bytes read from source, which may be more than the number copied,
  98. * due to escaping of double quotes and the escape byte itself.
  99. */
  100. KICOMMON_API int ReadDelimitedText( wxString* aDest, const char* aSource );
  101. /**
  102. * Return an 8 bit UTF8 string given aString in Unicode form.
  103. *
  104. * Any double quoted or back slashes are prefixed with a '\\' byte and the form
  105. * of this UTF8 byte string is compatible with function ReadDelimitedText().
  106. *
  107. * @param aString is the input string to convert.
  108. * @return the escaped input text, without the wrapping double quotes.
  109. */
  110. KICOMMON_API std::string EscapedUTF8( const wxString& aString );
  111. /**
  112. * Return a new wxString escaped for embedding in HTML.
  113. */
  114. KICOMMON_API wxString EscapeHTML( const wxString& aString );
  115. /**
  116. * Return a new wxString unescaped from HTML format.
  117. */
  118. KICOMMON_API wxString UnescapeHTML( const wxString& aString );
  119. /**
  120. * Removes HTML tags from a string.
  121. *
  122. * Do not use for filtering potentially malicious inputs and rendering as HTML
  123. * without escaping.
  124. */
  125. KICOMMON_API wxString RemoveHTMLTags( const wxString& aInput );
  126. /**
  127. * Wraps links in HTML <a href=""></a> tags.
  128. */
  129. KICOMMON_API wxString LinkifyHTML( wxString aStr );
  130. /**
  131. * Performs a URL sniff-test on a string.
  132. */
  133. KICOMMON_API bool IsURL( wxString aStr );
  134. /**
  135. * Read one line line from \a aFile.
  136. *
  137. * @return a pointer the first useful line read by eliminating blank lines and comments.
  138. */
  139. KICOMMON_API char* GetLine( FILE* aFile, char* Line, int* LineNum = nullptr, int SizeLine = 255 );
  140. /**
  141. * Return true if the string is empty or contains only whitespace.
  142. */
  143. KICOMMON_API bool NoPrintableChars( const wxString& aString );
  144. /**
  145. * Return the number of printable (ie: non-formatting) chars. Used to approximate rendered
  146. * text size when speed is more important than accuracy.
  147. */
  148. KICOMMON_API int PrintableCharCount( const wxString& aString );
  149. /**
  150. * Remove leading and training spaces, tabs and end of line chars in \a text
  151. *
  152. * @return a pointer on the first n char in text
  153. */
  154. KICOMMON_API char* StrPurge( char* text );
  155. /**
  156. * @return a string giving the current date and time.
  157. */
  158. KICOMMON_API wxString GetISO8601CurrentDateTime();
  159. /**
  160. * Compare two strings with alphanumerical content.
  161. *
  162. * This function is equivalent to strncmp() or strncasecmp() if \a aIgnoreCase is true
  163. * except that strings containing numbers are compared by their integer value not
  164. * by their ASCII code. In other words U10 would be greater than U2.
  165. *
  166. * @param aString1 A wxString reference to the reference string.
  167. * @param aString2 A wxString reference to the comparison string.
  168. * @param aIgnoreCase Use true to make the comparison case insensitive.
  169. * @return An integer value of -1 if \a aString1 is less than \a aString2, 0 if
  170. * \a aString1 is equal to \a aString2, or 1 if \a aString1 is greater
  171. * than \a aString2.
  172. */
  173. KICOMMON_API int StrNumCmp( const wxString& aString1, const wxString& aString2,
  174. bool aIgnoreCase = false );
  175. /**
  176. * Compare a string against wild card (* and ?) pattern using the usual rules.
  177. *
  178. * @return true if pattern matched otherwise false.
  179. */
  180. KICOMMON_API bool WildCompareString( const wxString& pattern,
  181. const wxString& string_to_tst,
  182. bool case_sensitive = true );
  183. /**
  184. * Compare strings like the strcmp function but handle numbers and modifiers within the
  185. * string text correctly for sorting. eg. 1mF > 55uF
  186. *
  187. * @return -1 if first string is less than the second, 0 if the strings are equal, or
  188. * 1 if the first string is greater than the second.
  189. */
  190. KICOMMON_API int ValueStringCompare( const wxString& strFWord, const wxString& strSWord );
  191. /**
  192. * Break a string into three parts: he alphabetic preamble, the numeric part, and any
  193. * alphabetic ending.
  194. *
  195. * For example C10A is split to C 10 A
  196. */
  197. KICOMMON_API int SplitString( const wxString& strToSplit,
  198. wxString* strBeginning,
  199. wxString* strDigits,
  200. wxString* strEnd );
  201. /**
  202. * Gets the trailing int, if any, from a string.
  203. *
  204. * @param aStr the string to check.
  205. * @return the trailing int or 0 if none found.
  206. */
  207. KICOMMON_API int GetTrailingInt( const wxString& aStr );
  208. /**
  209. * @return a wxString object containing the illegal file name characters for all platforms.
  210. */
  211. KICOMMON_API wxString GetIllegalFileNameWxChars();
  212. /**
  213. * Checks if a full filename is valid, i.e. does not contains illegal chars
  214. * path separators are allowed
  215. * @return true if OK.
  216. */
  217. KICOMMON_API bool IsFullFileNameValid( const wxString& aFullFilename );
  218. /**
  219. * Checks \a aName for illegal file name characters.
  220. *
  221. * The Windows (DOS) file system forbidden characters already include the forbidden file
  222. * name characters for both Posix and OSX systems. The characters \/?*|"\<\> are illegal
  223. * and are replaced with %xx where xx the hexadecimal equivalent of the replaced character.
  224. * This replacement may not be as elegant as using an underscore ('_') or hyphen ('-') but
  225. * it guarantees that there will be no naming conflicts when fixing footprint library names.
  226. * however, if aReplaceChar is given, it will replace the illegal chars
  227. *
  228. * @param aName is a point to a std::string object containing the footprint name to verify.
  229. * @param aReplaceChar (if not 0) is the replacement char.
  230. * @return true if any characters have been replaced in \a aName.
  231. */
  232. KICOMMON_API bool ReplaceIllegalFileNameChars( std::string* aName, int aReplaceChar = 0 );
  233. KICOMMON_API bool ReplaceIllegalFileNameChars( wxString& aName, int aReplaceChar = 0 );
  234. /**
  235. * A helper for sorting strings from the rear.
  236. *
  237. * Useful for things like 3D model names where they tend to be largely repetitious at the front.
  238. */
  239. struct rsort_wxString
  240. {
  241. bool operator() ( const wxString& strA, const wxString& strB ) const
  242. {
  243. wxString::const_reverse_iterator sA = strA.rbegin();
  244. wxString::const_reverse_iterator eA = strA.rend();
  245. wxString::const_reverse_iterator sB = strB.rbegin();
  246. wxString::const_reverse_iterator eB = strB.rend();
  247. if( strA.empty() )
  248. {
  249. if( strB.empty() )
  250. return false;
  251. // note: this rule implies that a null string is first in the sort order
  252. return true;
  253. }
  254. if( strB.empty() )
  255. return false;
  256. while( sA != eA && sB != eB )
  257. {
  258. if( ( *sA ) == ( *sB ) )
  259. {
  260. ++sA;
  261. ++sB;
  262. continue;
  263. }
  264. if( ( *sA ) < ( *sB ) )
  265. return true;
  266. else
  267. return false;
  268. }
  269. if( sB == eB )
  270. return false;
  271. return true;
  272. }
  273. };
  274. /**
  275. * Split the input string into a vector of output strings
  276. *
  277. * @note Multiple delimiters are considered to be separate records with empty strings
  278. *
  279. * @param aStr Input string with 0 or more delimiters.
  280. * @param aDelim The string of delimiter. Multiple characters here denote alternate delimiters.
  281. * @return a vector of strings
  282. */
  283. static inline std::vector<std::string> split( const std::string& aStr, const std::string& aDelim )
  284. {
  285. size_t pos = 0;
  286. size_t last_pos = 0;
  287. size_t len;
  288. std::vector<std::string> tokens;
  289. while( pos < aStr.size() )
  290. {
  291. pos = aStr.find_first_of( aDelim, last_pos );
  292. if( pos == std::string::npos )
  293. pos = aStr.size();
  294. len = pos - last_pos;
  295. tokens.push_back( aStr.substr( last_pos, len ) );
  296. last_pos = pos + 1;
  297. }
  298. return tokens;
  299. }
  300. /// Utility to build comma separated lists in messages
  301. inline void AccumulateDescription( wxString& aDesc, const wxString& aItem )
  302. {
  303. if( !aDesc.IsEmpty() )
  304. aDesc << wxT( ", " );
  305. aDesc << aItem;
  306. }
  307. /**
  308. * Build a comma-separated list from a collection of wxStrings.
  309. * (e.g. std::vector, wxArrayString, etc).
  310. */
  311. template <typename T>
  312. inline void AccumulateDescriptions( wxString& aDesc, const T& aItemCollection )
  313. {
  314. for( const auto& item : aItemCollection )
  315. AccumulateDescription( aDesc, item );
  316. }
  317. template <typename T>
  318. inline wxString AccumulateDescriptions( const T& aItemCollection )
  319. {
  320. wxString desc;
  321. AccumulateDescriptions( desc, aItemCollection );
  322. return desc;
  323. }
  324. /**
  325. * Split \a aString to a string list separated at \a aSplitter.
  326. *
  327. * @param aText is the text to split.
  328. * @param aStrings will contain the split lines.
  329. * @param aSplitter is the 'split' character.
  330. */
  331. KICOMMON_API void wxStringSplit( const wxString& aText, wxArrayString& aStrings, wxChar aSplitter );
  332. /**
  333. * Remove trailing zeros from a string containing a converted float number.
  334. *
  335. * The trailing zeros are removed if the mantissa has more than \a aTrailingZeroAllowed
  336. * digits and some trailing zeros.
  337. */
  338. KICOMMON_API void StripTrailingZeros( wxString& aStringValue, unsigned aTrailingZeroAllowed = 1 );
  339. /**
  340. * Print a float number without using scientific notation and no trailing 0
  341. * We want to avoid scientific notation in S-expr files (not easy to read)
  342. * for floating numbers.
  343. *
  344. * We cannot always just use the %g or the %f format to print a fp number
  345. * this helper function uses the %f format when needed, or %g when %f is
  346. * not well working and then removes trailing 0
  347. */
  348. KICOMMON_API std::string UIDouble2Str( double aValue );
  349. /**
  350. * Print a float number without using scientific notation and no trailing 0
  351. * This function is intended in uses to write to file, it ignores locale
  352. *
  353. * We cannot always just use the %g or the %f format to print a fp number
  354. * this helper function uses the %f format when needed, or %g when %f is
  355. * not well working and then removes trailing 0
  356. */
  357. KICOMMON_API std::string FormatDouble2Str( double aValue );
  358. /**
  359. * Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
  360. *
  361. * wxstring is a wxString, not a wxT() or _(). The scope of the return value
  362. * is very limited and volatile, but can be used with printf() style functions well.
  363. *
  364. * @note Trying to convert it to a function is tricky because of the type of the
  365. * parameter!
  366. */
  367. #define TO_UTF8( wxstring ) ( (const char*) ( wxstring ).utf8_str() )
  368. /**
  369. * Convert an expected UTF8 encoded std::string to a wxString.
  370. * If fails, try to convert using current locale
  371. * If still fails, return the initial string (can be already a converted string)
  372. */
  373. KICOMMON_API wxString From_UTF8( const std::string& aString );
  374. KICOMMON_API wxString From_UTF8( const char* cstring );
  375. /**
  376. * Normalize file path \a aFileUri to URI convention.
  377. *
  378. * Unfortunately none of the wxWidgets objects results in acceptable file URIs which breaks
  379. * PDF plotting URI links. This is an attempt to normalize Windows local file paths to a
  380. * URI that PDF readers that can run JavaScript can handle.
  381. *
  382. * @note This does not expand environment or user variables. Variable expansion should be
  383. * performed before calling. If \a aFileUri does not begin with 'file://', \a aFileUri
  384. * returned unchanged.
  385. *
  386. * @param aFileUri is the string to be normalized.
  387. * @return the normalized string.
  388. */
  389. KICOMMON_API wxString NormalizeFileUri( const wxString& aFileUri );
  390. #endif // STRING_UTILS_H