source: trunk/libs/newlib/src/newlib/libc/stdio/fgetws.c @ 567

Last change on this file since 567 was 444, checked in by satin@…, 6 years ago

add newlib,libalmos-mkh, restructure shared_syscalls.h and mini-libc

File size: 5.1 KB
Line 
1/*-
2 * Copyright (c) 2002-2004 Tim J. Robbins.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27/*
28FUNCTION
29<<fgetws>>, <<fgetws_unlocked>>---get wide character string from a file or stream
30
31INDEX
32        fgetws
33INDEX
34        fgetws_unlocked
35INDEX
36        _fgetws_r
37INDEX
38        _fgetws_unlocked_r
39
40SYNOPSIS
41        #include <wchar.h>
42        wchar_t *fgetws(wchar_t *__restrict <[ws]>, int <[n]>,
43                        FILE *__restrict <[fp]>);
44
45        #define _GNU_SOURCE
46        #include <wchar.h>
47        wchar_t *fgetws_unlocked(wchar_t *__restrict <[ws]>, int <[n]>,
48                        FILE *__restrict <[fp]>);
49
50        #include <wchar.h>
51        wchar_t *_fgetws_r(struct _reent *<[ptr]>, wchar_t *<[ws]>,
52                           int <[n]>, FILE *<[fp]>);
53
54        #include <wchar.h>
55        wchar_t *_fgetws_unlocked_r(struct _reent *<[ptr]>, wchar_t *<[ws]>,
56                           int <[n]>, FILE *<[fp]>);
57
58DESCRIPTION
59Reads at most <[n-1]> wide characters from <[fp]> until a newline
60is found. The wide characters including to the newline are stored
61in <[ws]>. The buffer is terminated with a 0.
62
63<<fgetws_unlocked>> is a non-thread-safe version of <<fgetws>>.
64<<fgetws_unlocked>> may only safely be used within a scope
65protected by flockfile() (or ftrylockfile()) and funlockfile().  This
66function may safely be used in a multi-threaded program if and only
67if they are called while the invoking thread owns the (FILE *)
68object, as is the case after a successful call to the flockfile() or
69ftrylockfile() functions.  If threads are disabled, then
70<<fgetws_unlocked>> is equivalent to <<fgetws>>.
71
72The <<_fgetws_r>> and <<_fgetws_unlocked_r>> functions are simply reentrant
73version of the above and are passed an additional reentrancy structure
74pointer: <[ptr]>.
75
76RETURNS
77<<fgetws>> returns the buffer passed to it, with the data
78filled in. If end of file occurs with some data already
79accumulated, the data is returned with no other indication. If
80no data are read, NULL is returned instead.
81
82PORTABILITY
83<<fgetws>> is required by C99 and POSIX.1-2001.
84
85<<fgetws_unlocked>> is a GNU extension.
86*/
87
88#include <_ansi.h>
89#include <reent.h>
90#include <errno.h>
91#include <stdio.h>
92#include <string.h>
93#include <wchar.h>
94#include "local.h"
95
96#ifdef __IMPL_UNLOCKED__
97#define _fgetws_r _fgetws_unlocked_r
98#define fgetws fgetws_unlocked
99#endif
100
101wchar_t *
102_fgetws_r (struct _reent *ptr,
103        wchar_t * ws,
104        int n,
105        FILE * fp)
106{
107  wchar_t *wsp;
108  size_t nconv;
109  const char *src;
110  unsigned char *nl;
111
112  _newlib_flockfile_start (fp);
113  ORIENT (fp, 1);
114
115  if (n <= 0)
116    {
117      errno = EINVAL;
118      goto error;
119    }
120
121  if (fp->_r <= 0 && __srefill_r (ptr, fp))
122    /* EOF */
123    goto error;
124  wsp = ws;
125  do
126    {
127      src = (char *) fp->_p;
128      nl = memchr (fp->_p, '\n', fp->_r);
129      nconv = _mbsnrtowcs_r (ptr, wsp, &src,
130                             /* Read all bytes up to the next NL, or up to the
131                                end of the buffer if there is no NL. */
132                             nl != NULL ? (nl - fp->_p + 1) : fp->_r,
133                             /* But never more than n - 1 wide chars. */
134                             n - 1,
135                             &fp->_mbstate);
136      if (nconv == (size_t) -1)
137        /* Conversion error */
138        goto error;
139      if (src == NULL)
140        {
141          /*
142           * We hit a null byte. Increment the character count,
143           * since mbsnrtowcs()'s return value doesn't include
144           * the terminating null, then resume conversion
145           * after the null.
146           */
147          nconv++;
148          src = memchr (fp->_p, '\0', fp->_r);
149          src++;
150        }
151      fp->_r -= (unsigned char *) src - fp->_p;
152      fp->_p = (unsigned char *) src;
153      n -= nconv;
154      wsp += nconv;
155    }
156  while (wsp[-1] != L'\n' && n > 1 && (fp->_r > 0
157         || __srefill_r (ptr, fp) == 0));
158  if (wsp == ws)
159    /* EOF */
160    goto error;
161  if (!mbsinit (&fp->_mbstate))
162    /* Incomplete character */
163    goto error;
164  *wsp++ = L'\0';
165  _newlib_flockfile_exit (fp);
166  return ws;
167
168error:
169  _newlib_flockfile_end (fp);
170  return NULL;
171}
172
173wchar_t *
174fgetws (wchar_t *__restrict ws,
175        int n,
176        FILE *__restrict fp)
177{
178  struct _reent *reent = _REENT;
179
180  CHECK_INIT (reent, fp);
181  return _fgetws_r (reent, ws, n, fp);
182}
Note: See TracBrowser for help on using the repository browser.