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' Push the unicode code point 'u' into the string 'str'
encoding it as a variable UTF8 encoded code point. 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) ##### size\_t string\_length\_u(string\_t str)
Return the number of UTF8 encoded code point in the string. 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_STARTING = 0,
M_STR1NG_UTF8_DECODING_1 = 8, M_STR1NG_UTF8_DECODING_1 = 8,
M_STR1NG_UTF8_DECODING_2 = 16, 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_ERROR = 32
} m_str1ng_utf8_state_e; } 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); 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 */ /* Compute the length in UTF8 code points in the string */
static inline size_t static inline size_t
m_string_length_u(m_string_t str) 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_get_cref m_string_get_cref
#define string_cref m_string_cref #define string_cref m_string_cref
#define string_push_u m_string_push_u #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_length_u m_string_length_u
#define string_utf8_p m_string_utf8_p #define string_utf8_p m_string_utf8_p
#define string_set_ui m_string_set_ui #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); string_push_u(s, i);
assert(string_utf8_p(s) == true); assert(string_utf8_p(s) == true);
assert(string_length_u(s) == 1); 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);
} }
} }