const uint16_t * u16_grapheme_prev (const uint16_t *s, const uint16_t *start) { ucs4_t next; if (s == start) return NULL; s = u16_prev (&next, s, start); while (s != start) { const uint16_t *prev_s; ucs4_t prev; prev_s = u16_prev (&prev, s, start); if (prev_s == NULL) { /* Ill-formed UTF-16 encoding. */ return start; } if (uc_is_grapheme_break (prev, next)) break; s = prev_s; next = prev; } return s; }
static int check_invalid (const uint16_t *input, size_t input_length) { ucs4_t uc; /* Test recognition when at the beginning of the string. */ uc = 0xBADFACE; if (u16_prev (&uc, input + input_length, input) != NULL) return 1; if (uc != 0xBADFACE) return 2; #if CONFIG_UNICODE_SAFETY /* Test recognition when preceded by a 1-unit character. */ { uint16_t buf[100]; uint16_t *ptr; size_t i; ptr = buf; *ptr++ = 0x2102; for (i = 0; i < input_length; i++) ptr[i] = input[i]; uc = 0xBADFACE; if (u16_prev (&uc, ptr + input_length, buf) != NULL) return 3; if (uc != 0xBADFACE) return 4; } /* Test recognition when preceded by a 2-unit character. */ { uint16_t buf[100]; uint16_t *ptr; size_t i; ptr = buf; *ptr++ = 0xD835; *ptr++ = 0xDD1E; for (i = 0; i < input_length; i++) ptr[i] = input[i]; uc = 0xBADFACE; if (u16_prev (&uc, ptr + input_length, buf) != NULL) return 5; if (uc != 0xBADFACE) return 6; } #endif return 0; }
static int check (const uint16_t *input, size_t input_length, ucs4_t *puc) { ucs4_t uc; /* Test recognition when at the beginning of the string. */ if (u16_prev (&uc, input + input_length, input) != input) return 1; /* Test recognition when preceded by a 1-unit character. */ { uint16_t buf[100]; uint16_t *ptr; size_t i; ucs4_t uc1; ptr = buf; *ptr++ = 0x2102; for (i = 0; i < input_length; i++) ptr[i] = input[i]; if (u16_prev (&uc1, ptr + input_length, buf) != ptr) return 2; if (uc1 != uc) return 3; } /* Test recognition when preceded by a 2-unit character. */ { uint16_t buf[100]; uint16_t *ptr; size_t i; ucs4_t uc1; ptr = buf; *ptr++ = 0xD835; *ptr++ = 0xDD1E; for (i = 0; i < input_length; i++) ptr[i] = input[i]; if (u16_prev (&uc1, ptr + input_length, buf) != ptr) return 4; if (uc1 != uc) return 5; } *puc = uc; return 0; }