Add new function string_pop_u
to pop the last unicode code point of a string.
This commit is contained in:
1 parent
dafe4bcec5
commit
ecfa4a9152
3 files changed
+72
-1
No files matched your search
@@ -5718,6 +5718,13 @@ Return true if both iterators reference the same position, false otherwise.
|
||||
Push the unicode code point 'u' into the string 'str'
|
||||
encoding it as a variable UTF8 encoded code point.
|
||||
|
||||
##### bool string\_pop\_u (string\_unicode\_t *u, string\_t str)
|
||||
|
||||
Pop the last unicode code point from the string 'str'
|
||||
encoded as a variable UTF8 encoded code point
|
||||
and store in '*u' the popped unicode code point if 'u' is not NULL.
|
||||
It returns true in case of succes or false otherwise (no character to pop or no valid UTF8).
|
||||
|
||||
##### size\_t string\_length\_u(string\_t str)
|
||||
|
||||
Return the number of UTF8 encoded code point in the string.
|
||||
|
||||
+34
-1
@@ -63,7 +63,7 @@ typedef enum {
|
||||
M_STR1NG_UTF8_STARTING = 0,
|
||||
M_STR1NG_UTF8_DECODING_1 = 8,
|
||||
M_STR1NG_UTF8_DECODING_2 = 16,
|
||||
M_STR1NG_UTF8_DOCODING_3 = 24,
|
||||
M_STR1NG_UTF8_DECODING_3 = 24,
|
||||
M_STR1NG_UTF8_ERROR = 32
|
||||
} m_str1ng_utf8_state_e;
|
||||
|
||||
@@ -1873,6 +1873,38 @@ m_string_push_u (m_string_t str, m_string_unicode_t u)
|
||||
m_string_cat_cstr(str, buffer);
|
||||
}
|
||||
|
||||
/* Pop last unicode code point into string, encoding it in UTF8 */
|
||||
static inline bool
|
||||
m_string_pop_u(m_string_unicode_t *u, m_string_t str)
|
||||
{
|
||||
M_STR1NG_CONTRACT(str);
|
||||
char *org = m_str1ng_get_cstr(str);
|
||||
size_t len = m_string_size(str);
|
||||
// From the last byte in the string
|
||||
while (len > 0) {
|
||||
len--;
|
||||
// Test if it is a start of an UTF8 code point
|
||||
if (m_str1ng_utf8_start_p((unsigned char) org[len])) {
|
||||
// Yes, so decode the UTF8
|
||||
m_str1ng_utf8_state_e state = M_STR1NG_UTF8_STARTING;
|
||||
const char *tmp = &org[len];
|
||||
// Support of NULL pointer
|
||||
m_string_unicode_t u_tmp;
|
||||
m_string_unicode_t *u_ptr = u == NULL ? &u_tmp : u;
|
||||
do {
|
||||
m_str1ng_utf8_decode(*tmp++, &state, u_ptr);
|
||||
} while (state != M_STR1NG_UTF8_STARTING && state != M_STR1NG_UTF8_ERROR);
|
||||
// Final null char for the string
|
||||
org[len] = 0;
|
||||
m_str1ng_set_size(str, len);
|
||||
M_STR1NG_CONTRACT(str);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// Fail to pop a unicode code
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Compute the length in UTF8 code points in the string */
|
||||
static inline size_t
|
||||
m_string_length_u(m_string_t str)
|
||||
@@ -2674,6 +2706,7 @@ namespace m_lib {
|
||||
#define string_get_cref m_string_get_cref
|
||||
#define string_cref m_string_cref
|
||||
#define string_push_u m_string_push_u
|
||||
#define string_pop_u m_string_pop_u
|
||||
#define string_length_u m_string_length_u
|
||||
#define string_utf8_p m_string_utf8_p
|
||||
#define string_set_ui m_string_set_ui
|
||||
|
||||
@@ -55,6 +55,37 @@ static void test_utf8_basic(void)
|
||||
string_push_u(s, i);
|
||||
assert(string_utf8_p(s) == true);
|
||||
assert(string_length_u(s) == 1);
|
||||
string_unicode_t j;
|
||||
bool b = string_pop_u(&j, s);
|
||||
assert(b);
|
||||
assert(i== j);
|
||||
assert(string_utf8_p(s) == true);
|
||||
assert(string_length_u(s) == 0);
|
||||
assert(string_size(s) == 0);
|
||||
string_push_u(s, 'A');
|
||||
string_push_u(s, i);
|
||||
size_t len = string_size(s);
|
||||
string_push_u(s, i);
|
||||
assert(string_utf8_p(s) == true);
|
||||
assert(string_length_u(s) == 3);
|
||||
b = string_pop_u(&j, s);
|
||||
assert(b);
|
||||
assert(i== j);
|
||||
assert(string_utf8_p(s) == true);
|
||||
assert(string_length_u(s) == 2);
|
||||
assert(string_size(s) == len);
|
||||
b = string_pop_u(NULL, s);
|
||||
assert(b);
|
||||
assert(string_utf8_p(s) == true);
|
||||
assert(string_length_u(s) == 1);
|
||||
assert(string_size(s) == 1);
|
||||
b = string_pop_u(NULL, s);
|
||||
assert(b);
|
||||
assert(string_utf8_p(s) == true);
|
||||
assert(string_length_u(s) == 0);
|
||||
assert(string_size(s) == 0);
|
||||
b = string_pop_u(NULL, s);
|
||||
assert(!b);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user