Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  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. /*
  28. FUNCTION
  29. <<fgetws>>, <<fgetws_unlocked>>---get wide character string from a file or stream
  30.  
  31. INDEX
  32.         fgetws
  33. INDEX
  34.         fgetws_unlocked
  35. INDEX
  36.         _fgetws_r
  37. INDEX
  38.         _fgetws_unlocked_r
  39.  
  40. ANSI_SYNOPSIS
  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.  
  58. TRAD_SYNOPSIS
  59.         #include <wchar.h>
  60.         wchar_t *fgetws(<[ws]>,<[n]>,<[fp]>)
  61.         wchar_t *__restrict <[ws]>;
  62.         int <[n]>;
  63.         FILE *__restrict <[fp]>;
  64.  
  65.         #define _GNU_SOURCE
  66.         #include <wchar.h>
  67.         wchar_t *fgetws_unlocked(<[ws]>,<[n]>,<[fp]>)
  68.         wchar_t *__restrict <[ws]>;
  69.         int <[n]>;
  70.         FILE *__restrict <[fp]>;
  71.  
  72.         #include <wchar.h>
  73.         wchar_t *_fgetws_r(<[ptr]>, <[ws]>,<[n]>,<[fp]>)
  74.         struct _reent *<[ptr]>;
  75.         wchar_t *<[ws]>;
  76.         int <[n]>;
  77.         FILE *<[fp]>;
  78.  
  79.         #include <wchar.h>
  80.         wchar_t *_fgetws_unlocked_r(<[ptr]>, <[ws]>,<[n]>,<[fp]>)
  81.         struct _reent *<[ptr]>;
  82.         wchar_t *<[ws]>;
  83.         int <[n]>;
  84.         FILE *<[fp]>;
  85.  
  86. DESCRIPTION
  87. Reads at most <[n-1]> wide characters from <[fp]> until a newline
  88. is found. The wide characters including to the newline are stored
  89. in <[ws]>. The buffer is terminated with a 0.
  90.  
  91. <<fgetws_unlocked>> is a non-thread-safe version of <<fgetws>>.
  92. <<fgetws_unlocked>> may only safely be used within a scope
  93. protected by flockfile() (or ftrylockfile()) and funlockfile().  This
  94. function may safely be used in a multi-threaded program if and only
  95. if they are called while the invoking thread owns the (FILE *)
  96. object, as is the case after a successful call to the flockfile() or
  97. ftrylockfile() functions.  If threads are disabled, then
  98. <<fgetws_unlocked>> is equivalent to <<fgetws>>.
  99.  
  100. The <<_fgetws_r>> and <<_fgetws_unlocked_r>> functions are simply reentrant
  101. version of the above and are passed an additional reentrancy structure
  102. pointer: <[ptr]>.
  103.  
  104. RETURNS
  105. <<fgetws>> returns the buffer passed to it, with the data
  106. filled in. If end of file occurs with some data already
  107. accumulated, the data is returned with no other indication. If
  108. no data are read, NULL is returned instead.
  109.  
  110. PORTABILITY
  111. <<fgetws>> is required by C99 and POSIX.1-2001.
  112.  
  113. <<fgetws_unlocked>> is a GNU extension.
  114. */
  115.  
  116. #include <_ansi.h>
  117. #include <reent.h>
  118. #include <errno.h>
  119. #include <stdio.h>
  120. #include <string.h>
  121. #include <wchar.h>
  122. #include "local.h"
  123.  
  124. #ifdef __IMPL_UNLOCKED__
  125. #define _fgetws_r _fgetws_unlocked_r
  126. #define fgetws fgetws_unlocked
  127. #endif
  128.  
  129. wchar_t *
  130. _DEFUN(_fgetws_r, (ptr, ws, n, fp),
  131.         struct _reent *ptr _AND
  132.         wchar_t * ws _AND
  133.         int n _AND
  134.         FILE * fp)
  135. {
  136.   wchar_t *wsp;
  137.   size_t nconv;
  138.   const char *src;
  139.   unsigned char *nl;
  140.  
  141.   _newlib_flockfile_start (fp);
  142.   ORIENT (fp, 1);
  143.  
  144.   if (n <= 0)
  145.     {
  146.       errno = EINVAL;
  147.       goto error;
  148.     }
  149.  
  150.   if (fp->_r <= 0 && __srefill_r (ptr, fp))
  151.     /* EOF */
  152.     goto error;
  153.   wsp = ws;
  154.   do
  155.     {
  156.       src = (char *) fp->_p;
  157.       nl = memchr (fp->_p, '\n', fp->_r);
  158.       nconv = _mbsnrtowcs_r (ptr, wsp, &src,
  159.                              /* Read all bytes up to the next NL, or up to the
  160.                                 end of the buffer if there is no NL. */
  161.                              nl != NULL ? (nl - fp->_p + 1) : fp->_r,
  162.                              /* But never more than n - 1 wide chars. */
  163.                              n - 1,
  164.                              &fp->_mbstate);
  165.       if (nconv == (size_t) -1)
  166.         /* Conversion error */
  167.         goto error;
  168.       if (src == NULL)
  169.         {
  170.           /*
  171.            * We hit a null byte. Increment the character count,
  172.            * since mbsnrtowcs()'s return value doesn't include
  173.            * the terminating null, then resume conversion
  174.            * after the null.
  175.            */
  176.           nconv++;
  177.           src = memchr (fp->_p, '\0', fp->_r);
  178.           src++;
  179.         }
  180.       fp->_r -= (unsigned char *) src - fp->_p;
  181.       fp->_p = (unsigned char *) src;
  182.       n -= nconv;
  183.       wsp += nconv;
  184.     }
  185.   while (wsp[-1] != L'\n' && n > 1 && (fp->_r > 0
  186.          || __srefill_r (ptr, fp) == 0));
  187.   if (wsp == ws)
  188.     /* EOF */
  189.     goto error;
  190.   if (!mbsinit (&fp->_mbstate))
  191.     /* Incomplete character */
  192.     goto error;
  193.   *wsp++ = L'\0';
  194.   _newlib_flockfile_exit (fp);
  195.   return ws;
  196.  
  197. error:
  198.   _newlib_flockfile_end (fp);
  199.   return NULL;
  200. }
  201.  
  202. wchar_t *
  203. _DEFUN(fgetws, (ws, n, fp),
  204.         wchar_t *__restrict ws _AND
  205.         int n _AND
  206.         FILE *__restrict fp)
  207. {
  208.   struct _reent *reent = _REENT;
  209.  
  210.   CHECK_INIT (reent, fp);
  211.   return _fgetws_r (reent, ws, n, fp);
  212. }
  213.