Add new function string_pop_u

to pop the last unicode code point
of a string.
This commit is contained in:
Patrick Pelissier committed 2023-06-03 00:59:34 +02:00
1 parent dafe4bcec5
commit ecfa4a9152
3 files changed
+72 -1

No files matched your search

+7
View File
@@ -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
View File
@@ -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
+31
View File
@@ -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);
}
}