diff options
author | Roland McGrath <roland@gnu.org> | 1996-07-09 23:17:59 +0000 |
---|---|---|
committer | Roland McGrath <roland@gnu.org> | 1996-07-09 23:17:59 +0000 |
commit | 07a4742f9ec2b0587c0d488bb65da2a6faa50fed (patch) | |
tree | 2b10e82cad4053bcbe27447bc3d444f6d2aef5e7 /wcsmbs/wcsrtombs.c | |
parent | Tue Jul 9 09:37:55 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu> (diff) | |
download | glibc-07a4742f9ec2b0587c0d488bb65da2a6faa50fed.tar.gz glibc-07a4742f9ec2b0587c0d488bb65da2a6faa50fed.tar.bz2 glibc-07a4742f9ec2b0587c0d488bb65da2a6faa50fed.zip |
* posix/glob.h (__glob_opendir_hook, __glob_readdir_hook,cvs/libc-960710
__glob_closedir_hook): Remove decls.
* sysdeps/generic/machine-gmon.h: Declare mcount_internal.
* sysdeps/unix/inet/syscalls.list: Define __ names with weak aliases
for send and connect syscalls.
* socket/sys/socket.h: New file, taken from non-sysdep parts of
linux/sys/socket.h; break sysdeps parts out into socketbits.h.
Declare __ names for send and connect.
* sysdeps/generic/socketbits.h: New file.
* sysdeps/unix/sysv/linux/socketbits.h: New file.
* sysdeps/unix/sysv/linux/sys/socket.h: File removed.
* sysdeps/generic/sys/socket.h: File removed.
* sysdeps/mach/hurd/connect.c: Define __ name and weak alias.
* sysdeps/mach/hurd/send.c: Likewise.
Diffstat (limited to 'wcsmbs/wcsrtombs.c')
-rw-r--r-- | wcsmbs/wcsrtombs.c | 95 |
1 files changed, 73 insertions, 22 deletions
diff --git a/wcsmbs/wcsrtombs.c b/wcsmbs/wcsrtombs.c index 9f1000937b..99ca6acc5b 100644 --- a/wcsmbs/wcsrtombs.c +++ b/wcsmbs/wcsrtombs.c @@ -1,6 +1,6 @@ /* Copyright (C) 1996 Free Software Foundation, Inc. This file is part of the GNU C Library. -Contributed by Ulrich Drepper, <drepper@gnu.ai.mit.edu> +Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1996. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as @@ -25,6 +25,18 @@ Boston, MA 02111-1307, USA. */ #endif +static const wchar_t encoding_mask[] = +{ + ~0x7ff, ~0xffff, ~0x1fffff, ~0x3ffffff +}; + +static const unsigned char encoding_byte[] = +{ + 0xc0, 0xe0, 0xf0, 0xf8, 0xfc +}; + +/* We don't need the state really because we don't have shift states + to maintain between calls to this function. */ static mbstate_t internal; size_t @@ -34,40 +46,79 @@ wcsrtombs (dst, src, len, ps) size_t len; mbstate_t *ps; { - size_t result = 0; + size_t written = 0; + const wchar_t *run = *src; if (ps == NULL) ps = &internal; - /*************************************************************\ - |* This is no complete implementation. While the multi-byte *| - |* character handling is not finished this will do. *| - \*************************************************************/ + if (dst == NULL) + /* The LEN parameter has to be ignored if we don't actually write + anything. */ + len = ~0; - while (len > 0 && **src != L'\0') + while (written < len) { - if ((**src & ~0xff) != 0) + wchar_t wc = *run++; + + if (wc < 0 || wc > 0x7fffffff) { + /* This is no correct ISO 10646 character. */ errno = EILSEQ; return (size_t) -1; } - if (dst != NULL) - dst[result] = (char) **src; - ++result; - ++(*src); - --len; - } - - if (len > 0) - { - if (dst != NULL) + if (wc == L'\0') + { + /* Found the end. */ + if (dst != NULL) + *dst = '\0'; + *src = NULL; + return written; + } + else if (wc < 0x80) { - dst[result] = '\0'; - *ps = 0; + /* It's an one byte sequence. */ + if (dst != NULL) + *dst++ = (char) wc; + ++written; + } + else + { + size_t step; + + for (step = 2; step < 6; ++step) + if ((wc & encoding_mask[step - 2]) == 0) + break; + + if (written + step >= len) + /* Too long. */ + break; + + if (dst != NULL) + { + size_t cnt = step; + + dst[0] = encoding_byte[cnt - 2]; + + --cnt; + do + { + dst[cnt] = 0x80 | (wc & 0x3f); + wc >>= 6; + } + while (--cnt > 0); + dst[0] |= wc; + + dst += step; + } + + written += step; } - *src = NULL; } - return result; + /* Store position of first unprocessed word. */ + *src = run; + + return written; } |