aboutsummaryrefslogtreecommitdiff
path: root/wcsmbs/wcrtomb.c
diff options
context:
space:
mode:
authorRoland McGrath <roland@gnu.org>1996-07-09 23:17:59 +0000
committerRoland McGrath <roland@gnu.org>1996-07-09 23:17:59 +0000
commit07a4742f9ec2b0587c0d488bb65da2a6faa50fed (patch)
tree2b10e82cad4053bcbe27447bc3d444f6d2aef5e7 /wcsmbs/wcrtomb.c
parentc150923988933b5db75a974d4cc08cd7f7aaf3dc (diff)
downloadglibc-07a4742f9ec2b0587c0d488bb65da2a6faa50fed.tar
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/wcrtomb.c')
-rw-r--r--wcsmbs/wcrtomb.c62
1 files changed, 42 insertions, 20 deletions
diff --git a/wcsmbs/wcrtomb.c b/wcsmbs/wcrtomb.c
index 9069fb105c..eb007a69b9 100644
--- a/wcsmbs/wcrtomb.c
+++ b/wcsmbs/wcrtomb.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
@@ -24,46 +24,68 @@ Boston, MA 02111-1307, USA. */
#define EILSEQ EINVAL
#endif
+static const wchar_t encoding_mask[] =
+{
+ ~0x7ff, ~0xffff, ~0x1fffff, ~0x3ffffff
+};
+
+static const unsigned char encoding_byte[] =
+{
+ 0xc0, 0xe0, 0xf0, 0xf8, 0xfc
+};
+/* The state is for this UTF8 encoding not used. */
static mbstate_t internal;
size_t
-wcrtomb (s, wc, ps)
- char *s;
- wchar_t wc;
- mbstate_t *ps;
+wcrtomb (char *s, wchar_t wc, mbstate_t *ps)
{
char fake[1];
+ size_t written = 0;
if (ps == NULL)
ps = &internal;
- /*************************************************************\
- |* This is no complete implementation. While the multi-byte *|
- |* character handling is not finished this will do. *|
- \*************************************************************/
-
if (s == NULL)
{
s = fake;
wc = L'\0';
}
- if (wc == L'\0')
+ /* Store the UTF8 representation of WC. */
+ if (wc < 0 || wc > 0x7fffffff)
{
- /* FIXME Write any shift sequence to get to *PS == NULL. */
- *ps = 0;
- *s = '\0';
+ /* This is no correct ISO 10646 character. */
+ errno = EILSEQ;
+ return (size_t) -1;
+ }
+
+ if (wc < 0x80)
+ {
+ /* It's a one byte sequence. */
+ if (s != NULL)
+ *s = (char) wc;
return 1;
}
- /* FIXME For now we don't handle real multi-byte encodings. */
- if ((wc & ~0xff) != 0)
+ for (written = 2; written < 6; ++written)
+ if ((wc & encoding_mask[written - 2]) == 0)
+ break;
+
+ if (s != NULL)
{
- errno = EILSEQ;
- return (size_t) -1;
+ size_t cnt = written;
+ s[0] = encoding_byte[cnt - 2];
+
+ --cnt;
+ do
+ {
+ s[cnt] = 0x80 | (wc & 0x3f);
+ wc >>= 6;
+ }
+ while (--cnt > 0);
+ s[0] |= wc;
}
- *s = (char) wc;
- return 1;
+ return written;
}