]> git.ipfire.org Git - thirdparty/glibc.git/blame - libio/iogetwline.c
posix/glob.c: update from gnulib
[thirdparty/glibc.git] / libio / iogetwline.c
CommitLineData
581c785b 1/* Copyright (C) 1993-2022 Free Software Foundation, Inc.
41bdb6e2 2 This file is part of the GNU C Library.
d64b6ad0 3
41bdb6e2
AJ
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
d64b6ad0 8
41bdb6e2
AJ
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
d64b6ad0 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
41bdb6e2
AJ
12 Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public
59ba27a6 15 License along with the GNU C Library; if not, see
5a82c748 16 <https://www.gnu.org/licenses/>.
41bdb6e2
AJ
17
18 As a special exception, if you link the code in this file with
19 files compiled with a GNU compiler to produce an executable,
20 that does not cause the resulting executable to be covered by
21 the GNU Lesser General Public License. This exception does not
22 however invalidate any other reasons why the executable file
23 might be covered by the GNU Lesser General Public License.
24 This exception applies to code released by its copyright holders
25 in files containing the exception. */
d64b6ad0
UD
26
27#include "libioP.h"
28#include <string.h>
29#include <wchar.h>
30
9964a145
ZW
31size_t
32_IO_getwline (FILE *fp, wchar_t *buf, size_t n, wint_t delim,
f63f2bfd 33 int extract_delim)
d64b6ad0
UD
34{
35 return _IO_getwline_info (fp, buf, n, delim, extract_delim, (wint_t *) 0);
36}
37
38/* Algorithm based on that used by Berkeley pre-4.4 fgets implementation.
39
40 Read chars into buf (of size n), until delim is seen.
41 Return number of chars read (at most n).
42 Does not put a terminating '\0' in buf.
43 If extract_delim < 0, leave delimiter unread.
44 If extract_delim > 0, insert delim in output. */
45
9964a145
ZW
46size_t
47_IO_getwline_info (FILE *fp, wchar_t *buf, size_t n, wint_t delim,
f63f2bfd 48 int extract_delim, wint_t *eof)
d64b6ad0
UD
49{
50 wchar_t *ptr = buf;
51 if (eof != NULL)
52 *eof = 0;
076bfcf6
UD
53 if (__builtin_expect (fp->_mode, 1) == 0)
54 _IO_fwide (fp, 1);
d64b6ad0
UD
55 while (n != 0)
56 {
9964a145
ZW
57 ssize_t len = (fp->_wide_data->_IO_read_end
58 - fp->_wide_data->_IO_read_ptr);
d64b6ad0
UD
59 if (len <= 0)
60 {
61 wint_t wc = __wuflow (fp);
62 if (wc == WEOF)
63 {
64 if (eof)
65 *eof = wc;
66 break;
67 }
68 if (wc == delim)
69 {
70 if (extract_delim > 0)
71 *ptr++ = wc;
72 else if (extract_delim < 0)
d18ea0c5 73 _IO_sputbackc (fp, wc);
d64b6ad0
UD
74 if (extract_delim > 0)
75 ++len;
b5352f2d 76 return ptr - buf;
d64b6ad0
UD
77 }
78 *ptr++ = wc;
79 n--;
80 }
a3b231b7
UD
81 else
82 {
83 wchar_t *t;
9964a145 84 if ((size_t) len >= n)
a3b231b7
UD
85 len = n;
86 t = wmemchr ((void *) fp->_wide_data->_IO_read_ptr, delim, len);
87 if (t != NULL)
88 {
9964a145 89 size_t old_len = ptr - buf;
a3b231b7
UD
90 len = t - fp->_wide_data->_IO_read_ptr;
91 if (extract_delim >= 0)
92 {
93 ++t;
94 if (extract_delim > 0)
95 ++len;
96 }
5f0704b6
FW
97 __wmemcpy ((void *) ptr, (void *) fp->_wide_data->_IO_read_ptr,
98 len);
a3b231b7
UD
99 fp->_wide_data->_IO_read_ptr = t;
100 return old_len + len;
101 }
5f0704b6 102 __wmemcpy ((void *) ptr, (void *) fp->_wide_data->_IO_read_ptr, len);
a3b231b7
UD
103 fp->_wide_data->_IO_read_ptr += len;
104 ptr += len;
105 n -= len;
106 }
d64b6ad0
UD
107 }
108 return ptr - buf;
109}