1
1
/* Iterating through multibyte strings: macros for multi-byte encodings.
2
Copyright (C) 2001, 2005, 2007 Free Software Foundation, Inc.
2
Copyright (C) 2001, 2005, 2007, 2009, 2010 Free Software Foundation, Inc.
4
4
This program is free software: you can redistribute it and/or modify
5
5
it under the terms of the GNU General Public License as published by
78
78
Here are the function prototypes of the macros.
80
extern void mbui_init (mbui_iterator_t iter, const char *startptr);
81
extern bool mbui_avail (mbui_iterator_t iter);
82
extern void mbui_advance (mbui_iterator_t iter);
83
extern mbchar_t mbui_cur (mbui_iterator_t iter);
84
extern const char * mbui_cur_ptr (mbui_iterator_t iter);
85
extern void mbui_reloc (mbui_iterator_t iter, ptrdiff_t ptrdiff);
86
extern void mbui_copy (mbui_iterator_t *new, const mbui_iterator_t *old);
80
extern void mbui_init (mbui_iterator_t iter, const char *startptr);
81
extern bool mbui_avail (mbui_iterator_t iter);
82
extern void mbui_advance (mbui_iterator_t iter);
83
extern mbchar_t mbui_cur (mbui_iterator_t iter);
84
extern const char * mbui_cur_ptr (mbui_iterator_t iter);
85
extern void mbui_reloc (mbui_iterator_t iter, ptrdiff_t ptrdiff);
86
extern void mbui_copy (mbui_iterator_t *new, const mbui_iterator_t *old);
109
109
struct mbuiter_multi
111
bool in_shift; /* true if next byte may not be interpreted as ASCII */
112
mbstate_t state; /* if in_shift: current shift state */
113
bool next_done; /* true if mbui_avail has already filled the following */
114
struct mbchar cur; /* the current character:
115
const char *cur.ptr pointer to current character
116
The following are only valid after mbui_avail.
117
size_t cur.bytes number of bytes of current character
118
bool cur.wc_valid true if wc is a valid wide character
119
wchar_t cur.wc if wc_valid: the current character
111
bool in_shift; /* true if next byte may not be interpreted as ASCII */
112
mbstate_t state; /* if in_shift: current shift state */
113
bool next_done; /* true if mbui_avail has already filled the following */
114
struct mbchar cur; /* the current character:
115
const char *cur.ptr pointer to current character
116
The following are only valid after mbui_avail.
117
size_t cur.bytes number of bytes of current character
118
bool cur.wc_valid true if wc is a valid wide character
119
wchar_t cur.wc if wc_valid: the current character
123
123
static inline void
131
131
if (is_basic (*iter->cur.ptr))
133
133
/* These characters are part of the basic character set. ISO C 99
134
guarantees that their wide character code is identical to their
134
guarantees that their wide character code is identical to their
136
136
iter->cur.bytes = 1;
137
137
iter->cur.wc = *iter->cur.ptr;
138
138
iter->cur.wc_valid = true;
143
143
iter->in_shift = true;
145
145
iter->cur.bytes = mbrtowc (&iter->cur.wc, iter->cur.ptr,
146
strnlen1 (iter->cur.ptr, MB_CUR_MAX),
146
strnlen1 (iter->cur.ptr, MB_CUR_MAX),
148
148
if (iter->cur.bytes == (size_t) -1)
150
/* An invalid multibyte sequence was encountered. */
152
iter->cur.wc_valid = false;
153
/* Whether to set iter->in_shift = false and reset iter->state
154
or not is not very important; the string is bogus anyway. */
150
/* An invalid multibyte sequence was encountered. */
152
iter->cur.wc_valid = false;
153
/* Whether to set iter->in_shift = false and reset iter->state
154
or not is not very important; the string is bogus anyway. */
156
156
else if (iter->cur.bytes == (size_t) -2)
158
/* An incomplete multibyte character at the end. */
159
iter->cur.bytes = strlen (iter->cur.ptr);
160
iter->cur.wc_valid = false;
161
/* Whether to set iter->in_shift = false and reset iter->state
162
or not is not important; the string end is reached anyway. */
158
/* An incomplete multibyte character at the end. */
159
iter->cur.bytes = strlen (iter->cur.ptr);
160
iter->cur.wc_valid = false;
161
/* Whether to set iter->in_shift = false and reset iter->state
162
or not is not important; the string end is reached anyway. */
166
if (iter->cur.bytes == 0)
168
/* A null wide character was encountered. */
170
assert (*iter->cur.ptr == '\0');
171
assert (iter->cur.wc == 0);
173
iter->cur.wc_valid = true;
166
if (iter->cur.bytes == 0)
168
/* A null wide character was encountered. */
170
assert (*iter->cur.ptr == '\0');
171
assert (iter->cur.wc == 0);
173
iter->cur.wc_valid = true;
175
/* When in the initial state, we can go back treating ASCII
176
characters more quickly. */
177
if (mbsinit (&iter->state))
178
iter->in_shift = false;
175
/* When in the initial state, we can go back treating ASCII
176
characters more quickly. */
177
if (mbsinit (&iter->state))
178
iter->in_shift = false;
181
181
iter->next_done = true;