/xmlfy-1.5.5/xmlfy/utf_io/utf_lib.c
# · C · 834 lines · 611 code · 89 blank · 134 comment · 349 complexity · 5d7eded3c26f1f5d058b3d964dbc004a MD5 · raw file
- /*
- * BSD License for xmlfy
- * Copyright (c) 2008-2011, Arthur Gouros
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * - Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * - Neither the name of Arthur Gouros nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
- /**************************************************************************
- * xmlfy - Convert to XML on the fly. *
- * Original Author: Arthur Gouros. *
- * *
- * Please consult the documentation for further information. *
- **************************************************************************
- */
- #include "utf_io.h"
- /* function templates */
- void strcpy_utf8(int level, const unsigned char *s_src);
- void strncpy_utf8(const unsigned char *s_src, long n);
- void strcat_utf8(const unsigned char *s_src);
- void strncat_utf8(const unsigned char *s_src, long n);
- void strcpy_utf16be(int level, const unsigned char *s_src);
- void strncpy_utf16be(const unsigned char *s_src, long n);
- void strcat_utf16be(const unsigned char *s_src);
- void strncat_utf16be(const unsigned char *s_src, long n);
- void strcpy_utf16le(int level, const unsigned char *s_src);
- void strncpy_utf16le(const unsigned char *s_src, long n);
- void strcat_utf16le(const unsigned char *s_src);
- void strncat_utf16le(const unsigned char *s_src, long n);
- void strcpy_utf32be(int level, const unsigned char *s_src);
- void strncpy_utf32be(const unsigned char *s_src, long n);
- void strcat_utf32be(const unsigned char *s_src);
- void strncat_utf32be(const unsigned char *s_src, long n);
- void strcpy_utf32le(int level, const unsigned char *s_src);
- void strncpy_utf32le(const unsigned char *s_src, long n);
- void strcat_utf32le(const unsigned char *s_src);
- void strncat_utf32le(const unsigned char *s_src, long n);
- int utf_xstrncmp(const unsigned char *utf_s, long utf_s_length, int utf_s_encoding, const unsigned char *ascii_s, long n);
- int utf_char_equals(long i, unsigned char byte_c);
- int utf_char_equals_2(long i, unsigned char byte_c, const unsigned char *utf_s, long utf_s_length, int utf_s_encoding);
- int utf_char_equals_level1(long i, unsigned char byte_c);
- int utf_isspace(long i);
- int utf_iscomposite(long i);
- long utf_get_first_word_length(const unsigned char *utf_s, long utf_s_length, int utf_s_encoding);
- /*****
- * UTF-8 routines
- *****/
- void strcpy_utf8(int level, const unsigned char *s_src)
- {
- /* Write s_src to start of output_record.line array with padding */
- long i;
- output_record.length = 0;
- /* pad */
- while (output_record.length < level * 2)
- output_record.line[output_record.length++] = ' ';
- /* copy */
- for (i = 0 ; s_src[i] != '\0' ; i++)
- output_record.line[output_record.length++] = s_src[i];
- }
- void strncpy_utf8(const unsigned char *s_src, long n)
- {
- /* Write at most n characters of s_src to start of output_record.line array */
- for (output_record.length = 0 ; output_record.length < n && s_src[output_record.length] != '\0' ; output_record.length++)
- output_record.line[output_record.length] = s_src[output_record.length];
- }
- void strcat_utf8(const unsigned char *s_src)
- {
- /* Concatenate s_src to output_record.line array
- * starting from output_record.length. */
- long i;
- for (i = 0 ; s_src[i] != '\0' ; i++)
- output_record.line[output_record.length++] = s_src[i];
- }
- void strncat_utf8(const unsigned char *s_src, long n)
- {
- /* Concatenate at most n characters of s_src to output_record.line array
- * starting from output_record.length. */
- long i;
- for (i = 0 ; i < n && s_src[i] != '\0' ; i++)
- output_record.line[output_record.length++] = s_src[i];
- }
- /*****
- * UTF-16 and UTF-16BE routines
- *****/
- void strcpy_utf16be(int level, const unsigned char *s_src)
- {
- /* Write s_src to start of output_record.line array with padding
- * whilst converting to UTF-16BE format. */
- long i;
- output_record.length = 0;
- /* pad */
- while (output_record.length < level * 4)
- {
- output_record.line[output_record.length++] = 0;
- output_record.line[output_record.length++] = ' ';
- }
- /* copy */
- for (i = 0 ; s_src[i] != '\0' ; i++)
- {
- output_record.line[output_record.length++] = 0;
- output_record.line[output_record.length++] = s_src[i];
- }
- }
- void strncpy_utf16be(const unsigned char *s_src, long n)
- {
- /* Write at most n characters of s_src to start of output_record.line array
- * whilst converting to UTF-16BE format. */
- long i;
- output_record.length = 0;
- for (i = 0 ; i < n && s_src[i] != '\0' ; i++)
- {
- output_record.line[output_record.length++] = 0;
- output_record.line[output_record.length++] = s_src[i];
- }
- }
- void strcat_utf16be(const unsigned char *s_src)
- {
- /* Concatenate s_src to output_record.line array
- * starting from output_record.length,
- * whilst converting to UTF-16BE format. */
- long i;
- /* mem checks */
- if (output_record.length > memseg_output_record)
- memadd_output_record(output_record.length);
- for (i = 0 ; s_src[i] != '\0' ; i++)
- {
- output_record.line[output_record.length++] = 0;
- output_record.line[output_record.length++] = s_src[i];
- }
- }
- void strncat_utf16be(const unsigned char *s_src, long n)
- {
- /* Concatenate at most n characters of s_src to output_record.line array
- * starting from output_record.length,
- * whilst converting to UTF-16BE format. */
- long i;
- /* mem checks */
- if (output_record.length > memseg_output_record)
- memadd_output_record(output_record.length);
- for (i = 0 ; i < n && s_src[i] != '\0' ; i++)
- {
- output_record.line[output_record.length++] = 0;
- output_record.line[output_record.length++] = s_src[i];
- }
- }
- /*****
- * UTF-16LE routines
- *****/
- void strcpy_utf16le(int level, const unsigned char *s_src)
- {
- /* Write s_src to start of output_record.line array with padding
- * whilst converting to UTF-16LE format. */
- long i;
- output_record.length = 0;
- /* pad */
- while (output_record.length < level * 4)
- {
- output_record.line[output_record.length++] = ' ';
- output_record.line[output_record.length++] = 0;
- }
- /* copy */
- for (i = 0 ; s_src[i] != '\0' ; i++)
- {
- output_record.line[output_record.length++] = s_src[i];
- output_record.line[output_record.length++] = 0;
- }
- }
- void strncpy_utf16le(const unsigned char *s_src, long n)
- {
- /* Write at most n characters of s_src to start of output_record.line array
- * whilst converting to UTF-16LE format. */
- long i;
- output_record.length = 0;
- for (i = 0 ; i < n && s_src[i] != '\0' ; i++)
- {
- output_record.line[output_record.length++] = s_src[i];
- output_record.line[output_record.length++] = 0;
- }
- }
- void strcat_utf16le(const unsigned char *s_src)
- {
- /* Concatenate s_src to output_record.line array
- * starting from output_record.length,
- * whilst converting to UTF-16LE format. */
- long i;
- /* mem checks */
- if (output_record.length > memseg_output_record)
- memadd_output_record(output_record.length);
- for (i = 0 ; s_src[i] != '\0' ; i++)
- {
- output_record.line[output_record.length++] = s_src[i];
- output_record.line[output_record.length++] = 0;
- }
- }
- void strncat_utf16le(const unsigned char *s_src, long n)
- {
- /* Concatenate at most n characters of s_src to output_record.line array
- * starting from output_record.length,
- * whilst converting to UTF-16LE format. */
- long i;
- /* mem checks */
- if (output_record.length > memseg_output_record)
- memadd_output_record(output_record.length);
- for (i = 0 ; i < n && s_src[i] != '\0' ; i++)
- {
- output_record.line[output_record.length++] = s_src[i];
- output_record.line[output_record.length++] = 0;
- }
- }
- /*****
- * UTF-32 and UTF-32BE routines
- *****/
- void strcpy_utf32be(int level, const unsigned char *s_src)
- {
- /* Write s_src to start of output_record.line array with padding
- * whilst converting to UTF-32BE format. */
- long i;
- output_record.length = 0;
- /* pad */
- while (output_record.length < level * 8)
- {
- output_record.line[output_record.length++] = 0;
- output_record.line[output_record.length++] = 0;
- output_record.line[output_record.length++] = 0;
- output_record.line[output_record.length++] = ' ';
- }
- /* copy */
- for (i = 0 ; s_src[i] != '\0' ; i++)
- {
- output_record.line[output_record.length++] = 0;
- output_record.line[output_record.length++] = 0;
- output_record.line[output_record.length++] = 0;
- output_record.line[output_record.length++] = s_src[i];
- }
- }
- void strncpy_utf32be(const unsigned char *s_src, long n)
- {
- /* Write at most n characters of s_src to start of output_record.line array
- * whilst converting to UTF-32BE format. */
- long i;
- output_record.length = 0;
- for (i = 0 ; i < n && s_src[i] != '\0' ; i++)
- {
- output_record.line[output_record.length++] = 0;
- output_record.line[output_record.length++] = 0;
- output_record.line[output_record.length++] = 0;
- output_record.line[output_record.length++] = s_src[i];
- }
- }
- void strcat_utf32be(const unsigned char *s_src)
- {
- /* Concatenate s_src to output_record.line array
- * starting from output_record.length,
- * whilst converting to UTF-32BE format. */
- long i;
- /* mem checks */
- if (output_record.length > memseg_output_record)
- memadd_output_record(output_record.length);
- for (i = 0 ; s_src[i] != '\0' ; i++)
- {
- output_record.line[output_record.length++] = 0;
- output_record.line[output_record.length++] = 0;
- output_record.line[output_record.length++] = 0;
- output_record.line[output_record.length++] = s_src[i];
- }
- }
- void strncat_utf32be(const unsigned char *s_src, long n)
- {
- /* Concatenate at most n characters of s_src to output_record.line array
- * starting from output_record.length,
- * whilst converting to UTF-32BE format. */
- long i;
- /* mem checks */
- if (output_record.length > memseg_output_record)
- memadd_output_record(output_record.length);
- for (i = 0 ; i < n && s_src[i] != '\0' ; i++)
- {
- output_record.line[output_record.length++] = 0;
- output_record.line[output_record.length++] = 0;
- output_record.line[output_record.length++] = 0;
- output_record.line[output_record.length++] = s_src[i];
- }
- }
- /*****
- * UTF-32LE routines
- *****/
- void strcpy_utf32le(int level, const unsigned char *s_src)
- {
- /* Write s_src to start of output_record.line array with padding
- * whilst converting to UTF-32LE format. */
- long i;
- output_record.length = 0;
- /* pad */
- while (output_record.length < level * 8)
- {
- output_record.line[output_record.length++] = ' ';
- output_record.line[output_record.length++] = 0;
- output_record.line[output_record.length++] = 0;
- output_record.line[output_record.length++] = 0;
- }
- /* copy */
- for (i = 0 ; s_src[i] != '\0' ; i++)
- {
- output_record.line[output_record.length++] = s_src[i];
- output_record.line[output_record.length++] = 0;
- output_record.line[output_record.length++] = 0;
- output_record.line[output_record.length++] = 0;
- }
- }
- void strncpy_utf32le(const unsigned char *s_src, long n)
- {
- /* Write at most n characters of s_src to start of output_record.line array
- * whilst converting to UTF-32LE format. */
- long i;
- output_record.length = 0;
- for (i = 0 ; i < n && s_src[i] != '\0' ; i++)
- {
- output_record.line[output_record.length++] = s_src[i];
- output_record.line[output_record.length++] = 0;
- output_record.line[output_record.length++] = 0;
- output_record.line[output_record.length++] = 0;
- }
- }
- void strcat_utf32le(const unsigned char *s_src)
- {
- /* Concatenate s_src to output_record.line array
- * starting from output_record.length,
- * whilst converting to UTF-32LE format. */
- long i;
- /* mem checks */
- if (output_record.length > memseg_output_record)
- memadd_output_record(output_record.length);
- for (i = 0 ; s_src[i] != '\0' ; i++)
- {
- output_record.line[output_record.length++] = s_src[i];
- output_record.line[output_record.length++] = 0;
- output_record.line[output_record.length++] = 0;
- output_record.line[output_record.length++] = 0;
- }
- }
- void strncat_utf32le(const unsigned char *s_src, long n)
- {
- /* Concatenate at most n characters of s_src to output_record.line array
- * starting from output_record.length,
- * whilst converting to UTF-32LE format. */
- long i;
- /* mem checks */
- if (output_record.length > memseg_output_record)
- memadd_output_record(output_record.length);
- for (i = 0 ; i < n && s_src[i] != '\0' ; i++)
- {
- output_record.line[output_record.length++] = s_src[i];
- output_record.line[output_record.length++] = 0;
- output_record.line[output_record.length++] = 0;
- output_record.line[output_record.length++] = 0;
- }
- }
- int utf_xstrncmp(const unsigned char *utf_s, long utf_s_length, int utf_s_encoding, const unsigned char *ascii_s, long n)
- {
- /* Check if utf_s == ascii_s for up to n ascii chars and ONLY return 0 (match) or 1 (nomatch)
- * whilst being encoding sensitive. */
- long i, j, n_match;
- int ret = 1;
- n_match = 0;
- i = 0;
- for (j = 0 ; j < n && ascii_s[j] != '\0' ; j++)
- {
- if (utf_s_encoding == UTF_8)
- {
- if (i < utf_s_length
- && utf_s[i] == ascii_s[j])
- {
- i++;
- n_match++;
- }
- else
- break; /* for/j */
- }
- else if (utf_s_encoding == UTF_16BE)
- {
- if (i + 1 < utf_s_length
- && utf_s[i] == 0
- && utf_s[i + 1] == ascii_s[j])
- {
- i += 2;
- n_match++;
- }
- else
- break; /* for/j */
- }
- else if (utf_s_encoding == UTF_16LE)
- {
- if (i + 1 < utf_s_length
- && utf_s[i] == ascii_s[j]
- && utf_s[i + 1] == 0)
- {
- i += 2;
- n_match++;
- }
- else
- break; /* for/j */
- }
- else if (utf_s_encoding == UTF_32BE)
- {
- if (i + 3 < utf_s_length
- && utf_s[i] == 0
- && utf_s[i + 1] == 0
- && utf_s[i + 2] == 0
- && utf_s[i + 3] == ascii_s[j])
- {
- i += 4;
- n_match++;
- }
- else
- break; /* for/j */
- }
- else if (utf_s_encoding == UTF_32LE)
- {
- if (i + 3 < utf_s_length
- && utf_s[i] == ascii_s[j]
- && utf_s[i + 1] == 0
- && utf_s[i + 2] == 0
- && utf_s[i + 3] == 0)
- {
- i += 4;
- n_match++;
- }
- else
- break; /* for/j */
- }
- } /* for/j */
- if (n == n_match)
- ret = 0;
- return (ret);
- }
- int utf_char_equals(long i, unsigned char byte_c)
- {
- /* check for matching char in input.record.line[i] array
- * whilst being encoding sensitive. */
- int ret = FALSE;
- if (input_record.encoding == UTF_8)
- {
- if (input_record.line[i] == byte_c)
- ret = TRUE;
- }
- else if (input_record.encoding == UTF_16BE)
- {
- if (i + 1 < input_record.length
- && input_record.line[i] == 0
- && input_record.line[i + 1] == byte_c)
- {
- ret = TRUE;
- }
- }
- else if (input_record.encoding == UTF_16LE)
- {
- if (i + 1 < input_record.length
- && input_record.line[i] == byte_c
- && input_record.line[i + 1] == 0)
- {
- ret = TRUE;
- }
- }
- else if (input_record.encoding == UTF_32BE)
- {
- if (i + 3 < input_record.length
- && input_record.line[i] == 0
- && input_record.line[i + 1] == 0
- && input_record.line[i + 2] == 0
- && input_record.line[i + 3] == byte_c)
- {
- ret = TRUE;
- }
- }
- else if (input_record.encoding == UTF_32LE)
- {
- if (i + 3 < input_record.length
- && input_record.line[i] == byte_c
- && input_record.line[i + 1] == 0
- && input_record.line[i + 2] == 0
- && input_record.line[i + 3] == 0)
- {
- ret = TRUE;
- }
- }
- return(ret);
- }
- int utf_char_equals_2(long i, unsigned char byte_c, const unsigned char *utf_s, long utf_s_length, int utf_s_encoding)
- {
- /* check for matching char in supplied array
- * whilst being encoding sensitive. */
- int ret = FALSE;
- if (utf_s_encoding == UTF_8)
- {
- if (utf_s[i] == byte_c)
- ret = TRUE;
- }
- else if (utf_s_encoding == UTF_16BE)
- {
- if (i + 1 < utf_s_length
- && utf_s[i] == 0
- && utf_s[i + 1] == byte_c)
- {
- ret = TRUE;
- }
- }
- else if (utf_s_encoding == UTF_16LE)
- {
- if (i + 1 < utf_s_length
- && utf_s[i] == byte_c
- && utf_s[i + 1] == 0)
- {
- ret = TRUE;
- }
- }
- else if (utf_s_encoding == UTF_32BE)
- {
- if (i + 3 < utf_s_length
- && utf_s[i] == 0
- && utf_s[i + 1] == 0
- && utf_s[i + 2] == 0
- && utf_s[i + 3] == byte_c)
- {
- ret = TRUE;
- }
- }
- else if (utf_s_encoding == UTF_32LE)
- {
- if (i + 3 < utf_s_length
- && utf_s[i] == byte_c
- && utf_s[i + 1] == 0
- && utf_s[i + 2] == 0
- && utf_s[i + 3] == 0)
- {
- ret = TRUE;
- }
- }
- return(ret);
- }
- int utf_char_equals_level1(long i, unsigned char byte_c)
- {
- /* check for default level 1 matching char in input.record.line[i] array.
- * NOTE: Unlike the utf_char_equals() functions above, level 1 record
- * default delimiter matching has a growing input_record.length,
- * so wide UTF encoding must be matched starting at the end
- * and working backwards */
- int ret = FALSE;
- if (input_record.encoding == UTF_8)
- {
- if (input_record.line[i] == byte_c)
- ret = TRUE;
- }
- else if (input_record.encoding == UTF_16BE)
- {
- if (i % 2
- && i > 0
- && input_record.line[i - 1] == 0
- && input_record.line[i] == byte_c)
- {
- ret = TRUE;
- }
- }
- else if (input_record.encoding == UTF_16LE)
- {
- if (i % 2
- && i > 0
- && input_record.line[i - 1] == byte_c
- && input_record.line[i] == 0)
- {
- ret = TRUE;
- }
- }
- else if (input_record.encoding == UTF_32BE)
- {
- if (i % 4 == 3 /* input array starts at 0 i.e. [3][2][1][0] */
- && i > 2
- && input_record.line[i - 3] == 0
- && input_record.line[i - 2] == 0
- && input_record.line[i - 1] == 0
- && input_record.line[i] == byte_c)
- {
- ret = TRUE;
- }
- }
- else if (input_record.encoding == UTF_32LE)
- {
- if (i % 4 == 3 /* input array starts at 0 i.e. [3][2][1][0] */
- && i > 2
- && input_record.line[i - 3] == byte_c
- && input_record.line[i - 2] == 0
- && input_record.line[i - 1] == 0
- && input_record.line[i] == 0)
- {
- ret = TRUE;
- }
- }
- return(ret);
- }
- int utf_isspace(long i)
- {
- /* check for whitespace
- * whilst being encoding sensitive. */
- int ret = FALSE;
- if (input_record.encoding == UTF_8)
- {
- if(isspace(input_record.line[i]))
- ret = TRUE;
- }
- else if (input_record.encoding == UTF_16BE)
- {
- if (i + 1 < input_record.length
- && isspace(input_record.line[i + 1])
- && input_record.line[i] == 0)
- {
- ret = TRUE;
- }
- }
- else if (input_record.encoding == UTF_16LE)
- {
- if (i + 1 < input_record.length
- && isspace(input_record.line[i])
- && input_record.line[i + 1] == 0)
- {
- ret = TRUE;
- }
- }
- else if (input_record.encoding == UTF_32BE)
- {
- if (i + 3 < input_record.length
- && isspace(input_record.line[i + 3])
- && input_record.line[i + 2] == 0
- && input_record.line[i + 1] == 0
- && input_record.line[i] == 0)
- {
- ret = TRUE;
- }
- }
- else if (input_record.encoding == UTF_32LE)
- {
- if (i + 3 < input_record.length
- && isspace(input_record.line[i])
- && input_record.line[i + 1] == 0
- && input_record.line[i + 2] == 0
- && input_record.line[i + 3] == 0)
- {
- ret = TRUE;
- }
- }
- return(ret);
- }
- int utf_iscomposite(long i)
- {
- /* check for composite char in input.record.line[i] array
- * E.g. Multi byte UTF-8 sequences.
- * E.g. Surrogate pairing in UTF-16. */
- int ret = FALSE;
- if (input_record.encoding == UTF_8)
- {
- if (input_record.line[i] > 0x7f && input_record.line[i] < 0xc0)
- ret = TRUE;
- }
- else if (input_record.encoding == UTF_16BE)
- {
- if (input_record.line[i] > 0xd7 && input_record.line[i] < 0xdc)
- ret = TRUE;
- }
- else if (input_record.encoding == UTF_16LE)
- {
- if (i + 1 < input_record.length
- && input_record.line[i + 1] > 0xd7 && input_record.line[i + 1] < 0xdc)
- ret = TRUE;
- }
- return(ret);
- }
- long utf_get_first_word_length(const unsigned char *utf_s, long utf_s_length, int utf_s_encoding)
- {
- /* Get the length of the first word in string utf_s */
- long i;
- /* Initialise */
- i = utf_s_length;
- if (utf_s_encoding == UTF_8)
- {
- for (i = 0 ; i < utf_s_length ; i++)
- if (isspace(utf_s[i]))
- break; /* for/i */
- }
- else if (utf_s_encoding == UTF_16BE)
- {
- for (i = 0 ; i < utf_s_length ; i += 2)
- if (i + 1 < utf_s_length
- && utf_s[i] == 0
- && isspace(utf_s[i + 1]))
- break; /* for/i */
- }
- else if (utf_s_encoding == UTF_16LE)
- {
- for (i = 0 ; i < utf_s_length ; i += 2)
- if (i + 1 < utf_s_length
- && isspace(utf_s[i])
- && utf_s[i + 1] == 0)
- break; /* for/i */
- }
- else if (utf_s_encoding == UTF_32BE)
- {
- for (i = 0 ; i < utf_s_length ; i += 4)
- if (i + 3 < utf_s_length
- && utf_s[i] == 0
- && utf_s[i + 1] == 0
- && utf_s[i + 2] == 0
- && isspace(utf_s[i + 3]))
- break; /* for/i */
- }
- else if (utf_s_encoding == UTF_32LE)
- {
- for (i = 0 ; i < utf_s_length ; i += 4)
- if (i + 3 < utf_s_length
- && isspace(utf_s[i])
- && utf_s[i + 1] == 0
- && utf_s[i + 2] == 0
- && utf_s[i + 3] == 0)
- break; /* for/i */
- }
- return(i);
- }