2017-01-23 06:19:43 +00:00
/*
internal_4coder_string . cpp - Base file for generating 4 coder_string . h
*/
2016-07-06 19:18:10 +00:00
# define FSTRING_DECLS
# define FSTRING_BEGIN
2016-11-02 03:27:51 +00:00
# define API_EXPORT_MACRO
# ifndef API_EXPORT
# define API_EXPORT
# endif
# ifndef API_EXPORT_INLINE
# define API_EXPORT_INLINE
# endif
2016-07-06 19:18:10 +00:00
2016-08-28 04:31:06 +00:00
# define CPP_NAME(n)
2016-07-06 19:18:10 +00:00
FSTRING_BEGIN
// TOP
2017-07-18 19:52:41 +00:00
# include "4tech_standard_preamble.h"
2016-07-06 19:18:10 +00:00
2017-01-23 06:19:43 +00:00
# if !defined(FSTRING_LINK)
2016-07-06 19:18:10 +00:00
# define FSTRING_LINK static
# endif
2017-01-23 06:19:43 +00:00
# if !defined(FSTRING_INLINE)
2019-01-31 13:06:42 +00:00
# define FSTRING_INLINE static
2016-07-06 19:18:10 +00:00
# endif
2017-01-23 06:19:43 +00:00
# if !defined(FSTRING_GUARD)
2018-12-10 01:31:30 +00:00
# define literal(s) (s), (sizeof(s) - 1)
2017-01-23 06:19:43 +00:00
2016-08-28 04:31:06 +00:00
typedef struct String {
2016-07-06 19:18:10 +00:00
char * str ;
2017-01-23 06:19:43 +00:00
i32_4tech size ;
i32_4tech memory_size ;
2016-08-28 04:31:06 +00:00
} String ;
2016-07-06 19:18:10 +00:00
2018-11-20 08:18:54 +00:00
static String null_string = { } ;
2016-07-06 19:18:10 +00:00
# endif
FSTRING_DECLS
//
// Character Helpers
//
2017-01-23 06:19:43 +00:00
API_EXPORT_INLINE FSTRING_INLINE b32_4tech
2016-07-12 22:17:45 +00:00
char_is_slash ( char c )
/* DOC(This call returns non-zero if c is \ or /.) */ {
2016-07-06 19:18:10 +00:00
return ( c = = ' \\ ' | | c = = ' / ' ) ;
}
2017-01-23 06:19:43 +00:00
API_EXPORT_INLINE FSTRING_INLINE b32_4tech
2016-09-08 22:03:43 +00:00
char_is_upper ( char c )
/* DOC(If c is an uppercase letter this call returns true.) */ {
return ( c > = ' A ' & & c < = ' Z ' ) ;
}
2017-03-27 22:36:42 +00:00
API_EXPORT_INLINE FSTRING_INLINE b32_4tech
char_is_upper_utf8 ( char c )
/* DOC(If c is an uppercase letter this call returns true.) */ {
2017-06-27 02:47:00 +00:00
return ( ( c > = ' A ' & & c < = ' Z ' ) | | ( unsigned char ) c > = 128 ) ;
2017-03-27 22:36:42 +00:00
}
2017-01-23 06:19:43 +00:00
API_EXPORT_INLINE FSTRING_INLINE b32_4tech
2016-09-08 22:03:43 +00:00
char_is_lower ( char c )
/* DOC(If c is a lower letter this call returns true.) */ {
return ( c > = ' a ' & & c < = ' z ' ) ;
}
2017-03-27 22:36:42 +00:00
API_EXPORT_INLINE FSTRING_INLINE b32_4tech
char_is_lower_utf8 ( u8_4tech c )
/* DOC(If c is a lower letter this call returns true.) */ {
2017-06-27 02:47:00 +00:00
return ( ( c > = ' a ' & & c < = ' z ' ) | | ( unsigned char ) c > = 128 ) ;
2017-03-27 22:36:42 +00:00
}
2016-11-02 03:27:51 +00:00
API_EXPORT_INLINE FSTRING_INLINE char
2016-07-12 22:17:45 +00:00
char_to_upper ( char c )
/* DOC(If c is a lowercase letter this call returns the uppercase equivalent, otherwise it returns c.) */ {
2016-07-06 19:18:10 +00:00
return ( c > = ' a ' & & c < = ' z ' ) ? c + ( char ) ( ' A ' - ' a ' ) : c ;
}
2016-11-02 03:27:51 +00:00
API_EXPORT_INLINE FSTRING_INLINE char
2016-07-12 22:17:45 +00:00
char_to_lower ( char c )
/* DOC(If c is an uppercase letter this call returns the lowercase equivalent, otherwise it returns c.) */ {
2016-07-06 19:18:10 +00:00
return ( c > = ' A ' & & c < = ' Z ' ) ? c - ( char ) ( ' A ' - ' a ' ) : c ;
}
2017-01-23 06:19:43 +00:00
API_EXPORT_INLINE FSTRING_INLINE b32_4tech
2016-07-12 22:17:45 +00:00
char_is_whitespace ( char c )
/* DOC(This call returns non-zero if c is whitespace.) */ {
2016-07-06 19:18:10 +00:00
return ( c = = ' ' | | c = = ' \n ' | | c = = ' \r ' | | c = = ' \t ' ) ;
}
2017-01-23 06:19:43 +00:00
API_EXPORT_INLINE FSTRING_INLINE b32_4tech
2016-07-12 22:17:45 +00:00
char_is_alpha_numeric ( char c )
/* DOC(This call returns non-zero if c is any alphanumeric character including underscore.) */ {
2017-06-27 02:47:00 +00:00
return ( ( c > = ' a ' & & c < = ' z ' ) | | ( c > = ' A ' & & c < = ' Z ' ) | | ( c > = ' 0 ' & & c < = ' 9 ' ) | | c = = ' _ ' ) ;
2016-07-06 19:18:10 +00:00
}
2017-03-27 22:36:42 +00:00
API_EXPORT_INLINE FSTRING_INLINE b32_4tech
char_is_alpha_numeric_utf8 ( u8_4tech c )
/* DOC(This call returns non-zero if c is any alphanumeric character including underscore, or is a part of a UTF8 sequence outside of ASCII.) */ {
2017-06-27 02:47:00 +00:00
return ( ( c > = ' a ' & & c < = ' z ' ) | | ( c > = ' A ' & & c < = ' Z ' ) | | ( c > = ' 0 ' & & c < = ' 9 ' ) | | c = = ' _ ' | | ( unsigned char ) c > = 128 ) ;
2017-03-27 22:36:42 +00:00
}
2017-01-23 06:19:43 +00:00
API_EXPORT_INLINE FSTRING_INLINE b32_4tech
2016-07-12 22:17:45 +00:00
char_is_alpha_numeric_true ( char c )
/* DOC(This call returns non-zero if c is any alphanumeric character no including underscore.) */ {
2017-06-27 02:47:00 +00:00
return ( ( c > = ' a ' & & c < = ' z ' ) | | ( c > = ' A ' & & c < = ' Z ' ) | | ( c > = ' 0 ' & & c < = ' 9 ' ) ) ;
2016-07-06 19:18:10 +00:00
}
2017-03-27 22:36:42 +00:00
API_EXPORT_INLINE FSTRING_INLINE b32_4tech
char_is_alpha_numeric_true_utf8 ( u8_4tech c )
/* DOC(This call returns non-zero if c is any alphanumeric character no including underscore.) */ {
2017-06-27 02:47:00 +00:00
return ( ( c > = ' a ' & & c < = ' z ' ) | | ( c > = ' A ' & & c < = ' Z ' ) | | ( c > = ' 0 ' & & c < = ' 9 ' ) | | ( unsigned char ) c > = 128 ) ;
2017-03-27 22:36:42 +00:00
}
2017-01-23 06:19:43 +00:00
API_EXPORT_INLINE FSTRING_INLINE b32_4tech
2016-07-12 22:17:45 +00:00
char_is_alpha ( char c )
/* DOC(This call returns non-zero if c is any alphabetic character including underscore.) */ {
2017-06-27 02:47:00 +00:00
return ( ( c > = ' a ' & & c < = ' z ' ) | | ( c > = ' A ' & & c < = ' Z ' ) | | c = = ' _ ' ) ;
2016-07-06 19:18:10 +00:00
}
2017-03-27 22:36:42 +00:00
API_EXPORT_INLINE FSTRING_INLINE b32_4tech
char_is_alpha_utf8 ( u8_4tech c )
/* DOC(This call returns non-zero if c is any alphabetic character including underscore, or is a part of a UTF8 sequence outside of ASCII.) */ {
2017-06-27 02:47:00 +00:00
return ( ( c > = ' a ' & & c < = ' z ' ) | | ( c > = ' A ' & & c < = ' Z ' ) | | c = = ' _ ' | | ( unsigned char ) c > = 128 ) ;
2017-03-27 22:36:42 +00:00
}
2017-01-23 06:19:43 +00:00
API_EXPORT_INLINE FSTRING_INLINE b32_4tech
2016-07-12 22:17:45 +00:00
char_is_alpha_true ( char c )
/* DOC(This call returns non-zero if c is any alphabetic character.) */ {
2017-06-27 02:47:00 +00:00
return ( ( c > = ' a ' & & c < = ' z ' ) | | ( c > = ' A ' & & c < = ' Z ' ) ) ;
2016-07-06 19:18:10 +00:00
}
2017-03-27 22:36:42 +00:00
API_EXPORT_INLINE FSTRING_INLINE b32_4tech
char_is_alpha_true_utf8 ( u8_4tech c )
/* DOC(This call returns non-zero if c is any alphabetic character, or is a part of a UTF8 sequence outside of ASCII.) */ {
2017-06-27 02:47:00 +00:00
return ( ( c > = ' a ' & & c < = ' z ' ) | | ( c > = ' A ' & & c < = ' Z ' ) | | ( unsigned char ) c > = 128 ) ;
2017-03-27 22:36:42 +00:00
}
2017-01-23 06:19:43 +00:00
API_EXPORT_INLINE FSTRING_INLINE b32_4tech
2016-07-12 22:17:45 +00:00
char_is_hex ( char c )
/* DOC(This call returns non-zero if c is any valid hexadecimal digit.) */ {
2017-06-27 02:47:00 +00:00
return ( ( c > = ' 0 ' & & c < = ' 9 ' ) | | ( c > = ' A ' & & c < = ' F ' ) | | ( c > = ' a ' & & c < = ' f ' ) ) ;
2016-07-06 19:18:10 +00:00
}
2017-03-27 22:36:42 +00:00
API_EXPORT_INLINE FSTRING_INLINE b32_4tech
char_is_hex_utf8 ( u8_4tech c )
/* DOC(This call returns non-zero if c is any valid hexadecimal digit, or is a part of a UTF8 sequence outside of ASCII.) */ {
2017-06-27 02:47:00 +00:00
return ( ( c > = ' 0 ' & & c < = ' 9 ' ) | | ( c > = ' A ' & & c < = ' F ' ) | | ( c > = ' a ' & & c < = ' f ' ) | | ( unsigned char ) c > = 128 ) ;
2017-03-27 22:36:42 +00:00
}
2017-01-23 06:19:43 +00:00
API_EXPORT_INLINE FSTRING_INLINE b32_4tech
2016-07-12 22:17:45 +00:00
char_is_numeric ( char c )
/* DOC(This call returns non-zero if c is any valid decimal digit.) */ {
return ( c > = ' 0 ' & & c < = ' 9 ' ) ;
2016-07-06 19:18:10 +00:00
}
2017-03-27 22:36:42 +00:00
API_EXPORT_INLINE FSTRING_INLINE b32_4tech
char_is_numeric_utf8 ( u8_4tech c )
/* DOC(This call returns non-zero if c is any valid decimal digit, or is a part of a UTF8 sequence outside of ASCII.) */ {
2017-06-27 02:47:00 +00:00
return ( ( c > = ' 0 ' & & c < = ' 9 ' ) | | ( unsigned char ) c > = 128 ) ;
2017-03-27 22:36:42 +00:00
}
2016-07-06 19:18:10 +00:00
//
// String Making Functions
//
2016-08-28 04:31:06 +00:00
CPP_NAME ( make_string )
2016-11-02 03:27:51 +00:00
API_EXPORT_INLINE FSTRING_INLINE String
2017-01-23 06:19:43 +00:00
make_string_cap ( void * str , i32_4tech size , i32_4tech mem_size ) /*
2016-07-12 22:17:45 +00:00
DOC_PARAM ( str , The str parameter provides the of memory with which the string shall operate . )
DOC_PARAM ( size , The size parameter expresses the initial size of the string .
If the memory does not already contain a useful string this should be zero . )
DOC_PARAM ( mem_size , The mem_size parameter expresses the full size of the memory provided by str . )
DOC ( This call returns the String created from the parameters . )
*/ {
2016-07-06 19:18:10 +00:00
String result ;
result . str = ( char * ) str ;
result . size = size ;
result . memory_size = mem_size ;
2016-09-03 05:03:03 +00:00
return ( result ) ;
2016-07-06 19:18:10 +00:00
}
2016-11-02 03:27:51 +00:00
API_EXPORT_INLINE FSTRING_INLINE String
2017-01-23 06:19:43 +00:00
make_string ( void * str , i32_4tech size ) /*
2016-07-12 22:17:45 +00:00
DOC_PARAM ( str , The str parameter provides the of memory with which the string shall operate . )
DOC_PARAM ( size , The size parameter expresses the initial size of the string .
If the memory does not already contain a useful string this should be zero . Since this version
does not specify the size of the memory it is also assumed that this size is the maximum size
of the memory . )
DOC ( This call returns the String created from the parameters . )
*/ {
2018-11-28 04:36:09 +00:00
return ( make_string ( str , size , size ) ) ;
2016-07-06 19:18:10 +00:00
}
2016-11-02 03:27:51 +00:00
API_EXPORT_MACRO
/* DOC(This macro takes a literal string in quotes and uses it to create a String with the correct size and memory size. Strings created this way should usually not be mutated.) */
2016-08-28 04:31:06 +00:00
# define make_lit_string(s) (make_string_cap((char*)(s), sizeof(s)-1, sizeof(s)))
2016-07-06 19:18:10 +00:00
2018-03-26 05:19:08 +00:00
API_EXPORT_MACRO
/* DOC(Rename for make_lit_string.) DOC_SEE(make_lit_string) */
# define lit(s) make_lit_string(s)
2016-11-02 03:27:51 +00:00
API_EXPORT_MACRO
/* DOC(This macro takes a local char array with a fixed width and uses it to create an empty String with the correct size and memory size to operate on the array.) */
2016-08-28 04:31:06 +00:00
# define make_fixed_width_string(s) (make_string_cap((char*)(s), 0, sizeof(s)))
2016-07-06 19:18:10 +00:00
2016-11-02 03:27:51 +00:00
API_EXPORT_MACRO
/* DOC(This macro is a helper for any calls that take a char*,integer pair to specify a string. This macro expands to both of those parameters from one String struct.) */
2016-07-06 19:18:10 +00:00
# define expand_str(s) ((s).str), ((s).size)
2017-01-23 06:19:43 +00:00
API_EXPORT FSTRING_LINK i32_4tech
2016-07-12 22:17:45 +00:00
str_size ( char * str )
/* DOC(This call returns the number of bytes before a null terminator starting at str.) */ {
2017-01-23 06:19:43 +00:00
i32_4tech i = 0 ;
2017-11-17 19:22:12 +00:00
if ( str ! = 0 ) {
for ( ; str [ i ] ; + + i ) ;
}
2016-09-03 05:03:03 +00:00
return ( i ) ;
2016-07-06 19:18:10 +00:00
}
2016-11-02 03:27:51 +00:00
API_EXPORT_INLINE FSTRING_INLINE String
2016-07-12 22:17:45 +00:00
make_string_slowly ( void * str )
2016-11-02 03:27:51 +00:00
/* DOC(This call makes a string by counting the number of bytes before a null terminator and treating that as the size and memory size of the string.) */ {
2016-07-06 19:18:10 +00:00
String result ;
result . str = ( char * ) str ;
result . size = str_size ( ( char * ) str ) ;
2017-11-17 19:22:12 +00:00
result . memory_size = result . size + 1 ;
2016-09-03 05:03:03 +00:00
return ( result ) ;
2016-07-06 19:18:10 +00:00
}
2016-08-28 04:31:06 +00:00
CPP_NAME ( substr )
2016-11-02 03:27:51 +00:00
API_EXPORT_INLINE FSTRING_INLINE String
2017-01-23 06:19:43 +00:00
substr_tail ( String str , i32_4tech start )
2016-07-12 22:17:45 +00:00
/* DOC(This call creates a substring of str that starts with an offset from str's base.
The new string uses the same underlying memory so both strings will see changes .
Usually strings created this way should only go through immutable calls . ) */ {
2016-07-06 19:18:10 +00:00
String result ;
result . str = str . str + start ;
result . size = str . size - start ;
result . memory_size = 0 ;
return ( result ) ;
}
2016-11-02 03:27:51 +00:00
API_EXPORT_INLINE FSTRING_INLINE String
2017-01-23 06:19:43 +00:00
substr ( String str , i32_4tech start , i32_4tech size )
2016-07-12 22:17:45 +00:00
/* DOC(This call creates a substring of str that starts with an offset from str's base,
and has a fixed size . The new string uses the same underlying memory so both strings
will see changes . Usually strings created this way should only go through immutable calls . ) */ {
2016-07-06 19:18:10 +00:00
String result ;
result . str = str . str + start ;
result . size = size ;
if ( start + size > str . size ) {
result . size = str . size - start ;
}
result . memory_size = 0 ;
return ( result ) ;
}
2016-11-02 03:27:51 +00:00
API_EXPORT FSTRING_LINK String
2016-07-12 22:17:45 +00:00
skip_whitespace ( String str )
/* DOC(This call creates a substring that starts with the first non-whitespace character of str.
Like other substr calls , the new string uses the underlying memory and so should usually be
considered immutable . ) DOC_SEE ( substr ) */ {
2018-11-20 08:18:54 +00:00
String result = { } ;
2017-01-23 06:19:43 +00:00
i32_4tech i = 0 ;
2016-07-06 19:18:10 +00:00
for ( ; i < str . size & & char_is_whitespace ( str . str [ i ] ) ; + + i ) ;
result = substr ( str , i , str . size - i ) ;
return ( result ) ;
}
2017-01-29 00:03:23 +00:00
CPP_NAME ( skip_whitespace )
API_EXPORT FSTRING_LINK String
skip_whitespace_measure ( String str , i32_4tech * skip_length )
/* DOC(This call creates a substring that starts with the first non-whitespace character of str.
Like other substr calls , the new string uses the underlying memory and so should usually be
considered immutable . ) DOC_SEE ( substr ) */ {
2018-11-20 08:18:54 +00:00
String result = { } ;
2017-01-29 00:03:23 +00:00
i32_4tech i = 0 ;
for ( ; i < str . size & & char_is_whitespace ( str . str [ i ] ) ; + + i ) ;
result = substr ( str , i , str . size - i ) ;
* skip_length = i ;
return ( result ) ;
}
2016-11-02 03:27:51 +00:00
API_EXPORT FSTRING_LINK String
2016-07-12 22:17:45 +00:00
chop_whitespace ( String str )
/* DOC(This call creates a substring that ends with the last non-whitespace character of str.
Like other substr calls , the new string uses the underlying memory and so should usually be
considered immutable . ) DOC_SEE ( substr ) */ {
2018-11-20 08:18:54 +00:00
String result = { } ;
2017-01-23 06:19:43 +00:00
i32_4tech i = str . size ;
2016-07-06 19:18:10 +00:00
for ( ; i > 0 & & char_is_whitespace ( str . str [ i - 1 ] ) ; - - i ) ;
result = substr ( str , 0 , i ) ;
return ( result ) ;
}
2016-11-02 03:27:51 +00:00
API_EXPORT FSTRING_LINK String
2016-07-12 22:17:45 +00:00
skip_chop_whitespace ( String str )
/* DOC(This call is equivalent to calling skip_whitespace and chop_whitespace together.)
DOC_SEE ( skip_whitespace ) DOC_SEE ( chop_whitespace ) */ {
2016-07-06 19:18:10 +00:00
str = skip_whitespace ( str ) ;
str = chop_whitespace ( str ) ;
return ( str ) ;
}
2017-01-29 00:03:23 +00:00
CPP_NAME ( skip_chop_whitespace )
API_EXPORT FSTRING_LINK String
skip_chop_whitespace_measure ( String str , i32_4tech * skip_length )
/* DOC(This call is equivalent to calling skip_whitespace and chop_whitespace together.)
DOC_SEE ( skip_whitespace ) DOC_SEE ( chop_whitespace ) */ {
str = skip_whitespace_measure ( str , skip_length ) ;
str = chop_whitespace ( str ) ;
return ( str ) ;
}
2016-11-02 03:27:51 +00:00
API_EXPORT_INLINE FSTRING_INLINE String
2016-07-12 22:17:45 +00:00
tailstr ( String str )
/* DOC(This call returns an empty String with underlying memory taken from
the portion of str ' s memory that is not used . ) */ {
String result ;
result . str = str . str + str . size ;
result . memory_size = str . memory_size - str . size ;
result . size = 0 ;
return ( result ) ;
}
2016-07-06 19:18:10 +00:00
//
// String Comparison
//
2016-08-28 04:31:06 +00:00
CPP_NAME ( match )
2017-01-23 06:19:43 +00:00
API_EXPORT FSTRING_LINK b32_4tech
2016-08-28 04:31:06 +00:00
match_cc ( char * a , char * b ) /* DOC(This call returns non-zero if a and b are equivalent.) */ {
2017-01-23 06:19:43 +00:00
for ( i32_4tech i = 0 ; ; + + i ) {
2016-07-06 19:18:10 +00:00
if ( a [ i ] ! = b [ i ] ) {
return 0 ;
}
if ( a [ i ] = = 0 ) {
return 1 ;
}
}
}
2016-08-28 04:31:06 +00:00
CPP_NAME ( match )
2017-01-23 06:19:43 +00:00
API_EXPORT FSTRING_LINK b32_4tech
2016-08-28 04:31:06 +00:00
match_sc ( String a , char * b ) /* DOC(This call returns non-zero if a and b are equivalent.) */ {
2017-01-23 06:19:43 +00:00
i32_4tech i = 0 ;
2016-07-06 19:18:10 +00:00
for ( ; i < a . size ; + + i ) {
if ( a . str [ i ] ! = b [ i ] ) {
return 0 ;
}
}
if ( b [ i ] ! = 0 ) {
return 0 ;
}
return 1 ;
}
2016-08-28 04:31:06 +00:00
CPP_NAME ( match )
2017-01-23 06:19:43 +00:00
API_EXPORT_INLINE FSTRING_INLINE b32_4tech
2016-08-28 04:31:06 +00:00
match_cs ( char * a , String b ) /* DOC(This call returns non-zero if a and b are equivalent.) */ {
return ( match_sc ( b , a ) ) ;
2016-07-06 19:18:10 +00:00
}
2016-08-28 04:31:06 +00:00
CPP_NAME ( match )
2017-01-23 06:19:43 +00:00
API_EXPORT FSTRING_LINK b32_4tech
2016-08-28 04:31:06 +00:00
match_ss ( String a , String b ) /* DOC(This call returns non-zero if a and b are equivalent.) */ {
2016-07-06 19:18:10 +00:00
if ( a . size ! = b . size ) {
return 0 ;
}
2017-01-23 06:19:43 +00:00
for ( i32_4tech i = 0 ; i < b . size ; + + i ) {
2016-07-06 19:18:10 +00:00
if ( a . str [ i ] ! = b . str [ i ] ) {
return 0 ;
}
}
return 1 ;
}
2016-08-28 04:31:06 +00:00
CPP_NAME ( match_part )
2017-01-23 06:19:43 +00:00
API_EXPORT FSTRING_LINK b32_4tech
match_part_ccl ( char * a , char * b , i32_4tech * len ) /*
2016-07-12 22:17:45 +00:00
DOC_PARAM ( len , If this call returns non - zero this parameter is used to output the length of b . )
DOC ( This call is similar to a match call , except that it is permitted for a to be longer than b .
In other words this call returns non - zero if b is a prefix of a . ) */ {
2017-07-17 18:12:28 +00:00
if ( a = = 0 ) {
a = " " ;
}
if ( b = = 0 ) {
b = " " ;
}
2017-01-23 06:19:43 +00:00
i32_4tech i ;
2016-07-06 19:18:10 +00:00
for ( i = 0 ; b [ i ] ! = 0 ; + + i ) {
if ( a [ i ] ! = b [ i ] ) {
2017-07-17 18:12:28 +00:00
return ( 0 ) ;
2016-07-06 19:18:10 +00:00
}
}
* len = i ;
2017-07-17 18:12:28 +00:00
return ( 1 ) ;
2016-07-06 19:18:10 +00:00
}
2016-08-28 04:31:06 +00:00
CPP_NAME ( match_part )
2017-01-23 06:19:43 +00:00
API_EXPORT FSTRING_LINK b32_4tech
match_part_scl ( String a , char * b , i32_4tech * len ) /*
2016-07-12 22:17:45 +00:00
DOC_PARAM ( len , If this call returns non - zero this parameter is used to output the length of b . )
DOC ( This call is similar to a match call , except that it is permitted for a to be longer than b .
In other words this call returns non - zero if b is a prefix of a . ) */ {
2017-07-17 18:12:28 +00:00
if ( b = = 0 ) {
b = " " ;
}
2017-01-23 06:19:43 +00:00
i32_4tech i ;
2016-07-06 19:18:10 +00:00
for ( i = 0 ; b [ i ] ! = 0 ; + + i ) {
2017-07-17 18:12:28 +00:00
if ( i = = a . size | | a . str [ i ] ! = b [ i ] ) {
return ( 0 ) ;
2016-07-06 19:18:10 +00:00
}
}
* len = i ;
2017-07-17 18:12:28 +00:00
return ( 1 ) ;
2016-07-06 19:18:10 +00:00
}
2016-08-28 04:31:06 +00:00
CPP_NAME ( match_part )
2017-01-23 06:19:43 +00:00
API_EXPORT_INLINE FSTRING_INLINE b32_4tech
2016-08-28 04:31:06 +00:00
match_part_cc ( char * a , char * b ) /*
2016-07-12 22:17:45 +00:00
DOC_PARAM ( len , If this call returns non - zero this parameter is used to output the length of b . )
DOC ( This call is similar to a match call , except that it is permitted for a to be longer than b .
In other words this call returns non - zero if b is a prefix of a . ) */ {
2017-01-23 06:19:43 +00:00
i32_4tech x ;
2016-08-28 04:31:06 +00:00
return match_part_ccl ( a , b , & x ) ;
2016-07-06 19:18:10 +00:00
}
2016-08-28 04:31:06 +00:00
CPP_NAME ( match_part )
2017-01-23 06:19:43 +00:00
API_EXPORT_INLINE FSTRING_INLINE b32_4tech
2016-08-28 04:31:06 +00:00
match_part_sc ( String a , char * b ) /*
2016-07-12 22:17:45 +00:00
DOC ( This call is similar to a match call , except that it is permitted for a to be longer than b .
In other words this call returns non - zero if b is a prefix of a . ) */ {
2017-01-23 06:19:43 +00:00
i32_4tech x ;
2016-08-28 04:31:06 +00:00
return match_part_scl ( a , b , & x ) ;
2016-07-06 19:18:10 +00:00
}
2016-08-28 04:31:06 +00:00
CPP_NAME ( match_part )
2017-01-23 06:19:43 +00:00
API_EXPORT FSTRING_LINK b32_4tech
2016-08-28 04:31:06 +00:00
match_part_cs ( char * a , String b ) /*
2016-07-12 22:17:45 +00:00
DOC ( This call is similar to a match call , except that it is permitted for a to be longer than b .
In other words this call returns non - zero if b is a prefix of a . ) */ {
2017-01-23 06:19:43 +00:00
for ( i32_4tech i = 0 ; i ! = b . size ; + + i ) {
2016-07-06 19:18:10 +00:00
if ( a [ i ] ! = b . str [ i ] ) {
return 0 ;
}
}
return 1 ;
}
2016-08-28 04:31:06 +00:00
CPP_NAME ( match_part )
2017-01-23 06:19:43 +00:00
API_EXPORT FSTRING_LINK b32_4tech
2016-08-28 04:31:06 +00:00
match_part_ss ( String a , String b ) /*
2016-07-12 22:17:45 +00:00
DOC ( This call is similar to a match call , except that it is permitted for a to be longer than b .
In other words this call returns non - zero if b is a prefix of a . ) */ {
2016-07-06 19:18:10 +00:00
if ( a . size < b . size ) {
2017-07-17 18:12:28 +00:00
return ( 0 ) ;
2016-07-06 19:18:10 +00:00
}
2017-01-23 06:19:43 +00:00
for ( i32_4tech i = 0 ; i < b . size ; + + i ) {
2016-07-06 19:18:10 +00:00
if ( a . str [ i ] ! = b . str [ i ] ) {
2017-07-17 18:12:28 +00:00
return ( 0 ) ;
2016-07-06 19:18:10 +00:00
}
}
2017-07-17 18:12:28 +00:00
return ( 1 ) ;
2016-07-06 19:18:10 +00:00
}
2016-08-28 04:31:06 +00:00
CPP_NAME ( match_insensitive )
2017-01-23 06:19:43 +00:00
API_EXPORT FSTRING_LINK b32_4tech
2016-08-28 04:31:06 +00:00
match_insensitive_cc ( char * a , char * b ) /*
2016-07-12 22:17:45 +00:00
DOC ( This call returns non - zero if a and b are equivalent under case insensitive comparison . ) */ {
2017-01-23 06:19:43 +00:00
for ( i32_4tech i = 0 ; ; + + i ) {
2016-07-06 19:18:10 +00:00
if ( char_to_upper ( a [ i ] ) ! =
char_to_upper ( b [ i ] ) ) {
return 0 ;
}
if ( a [ i ] = = 0 ) {
return 1 ;
}
}
}
2016-08-28 04:31:06 +00:00
CPP_NAME ( match_insensitive )
2017-01-23 06:19:43 +00:00
API_EXPORT FSTRING_LINK b32_4tech
2016-08-28 04:31:06 +00:00
match_insensitive_sc ( String a , char * b ) /*
2016-07-12 22:17:45 +00:00
DOC ( This call returns non - zero if a and b are equivalent under case insensitive comparison . ) */ {
2017-01-23 06:19:43 +00:00
i32_4tech i = 0 ;
2016-07-06 19:18:10 +00:00
for ( ; i < a . size ; + + i ) {
if ( char_to_upper ( a . str [ i ] ) ! =
char_to_upper ( b [ i ] ) ) {
return 0 ;
}
}
if ( b [ i ] ! = 0 ) {
return 0 ;
}
return 1 ;
}
2016-08-28 04:31:06 +00:00
CPP_NAME ( match_insensitive )
2017-01-23 06:19:43 +00:00
API_EXPORT_INLINE FSTRING_INLINE b32_4tech
2016-08-28 04:31:06 +00:00
match_insensitive_cs ( char * a , String b ) /*
2016-07-12 22:17:45 +00:00
DOC ( This call returns non - zero if a and b are equivalent under case insensitive comparison . ) */ {
2016-08-28 04:31:06 +00:00
return match_insensitive_sc ( b , a ) ;
2016-07-06 19:18:10 +00:00
}
2016-08-28 04:31:06 +00:00
CPP_NAME ( match_insensitive )
2017-01-23 06:19:43 +00:00
API_EXPORT FSTRING_LINK b32_4tech
2016-08-28 04:31:06 +00:00
match_insensitive_ss ( String a , String b ) /*
2016-07-12 22:17:45 +00:00
DOC ( This call returns non - zero if a and b are equivalent under case insensitive comparison . ) */ {
2016-07-06 19:18:10 +00:00
if ( a . size ! = b . size ) {
return 0 ;
}
2017-01-23 06:19:43 +00:00
for ( i32_4tech i = 0 ; i < b . size ; + + i ) {
2016-07-06 19:18:10 +00:00
if ( char_to_upper ( a . str [ i ] ) ! =
char_to_upper ( b . str [ i ] ) ) {
return 0 ;
}
}
return 1 ;
}
2016-08-28 04:31:06 +00:00
CPP_NAME ( match_part_insensitive )
2017-01-23 06:19:43 +00:00
API_EXPORT FSTRING_LINK b32_4tech
match_part_insensitive_ccl ( char * a , char * b , i32_4tech * len ) /*
2016-07-12 22:17:45 +00:00
DOC_PARAM ( len , If this call returns non - zero this parameter is used to output the length of b . )
DOC ( This call performs the same partial matching rule as match_part under case insensitive comparison . )
DOC_SEE ( match_part ) */ {
2017-01-23 06:19:43 +00:00
i32_4tech i ;
2016-07-06 19:18:10 +00:00
for ( i = 0 ; b [ i ] ! = 0 ; + + i ) {
if ( char_to_upper ( a [ i ] ) ! = char_to_upper ( b [ i ] ) ) {
return 0 ;
}
}
* len = i ;
return 1 ;
}
2016-08-28 04:31:06 +00:00
CPP_NAME ( match_part_insensitive )
2017-01-23 06:19:43 +00:00
API_EXPORT FSTRING_LINK b32_4tech
match_part_insensitive_scl ( String a , char * b , i32_4tech * len ) /*
2016-07-12 22:17:45 +00:00
DOC_PARAM ( len , If this call returns non - zero this parameter is used to output the length of b . )
DOC ( This call performs the same partial matching rule as match_part under case insensitive comparison . )
DOC_SEE ( match_part ) */ {
2017-01-23 06:19:43 +00:00
i32_4tech i ;
2016-07-06 19:18:10 +00:00
for ( i = 0 ; b [ i ] ! = 0 ; + + i ) {
if ( char_to_upper ( a . str [ i ] ) ! = char_to_upper ( b [ i ] ) | |
i = = a . size ) {
return 0 ;
}
}
* len = i ;
return 1 ;
}
2016-08-28 04:31:06 +00:00
CPP_NAME ( match_part_insensitive )
2017-01-23 06:19:43 +00:00
API_EXPORT_INLINE FSTRING_INLINE b32_4tech
2016-08-28 04:31:06 +00:00
match_part_insensitive_cc ( char * a , char * b ) /*
2016-07-12 22:17:45 +00:00
DOC ( This call performs the same partial matching rule as match_part under case insensitive comparison . )
DOC_SEE ( match_part ) */ {
2017-01-23 06:19:43 +00:00
i32_4tech x ;
2016-08-28 04:31:06 +00:00
return match_part_insensitive_ccl ( a , b , & x ) ;
2016-07-06 19:18:10 +00:00
}
2016-08-28 04:31:06 +00:00
CPP_NAME ( match_part_insensitive )
2017-01-23 06:19:43 +00:00
API_EXPORT_INLINE FSTRING_INLINE b32_4tech
2016-08-28 04:31:06 +00:00
match_part_insensitive_sc ( String a , char * b ) /*
2016-07-12 22:17:45 +00:00
DOC ( This call performs the same partial matching rule as match_part under case insensitive comparison . )
DOC_SEE ( match_part ) */ {
2017-01-23 06:19:43 +00:00
i32_4tech x ;
2016-08-28 04:31:06 +00:00
return match_part_insensitive_scl ( a , b , & x ) ;
2016-07-06 19:18:10 +00:00
}
2016-08-28 04:31:06 +00:00
CPP_NAME ( match_part_insensitive )
2017-01-23 06:19:43 +00:00
API_EXPORT FSTRING_LINK b32_4tech
2016-08-28 04:31:06 +00:00
match_part_insensitive_cs ( char * a , String b ) /*
2016-07-12 22:17:45 +00:00
DOC ( This call performs the same partial matching rule as match_part under case insensitive comparison . )
DOC_SEE ( match_part ) */ {
2017-01-23 06:19:43 +00:00
for ( i32_4tech i = 0 ; i ! = b . size ; + + i ) {
2016-07-06 19:18:10 +00:00
if ( char_to_upper ( a [ i ] ) ! = char_to_upper ( b . str [ i ] ) ) {
2016-08-31 16:52:46 +00:00
return ( 0 ) ;
2016-07-06 19:18:10 +00:00
}
}
2016-08-31 16:52:46 +00:00
return ( 1 ) ;
2016-07-06 19:18:10 +00:00
}
2016-08-28 04:31:06 +00:00
CPP_NAME ( match_part_insensitive )
2017-01-23 06:19:43 +00:00
API_EXPORT FSTRING_LINK b32_4tech
2016-08-28 04:31:06 +00:00
match_part_insensitive_ss ( String a , String b ) /*
2016-07-12 22:17:45 +00:00
DOC ( This call performs the same partial matching rule as match_part under case insensitive comparison . )
DOC_SEE ( match_part ) */ {
2016-07-06 19:18:10 +00:00
if ( a . size < b . size ) {
2016-08-31 16:52:46 +00:00
return ( 0 ) ;
2016-07-06 19:18:10 +00:00
}
2017-01-23 06:19:43 +00:00
for ( i32_4tech i = 0 ; i < b . size ; + + i ) {
2016-07-06 19:18:10 +00:00
if ( char_to_upper ( a . str [ i ] ) ! = char_to_upper ( b . str [ i ] ) ) {
2016-08-31 16:52:46 +00:00
return ( 0 ) ;
2016-07-06 19:18:10 +00:00
}
}
2016-08-31 16:52:46 +00:00
return ( 1 ) ;
2016-07-06 19:18:10 +00:00
}
2016-08-28 04:31:06 +00:00
CPP_NAME ( compare )
2017-01-23 06:19:43 +00:00
API_EXPORT FSTRING_LINK i32_4tech
2016-08-28 04:31:06 +00:00
compare_cc ( char * a , char * b ) /*
2016-07-12 22:17:45 +00:00
DOC ( This call returns zero if a and b are equivalent ,
it returns negative if a sorts before b alphabetically ,
and positive if a sorts after b alphabetically . ) */ {
2017-01-23 06:19:43 +00:00
i32_4tech i = 0 , r = 0 ;
2016-07-06 19:18:10 +00:00
while ( a [ i ] = = b [ i ] & & a [ i ] ! = 0 ) {
+ + i ;
}
2016-08-31 16:52:46 +00:00
r = ( a [ i ] > b [ i ] ) - ( a [ i ] < b [ i ] ) ;
return ( r ) ;
2016-07-06 19:18:10 +00:00
}
2016-08-28 04:31:06 +00:00
CPP_NAME ( compare )
2017-01-23 06:19:43 +00:00
API_EXPORT FSTRING_LINK i32_4tech
2016-08-28 04:31:06 +00:00
compare_sc ( String a , char * b ) /*
2016-07-12 22:17:45 +00:00
DOC ( This call returns zero if a and b are equivalent ,
it returns negative if a sorts before b alphabetically ,
and positive if a sorts after b alphabetically . ) */ {
2017-01-23 06:19:43 +00:00
i32_4tech i = 0 , r = 0 ;
2016-07-06 19:18:10 +00:00
while ( i < a . size & & a . str [ i ] = = b [ i ] ) {
+ + i ;
}
if ( i < a . size ) {
2016-08-31 16:52:46 +00:00
r = ( a . str [ i ] > b [ i ] ) - ( a . str [ i ] < b [ i ] ) ;
2016-07-06 19:18:10 +00:00
}
else {
if ( b [ i ] = = 0 ) {
2016-08-31 16:52:46 +00:00
r = 0 ;
2016-07-06 19:18:10 +00:00
}
else {
2016-08-31 16:52:46 +00:00
r = - 1 ;
2016-07-06 19:18:10 +00:00
}
}
2016-08-31 16:52:46 +00:00
return ( r ) ;
2016-07-06 19:18:10 +00:00
}
2016-08-28 04:31:06 +00:00
CPP_NAME ( compare )
2017-01-23 06:19:43 +00:00
API_EXPORT_INLINE FSTRING_INLINE i32_4tech
2016-08-28 04:31:06 +00:00
compare_cs ( char * a , String b ) /*
2016-07-12 22:17:45 +00:00
DOC ( This call returns zero if a and b are equivalent ,
it returns negative if a sorts before b alphabetically ,
and positive if a sorts after b alphabetically . ) */ {
2017-01-23 06:19:43 +00:00
i32_4tech r = - compare_sc ( b , a ) ;
2016-08-31 16:52:46 +00:00
return ( r ) ;
2016-07-06 19:18:10 +00:00
}
2016-08-28 04:31:06 +00:00
CPP_NAME ( compare )
2017-01-23 06:19:43 +00:00
API_EXPORT FSTRING_LINK i32_4tech
2016-08-28 04:31:06 +00:00
compare_ss ( String a , String b ) /*
2016-07-12 22:17:45 +00:00
DOC ( This call returns zero if a and b are equivalent ,
it returns negative if a sorts before b alphabetically ,
and positive if a sorts after b alphabetically . ) */ {
2017-01-23 06:19:43 +00:00
i32_4tech i = 0 , r = 0 ;
i32_4tech m = a . size ;
2016-08-31 16:52:46 +00:00
if ( b . size < m ) {
m = b . size ;
}
while ( i < m & & a . str [ i ] = = b . str [ i ] ) {
2016-07-06 19:18:10 +00:00
+ + i ;
}
2016-08-31 16:52:46 +00:00
if ( i < m ) {
r = ( a . str [ i ] > b . str [ i ] ) - ( b . str [ i ] > a . str [ i ] ) ;
2016-07-06 19:18:10 +00:00
}
else {
2016-08-31 18:40:22 +00:00
r = ( a . size > b . size ) - ( b . size > a . size ) ;
2016-07-06 19:18:10 +00:00
}
2016-08-31 16:52:46 +00:00
return ( r ) ;
2016-07-06 19:18:10 +00:00
}
//
// Finding Characters and Substrings
//
2016-08-28 04:31:06 +00:00
CPP_NAME ( find )
2017-01-23 06:19:43 +00:00
API_EXPORT FSTRING_LINK i32_4tech
find_c_char ( char * str , i32_4tech start , char character ) /*
2016-07-12 22:17:45 +00:00
DOC_PARAM ( str , The str parameter provides a null terminated string to search . )
DOC_PARAM ( start , The start parameter provides the index of the first character in str to search . )
DOC_PARAM ( character , The character parameter provides the character for which to search . )
DOC ( This call returns the index of the first occurance of character , or the size of the string
if the character is not found . ) */ {
2017-01-23 06:19:43 +00:00
i32_4tech i = start ;
2016-07-06 19:18:10 +00:00
while ( str [ i ] ! = character & & str [ i ] ! = 0 ) + + i ;
2016-08-31 16:52:46 +00:00
return ( i ) ;
2016-07-06 19:18:10 +00:00
}
2016-08-28 04:31:06 +00:00
CPP_NAME ( find )
2017-01-23 06:19:43 +00:00
API_EXPORT FSTRING_LINK i32_4tech
find_s_char ( String str , i32_4tech start , char character ) /*
2016-07-12 22:17:45 +00:00
DOC_PARAM ( str , The str parameter provides a string to search . )
DOC_PARAM ( start , The start parameter provides the index of the first character in str to search . )
DOC_PARAM ( character , The character parameter provides the character for which to search . )
DOC ( This call returns the index of the first occurance of character , or the size of the string
if the character is not found . ) */ {
2017-01-23 06:19:43 +00:00
i32_4tech i = start ;
2016-07-06 19:18:10 +00:00
while ( i < str . size & & str . str [ i ] ! = character ) + + i ;
2016-08-31 16:52:46 +00:00
return ( i ) ;
}
CPP_NAME ( rfind )
2017-01-23 06:19:43 +00:00
API_EXPORT FSTRING_LINK i32_4tech
rfind_s_char ( String str , i32_4tech start , char character ) /*
2016-08-31 16:52:46 +00:00
DOC_PARAM ( str , The str parameter provides a string to search . )
DOC_PARAM ( start , The start parameter provides the index of the first character in str to search . )
DOC_PARAM ( character , The character parameter provides the character for which to search . )
DOC ( This call looks for the largest index less than or equal to the start position where
the given character occurs . If the index is found it is returned otherwise - 1 is returned . ) */ {
2017-01-23 06:19:43 +00:00
i32_4tech i = start ;
2016-08-31 16:52:46 +00:00
while ( i > = 0 & & str . str [ i ] ! = character ) - - i ;
return ( i ) ;
2016-07-06 19:18:10 +00:00
}
2016-08-28 04:31:06 +00:00
CPP_NAME ( find )
2017-01-23 06:19:43 +00:00
API_EXPORT FSTRING_LINK i32_4tech
find_c_chars ( char * str , i32_4tech start , char * characters ) /*
2016-07-12 22:17:45 +00:00
DOC_PARAM ( str , The str parameter provides a null terminated string to search . )
DOC_PARAM ( start , The start parameter provides the index of the first character in str to search . )
DOC_PARAM ( character , The characters parameter provides a null terminated array of characters for which to search . )
DOC ( This call returns the index of the first occurance of a character in the characters array ,
or the size of the string if no such character is not found . ) */ {
2017-01-23 06:19:43 +00:00
i32_4tech i = start , j ;
2016-07-06 19:18:10 +00:00
while ( str [ i ] ! = 0 ) {
for ( j = 0 ; characters [ j ] ; + + j ) {
if ( str [ i ] = = characters [ j ] ) {
2016-08-31 16:52:46 +00:00
return ( i ) ;
2016-07-06 19:18:10 +00:00
}
}
+ + i ;
}
2016-08-31 16:52:46 +00:00
return ( i ) ;
2016-07-06 19:18:10 +00:00
}
2016-08-28 04:31:06 +00:00
CPP_NAME ( find )
2017-01-23 06:19:43 +00:00
API_EXPORT FSTRING_LINK i32_4tech
find_s_chars ( String str , i32_4tech start , char * characters ) /*
2016-07-12 22:17:45 +00:00
DOC_PARAM ( str , The str parameter provides a string to search . )
DOC_PARAM ( start , The start parameter provides the index of the first character in str to search . )
DOC_PARAM ( character , The characters parameter provides a null terminated array of characters for which to search . )
DOC ( This call returns the index of the first occurance of a character in the characters array ,
or the size of the string if no such character is not found . ) */ {
2017-01-23 06:19:43 +00:00
i32_4tech i = start , j ;
2016-07-06 19:18:10 +00:00
while ( i < str . size ) {
for ( j = 0 ; characters [ j ] ; + + j ) {
if ( str . str [ i ] = = characters [ j ] ) {
2016-08-31 16:52:46 +00:00
return ( i ) ;
2016-07-06 19:18:10 +00:00
}
}
+ + i ;
}
2016-08-31 16:52:46 +00:00
return ( i ) ;
2016-07-06 19:18:10 +00:00
}
2016-08-28 04:31:06 +00:00
CPP_NAME ( find_substr )
2017-01-23 06:19:43 +00:00
API_EXPORT FSTRING_LINK i32_4tech
find_substr_c ( char * str , i32_4tech start , String seek ) /*
2016-07-12 22:17:45 +00:00
DOC_PARAM ( str , The str parameter provides a null terminated string to search . )
DOC_PARAM ( start , The start parameter provides the index of the first character in str to search . )
DOC_PARAM ( seek , The seek parameter provides a string to find in str . )
DOC ( This call returns the index of the first occurance of the seek substring in str or the
size of str if no such substring in str is found . ) */ {
2017-01-23 06:19:43 +00:00
i32_4tech i , j , k ;
b32_4tech hit ;
2016-07-06 19:18:10 +00:00
if ( seek . size = = 0 ) {
2016-08-31 16:52:46 +00:00
i = str_size ( str ) ;
return ( i ) ;
2016-07-06 19:18:10 +00:00
}
for ( i = start ; str [ i ] ; + + i ) {
if ( str [ i ] = = seek . str [ 0 ] ) {
hit = 1 ;
for ( j = 1 , k = i + 1 ; j < seek . size ; + + j , + + k ) {
if ( str [ k ] ! = seek . str [ j ] ) {
hit = 0 ;
break ;
}
}
if ( hit ) {
2016-08-31 16:52:46 +00:00
return ( i ) ;
2016-07-06 19:18:10 +00:00
}
}
}
2016-08-31 16:52:46 +00:00
return ( i ) ;
2016-07-06 19:18:10 +00:00
}
2016-08-28 04:31:06 +00:00
CPP_NAME ( find_substr )
2017-01-23 06:19:43 +00:00
API_EXPORT FSTRING_LINK i32_4tech
find_substr_s ( String str , i32_4tech start , String seek ) /*
2016-07-12 22:17:45 +00:00
DOC_PARAM ( str , The str parameter provides a string to search . )
DOC_PARAM ( start , The start parameter provides the index of the first character in str to search . )
DOC_PARAM ( seek , The seek parameter provides a string to find in str . )
DOC ( This call returns the index of the first occurance of the seek substring in str or the
size of str if no such substring in str is found . ) */ {
2017-01-23 06:19:43 +00:00
i32_4tech stop_at , i , j , k ;
b32_4tech hit ;
2016-07-06 19:18:10 +00:00
if ( seek . size = = 0 ) {
return str . size ;
}
stop_at = str . size - seek . size + 1 ;
for ( i = start ; i < stop_at ; + + i ) {
if ( str . str [ i ] = = seek . str [ 0 ] ) {
hit = 1 ;
for ( j = 1 , k = i + 1 ; j < seek . size ; + + j , + + k ) {
if ( str . str [ k ] ! = seek . str [ j ] ) {
hit = 0 ;
break ;
}
}
if ( hit ) {
return i ;
}
}
}
2016-08-31 16:52:46 +00:00
return ( str . size ) ;
2016-07-06 19:18:10 +00:00
}
2016-08-28 04:31:06 +00:00
CPP_NAME ( rfind_substr )
2017-01-23 06:19:43 +00:00
API_EXPORT FSTRING_LINK i32_4tech
rfind_substr_s ( String str , i32_4tech start , String seek ) /*
2016-07-12 22:17:45 +00:00
DOC_PARAM ( str , The str parameter provides a string to search . )
DOC_PARAM ( start , The start parameter provides the index of the first character in str to search . )
DOC_PARAM ( seek , The seek parameter provides a string to find in str . )
DOC ( This call returns the index of the last occurance of the seek substring in str
or - 1 if no such substring in str is found . ) */ {
2017-01-23 06:19:43 +00:00
i32_4tech i , j , k ;
b32_4tech hit ;
2016-07-06 19:18:10 +00:00
if ( seek . size = = 0 ) {
return - 1 ;
}
if ( start + seek . size > str . size ) {
start = str . size - seek . size ;
}
for ( i = start ; i > = 0 ; - - i ) {
if ( str . str [ i ] = = seek . str [ 0 ] ) {
hit = 1 ;
for ( j = 1 , k = i + 1 ; j < seek . size ; + + j , + + k ) {
if ( str . str [ k ] ! = seek . str [ j ] ) {
hit = 0 ;
break ;
}
}
if ( hit ) {
return i ;
}
}
}
return - 1 ;
}
2016-08-28 04:31:06 +00:00
CPP_NAME ( find_substr_insensitive )
2017-01-23 06:19:43 +00:00
API_EXPORT FSTRING_LINK i32_4tech
find_substr_insensitive_c ( char * str , i32_4tech start , String seek ) /*
2016-07-12 22:17:45 +00:00
DOC_PARAM ( str , The str parameter provides a null terminated string to search . )
DOC_PARAM ( start , The start parameter provides the index of the first character in str to search . )
DOC_PARAM ( seek , The seek parameter provides a string to find in str . )
DOC ( This call acts as find_substr under case insensitive comparison . )
DOC_SEE ( find_substr ) */ {
2017-01-23 06:19:43 +00:00
i32_4tech i , j , k ;
b32_4tech hit ;
2016-07-06 19:18:10 +00:00
char a_upper , b_upper ;
2017-02-10 18:02:17 +00:00
char first_test_char ;
2016-07-06 19:18:10 +00:00
if ( seek . size = = 0 ) {
return str_size ( str ) ;
}
2017-02-10 18:02:17 +00:00
first_test_char = char_to_upper ( seek . str [ 0 ] ) ;
2016-07-06 19:18:10 +00:00
for ( i = start ; str [ i ] ; + + i ) {
2017-02-10 18:02:17 +00:00
a_upper = char_to_upper ( str [ i ] ) ;
if ( a_upper = = first_test_char ) {
2016-07-06 19:18:10 +00:00
hit = 1 ;
for ( j = 1 , k = i + 1 ; j < seek . size ; + + j , + + k ) {
a_upper = char_to_upper ( str [ k ] ) ;
b_upper = char_to_upper ( seek . str [ j ] ) ;
if ( a_upper ! = b_upper ) {
hit = 0 ;
break ;
}
}
if ( hit ) {
return i ;
}
}
}
return i ;
}
2016-08-28 04:31:06 +00:00
CPP_NAME ( find_substr_insensitive )
2017-01-23 06:19:43 +00:00
API_EXPORT FSTRING_LINK i32_4tech
find_substr_insensitive_s ( String str , i32_4tech start , String seek ) /*
2016-07-12 22:17:45 +00:00
DOC_PARAM ( str , The str parameter provides a string to search . )
DOC_PARAM ( start , The start parameter provides the index of the first character in str to search . )
DOC_PARAM ( seek , The seek parameter provides a string to find in str . )
DOC ( This call acts as find_substr under case insensitive comparison . )
DOC_SEE ( find_substr ) */ {
2017-01-23 06:19:43 +00:00
i32_4tech i , j , k ;
i32_4tech stop_at ;
b32_4tech hit ;
2016-07-06 19:18:10 +00:00
char a_upper , b_upper ;
2017-02-10 18:02:17 +00:00
char first_test_char ;
2016-07-06 19:18:10 +00:00
if ( seek . size = = 0 ) {
return str . size ;
}
stop_at = str . size - seek . size + 1 ;
2017-02-10 18:02:17 +00:00
first_test_char = char_to_upper ( seek . str [ 0 ] ) ;
2016-07-06 19:18:10 +00:00
for ( i = start ; i < stop_at ; + + i ) {
2017-02-10 18:02:17 +00:00
a_upper = char_to_upper ( str . str [ i ] ) ;
if ( a_upper = = first_test_char ) {
2016-07-06 19:18:10 +00:00
hit = 1 ;
for ( j = 1 , k = i + 1 ; j < seek . size ; + + j , + + k ) {
a_upper = char_to_upper ( str . str [ k ] ) ;
b_upper = char_to_upper ( seek . str [ j ] ) ;
if ( a_upper ! = b_upper ) {
hit = 0 ;
break ;
}
}
if ( hit ) {
return i ;
}
}
}
return str . size ;
}
2016-08-28 04:31:06 +00:00
CPP_NAME ( has_substr )
2017-01-23 06:19:43 +00:00
API_EXPORT_INLINE FSTRING_INLINE b32_4tech
2016-08-28 04:31:06 +00:00
has_substr_c ( char * s , String seek ) /*
2016-07-12 22:17:45 +00:00
DOC ( This call returns non - zero if the string s contains a substring equivalent to seek . ) */ {
2016-08-28 04:31:06 +00:00
return ( s [ find_substr_c ( s , 0 , seek ) ] ! = 0 ) ;
2016-07-06 19:18:10 +00:00
}
2016-08-28 04:31:06 +00:00
CPP_NAME ( has_substr )
2017-01-23 06:19:43 +00:00
API_EXPORT_INLINE FSTRING_INLINE b32_4tech
2016-08-28 04:31:06 +00:00
has_substr_s ( String s , String seek ) /*
2016-07-12 22:17:45 +00:00
DOC ( This call returns non - zero if the string s contains a substring equivalent to seek . ) */ {
2016-08-28 04:31:06 +00:00
return ( find_substr_s ( s , 0 , seek ) < s . size ) ;
2016-07-06 19:18:10 +00:00
}
2016-08-28 04:31:06 +00:00
CPP_NAME ( has_substr_insensitive )
2017-01-23 06:19:43 +00:00
API_EXPORT_INLINE FSTRING_INLINE b32_4tech
2016-08-28 04:31:06 +00:00
has_substr_insensitive_c ( char * s , String seek ) /*
2016-07-12 22:17:45 +00:00
DOC ( This call returns non - zero if the string s contains a substring equivalent to seek
under case insensitive comparison . ) */ {
2016-08-28 04:31:06 +00:00
return ( s [ find_substr_insensitive_c ( s , 0 , seek ) ] ! = 0 ) ;
2016-07-06 19:18:10 +00:00
}
2016-08-28 04:31:06 +00:00
CPP_NAME ( has_substr_insensitive )
2017-01-23 06:19:43 +00:00
API_EXPORT_INLINE FSTRING_INLINE b32_4tech
2016-08-28 04:31:06 +00:00
has_substr_insensitive_s ( String s , String seek ) /*
2016-07-12 22:17:45 +00:00
DOC ( This call returns non - zero if the string s contains a substring equivalent to seek
under case insensitive comparison . ) */ {
2016-08-28 04:31:06 +00:00
return ( find_substr_insensitive_s ( s , 0 , seek ) < s . size ) ;
2016-07-06 19:18:10 +00:00
}
//
// String Copies and Appends
//
2016-08-28 04:31:06 +00:00
CPP_NAME ( copy_fast_unsafe )
2017-01-23 06:19:43 +00:00
API_EXPORT FSTRING_LINK i32_4tech
2016-08-28 04:31:06 +00:00
copy_fast_unsafe_cc ( char * dest , char * src ) /*
2016-07-12 22:17:45 +00:00
DOC ( This call performs a copy from the src buffer to the dest buffer .
The copy does not stop until a null terminator is found in src . There
is no safety against overrun so dest must be large enough to contain src .
The null terminator is not written to dest . This call returns the number
of bytes coppied to dest . ) */ {
2016-07-06 19:18:10 +00:00
char * start = dest ;
while ( * src ! = 0 ) {
* dest = * src ;
+ + dest ;
+ + src ;
}
2017-01-23 06:19:43 +00:00
return ( i32_4tech ) ( dest - start ) ;
2016-07-06 19:18:10 +00:00
}
2016-08-28 04:31:06 +00:00
CPP_NAME ( copy_fast_unsafe )
2017-01-23 06:19:43 +00:00
API_EXPORT FSTRING_LINK i32_4tech
2016-08-28 04:31:06 +00:00
copy_fast_unsafe_cs ( char * dest , String src ) /*
2016-07-12 22:17:45 +00:00
DOC ( This call performs a copy from the src string to the dest buffer .
The copy does not stop until src . size characters are coppied . There
is no safety against overrun so dest must be large enough to contain src .
The null terminator is not written to dest . This call returns the number
of bytes coppied to dest . ) */ {
2017-01-23 06:19:43 +00:00
i32_4tech i = 0 ;
2016-07-06 19:18:10 +00:00
while ( i ! = src . size ) {
dest [ i ] = src . str [ i ] ;
+ + i ;
}
2016-07-12 22:17:45 +00:00
return ( src . size ) ;
2016-07-06 19:18:10 +00:00
}
2016-08-28 04:31:06 +00:00
CPP_NAME ( copy_checked )
2017-01-23 06:19:43 +00:00
API_EXPORT FSTRING_LINK b32_4tech
2016-08-28 04:31:06 +00:00
copy_checked_ss ( String * dest , String src ) /*
2016-07-12 22:17:45 +00:00
DOC ( This call performs a copy from the src string to the dest string .
The memory_size of dest is checked before any coppying is done .
This call returns non - zero on a successful copy . ) */ {
2016-07-06 19:18:10 +00:00
char * dest_str ;
2017-01-23 06:19:43 +00:00
i32_4tech i ;
2016-07-06 19:18:10 +00:00
if ( dest - > memory_size < src . size ) {
return 0 ;
}
dest_str = dest - > str ;
for ( i = 0 ; i < src . size ; + + i ) {
dest_str [ i ] = src . str [ i ] ;
}
dest - > size = src . size ;
return 1 ;
}
2017-03-13 23:48:11 +00:00
CPP_NAME ( copy_checked )
API_EXPORT FSTRING_LINK b32_4tech
copy_checked_cs ( char * dest , i32_4tech dest_cap , String src ) /*
DOC ( This call performs a copy from the src string to the dest string .
The value dest_cap is checked before any coppying is done .
This call returns non - zero on a successful copy . )
*/ {
i32_4tech i ;
if ( dest_cap < src . size ) {
return 0 ;
}
for ( i = 0 ; i < src . size ; + + i ) {
dest [ i ] = src . str [ i ] ;
}
return 1 ;
}
2016-08-28 04:31:06 +00:00
CPP_NAME ( copy_partial )
2017-01-23 06:19:43 +00:00
API_EXPORT FSTRING_LINK b32_4tech
2016-08-28 04:31:06 +00:00
copy_partial_sc ( String * dest , char * src ) /*
2016-07-12 22:17:45 +00:00
DOC ( This call performs a copy from the src buffer to the dest string .
The memory_size of dest is checked if the entire copy cannot be performed ,
as many bytes as possible are coppied to dest . This call returns non - zero
if the entire string is coppied to dest . ) */ {
2017-01-23 06:19:43 +00:00
i32_4tech i = 0 ;
i32_4tech memory_size = dest - > memory_size ;
2016-07-06 19:18:10 +00:00
char * dest_str = dest - > str ;
while ( src [ i ] ! = 0 ) {
if ( i > = memory_size ) {
return 0 ;
}
dest_str [ i ] = src [ i ] ;
+ + i ;
}
dest - > size = i ;
return 1 ;
}
2016-08-28 04:31:06 +00:00
CPP_NAME ( copy_partial )
2017-01-23 06:19:43 +00:00
API_EXPORT FSTRING_LINK b32_4tech
2016-08-28 04:31:06 +00:00
copy_partial_ss ( String * dest , String src ) /*
2016-07-12 22:17:45 +00:00
DOC ( This call performs a copy from the src string to the dest string .
2017-03-13 23:48:11 +00:00
The memory_size of dest is checked . If the entire copy cannot be performed ,
as many bytes as possible are coppied to dest .
This call returns non - zero if the entire string is coppied to dest . ) */ {
2016-07-06 19:18:10 +00:00
char * dest_str = dest - > str ;
2017-01-23 06:19:43 +00:00
i32_4tech memory_size = dest - > memory_size ;
b32_4tech result = 0 ;
2016-07-12 22:17:45 +00:00
if ( memory_size > = src . size ) {
2016-08-28 04:31:06 +00:00
result = 1 ;
2016-07-12 22:17:45 +00:00
memory_size = src . size ;
2016-07-06 19:18:10 +00:00
}
2017-01-23 06:19:43 +00:00
for ( i32_4tech i = 0 ; i < memory_size ; + + i ) {
2016-07-12 22:17:45 +00:00
dest_str [ i ] = src . str [ i ] ;
2016-07-06 19:18:10 +00:00
}
2016-07-12 22:17:45 +00:00
dest - > size = memory_size ;
2017-03-13 23:48:11 +00:00
return ( result ) ;
}
CPP_NAME ( copy_partial )
API_EXPORT FSTRING_LINK b32_4tech
copy_partial_cs ( char * dest , i32_4tech dest_cap , String src ) /*
DOC ( This call performs a copy from the src string to the dest string .
The value dest_cap is checked . If the entire copy cannot be performed ,
as many bytes as possible are coppied to dest .
This call returns non - zero if the entire string is coppied to dest . )
*/ {
b32_4tech result = 0 ;
i32_4tech copy_size = dest_cap ;
i32_4tech i ;
if ( dest_cap > = src . size ) {
result = 1 ;
copy_size = src . size ;
}
for ( i = 0 ; i < copy_size ; + + i ) {
dest [ i ] = src . str [ i ] ;
}
return ( result ) ;
2016-07-06 19:18:10 +00:00
}
2016-08-28 04:31:06 +00:00
CPP_NAME ( copy )
2017-01-23 06:19:43 +00:00
API_EXPORT_INLINE FSTRING_INLINE i32_4tech
2016-08-28 04:31:06 +00:00
copy_cc ( char * dest , char * src ) /*
2016-07-12 22:17:45 +00:00
DOC ( This call performs a copy from src to dest equivalent to copy_fast_unsafe . )
DOC_SEE ( copy_fast_unsafe ) */ {
2016-08-28 04:31:06 +00:00
return copy_fast_unsafe_cc ( dest , src ) ;
2016-07-06 19:18:10 +00:00
}
2016-08-28 04:31:06 +00:00
CPP_NAME ( copy )
2016-11-02 03:27:51 +00:00
API_EXPORT_INLINE FSTRING_INLINE void
2016-08-28 04:31:06 +00:00
copy_ss ( String * dest , String src ) /*
2016-07-12 22:17:45 +00:00
DOC ( This call performs a copy from src to dest equivalent to copy_checked . )
DOC_SEE ( copy_checked ) */ {
2016-08-28 04:31:06 +00:00
copy_checked_ss ( dest , src ) ;
2016-07-06 19:18:10 +00:00
}
2016-08-28 04:31:06 +00:00
CPP_NAME ( copy )
2016-11-02 03:27:51 +00:00
API_EXPORT_INLINE FSTRING_INLINE void
2016-08-28 04:31:06 +00:00
copy_sc ( String * dest , char * src ) /*
2016-07-12 22:17:45 +00:00
DOC ( This call performs a copy from src to dest equivalent to copy_partial . )
DOC_SEE ( copy_partial ) */ {
2016-08-28 04:31:06 +00:00
copy_partial_sc ( dest , src ) ;
2016-07-06 19:18:10 +00:00
}
2016-08-28 04:31:06 +00:00
CPP_NAME ( append_checked )
2017-01-23 06:19:43 +00:00
API_EXPORT FSTRING_LINK b32_4tech
2016-08-28 04:31:06 +00:00
append_checked_ss ( String * dest , String src ) /*
2016-07-12 22:17:45 +00:00
DOC ( This call checks if there is enough space in dest ' s underlying memory
to append src onto dest . If there is src is appended and the call returns non - zero . ) */ {
2016-07-06 19:18:10 +00:00
String end ;
end = tailstr ( * dest ) ;
2017-01-23 06:19:43 +00:00
b32_4tech result = copy_checked_ss ( & end , src ) ;
2016-07-06 19:18:10 +00:00
// NOTE(allen): This depends on end.size still being 0 if
// the check failed and no coppy occurred.
dest - > size + = end . size ;
return result ;
}
2016-08-28 04:31:06 +00:00
CPP_NAME ( append_partial )
2017-01-23 06:19:43 +00:00
API_EXPORT FSTRING_LINK b32_4tech
2016-08-28 04:31:06 +00:00
append_partial_sc ( String * dest , char * src ) /*
2016-07-12 22:17:45 +00:00
DOC ( This call attemps to append as much of src into the space in dest ' s underlying memory
as possible . If the entire string is appended the call returns non - zero . ) */ {
2016-07-06 19:18:10 +00:00
String end = tailstr ( * dest ) ;
2017-01-23 06:19:43 +00:00
b32_4tech result = copy_partial_sc ( & end , src ) ;
2016-07-06 19:18:10 +00:00
dest - > size + = end . size ;
return result ;
}
2016-08-28 04:31:06 +00:00
CPP_NAME ( append_partial )
2017-01-23 06:19:43 +00:00
API_EXPORT FSTRING_LINK b32_4tech
2016-08-28 04:31:06 +00:00
append_partial_ss ( String * dest , String src ) /*
2016-07-12 22:17:45 +00:00
DOC ( This call attemps to append as much of src into the space in dest ' s underlying memory
as possible . If the entire string is appended the call returns non - zero . ) */ {
2016-07-06 19:18:10 +00:00
String end = tailstr ( * dest ) ;
2017-01-23 06:19:43 +00:00
b32_4tech result = copy_partial_ss ( & end , src ) ;
2016-07-06 19:18:10 +00:00
dest - > size + = end . size ;
return result ;
}
2016-08-28 04:31:06 +00:00
CPP_NAME ( append )
2017-01-23 06:19:43 +00:00
API_EXPORT FSTRING_LINK b32_4tech
2016-08-28 04:31:06 +00:00
append_s_char ( String * dest , char c ) /*
2016-07-12 22:17:45 +00:00
DOC ( This call attemps to append c onto dest . If there is space left in dest ' s underlying
memory the character is appended and the call returns non - zero . ) */ {
2017-01-23 06:19:43 +00:00
b32_4tech result = 0 ;
2016-07-06 19:18:10 +00:00
if ( dest - > size < dest - > memory_size ) {
dest - > str [ dest - > size + + ] = c ;
result = 1 ;
}
return result ;
}
2016-08-28 04:31:06 +00:00
CPP_NAME ( append )
2017-01-23 06:19:43 +00:00
API_EXPORT_INLINE FSTRING_INLINE b32_4tech
2016-08-28 04:31:06 +00:00
append_ss ( String * dest , String src ) /*
2016-07-12 22:17:45 +00:00
DOC ( This call is equivalent to append_partial . ) DOC_SEE ( append_partial ) */ {
2016-08-28 04:31:06 +00:00
return append_partial_ss ( dest , src ) ;
2016-07-06 19:18:10 +00:00
}
2016-08-28 04:31:06 +00:00
CPP_NAME ( append )
2017-01-23 06:19:43 +00:00
API_EXPORT_INLINE FSTRING_INLINE b32_4tech
2016-08-28 04:31:06 +00:00
append_sc ( String * dest , char * src ) /*
2016-07-12 22:17:45 +00:00
DOC ( This call is equivalent to append_partial . ) DOC_SEE ( append_partial ) */ {
2016-08-28 04:31:06 +00:00
return append_partial_sc ( dest , src ) ;
2016-07-06 19:18:10 +00:00
}
2017-01-23 06:19:43 +00:00
API_EXPORT FSTRING_LINK b32_4tech
2016-07-12 22:17:45 +00:00
terminate_with_null ( String * str ) /*
DOC ( This call attemps to append a null terminator onto str without effecting the
size of str . This is usually called when the time comes to pass the the string to an
API that requires a null terminator . This call returns non - zero if there was a spare
byte in the strings underlying memory . ) */ {
2017-01-23 06:19:43 +00:00
b32_4tech result = 0 ;
2016-07-06 19:18:10 +00:00
if ( str - > size < str - > memory_size ) {
str - > str [ str - > size ] = 0 ;
result = 1 ;
}
return ( result ) ;
}
2017-01-23 06:19:43 +00:00
API_EXPORT FSTRING_LINK b32_4tech
append_padding ( String * dest , char c , i32_4tech target_size ) /*
2016-07-12 22:17:45 +00:00
DOC ( This call pads out dest so that it has a size of target_size by appending
the padding character c until the target size is achieved . This call returns
non - zero if dest does not run out of space in the underlying memory . ) */ {
2017-01-23 06:19:43 +00:00
b32_4tech result = 1 ;
i32_4tech offset = target_size - dest - > size ;
i32_4tech r = 0 ;
2016-07-06 19:18:10 +00:00
if ( offset > 0 ) {
for ( r = 0 ; r < offset ; + + r ) {
2016-08-28 04:31:06 +00:00
if ( append_s_char ( dest , c ) = = 0 ) {
2016-07-06 19:18:10 +00:00
result = 0 ;
break ;
}
}
}
return ( result ) ;
}
//
// Other Edits
//
2018-05-08 07:14:23 +00:00
API_EXPORT FSTRING_LINK void
2018-10-06 15:26:20 +00:00
string_interpret_escapes ( String src , char * dst )
/* DOC(Rewrites a string with escape sequences into a flattened string. In particular:
" \\ " becomes " \"
" \n " becomes LF
" \t " becomes TAB
" \" " becomes " " "
" 0 " becomes NULL
) */ {
2018-05-08 07:14:23 +00:00
i32_4tech mode = 0 ;
i32_4tech j = 0 ;
for ( i32_4tech i = 0 ; i < src . size ; + + i ) {
switch ( mode ) {
case 0 :
{
if ( src . str [ i ] = = ' \\ ' ) {
mode = 1 ;
}
else {
dst [ j + + ] = src . str [ i ] ;
}
} break ;
case 1 :
{
2018-06-10 02:28:22 +00:00
char c = src . str [ i ] ;
switch ( c ) {
case ' \\ ' : { dst [ j + + ] = ' \\ ' ; } break ;
case ' n ' : { dst [ j + + ] = ' \n ' ; } break ;
case ' t ' : { dst [ j + + ] = ' \t ' ; } break ;
case ' " ' : { dst [ j + + ] = ' " ' ; } break ;
case ' 0 ' : { dst [ j + + ] = ' \0 ' ; } break ;
default : { dst [ j + + ] = ' \\ ' ; dst [ j + + ] = c ; } break ;
2018-05-08 07:14:23 +00:00
}
2018-06-10 02:28:22 +00:00
mode = 0 ;
2018-05-08 07:14:23 +00:00
} break ;
}
}
dst [ j ] = 0 ;
}
2016-11-02 03:27:51 +00:00
API_EXPORT FSTRING_LINK void
2016-07-12 22:17:45 +00:00
replace_char ( String * str , char replace , char with ) /*
DOC_PARAM ( str , The str parameter provides the string in which replacement shall be performed . )
DOC_PARAM ( replace , The replace character specifies which character should be replaced . )
DOC_PARAM ( with , The with character specifies what to write into the positions where replacement occurs . )
DOC ( This call replaces all occurances of character in str with another character . ) */ {
2016-07-06 19:18:10 +00:00
char * s = str - > str ;
2017-01-23 06:19:43 +00:00
i32_4tech i = 0 ;
2016-07-06 19:18:10 +00:00
for ( i = 0 ; i < str - > size ; + + i , + + s ) {
if ( * s = = replace ) * s = with ;
}
}
2017-11-09 18:30:24 +00:00
# if !defined(FSTRING_GUARD)
void
block_move ( void * a_ptr , void * b_ptr , i32_4tech s ) {
u8_4tech * a = ( u8_4tech * ) a_ptr ;
u8_4tech * b = ( u8_4tech * ) b_ptr ;
if ( a < b ) {
for ( i32_4tech i = 0 ; i < s ; + + i , + + a , + + b ) {
* a = * b ;
}
}
else if ( a > b ) {
a = a + s - 1 ;
b = b + s - 1 ;
for ( i32_4tech i = 0 ; i < s ; + + i , - - a , - - b ) {
* a = * b ;
}
}
}
void
replace_range_str ( String * str , i32_4tech first , i32_4tech one_past_last , String with ) {
i32_4tech shift = with . size - ( one_past_last - first ) ;
i32_4tech new_size = str - > size + shift ;
if ( new_size < = str - > memory_size ) {
if ( shift ! = 0 ) {
char * tail = str - > str + one_past_last ;
char * new_tail_pos = tail + shift ;
block_move ( new_tail_pos , tail , str - > size - one_past_last ) ;
}
block_move ( str - > str + first , with . str , with . size ) ;
str - > size + = shift ;
}
}
# endif
CPP_NAME ( replace_str )
API_EXPORT FSTRING_LINK void
2017-11-10 18:27:39 +00:00
replace_str_ss ( String * str , String replace , String with ) /*
DOC_PARAM ( str , The string to modify . )
DOC_PARAM ( replace , A string matching the zero or more substring to be replaced within str . )
DOC_PARAM ( with , The string to be placed into str in place of occurrences of replace . )
DOC ( Modifies str so that every occurence of replace that was within str is gone and the string in with has taken their places . )
*/ {
2017-11-09 18:30:24 +00:00
i32_4tech i = 0 ;
for ( ; ; ) {
i = find_substr_s ( * str , i , replace ) ;
if ( i > = str - > size ) {
break ;
}
replace_range_str ( str , i , i + replace . size , with ) ;
i + = with . size ;
}
}
CPP_NAME ( replace_str )
API_EXPORT FSTRING_LINK void
2017-11-10 18:27:39 +00:00
replace_str_sc ( String * str , String replace , char * with ) /*
DOC_PARAM ( str , The string to modify . )
DOC_PARAM ( replace , A string matching the zero or more substring to be replaced within str . Must be null terminated , and will be counted , it is always faster to use a String parameter here when possible . )
DOC_PARAM ( with , The string to be placed into str in place of occurrences of replace . )
DOC ( Modifies str so that every occurence of replace that was within str is gone and the string in with has taken their places . )
*/ {
2017-11-09 18:30:24 +00:00
String w = make_string_slowly ( with ) ;
replace_str_ss ( str , replace , w ) ;
}
CPP_NAME ( replace_str )
API_EXPORT FSTRING_LINK void
2017-11-10 18:27:39 +00:00
replace_str_cs ( String * str , char * replace , String with ) /*
DOC_PARAM ( str , The string to modify . )
DOC_PARAM ( replace , A string matching the zero or more substring to be replaced within str . )
DOC_PARAM ( with , The string to be placed into str in place of occurrences of replace . Must be null terminated , and will be counted , it is always faster to use a String parameter here when possible . )
DOC ( Modifies str so that every occurence of replace that was within str is gone and the string in with has taken their places . )
*/ {
2017-11-09 18:30:24 +00:00
String r = make_string_slowly ( replace ) ;
replace_str_ss ( str , r , with ) ;
}
CPP_NAME ( replace_str )
API_EXPORT FSTRING_LINK void
2017-11-10 18:27:39 +00:00
replace_str_cc ( String * str , char * replace , char * with ) /*
DOC_PARAM ( str , The string to modify . )
DOC_PARAM ( replace , A string matching the zero or more substring to be replaced within str . Must be null terminated , and will be counted , it is always faster to use a String parameter here when possible . )
DOC_PARAM ( with , The string to be placed into str in place of occurrences of replace . Must be null terminated , and will be counted , it is always faster to use a String parameter here when possible . )
DOC ( Modifies str so that every occurence of replace that was within str is gone and the string in with has taken their places . )
*/ {
2017-11-09 18:30:24 +00:00
String r = make_string_slowly ( replace ) ;
String w = make_string_slowly ( with ) ;
replace_str_ss ( str , r , w ) ;
}
2016-09-02 17:01:52 +00:00
CPP_NAME ( to_lower )
2016-11-02 03:27:51 +00:00
API_EXPORT FSTRING_LINK void
2016-09-02 17:01:52 +00:00
to_lower_cc ( char * src , char * dst ) /*
DOC_PARAM ( src , The source string to conver to lowercase . This string must be null terminated . )
DOC_PARAM ( dst , The destination buffer to receive the converted string . This must be large
enough to contain all of src and a null terminator . )
DOC ( Rewrites the string in src into dst with all letters lowercased . src and dst should not
overlap with the exception that src and dst may be exactly equal in order to convert the
string in place . )
*/ {
for ( ; * src ! = 0 ; + + src ) {
* dst + + = char_to_lower ( * src ) ;
}
* dst + + = 0 ;
}
CPP_NAME ( to_lower )
2016-11-02 03:27:51 +00:00
API_EXPORT FSTRING_LINK void
2016-09-04 01:44:12 +00:00
to_lower_ss ( String * dst , String src ) /*
2016-09-02 17:01:52 +00:00
DOC_PARAM ( dst , The destination buffer to receive the converted string .
This must have a capacity of at least the size of src . )
2016-09-04 01:44:12 +00:00
DOC_PARAM ( src , The source string to conver to lowercase . )
2016-09-02 17:01:52 +00:00
DOC ( Rewrites the string in src into dst . src and dst should not overlap with the exception
that src and dst may be exactly equal in order to convert the string in place . )
*/ {
2017-01-23 06:19:43 +00:00
i32_4tech i = 0 ;
i32_4tech size = src . size ;
2016-09-04 01:44:12 +00:00
char * c = src . str ;
2016-09-02 17:01:52 +00:00
char * d = dst - > str ;
if ( dst - > memory_size > = size ) {
for ( ; i < size ; + + i ) {
* d + + = char_to_lower ( * c + + ) ;
}
2016-09-04 01:44:12 +00:00
dst - > size = size ;
2016-09-02 17:01:52 +00:00
}
}
CPP_NAME ( to_lower )
2016-11-02 03:27:51 +00:00
API_EXPORT FSTRING_LINK void
2016-09-02 17:01:52 +00:00
to_lower_s ( String * str ) /*
DOC_PARAM ( str , The string to be converted to all lowercase . )
DOC ( This version of to_lower converts str to lowercase in place . )
*/ {
2017-01-23 06:19:43 +00:00
i32_4tech i = 0 ;
i32_4tech size = str - > size ;
2016-09-02 17:01:52 +00:00
char * c = str - > str ;
for ( ; i < size ; + + c , + + i ) {
* c = char_to_lower ( * c ) ;
}
}
CPP_NAME ( to_upper )
2016-11-02 03:27:51 +00:00
API_EXPORT FSTRING_LINK void
2016-09-02 17:01:52 +00:00
to_upper_cc ( char * src , char * dst ) /*
DOC_PARAM ( src , The source string to convert to uppercase . This string must be null terminated . )
2016-09-02 19:39:38 +00:00
DOC_PARAM ( dst , The destination buffer to receive the converted string .
This must be large enough to contain all of src and a null terminator . )
2016-09-02 17:01:52 +00:00
DOC ( Rewrites the string in src into dst . src and dst should not overlap with the exception
that src and dst may be exactly equal in order to convert the string in place . )
*/ {
for ( ; * src ! = 0 ; + + src ) {
* dst + + = char_to_upper ( * src ) ;
}
* dst + + = 0 ;
}
CPP_NAME ( to_upper )
2016-11-02 03:27:51 +00:00
API_EXPORT FSTRING_LINK void
2016-09-04 01:44:12 +00:00
to_upper_ss ( String * dst , String src ) /*
2016-09-02 17:01:52 +00:00
DOC_PARAM ( dst , The destination buffer to receive the converted string .
This must have a capacity of at least the size of src . )
2016-09-04 01:44:12 +00:00
DOC_PARAM ( src , The source string to convert to uppercase . )
2016-09-02 17:01:52 +00:00
DOC ( Rewrites the string in src into dst . src and dst should not overlap with the exception
that src and dst may be exactly equal in order to convert the string in place . )
*/ {
2017-01-23 06:19:43 +00:00
i32_4tech i = 0 ;
i32_4tech size = src . size ;
2016-09-04 01:44:12 +00:00
char * c = src . str ;
2016-09-02 17:01:52 +00:00
char * d = dst - > str ;
if ( dst - > memory_size > = size ) {
for ( ; i < size ; + + i ) {
* d + + = char_to_upper ( * c + + ) ;
}
2016-09-04 01:44:12 +00:00
dst - > size = size ;
2016-09-02 17:01:52 +00:00
}
}
CPP_NAME ( to_upper )
2016-11-02 03:27:51 +00:00
API_EXPORT FSTRING_LINK void
2016-09-02 17:01:52 +00:00
to_upper_s ( String * str ) /*
DOC_PARAM ( str , The string to be converted to all uppercase . )
DOC ( This version of to_upper converts str to uppercase in place . )
*/ {
2017-01-23 06:19:43 +00:00
i32_4tech i = 0 ;
i32_4tech size = str - > size ;
2016-09-02 17:01:52 +00:00
char * c = str - > str ;
for ( ; i < size ; + + c , + + i ) {
* c = char_to_upper ( * c ) ;
}
}
2016-09-02 19:39:38 +00:00
CPP_NAME ( to_camel )
2016-11-02 03:27:51 +00:00
API_EXPORT FSTRING_LINK void
2016-09-02 19:39:38 +00:00
to_camel_cc ( char * src , char * dst ) /*
DOC_PARAM ( src , The source string to convert to camel case . )
DOC_PARAM ( dst , The destination buffer to receive the converted string .
This must be large enough to contain all of src and a null terminator . )
DOC ( Rewrites the string in src into dst . src and dst should not overlap
with the exception that src and dst may be exactly equal in order to
convert the string in place . )
*/ {
char * c , ch ;
2017-01-23 06:19:43 +00:00
i32_4tech is_first = 1 ;
2016-09-02 19:39:38 +00:00
for ( c = src ; * c ! = 0 ; + + c ) {
ch = * c ;
if ( char_is_alpha_numeric_true ( ch ) ) {
if ( is_first ) {
is_first = 0 ;
ch = char_to_upper ( ch ) ;
}
else {
ch = char_to_lower ( ch ) ;
}
}
else {
is_first = 1 ;
}
* dst + + = ch ;
}
* dst = 0 ;
}
2016-07-06 19:18:10 +00:00
//
// String <-> Number Conversions
//
2017-01-23 06:19:43 +00:00
API_EXPORT FSTRING_LINK i32_4tech
int_to_str_size ( i32_4tech x ) /*
2016-07-12 22:17:45 +00:00
DOC ( This call returns the number of bytes required to represent x as a string . ) */ {
2017-01-23 06:19:43 +00:00
i32_4tech size = 1 ;
2016-07-06 19:18:10 +00:00
if ( x < 0 ) {
size = 2 ;
}
x / = 10 ;
while ( x ! = 0 ) {
x / = 10 ;
+ + size ;
}
return ( size ) ;
}
2017-01-23 06:19:43 +00:00
API_EXPORT FSTRING_LINK b32_4tech
int_to_str ( String * dest , i32_4tech x ) /*
2016-07-12 22:17:45 +00:00
DOC ( This call writes a string representation of x into dest . If there is enough
space in dest this call returns non - zero . ) */ {
2017-01-23 06:19:43 +00:00
b32_4tech result = 1 ;
2016-07-06 19:18:10 +00:00
char * str = dest - > str ;
2017-01-23 06:19:43 +00:00
i32_4tech memory_size = dest - > memory_size ;
i32_4tech size , i , j ;
b32_4tech negative ;
2016-07-06 19:18:10 +00:00
if ( x = = 0 ) {
str [ 0 ] = ' 0 ' ;
dest - > size = 1 ;
}
else {
size = 0 ;
negative = 0 ;
if ( x < 0 ) {
negative = 1 ;
x = - x ;
str [ size + + ] = ' - ' ;
}
while ( x ! = 0 ) {
if ( size = = memory_size ) {
result = 0 ;
break ;
}
i = x % 10 ;
x / = 10 ;
str [ size + + ] = ( char ) ( ' 0 ' + i ) ;
}
if ( result ) {
2017-01-23 06:19:43 +00:00
// NOTE(allen): Start i = 0 if not negative, start i = 1 if is negative because - should not be flipped if it is negative :)
2016-07-06 19:18:10 +00:00
for ( i = negative , j = size - 1 ; i < j ; + + i , - - j ) {
char temp = str [ i ] ;
str [ i ] = str [ j ] ;
str [ j ] = temp ;
}
dest - > size = size ;
}
else {
dest - > size = 0 ;
}
}
return ( result ) ;
}
2017-01-23 06:19:43 +00:00
API_EXPORT FSTRING_LINK b32_4tech
append_int_to_str ( String * dest , i32_4tech x ) /*
2016-07-12 22:17:45 +00:00
DOC ( This call appends a string representation of x onto dest . If there is enough
space in dest this call returns non - zero . ) */ {
2016-07-06 19:18:10 +00:00
String last_part = tailstr ( * dest ) ;
2017-01-23 06:19:43 +00:00
b32_4tech result = int_to_str ( & last_part , x ) ;
2016-07-06 19:18:10 +00:00
if ( result ) {
dest - > size + = last_part . size ;
}
return ( result ) ;
}
2017-01-23 06:19:43 +00:00
API_EXPORT FSTRING_LINK i32_4tech
2016-07-12 22:17:45 +00:00
u64_to_str_size ( uint64_t x ) /*
DOC ( This call returns the number of bytes required to represent x as a string . ) */ {
2017-06-27 01:11:23 +00:00
i32_4tech size = 1 ;
x / = 10 ;
while ( x ! = 0 ) {
2016-07-06 19:18:10 +00:00
x / = 10 ;
2017-06-27 01:11:23 +00:00
+ + size ;
2016-07-06 19:18:10 +00:00
}
return ( size ) ;
}
2017-01-23 06:19:43 +00:00
API_EXPORT FSTRING_LINK b32_4tech
2016-07-12 22:17:45 +00:00
u64_to_str ( String * dest , uint64_t x ) /*
DOC ( This call writes a string representation of x into dest . If there is enough
space in dest this call returns non - zero . ) */ {
2017-01-23 06:19:43 +00:00
b32_4tech result = 1 ;
2016-07-06 19:18:10 +00:00
char * str = dest - > str ;
2017-01-23 06:19:43 +00:00
i32_4tech memory_size = dest - > memory_size ;
i32_4tech size , i , j ;
2016-07-06 19:18:10 +00:00
if ( x = = 0 ) {
str [ 0 ] = ' 0 ' ;
dest - > size = 1 ;
}
else {
size = 0 ;
while ( x ! = 0 ) {
if ( size = = memory_size ) {
result = 0 ;
break ;
}
i = x % 10 ;
x / = 10 ;
str [ size + + ] = ( char ) ( ' 0 ' + i ) ;
}
if ( result ) {
for ( i = 0 , j = size - 1 ; i < j ; + + i , - - j ) {
char temp = str [ i ] ;
str [ i ] = str [ j ] ;
str [ j ] = temp ;
}
dest - > size = size ;
}
else {
dest - > size = 0 ;
}
}
return ( result ) ;
}
2017-01-23 06:19:43 +00:00
API_EXPORT FSTRING_LINK b32_4tech
2016-07-12 22:17:45 +00:00
append_u64_to_str ( String * dest , uint64_t x ) /*
DOC ( This call appends a string representation of x onto dest . If there is enough
space in dest this call returns non - zero . ) */ {
2016-07-06 19:18:10 +00:00
String last_part = tailstr ( * dest ) ;
2017-01-23 06:19:43 +00:00
b32_4tech result = u64_to_str ( & last_part , x ) ;
2016-07-06 19:18:10 +00:00
if ( result ) {
dest - > size + = last_part . size ;
}
return ( result ) ;
}
2017-01-23 06:19:43 +00:00
# if !defined(FSTRING_GUARD)
2016-08-28 04:31:06 +00:00
typedef struct Float_To_Str_Variables {
2017-01-23 06:19:43 +00:00
b32_4tech negative ;
i32_4tech int_part ;
i32_4tech dec_part ;
2016-08-28 04:31:06 +00:00
} Float_To_Str_Variables ;
2016-07-06 19:18:10 +00:00
2016-08-28 04:31:06 +00:00
static Float_To_Str_Variables
2016-07-06 19:18:10 +00:00
get_float_vars ( float x ) {
2018-11-20 08:18:54 +00:00
Float_To_Str_Variables vars = { } ;
2016-07-06 19:18:10 +00:00
if ( x < 0 ) {
2016-08-28 04:31:06 +00:00
vars . negative = 1 ;
2016-07-06 19:18:10 +00:00
x = - x ;
}
2017-01-23 06:19:43 +00:00
vars . int_part = ( i32_4tech ) ( x ) ;
vars . dec_part = ( i32_4tech ) ( ( x - vars . int_part ) * 1000 ) ;
2016-07-06 19:18:10 +00:00
return ( vars ) ;
}
# endif
2017-01-23 06:19:43 +00:00
API_EXPORT FSTRING_LINK i32_4tech
2016-07-12 22:17:45 +00:00
float_to_str_size ( float x ) /*
DOC ( This call returns the number of bytes required to represent x as a string . ) */ {
2016-07-06 19:18:10 +00:00
Float_To_Str_Variables vars = get_float_vars ( x ) ;
2017-01-23 06:19:43 +00:00
i32_4tech size = vars . negative + int_to_str_size ( vars . int_part ) + 1 + int_to_str_size ( vars . dec_part ) ;
2016-07-06 19:18:10 +00:00
return ( size ) ;
}
2017-01-23 06:19:43 +00:00
API_EXPORT FSTRING_LINK b32_4tech
2016-07-12 22:17:45 +00:00
append_float_to_str ( String * dest , float x ) /*
2017-01-23 06:19:43 +00:00
DOC ( This call writes a string representation of x into dest . If there is enough space in dest this call returns non - zero . ) */ {
b32_4tech result = 1 ;
2016-07-06 19:18:10 +00:00
Float_To_Str_Variables vars = get_float_vars ( x ) ;
if ( vars . negative ) {
2016-08-28 04:31:06 +00:00
append_s_char ( dest , ' - ' ) ;
2016-07-06 19:18:10 +00:00
}
append_int_to_str ( dest , vars . int_part ) ;
2016-08-28 04:31:06 +00:00
append_s_char ( dest , ' . ' ) ;
2016-07-06 19:18:10 +00:00
append_int_to_str ( dest , vars . dec_part ) ;
return ( result ) ;
}
2017-01-23 06:19:43 +00:00
API_EXPORT FSTRING_LINK b32_4tech
2016-07-12 22:17:45 +00:00
float_to_str ( String * dest , float x ) /*
2017-01-23 06:19:43 +00:00
DOC ( This call appends a string representation of x onto dest . If there is enough space in dest this call returns non - zero . ) */ {
b32_4tech result = 1 ;
2016-07-06 19:18:10 +00:00
dest - > size = 0 ;
append_float_to_str ( dest , x ) ;
return ( result ) ;
}
2016-08-28 04:31:06 +00:00
CPP_NAME ( str_is_int )
2017-01-23 06:19:43 +00:00
API_EXPORT FSTRING_LINK i32_4tech
2016-08-28 04:31:06 +00:00
str_is_int_c ( char * str ) /*
DOC ( If str is a valid string representation of an integer , this call returns non - zero ) */ {
2017-01-23 06:19:43 +00:00
b32_4tech result = 1 ;
2016-08-28 04:31:06 +00:00
for ( ; * str ; + + str ) {
if ( ! char_is_numeric ( * str ) ) {
result = 0 ;
break ;
}
}
return ( result ) ;
}
CPP_NAME ( str_is_int )
2017-01-23 06:19:43 +00:00
API_EXPORT FSTRING_LINK b32_4tech
2016-08-28 04:31:06 +00:00
str_is_int_s ( String str ) /*
2016-07-14 16:41:23 +00:00
DOC ( If str is a valid string representation of an integer , this call returns non - zero . ) */ {
2017-01-23 06:19:43 +00:00
b32_4tech result = 1 ;
for ( i32_4tech i = 0 ; i < str . size ; + + i ) {
2016-07-14 16:41:23 +00:00
if ( ! char_is_numeric ( str . str [ i ] ) ) {
2016-08-28 04:31:06 +00:00
result = 0 ;
2016-07-14 16:41:23 +00:00
break ;
}
}
return ( result ) ;
}
2016-08-28 04:31:06 +00:00
CPP_NAME ( str_to_int )
2017-01-23 06:19:43 +00:00
API_EXPORT FSTRING_LINK i32_4tech
2016-08-28 04:31:06 +00:00
str_to_int_c ( char * str ) /*
2016-07-14 16:41:23 +00:00
DOC ( If str is a valid string representation of an integer , this call will return
2016-07-12 22:17:45 +00:00
the integer represented by the string . Otherwise this call returns zero . ) */ {
2017-01-23 06:19:43 +00:00
i32_4tech x = 0 ;
2016-07-06 19:18:10 +00:00
for ( ; * str ; + + str ) {
2016-08-31 15:10:22 +00:00
if ( * str > = ' 0 ' & & * str < = ' 9 ' ) {
2016-07-06 19:18:10 +00:00
x * = 10 ;
x + = * str - ' 0 ' ;
}
else {
x = 0 ;
break ;
}
}
return ( x ) ;
}
2016-08-28 04:31:06 +00:00
CPP_NAME ( str_to_int )
2017-01-23 06:19:43 +00:00
API_EXPORT FSTRING_LINK i32_4tech
2016-08-28 04:31:06 +00:00
str_to_int_s ( String str ) /*
2016-07-12 22:17:45 +00:00
DOC ( If str represents a valid string representation of an integer , this call will return
the integer represented by the string . Otherwise this call returns zero . ) */ {
2017-01-23 06:19:43 +00:00
i32_4tech x , i ;
2016-07-06 19:18:10 +00:00
if ( str . size = = 0 ) {
x = 0 ;
}
else {
x = str . str [ 0 ] - ' 0 ' ;
for ( i = 1 ; i < str . size ; + + i ) {
x * = 10 ;
x + = str . str [ i ] - ' 0 ' ;
}
}
return ( x ) ;
}
2017-01-23 06:19:43 +00:00
API_EXPORT FSTRING_LINK i32_4tech
2016-07-12 22:17:45 +00:00
hexchar_to_int ( char c ) /*
DOC ( If c is a valid hexadecimal digit [ 0 - 9 a - fA - F ] this call returns the value of
the integer value of the digit . Otherwise the return is some nonsense value . ) */ {
2017-01-23 06:19:43 +00:00
i32_4tech x = 0 ;
2016-07-06 19:18:10 +00:00
if ( c > = ' 0 ' & & c < = ' 9 ' ) {
x = c - ' 0 ' ;
}
else if ( c > ' F ' ) {
x = c + ( 10 - ' a ' ) ;
}
else {
x = c + ( 10 - ' A ' ) ;
}
return ( x ) ;
}
2016-11-02 03:27:51 +00:00
API_EXPORT FSTRING_LINK char
2017-01-23 06:19:43 +00:00
int_to_hexchar ( i32_4tech x ) /*
2016-07-12 22:17:45 +00:00
DOC ( If x is in the range [ 0 , 15 ] this call returns the equivalent lowercase hexadecimal digit .
Otherwise the return is some nonsense value . ) */ {
2016-07-06 19:18:10 +00:00
return ( x < 10 ) ? ( ( char ) x + ' 0 ' ) : ( ( char ) x + ' a ' - 10 ) ;
}
2017-01-23 06:19:43 +00:00
API_EXPORT FSTRING_LINK u32_4tech
2016-07-12 22:17:45 +00:00
hexstr_to_int ( String str ) /*
DOC ( This call interprets str has a hexadecimal representation of an integer and returns
the represented integer value . ) */ {
2017-01-23 06:19:43 +00:00
u32_4tech x ;
i32_4tech i ;
2016-07-06 19:18:10 +00:00
if ( str . size = = 0 ) {
x = 0 ;
}
else {
x = hexchar_to_int ( str . str [ 0 ] ) ;
for ( i = 1 ; i < str . size ; + + i ) {
x * = 0x10 ;
x + = hexchar_to_int ( str . str [ i ] ) ;
}
}
return ( x ) ;
}
2017-01-23 06:19:43 +00:00
API_EXPORT FSTRING_LINK b32_4tech
color_to_hexstr ( String * s , u32_4tech color ) /*
2016-07-12 22:17:45 +00:00
DOC ( This call fills s with the hexadecimal representation of the color .
If there is enough memory in s to represent the color this call returns non - zero . ) */ {
2017-01-23 06:19:43 +00:00
b32_4tech result = 0 ;
i32_4tech i ;
2016-07-06 19:18:10 +00:00
if ( s - > memory_size = = 7 | | s - > memory_size = = 8 ) {
result = 1 ;
s - > size = 6 ;
s - > str [ 6 ] = 0 ;
color = color & 0x00FFFFFF ;
for ( i = 5 ; i > = 0 ; - - i ) {
s - > str [ i ] = int_to_hexchar ( color & 0xF ) ;
color > > = 4 ;
}
}
else if ( s - > memory_size > 8 ) {
result = 1 ;
s - > size = 8 ;
s - > str [ 8 ] = 0 ;
for ( i = 7 ; i > = 0 ; - - i ) {
s - > str [ i ] = int_to_hexchar ( color & 0xF ) ;
color > > = 4 ;
}
}
return ( result ) ;
}
2017-01-23 06:19:43 +00:00
API_EXPORT FSTRING_LINK b32_4tech
hexstr_to_color ( String s , u32_4tech * out ) /*
2016-07-12 22:17:45 +00:00
DOC ( This call interprets s as a color and writes the 32 - bit integer representation into out . ) */ {
2017-01-23 06:19:43 +00:00
b32_4tech result = 0 ;
u32_4tech color = 0 ;
2016-07-06 19:18:10 +00:00
if ( s . size = = 6 ) {
result = 1 ;
2017-01-23 06:19:43 +00:00
color = ( u32_4tech ) hexstr_to_int ( s ) ;
2016-07-06 19:18:10 +00:00
color | = ( 0xFF < < 24 ) ;
* out = color ;
}
else if ( s . size = = 8 ) {
result = 1 ;
2017-01-23 06:19:43 +00:00
color = ( u32_4tech ) hexstr_to_int ( s ) ;
2016-07-06 19:18:10 +00:00
* out = color ;
}
return ( result ) ;
}
//
// Directory String Management
//
2016-08-28 04:31:06 +00:00
CPP_NAME ( reverse_seek_slash )
2017-01-23 06:19:43 +00:00
API_EXPORT FSTRING_LINK i32_4tech
reverse_seek_slash_pos ( String str , i32_4tech pos ) /*
2016-07-12 22:17:45 +00:00
DOC ( This call searches for a slash in str by starting pos bytes from the end and going backwards . ) */ {
2017-01-23 06:19:43 +00:00
i32_4tech i = str . size - 1 - pos ;
2016-07-12 22:17:45 +00:00
while ( i > = 0 & & ! char_is_slash ( str . str [ i ] ) ) {
2016-07-06 19:18:10 +00:00
- - i ;
}
return i ;
}
2017-01-23 06:19:43 +00:00
API_EXPORT_INLINE FSTRING_INLINE i32_4tech
2016-07-12 22:17:45 +00:00
reverse_seek_slash ( String str ) /*
DOC ( This call searches for a slash in str by starting at the end and going backwards . ) */ {
2016-08-28 04:31:06 +00:00
return ( reverse_seek_slash_pos ( str , 0 ) ) ;
2016-07-06 19:18:10 +00:00
}
2016-11-02 03:27:51 +00:00
API_EXPORT_INLINE FSTRING_INLINE String
2016-07-12 22:17:45 +00:00
front_of_directory ( String dir ) /*
DOC ( This call returns a substring of dir containing only the file name or
folder name furthest to the right in the directory . ) DOC_SEE ( substr ) */ {
2016-08-28 04:31:06 +00:00
return substr_tail ( dir , reverse_seek_slash ( dir ) + 1 ) ;
2016-07-06 19:18:10 +00:00
}
2016-11-02 03:27:51 +00:00
API_EXPORT_INLINE FSTRING_INLINE String
2016-07-12 22:17:45 +00:00
path_of_directory ( String dir ) /*
DOC ( This call returns a substring of dir containing the whole path except
for the final file or folder name . ) DOC_SEE ( substr ) */ {
2016-07-06 19:18:10 +00:00
return substr ( dir , 0 , reverse_seek_slash ( dir ) + 1 ) ;
}
2016-08-28 04:31:06 +00:00
CPP_NAME ( set_last_folder )
2017-01-23 06:19:43 +00:00
API_EXPORT FSTRING_LINK b32_4tech
2016-08-28 04:31:06 +00:00
set_last_folder_sc ( String * dir , char * folder_name , char slash ) /*
2016-07-12 22:17:45 +00:00
DOC_PARAM ( dir , The dir parameter is the directory string in which to set the last folder in the directory . )
DOC_PARAM ( folder_name , The folder_name parameter is a null terminated string specifying the name to set
at the end of the directory . )
DOC_PARAM ( slash , The slash parameter specifies what slash to use between names in the directory . )
DOC ( This call deletes the last file name or folder name in the dir string and appends the new provided one .
If there is enough memory in dir this call returns non - zero . ) */ {
2017-01-23 06:19:43 +00:00
b32_4tech result = 0 ;
i32_4tech size = reverse_seek_slash ( * dir ) + 1 ;
2016-07-06 19:18:10 +00:00
dir - > size = size ;
2016-08-28 04:31:06 +00:00
if ( append_sc ( dir , folder_name ) ) {
if ( append_s_char ( dir , slash ) ) {
2016-07-06 19:18:10 +00:00
result = 1 ;
}
}
if ( ! result ) {
dir - > size = size ;
}
2016-08-28 04:31:06 +00:00
return ( result ) ;
2016-07-06 19:18:10 +00:00
}
2016-08-28 04:31:06 +00:00
CPP_NAME ( set_last_folder )
2017-01-23 06:19:43 +00:00
API_EXPORT FSTRING_LINK b32_4tech
2016-08-28 04:31:06 +00:00
set_last_folder_ss ( String * dir , String folder_name , char slash ) /*
2016-07-12 22:17:45 +00:00
DOC_PARAM ( dir , The dir parameter is the directory string in which to set the last folder in the directory . )
DOC_PARAM ( folder_name , The folder_name parameter is a string specifying the name to set at the end of the directory . )
DOC_PARAM ( slash , The slash parameter specifies what slash to use between names in the directory . )
DOC ( This call deletes the last file name or folder name in the dir string and appends the new provided one .
If there is enough memory in dir this call returns non - zero . ) */ {
2017-01-23 06:19:43 +00:00
b32_4tech result = 0 ;
i32_4tech size = reverse_seek_slash ( * dir ) + 1 ;
2016-07-06 19:18:10 +00:00
dir - > size = size ;
2016-08-28 04:31:06 +00:00
if ( append_ss ( dir , folder_name ) ) {
if ( append_s_char ( dir , slash ) ) {
2016-07-06 19:18:10 +00:00
result = 1 ;
}
}
if ( ! result ) {
dir - > size = size ;
}
2016-08-28 04:31:06 +00:00
return ( result ) ;
2016-07-06 19:18:10 +00:00
}
2016-11-02 03:27:51 +00:00
API_EXPORT FSTRING_LINK String
2016-07-12 22:17:45 +00:00
file_extension ( String str ) /*
DOC ( This call returns a substring containing only the file extension of the provided filename . )
DOC_SEE ( substr ) */ {
2017-01-23 06:19:43 +00:00
i32_4tech i ;
2016-07-06 19:18:10 +00:00
for ( i = str . size - 1 ; i > = 0 ; - - i ) {
if ( str . str [ i ] = = ' . ' ) break ;
}
+ + i ;
2016-08-28 04:31:06 +00:00
return ( make_string ( str . str + i , str . size - i ) ) ;
2016-07-06 19:18:10 +00:00
}
2017-01-23 06:19:43 +00:00
API_EXPORT FSTRING_LINK b32_4tech
2016-09-02 15:58:04 +00:00
remove_extension ( String * str ) /*
DOC ( This call attemps to delete a file extension off the end of a filename .
This call returns non - zero on success . ) */ {
2017-01-23 06:19:43 +00:00
b32_4tech result = 0 ;
i32_4tech i ;
2016-09-02 15:58:04 +00:00
for ( i = str - > size - 1 ; i > = 0 ; - - i ) {
if ( str - > str [ i ] = = ' . ' ) break ;
}
if ( i > = 0 ) {
result = 1 ;
str - > size = i + 1 ;
}
return ( result ) ;
}
2017-01-23 06:19:43 +00:00
API_EXPORT FSTRING_LINK b32_4tech
2016-07-12 22:17:45 +00:00
remove_last_folder ( String * str ) /*
DOC ( This call attemps to delete a folder or filename off the end of a path string .
This call returns non - zero on success . ) */ {
2017-01-23 06:19:43 +00:00
b32_4tech result = 0 ;
i32_4tech end = reverse_seek_slash_pos ( * str , 1 ) ;
2016-07-06 19:18:10 +00:00
if ( end > = 0 ) {
result = 1 ;
str - > size = end + 1 ;
}
return ( result ) ;
}
2016-09-03 21:04:55 +00:00
CPP_NAME ( string_set_match )
2017-01-23 06:19:43 +00:00
API_EXPORT FSTRING_LINK b32_4tech
string_set_match_table ( void * str_set , i32_4tech item_size , i32_4tech count , String str , i32_4tech * match_index ) /*
2016-11-12 21:33:54 +00:00
DOC_PARAM ( str_set , The str_set parameter may be an array of any type . It should point at the String in the first element of the array . )
DOC_PARAM ( count , The item_size parameter should describe the " stride " from one String to the next , in other words it should be the size of one element of the array . )
2016-09-06 01:46:41 +00:00
DOC_PARAM ( count , The count parameter specifies the number of elements in the str_set array . )
2016-07-12 22:17:45 +00:00
DOC_PARAM ( str , The str parameter specifies the string to match against the str_set . )
DOC_PARAM ( match_index , If this call succeeds match_index is filled with the index into str_set where the match occurred . )
2016-11-12 21:33:54 +00:00
DOC ( This call tries to see if str matches any of the strings in str_set . If there is a match the call succeeds and returns non - zero . The matching rule is equivalent to the matching rule for match . )
2016-07-12 22:17:45 +00:00
DOC_SEE ( match ) */ {
2017-01-23 06:19:43 +00:00
b32_4tech result = 0 ;
i32_4tech i = 0 ;
2019-02-26 23:30:08 +00:00
u8_4tech * ptr = ( u8_4tech * ) str_set ;
2016-09-03 21:04:55 +00:00
for ( ; i < count ; + + i , ptr + = item_size ) {
if ( match_ss ( * ( String * ) ptr , str ) ) {
2016-07-06 19:18:10 +00:00
* match_index = i ;
2016-08-28 04:31:06 +00:00
result = 1 ;
2016-07-06 19:18:10 +00:00
break ;
}
}
return ( result ) ;
}
2017-01-23 06:19:43 +00:00
API_EXPORT FSTRING_LINK b32_4tech
string_set_match ( String * str_set , i32_4tech count , String str , i32_4tech * match_index ) /*
2016-09-03 21:04:55 +00:00
DOC_PARAM ( str_set , The str_set parameter is an array of String structs specifying matchable strings . )
DOC_PARAM ( count , The count parameter specifies the number of String structs in the str_set array . )
DOC_PARAM ( str , The str parameter specifies the string to match against the str_set . )
DOC_PARAM ( match_index , If this call succeeds match_index is filled with the index into str_set where the match occurred . )
2016-11-12 21:33:54 +00:00
DOC ( This call tries to see if str matches any of the strings in str_set . If there is a match the call succeeds and returns non - zero . The matching rule is equivalent to the matching rule for match . )
2016-09-03 21:04:55 +00:00
DOC_SEE ( match ) */ {
2017-01-23 06:19:43 +00:00
b32_4tech result = string_set_match_table ( str_set , sizeof ( String ) , count , str , match_index ) ;
2016-09-03 21:04:55 +00:00
return ( result ) ;
}
2016-11-05 02:59:35 +00:00
API_EXPORT FSTRING_LINK String
2016-11-12 21:33:54 +00:00
get_first_double_line ( String source ) /*
DOC_PARAM ( source , the source string accross which a ' double line ' iteration will occur )
DOC_RETURN ( The returned value is the first ' double line ' in the source string . )
DOC ( A ' double line ' is a string of characters delimited by two new line characters . This call begins an iteration over all the double lines in the given source string . )
DOC_SEE ( get_next_double_line )
*/ {
2018-11-20 08:18:54 +00:00
String line = { } ;
2017-01-23 06:19:43 +00:00
i32_4tech pos0 = find_substr_s ( source , 0 , make_lit_string ( " \n \n " ) ) ;
i32_4tech pos1 = find_substr_s ( source , 0 , make_lit_string ( " \r \n \r \n " ) ) ;
2016-11-05 02:59:35 +00:00
if ( pos1 < pos0 ) {
pos0 = pos1 ;
}
line = substr ( source , 0 , pos0 ) ;
return ( line ) ;
}
API_EXPORT FSTRING_LINK String
2016-11-12 21:33:54 +00:00
get_next_double_line ( String source , String line ) /*
DOC_PARAM ( source , the source string accross which the ' double line ' iteration is occurring )
DOC_PARAM ( line , the value returned from the previous call of get_first_double_line or get_next_double_line )
DOC_RETURN ( The returned value is the first ' double line ' in the source string . )
DOC_SEE ( get_first_double_line )
*/ {
2018-11-20 08:18:54 +00:00
String next = { } ;
2017-01-23 06:19:43 +00:00
i32_4tech pos = ( i32_4tech ) ( line . str - source . str ) + line . size ;
i32_4tech start = 0 , pos0 = 0 , pos1 = 0 ;
2016-11-05 02:59:35 +00:00
if ( pos < source . size ) {
//Assert(source.str[pos] == '\n' || source.str[pos] == '\r');
start = pos + 1 ;
if ( start < source . size ) {
pos0 = find_substr_s ( source , start , make_lit_string ( " \n \n " ) ) ;
pos1 = find_substr_s ( source , start , make_lit_string ( " \r \n \r \n " ) ) ;
if ( pos1 < pos0 ) {
pos0 = pos1 ;
}
next = substr ( source , start , pos0 - start ) ;
}
}
return ( next ) ;
}
API_EXPORT FSTRING_LINK String
2016-11-12 21:33:54 +00:00
get_next_word ( String source , String prev_word ) /*
DOC_PARAM ( source , the source string accross which the ' word ' iteration is occurring )
DOC_PARAM ( line , the value returned from the previous call of get_first_word or get_next_word )
DOC_RETURN ( The returned value is the first ' word ' in the source string . )
DOC_SEE ( get_first_word )
*/ {
2016-11-05 02:59:35 +00:00
2018-11-20 08:18:54 +00:00
String word = { } ;
2017-01-23 06:19:43 +00:00
i32_4tech pos0 = ( i32_4tech ) ( prev_word . str - source . str ) + prev_word . size ;
i32_4tech pos1 = 0 ;
2016-11-05 02:59:35 +00:00
char c = 0 ;
for ( ; pos0 < source . size ; + + pos0 ) {
c = source . str [ pos0 ] ;
if ( ! ( char_is_whitespace ( c ) | | c = = ' ( ' | | c = = ' ) ' ) ) {
break ;
}
}
if ( pos0 < source . size ) {
for ( pos1 = pos0 ; pos1 < source . size ; + + pos1 ) {
c = source . str [ pos1 ] ;
if ( char_is_whitespace ( c ) | | c = = ' ( ' | | c = = ' ) ' ) {
break ;
}
}
word = substr ( source , pos0 , pos1 - pos0 ) ;
}
return ( word ) ;
}
API_EXPORT FSTRING_LINK String
2016-11-12 21:33:54 +00:00
get_first_word ( String source ) /*
DOC_PARAM ( source , the source string accross which a ' word ' iteration will occur )
DOC_RETURN ( The returned value is the first ' word ' in the source string . )
DOC ( A ' word ' is a string of characters delimited by whitespace or parentheses . This call begins an iteration over all the double lines in the given source string . )
DOC_SEE ( get_next_word )
*/ {
2016-11-05 02:59:35 +00:00
String start_str = make_string ( source . str , 0 ) ;
String word = get_next_word ( source , start_str ) ;
return ( word ) ;
}
2016-09-03 21:04:55 +00:00
2018-11-28 04:36:09 +00:00
API_EXPORT FSTRING_LINK String
string_push ( Partition * part , i32_4tech size ) /*
DOC_PARAM ( part , A partition on which the string will be allocated . )
DOC_PARAM ( size , The number of bytes to allocated for the new string . )
DOC_RETURN ( If successfull returns an empty string with capacity equal to the size parameter , otherwise returns a null string . ) */ {
String result = { } ;
2018-12-10 01:31:30 +00:00
if ( size > 0 ) {
result . str = push_array ( part , char , size ) ;
if ( result . str ! = 0 ) {
result . memory_size = size ;
}
2018-11-28 04:36:09 +00:00
}
return ( result ) ;
}
API_EXPORT FSTRING_LINK String
string_push_copy ( Partition * part , String str ) /*
DOC_PARAM ( part , A partition on which the string will be allocated . )
DOC_PARAM ( str , The source string to copy into the new string . The copy includes a null terminator whther or not the source does . )
DOC_RETURN ( If successfull returns a string copy of str , otherwise returns a null string . ) */ {
String result = { } ;
2018-12-10 01:31:30 +00:00
if ( str . str ! = 0 ) {
result . str = push_array ( part , char , str . size + 1 ) ;
if ( result . str ! = 0 ) {
result . memory_size = str . size + 1 ;
copy ( & result , str ) ;
result . str [ result . size ] = 0 ;
}
2018-11-28 04:36:09 +00:00
}
return ( result ) ;
}
2017-01-23 06:19:43 +00:00
// TODO(allen): eliminate this.
2016-07-06 19:18:10 +00:00
# ifndef FSTRING_EXPERIMENTAL
# define FSTRING_EXPERIMENTAL
// NOTE(allen): experimental section, things below here are
// not promoted to public API level yet.
2016-08-28 04:31:06 +00:00
typedef struct Absolutes {
2016-07-06 19:18:10 +00:00
String a [ 8 ] ;
2017-01-23 06:19:43 +00:00
i32_4tech count ;
2016-08-28 04:31:06 +00:00
} Absolutes ;
2016-07-06 19:18:10 +00:00
static void
2017-01-23 06:19:43 +00:00
get_absolutes ( String name , Absolutes * absolutes , b32_4tech implicit_first , b32_4tech implicit_last ) {
2017-01-03 20:05:35 +00:00
if ( name . size ! = 0 ) {
2017-01-23 06:19:43 +00:00
i32_4tech count = 0 ;
2017-01-29 00:03:23 +00:00
i32_4tech max = ( sizeof ( absolutes - > a ) / sizeof ( * absolutes - > a ) ) - 1 ;
2017-01-03 20:05:35 +00:00
if ( implicit_last ) - - max ;
String str ;
str . str = name . str ;
str . size = 0 ;
str . memory_size = 0 ;
2017-01-23 06:19:43 +00:00
b32_4tech prev_was_wild = 0 ;
2017-01-03 20:05:35 +00:00
if ( implicit_first ) {
absolutes - > a [ count + + ] = str ;
2016-07-06 19:18:10 +00:00
prev_was_wild = 1 ;
}
2017-01-03 20:05:35 +00:00
2017-01-23 06:19:43 +00:00
i32_4tech i ;
2017-01-03 20:05:35 +00:00
for ( i = 0 ; i < name . size ; + + i ) {
if ( name . str [ i ] = = ' * ' & & count < max ) {
if ( ! prev_was_wild ) {
str . memory_size = str . size ;
absolutes - > a [ count + + ] = str ;
str . size = 0 ;
}
str . str = name . str + i + 1 ;
prev_was_wild = 1 ;
}
else {
+ + str . size ;
prev_was_wild = 0 ;
}
2016-07-06 19:18:10 +00:00
}
2017-01-03 20:05:35 +00:00
str . memory_size = str . size ;
2016-07-06 19:18:10 +00:00
absolutes - > a [ count + + ] = str ;
2017-01-03 20:05:35 +00:00
if ( implicit_last ) {
str . size = 0 ;
str . memory_size = 0 ;
absolutes - > a [ count + + ] = str ;
}
absolutes - > count = count ;
}
else {
absolutes - > count = 0 ;
2016-07-06 19:18:10 +00:00
}
}
2017-01-23 06:19:43 +00:00
static b32_4tech
wildcard_match_c ( Absolutes * absolutes , char * x , i32_4tech case_sensitive ) {
b32_4tech r = 1 ;
2016-07-06 19:18:10 +00:00
2017-01-03 20:05:35 +00:00
if ( absolutes - > count > 0 ) {
String * a = absolutes - > a ;
2017-01-23 06:19:43 +00:00
b32_4tech ( * match_func ) ( char * , String ) ;
b32_4tech ( * match_part_func ) ( char * , String ) ;
2017-01-03 20:05:35 +00:00
if ( case_sensitive ) {
match_func = match_cs ;
match_part_func = match_part_cs ;
2016-07-06 19:18:10 +00:00
}
else {
2017-01-03 20:05:35 +00:00
match_func = match_insensitive_cs ;
match_part_func = match_part_insensitive_cs ;
}
if ( absolutes - > count = = 1 ) {
r = match_func ( x , * a ) ;
}
else {
if ( ! match_part_func ( x , * a ) ) {
2016-07-06 19:18:10 +00:00
r = 0 ;
2017-01-03 20:05:35 +00:00
}
else {
String * max = a + absolutes - > count - 1 ;
x + = a - > size ;
+ + a ;
while ( a < max ) {
if ( * x = = 0 ) {
r = 0 ;
2016-07-06 19:18:10 +00:00
break ;
}
2017-01-03 20:05:35 +00:00
if ( match_part_func ( x , * a ) ) {
x + = a - > size ;
+ + a ;
}
2016-07-06 19:18:10 +00:00
else {
+ + x ;
}
}
2017-01-03 20:05:35 +00:00
if ( r & & a - > size > 0 ) {
r = 0 ;
while ( * x ! = 0 ) {
if ( match_part_func ( x , * a ) & & * ( x + a - > size ) = = 0 ) {
r = 1 ;
break ;
}
else {
+ + x ;
}
}
}
2016-07-06 19:18:10 +00:00
}
}
}
2016-08-28 04:31:06 +00:00
return ( r ) ;
2016-07-06 19:18:10 +00:00
}
2017-01-23 06:19:43 +00:00
static b32_4tech
wildcard_match_s ( Absolutes * absolutes , String x , i32_4tech case_sensitive ) {
2016-07-06 19:18:10 +00:00
terminate_with_null ( & x ) ;
2016-08-28 04:31:06 +00:00
return ( wildcard_match_c ( absolutes , x . str , case_sensitive ) ) ;
2016-07-06 19:18:10 +00:00
}
# endif
2016-08-28 04:31:06 +00:00
# if defined(FSTRING_IMPLEMENTATION)
2016-07-06 19:18:10 +00:00
# undef FSTRING_IMPLEMENTATION
2017-01-23 06:19:43 +00:00
# define FSTRING_IMPL_GUARD
2016-07-06 19:18:10 +00:00
# endif
2016-08-28 04:31:06 +00:00
# if !defined(FSTRING_GUARD)
2016-07-06 19:18:10 +00:00
# define FSTRING_GUARD
# endif
// BOTTOM