2013-11-29 18:29:41 +00:00
|
|
|
/*
|
|
|
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
|
|
|
*
|
2021-06-08 14:09:24 +00:00
|
|
|
* Copyright (C) 2004-2021 KiCad Developers, see change_log.txt for contributors.
|
2013-11-29 18:29:41 +00:00
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, you may find one here:
|
|
|
|
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
|
|
|
* or you may search the http://www.gnu.org website for the version 2 license,
|
|
|
|
* or you may write to the Free Software Foundation, Inc.,
|
|
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
|
|
|
*/
|
|
|
|
|
2021-07-29 09:56:22 +00:00
|
|
|
#ifndef STRING_UTILS_H
|
|
|
|
#define STRING_UTILS_H
|
2009-01-19 19:08:42 +00:00
|
|
|
|
2016-11-02 14:46:45 +00:00
|
|
|
#include "config.h"
|
|
|
|
|
2020-07-18 19:23:41 +00:00
|
|
|
#include <string>
|
|
|
|
#include <vector>
|
2010-12-19 21:42:55 +00:00
|
|
|
#include <wx/string.h>
|
2013-11-29 18:29:41 +00:00
|
|
|
#include <wx/filename.h>
|
2009-01-19 19:08:42 +00:00
|
|
|
|
2011-02-27 05:43:19 +00:00
|
|
|
|
2021-08-03 00:11:11 +00:00
|
|
|
void ConvertMarkdown2Html( const wxString& aMarkdownInput, wxString& aHtmlOutput );
|
|
|
|
|
2021-06-11 17:06:13 +00:00
|
|
|
/**
|
|
|
|
* Convert the old `~...~` overbar notation to the new `~{...}` one.
|
|
|
|
*/
|
|
|
|
wxString ConvertToNewOverbarNotation( const wxString& aOldStr );
|
|
|
|
|
2020-08-10 17:15:44 +00:00
|
|
|
/**
|
2021-06-08 14:09:24 +00:00
|
|
|
* Convert curly quotes and em/en dashes to straight quotes and dashes.
|
2020-12-19 16:00:52 +00:00
|
|
|
*
|
2020-08-10 17:15:44 +00:00
|
|
|
* @return true if any characters required conversion.
|
|
|
|
*/
|
|
|
|
bool ConvertSmartQuotesAndDashes( wxString* aString );
|
|
|
|
|
2018-09-27 10:56:51 +00:00
|
|
|
/**
|
2020-12-19 16:00:52 +00:00
|
|
|
* Escape/Unescape routines to safely encode reserved-characters in various contexts.
|
2018-09-27 10:56:51 +00:00
|
|
|
*/
|
2018-10-19 11:28:34 +00:00
|
|
|
enum ESCAPE_CONTEXT
|
|
|
|
{
|
|
|
|
CTX_NETNAME,
|
|
|
|
CTX_LIBID,
|
|
|
|
CTX_QUOTED_STR,
|
2020-08-04 22:53:40 +00:00
|
|
|
CTX_LINE,
|
2021-08-23 15:59:36 +00:00
|
|
|
CTX_FILENAME,
|
|
|
|
CTX_NO_SPACE // to replace spaces in names that do not accept spaces
|
2018-10-19 11:28:34 +00:00
|
|
|
};
|
|
|
|
|
2021-06-08 14:09:24 +00:00
|
|
|
/**
|
|
|
|
* 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
|
|
|
|
*/
|
2018-10-19 11:28:34 +00:00
|
|
|
wxString EscapeString( const wxString& aSource, ESCAPE_CONTEXT aContext );
|
2018-09-27 10:56:51 +00:00
|
|
|
|
|
|
|
wxString UnescapeString( const wxString& aSource );
|
|
|
|
|
2020-05-13 15:26:53 +00:00
|
|
|
/**
|
|
|
|
* Remove markup (such as overbar or subscript) that we can't render to menu items.
|
|
|
|
*/
|
|
|
|
wxString PrettyPrintForMenu( const wxString& aString );
|
|
|
|
|
2021-03-20 00:01:37 +00:00
|
|
|
/**
|
|
|
|
* Capitalize the first letter in each word.
|
|
|
|
*/
|
|
|
|
wxString TitleCaps( const wxString& aString );
|
|
|
|
|
2011-02-27 05:43:19 +00:00
|
|
|
/**
|
2019-03-02 13:20:53 +00:00
|
|
|
* Copy bytes from @a aSource delimited string segment to @a aDest buffer.
|
|
|
|
*
|
2011-02-27 05:43:19 +00:00
|
|
|
* The extracted string will be null terminated even if truncation is necessary
|
|
|
|
* because aDestSize was not large enough.
|
|
|
|
*
|
|
|
|
* @param aDest is the destination byte buffer.
|
|
|
|
* @param aSource is the source bytes as a C string.
|
|
|
|
* @param aDestSize is the size of the destination byte buffer.
|
2020-12-19 16:00:52 +00:00
|
|
|
* @return 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.
|
2011-03-24 00:15:33 +00:00
|
|
|
* @deprecated should use the one which fetches a wxString, below.
|
2009-11-23 20:18:47 +00:00
|
|
|
*/
|
2011-11-08 16:37:25 +00:00
|
|
|
int ReadDelimitedText( char* aDest, const char* aSource, int aDestSize );
|
2011-02-27 05:43:19 +00:00
|
|
|
|
2011-03-24 00:15:33 +00:00
|
|
|
/**
|
2019-03-02 13:20:53 +00:00
|
|
|
* Copy bytes from @a aSource delimited string segment to @a aDest wxString.
|
2011-03-24 00:15:33 +00:00
|
|
|
*
|
2020-12-19 16:00:52 +00:00
|
|
|
* @param aDest is the destination wxString.
|
2011-03-24 00:15:33 +00:00
|
|
|
* @param aSource is the source C string holding utf8 encoded bytes.
|
2020-12-19 16:00:52 +00:00
|
|
|
* @return 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.
|
2011-03-24 00:15:33 +00:00
|
|
|
*/
|
|
|
|
int ReadDelimitedText( wxString* aDest, const char* aSource );
|
2011-02-27 05:43:19 +00:00
|
|
|
|
|
|
|
/**
|
2020-12-19 16:00:52 +00:00
|
|
|
* Return an 8 bit UTF8 string given aString in Unicode form.
|
|
|
|
*
|
2011-02-27 05:43:19 +00:00
|
|
|
* Any double quoted or back slashes are prefixed with a '\\' byte and the form
|
|
|
|
* of this UTF8 byte string is compatible with function ReadDelimitedText().
|
|
|
|
*
|
|
|
|
* @param aString is the input string to convert.
|
2020-12-19 16:00:52 +00:00
|
|
|
* @return the escaped input text, without the wrapping double quotes.
|
2011-02-27 05:43:19 +00:00
|
|
|
*/
|
2021-06-08 14:09:24 +00:00
|
|
|
std::string EscapedUTF8( const wxString& aString );
|
2011-02-27 05:43:19 +00:00
|
|
|
|
2017-02-05 19:18:29 +00:00
|
|
|
/**
|
|
|
|
* Return a new wxString escaped for embedding in HTML.
|
|
|
|
*/
|
2020-11-30 12:14:22 +00:00
|
|
|
wxString EscapeHTML( const wxString& aString );
|
2017-02-05 19:18:29 +00:00
|
|
|
|
2011-11-08 16:37:25 +00:00
|
|
|
/**
|
2019-03-02 13:20:53 +00:00
|
|
|
* Read one line line from \a aFile.
|
|
|
|
*
|
|
|
|
* @return a pointer the first useful line read by eliminating blank lines and comments.
|
2009-11-23 20:18:47 +00:00
|
|
|
*/
|
2020-12-19 16:00:52 +00:00
|
|
|
char* GetLine( FILE* aFile, char* Line, int* LineNum = nullptr, int SizeLine = 255 );
|
2009-01-19 19:08:42 +00:00
|
|
|
|
2020-12-01 14:58:33 +00:00
|
|
|
/**
|
|
|
|
* Return true if the string is empty or contains only whitespace.
|
|
|
|
*/
|
2021-06-08 14:09:24 +00:00
|
|
|
bool NoPrintableChars( const wxString& aString );
|
2020-12-01 14:58:33 +00:00
|
|
|
|
2021-09-04 21:08:52 +00:00
|
|
|
/**
|
|
|
|
* Return the number of printable (ie: non-formatting) chars. Used to approximate rendered
|
|
|
|
* text size when speed is more important than accuracy.
|
|
|
|
*/
|
|
|
|
int PrintableCharCount( const wxString& aString );
|
|
|
|
|
2011-11-08 16:37:25 +00:00
|
|
|
/**
|
2019-03-02 13:20:53 +00:00
|
|
|
* Remove leading and training spaces, tabs and end of line chars in \a text
|
|
|
|
*
|
|
|
|
* @return a pointer on the first n char in text
|
2009-11-23 20:18:47 +00:00
|
|
|
*/
|
2011-11-08 16:37:25 +00:00
|
|
|
char* StrPurge( char* text );
|
2009-01-19 19:08:42 +00:00
|
|
|
|
2011-11-08 16:37:25 +00:00
|
|
|
/**
|
|
|
|
* @return a string giving the current date and time.
|
|
|
|
*/
|
2009-11-23 20:18:47 +00:00
|
|
|
wxString DateAndTime();
|
2009-01-19 19:08:42 +00:00
|
|
|
|
2011-11-08 16:37:25 +00:00
|
|
|
/**
|
2019-03-02 13:20:53 +00:00
|
|
|
* Compare two strings with alphanumerical content.
|
2011-11-08 16:37:25 +00:00
|
|
|
*
|
2016-08-16 08:27:09 +00:00
|
|
|
* This function is equivalent to strncmp() or strncasecmp() if \a aIgnoreCase is true
|
2011-11-08 16:37:25 +00:00
|
|
|
* except that strings containing numbers are compared by their integer value not
|
2019-03-02 13:20:53 +00:00
|
|
|
* by their ASCII code. In other words U10 would be greater than U2.
|
2011-11-08 16:37:25 +00:00
|
|
|
*
|
2014-01-18 09:07:05 +00:00
|
|
|
* @param aString1 A wxString reference to the reference string.
|
|
|
|
* @param aString2 A wxString reference to the comparison string.
|
2011-11-08 16:37:25 +00:00
|
|
|
* @param aIgnoreCase Use true to make the comparison case insensitive.
|
|
|
|
* @return An integer value of -1 if \a aString1 is less than \a aString2, 0 if
|
|
|
|
* \a aString1 is equal to \a aString2, or 1 if \a aString1 is greater
|
|
|
|
* than \a aString2.
|
2009-11-23 20:18:47 +00:00
|
|
|
*/
|
2019-03-02 13:20:53 +00:00
|
|
|
int StrNumCmp( const wxString& aString1, const wxString& aString2, bool aIgnoreCase = false );
|
2009-01-19 19:08:42 +00:00
|
|
|
|
2011-11-08 16:37:25 +00:00
|
|
|
/**
|
2019-03-02 13:20:53 +00:00
|
|
|
* Compare a string against wild card (* and ?) pattern using the usual rules.
|
|
|
|
*
|
2011-11-08 16:37:25 +00:00
|
|
|
* @return true if pattern matched otherwise false.
|
2009-11-23 20:18:47 +00:00
|
|
|
*/
|
2011-11-08 16:37:25 +00:00
|
|
|
bool WildCompareString( const wxString& pattern,
|
|
|
|
const wxString& string_to_tst,
|
|
|
|
bool case_sensitive = true );
|
2009-01-19 19:08:42 +00:00
|
|
|
|
2018-04-17 10:34:48 +00:00
|
|
|
/**
|
2019-03-02 13:20:53 +00:00
|
|
|
* Compare strings like the strcmp function but handle numbers and modifiers within the
|
2018-04-17 10:34:48 +00:00
|
|
|
* string text correctly for sorting. eg. 1mF > 55uF
|
2019-03-02 13:20:53 +00:00
|
|
|
*
|
|
|
|
* @return -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.
|
2018-04-17 10:34:48 +00:00
|
|
|
*/
|
2021-07-27 12:22:27 +00:00
|
|
|
int ValueStringCompare( const wxString& strFWord, const wxString& strSWord );
|
2018-04-17 10:34:48 +00:00
|
|
|
|
2010-08-03 02:13:33 +00:00
|
|
|
/**
|
2021-06-08 14:09:24 +00:00
|
|
|
* Break a string into three parts: he alphabetic preamble, the numeric part, and any
|
2019-03-02 13:20:53 +00:00
|
|
|
* alphabetic ending.
|
|
|
|
*
|
2010-08-03 02:13:33 +00:00
|
|
|
* For example C10A is split to C 10 A
|
|
|
|
*/
|
2021-06-08 14:09:24 +00:00
|
|
|
int SplitString( const wxString& strToSplit,
|
2010-08-03 02:13:33 +00:00
|
|
|
wxString* strBeginning,
|
|
|
|
wxString* strDigits,
|
|
|
|
wxString* strEnd );
|
2009-01-19 19:08:42 +00:00
|
|
|
|
2019-01-29 10:15:44 +00:00
|
|
|
/**
|
|
|
|
* Gets the trailing int, if any, from a string.
|
2019-03-02 13:20:53 +00:00
|
|
|
*
|
2020-12-19 16:00:52 +00:00
|
|
|
* @param aStr the string to check.
|
|
|
|
* @return the trailing int or 0 if none found.
|
2019-01-29 10:15:44 +00:00
|
|
|
*/
|
|
|
|
int GetTrailingInt( const wxString& aStr );
|
|
|
|
|
2013-11-29 18:29:41 +00:00
|
|
|
/**
|
2019-03-02 13:20:53 +00:00
|
|
|
* @return a wxString object containing the illegal file name characters for all platforms.
|
2013-11-29 18:29:41 +00:00
|
|
|
*/
|
|
|
|
wxString GetIllegalFileNameWxChars();
|
|
|
|
|
|
|
|
/**
|
2019-03-02 13:20:53 +00:00
|
|
|
* Checks \a aName for illegal file name characters.
|
2013-11-29 18:29:41 +00:00
|
|
|
*
|
|
|
|
* 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
|
2019-03-02 13:20:53 +00:00
|
|
|
* it guarantees that there will be no naming conflicts when fixing footprint library names.
|
2015-08-23 12:35:49 +00:00
|
|
|
* however, if aReplaceChar is given, it will replace the illegal chars
|
2013-11-29 18:29:41 +00:00
|
|
|
*
|
|
|
|
* @param aName is a point to a std::string object containing the footprint name to verify.
|
2015-08-23 12:35:49 +00:00
|
|
|
* @param aReplaceChar (if not 0) is the replacement char.
|
2013-11-29 18:29:41 +00:00
|
|
|
* @return true if any characters have been replaced in \a aName.
|
|
|
|
*/
|
2015-08-23 12:35:49 +00:00
|
|
|
bool ReplaceIllegalFileNameChars( std::string* aName, int aReplaceChar = 0 );
|
2018-03-06 09:11:54 +00:00
|
|
|
bool ReplaceIllegalFileNameChars( wxString& aName, int aReplaceChar = 0 );
|
2013-11-29 18:29:41 +00:00
|
|
|
|
2013-12-10 23:41:34 +00:00
|
|
|
#ifndef HAVE_STRTOKR
|
|
|
|
// common/strtok_r.c optionally:
|
|
|
|
extern "C" char* strtok_r( char* str, const char* delim, char** nextp );
|
|
|
|
#endif
|
|
|
|
|
2020-07-18 19:23:41 +00:00
|
|
|
|
2018-03-07 13:05:12 +00:00
|
|
|
/**
|
2020-12-19 16:00:52 +00:00
|
|
|
* A helper for sorting strings from the rear.
|
|
|
|
*
|
|
|
|
* Useful for things like 3D model names where they tend to be largely repetitious at the front.
|
2018-03-07 13:05:12 +00:00
|
|
|
*/
|
|
|
|
struct rsort_wxString
|
|
|
|
{
|
2021-06-08 14:09:24 +00:00
|
|
|
bool operator() ( const wxString& strA, const wxString& strB ) const
|
2018-03-07 13:05:12 +00:00
|
|
|
{
|
|
|
|
wxString::const_reverse_iterator sA = strA.rbegin();
|
|
|
|
wxString::const_reverse_iterator eA = strA.rend();
|
|
|
|
|
|
|
|
wxString::const_reverse_iterator sB = strB.rbegin();
|
|
|
|
wxString::const_reverse_iterator eB = strB.rend();
|
|
|
|
|
|
|
|
if( strA.empty() )
|
|
|
|
{
|
|
|
|
if( strB.empty() )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
// note: this rule implies that a null string is first in the sort order
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( strB.empty() )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
while( sA != eA && sB != eB )
|
|
|
|
{
|
2021-06-08 14:09:24 +00:00
|
|
|
if( ( *sA ) == ( *sB ) )
|
2018-03-07 13:05:12 +00:00
|
|
|
{
|
|
|
|
++sA;
|
|
|
|
++sB;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2021-06-08 14:09:24 +00:00
|
|
|
if( ( *sA ) < ( *sB ) )
|
2018-03-07 13:05:12 +00:00
|
|
|
return true;
|
|
|
|
else
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( sB == eB )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2020-07-18 19:23:41 +00:00
|
|
|
/**
|
2021-06-08 14:09:24 +00:00
|
|
|
* Split the input string into a vector of output strings
|
2020-07-18 19:23:41 +00:00
|
|
|
*
|
|
|
|
* @note Multiple delimiters are considered to be separate records with empty strings
|
2020-12-19 16:00:52 +00:00
|
|
|
*
|
|
|
|
* @param aStr Input string with 0 or more delimiters.
|
|
|
|
* @param aDelim The string of delimiter. Multiple characters here denote alternate delimiters.
|
2020-07-18 19:23:41 +00:00
|
|
|
* @return a vector of strings
|
|
|
|
*/
|
|
|
|
static inline std::vector<std::string> split( const std::string& aStr, const std::string& aDelim )
|
|
|
|
{
|
|
|
|
size_t pos = 0;
|
|
|
|
size_t last_pos = 0;
|
|
|
|
size_t len;
|
|
|
|
|
|
|
|
std::vector<std::string> tokens;
|
|
|
|
|
|
|
|
while( pos < aStr.size() )
|
|
|
|
{
|
|
|
|
pos = aStr.find_first_of( aDelim, last_pos );
|
|
|
|
|
|
|
|
if( pos == std::string::npos )
|
|
|
|
pos = aStr.size();
|
|
|
|
|
|
|
|
len = pos - last_pos;
|
|
|
|
|
|
|
|
tokens.push_back( aStr.substr( last_pos, len ) );
|
|
|
|
|
|
|
|
last_pos = pos + 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return tokens;
|
|
|
|
}
|
|
|
|
|
2020-10-15 02:13:01 +00:00
|
|
|
/// Utility to build comma separated lists in messages
|
|
|
|
inline void AccumulateDescription( wxString& aDesc, const wxString& aItem )
|
|
|
|
{
|
|
|
|
if( !aDesc.IsEmpty() )
|
|
|
|
aDesc << wxT( ", " );
|
|
|
|
|
|
|
|
aDesc << aItem;
|
|
|
|
}
|
|
|
|
|
2020-10-24 02:06:42 +00:00
|
|
|
/**
|
|
|
|
* Split \a aString to a string list separated at \a aSplitter.
|
|
|
|
*
|
2020-12-19 16:00:52 +00:00
|
|
|
* @param aText is the text to split.
|
|
|
|
* @param aStrings will contain the split lines.
|
|
|
|
* @param aSplitter is the 'split' character.
|
2020-10-24 02:06:42 +00:00
|
|
|
*/
|
|
|
|
void wxStringSplit( const wxString& aText, wxArrayString& aStrings, wxChar aSplitter );
|
|
|
|
|
2020-10-24 15:23:19 +00:00
|
|
|
/**
|
2020-12-19 16:00:52 +00:00
|
|
|
* Remove trailing zeros from a string containing a converted float number.
|
|
|
|
*
|
|
|
|
* The trailing zeros are removed if the mantissa has more than \a aTrailingZeroAllowed
|
|
|
|
* digits and some trailing zeros.
|
2020-10-24 15:23:19 +00:00
|
|
|
*/
|
|
|
|
void StripTrailingZeros( wxString& aStringValue, unsigned aTrailingZeroAllowed = 1 );
|
2020-10-24 02:06:42 +00:00
|
|
|
|
2021-04-15 03:20:36 +00:00
|
|
|
/**
|
2021-06-08 14:09:24 +00:00
|
|
|
* Print a float number without using scientific notation and no trailing 0
|
2021-04-15 03:20:36 +00:00
|
|
|
* We want to avoid scientific notation in S-expr files (not easy to read)
|
|
|
|
* for floating numbers.
|
2021-06-08 14:09:24 +00:00
|
|
|
*
|
|
|
|
* We cannot always just use the %g or the %f format to print a fp number
|
2021-04-15 03:20:36 +00:00
|
|
|
* this helper function uses the %f format when needed, or %g when %f is
|
|
|
|
* not well working and then removes trailing 0
|
|
|
|
*/
|
|
|
|
std::string Double2Str( double aValue );
|
|
|
|
|
|
|
|
/**
|
2021-06-08 14:09:24 +00:00
|
|
|
* A helper to convert the \a double \a aAngle (in internal unit) to a string in degrees.
|
2021-04-15 03:20:36 +00:00
|
|
|
*/
|
|
|
|
wxString AngleToStringDegrees( double aAngle );
|
|
|
|
|
2021-07-29 09:56:22 +00:00
|
|
|
#endif // STRING_UTILS_H
|