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'
|
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
@@ -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
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user