annotate lib/getndelim2.c @ 17907:0a1c2535cad9

euidaccess: Fix Android build * modules/euidaccess (Depends-on): Add fcntl-h to ensure that AT_EACCESS gets declared.
author Kevin Cernekee <cernekee@google.com>
date Wed, 11 Feb 2015 15:22:54 -0800
parents ab58d4870664
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
4463
7564fca8961e New module 'getndelim2'.
Bruno Haible <bruno@clisp.org>
parents: 4460
diff changeset
1 /* getndelim2 - Read a line from a stream, stopping at one of 2 delimiters,
7564fca8961e New module 'getndelim2'.
Bruno Haible <bruno@clisp.org>
parents: 4460
diff changeset
2 with bounded memory allocation.
4460
1892b6732a40 New module 'getnline'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
3
17848
ab58d4870664 version-etc: new year
Paul Eggert <eggert@cs.ucla.edu>
parents: 17587
diff changeset
4 Copyright (C) 1993, 1996-1998, 2000, 2003-2004, 2006, 2008-2015 Free
14079
97fc9a21a8fb maint: update almost all copyright ranges to include 2011
Jim Meyering <meyering@redhat.com>
parents: 12559
diff changeset
5 Software Foundation, Inc.
4460
1892b6732a40 New module 'getnline'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
6
9309
bbbbbf4cd1c5 Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents: 7539
diff changeset
7 This program is free software: you can redistribute it and/or modify
4460
1892b6732a40 New module 'getnline'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
8 it under the terms of the GNU General Public License as published by
9309
bbbbbf4cd1c5 Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents: 7539
diff changeset
9 the Free Software Foundation; either version 3 of the License, or
bbbbbf4cd1c5 Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents: 7539
diff changeset
10 (at your option) any later version.
4460
1892b6732a40 New module 'getnline'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
11
1892b6732a40 New module 'getnline'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
12 This program is distributed in the hope that it will be useful,
1892b6732a40 New module 'getnline'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
1892b6732a40 New module 'getnline'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1892b6732a40 New module 'getnline'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
15 GNU General Public License for more details.
1892b6732a40 New module 'getnline'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
16
1892b6732a40 New module 'getnline'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
17 You should have received a copy of the GNU General Public License
9309
bbbbbf4cd1c5 Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents: 7539
diff changeset
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
4460
1892b6732a40 New module 'getnline'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
19
4463
7564fca8961e New module 'getndelim2'.
Bruno Haible <bruno@clisp.org>
parents: 4460
diff changeset
20 /* Originally written by Jan Brittenson, bson@gnu.ai.mit.edu. */
7564fca8961e New module 'getndelim2'.
Bruno Haible <bruno@clisp.org>
parents: 4460
diff changeset
21
7302
8a1a9361108c * _fpending.c: Include <config.h> unconditionally, since we no
Paul Eggert <eggert@cs.ucla.edu>
parents: 7162
diff changeset
22 #include <config.h>
4463
7564fca8961e New module 'getndelim2'.
Bruno Haible <bruno@clisp.org>
parents: 4460
diff changeset
23
7564fca8961e New module 'getndelim2'.
Bruno Haible <bruno@clisp.org>
parents: 4460
diff changeset
24 #include "getndelim2.h"
7564fca8961e New module 'getndelim2'.
Bruno Haible <bruno@clisp.org>
parents: 4460
diff changeset
25
10019
e435c0a7bace Optimize getndelim2 to use block operations when possible.
Eric Blake <ebb9@byu.net>
parents: 10006
diff changeset
26 #include <stdbool.h>
e435c0a7bace Optimize getndelim2 to use block operations when possible.
Eric Blake <ebb9@byu.net>
parents: 10006
diff changeset
27 #include <stddef.h>
4650
179b16276bbf Remove K&R cruft.
Paul Eggert <eggert@cs.ucla.edu>
parents: 4463
diff changeset
28 #include <stdlib.h>
10019
e435c0a7bace Optimize getndelim2 to use block operations when possible.
Eric Blake <ebb9@byu.net>
parents: 10006
diff changeset
29 #include <string.h>
4460
1892b6732a40 New module 'getnline'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
30
5318
7c24a825b51d Remove dependencies on unlocked-io.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5102
diff changeset
31 #if USE_UNLOCKED_IO
7c24a825b51d Remove dependencies on unlocked-io.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5102
diff changeset
32 # include "unlocked-io.h"
7c24a825b51d Remove dependencies on unlocked-io.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5102
diff changeset
33 #endif
10006
b0a275071b2c Test getndelim2.
Eric Blake <ebb9@byu.net>
parents: 9309
diff changeset
34 #if !HAVE_FLOCKFILE
b0a275071b2c Test getndelim2.
Eric Blake <ebb9@byu.net>
parents: 9309
diff changeset
35 # undef flockfile
b0a275071b2c Test getndelim2.
Eric Blake <ebb9@byu.net>
parents: 9309
diff changeset
36 # define flockfile(x) ((void) 0)
b0a275071b2c Test getndelim2.
Eric Blake <ebb9@byu.net>
parents: 9309
diff changeset
37 #endif
b0a275071b2c Test getndelim2.
Eric Blake <ebb9@byu.net>
parents: 9309
diff changeset
38 #if !HAVE_FUNLOCKFILE
b0a275071b2c Test getndelim2.
Eric Blake <ebb9@byu.net>
parents: 9309
diff changeset
39 # undef funlockfile
b0a275071b2c Test getndelim2.
Eric Blake <ebb9@byu.net>
parents: 9309
diff changeset
40 # define funlockfile(x) ((void) 0)
b0a275071b2c Test getndelim2.
Eric Blake <ebb9@byu.net>
parents: 9309
diff changeset
41 #endif
4460
1892b6732a40 New module 'getnline'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
42
5062
aa119e787246 getline cleanup. This changes the getndelim2 API: both order of arguments,
Paul Eggert <eggert@cs.ucla.edu>
parents: 5049
diff changeset
43 #include <limits.h>
7162
19c2e5121b2f Add and change modules to make it easier for coreutils to use
Paul Eggert <eggert@cs.ucla.edu>
parents: 6259
diff changeset
44 #include <stdint.h>
5062
aa119e787246 getline cleanup. This changes the getndelim2 API: both order of arguments,
Paul Eggert <eggert@cs.ucla.edu>
parents: 5049
diff changeset
45
10019
e435c0a7bace Optimize getndelim2 to use block operations when possible.
Eric Blake <ebb9@byu.net>
parents: 10006
diff changeset
46 #include "freadptr.h"
e435c0a7bace Optimize getndelim2 to use block operations when possible.
Eric Blake <ebb9@byu.net>
parents: 10006
diff changeset
47 #include "freadseek.h"
e435c0a7bace Optimize getndelim2 to use block operations when possible.
Eric Blake <ebb9@byu.net>
parents: 10006
diff changeset
48 #include "memchr2.h"
e435c0a7bace Optimize getndelim2 to use block operations when possible.
Eric Blake <ebb9@byu.net>
parents: 10006
diff changeset
49
7538
a75213853379 Make getndelim2 compile on mingw.
Bruno Haible <bruno@clisp.org>
parents: 7302
diff changeset
50 #ifndef SSIZE_MAX
7539
84cd79e074c1 * lib/getndelim2.c (SSIZE_MAX): Use same defn that getdelim.c
Paul Eggert <eggert@cs.ucla.edu>
parents: 7538
diff changeset
51 # define SSIZE_MAX ((ssize_t) (SIZE_MAX / 2))
7538
a75213853379 Make getndelim2 compile on mingw.
Bruno Haible <bruno@clisp.org>
parents: 7302
diff changeset
52 #endif
a75213853379 Make getndelim2 compile on mingw.
Bruno Haible <bruno@clisp.org>
parents: 7302
diff changeset
53
16235
18a38c9615f0 In commentary, do not use ` to quote.
Paul Eggert <eggert@cs.ucla.edu>
parents: 16201
diff changeset
54 /* Use this to suppress gcc's "...may be used before initialized" warnings. */
10024
3c66797099ef avoid a warning from gcc
Jim Meyering <meyering@redhat.com>
parents: 10019
diff changeset
55 #ifdef lint
3c66797099ef avoid a warning from gcc
Jim Meyering <meyering@redhat.com>
parents: 10019
diff changeset
56 # define IF_LINT(Code) Code
3c66797099ef avoid a warning from gcc
Jim Meyering <meyering@redhat.com>
parents: 10019
diff changeset
57 #else
3c66797099ef avoid a warning from gcc
Jim Meyering <meyering@redhat.com>
parents: 10019
diff changeset
58 # define IF_LINT(Code) /* empty */
3c66797099ef avoid a warning from gcc
Jim Meyering <meyering@redhat.com>
parents: 10019
diff changeset
59 #endif
3c66797099ef avoid a warning from gcc
Jim Meyering <meyering@redhat.com>
parents: 10019
diff changeset
60
5062
aa119e787246 getline cleanup. This changes the getndelim2 API: both order of arguments,
Paul Eggert <eggert@cs.ucla.edu>
parents: 5049
diff changeset
61 /* The maximum value that getndelim2 can return without suffering from
aa119e787246 getline cleanup. This changes the getndelim2 API: both order of arguments,
Paul Eggert <eggert@cs.ucla.edu>
parents: 5049
diff changeset
62 overflow problems, either internally (because of pointer
aa119e787246 getline cleanup. This changes the getndelim2 API: both order of arguments,
Paul Eggert <eggert@cs.ucla.edu>
parents: 5049
diff changeset
63 subtraction overflow) or due to the API (because of ssize_t). */
aa119e787246 getline cleanup. This changes the getndelim2 API: both order of arguments,
Paul Eggert <eggert@cs.ucla.edu>
parents: 5049
diff changeset
64 #define GETNDELIM2_MAXIMUM (PTRDIFF_MAX < SSIZE_MAX ? PTRDIFF_MAX : SSIZE_MAX)
aa119e787246 getline cleanup. This changes the getndelim2 API: both order of arguments,
Paul Eggert <eggert@cs.ucla.edu>
parents: 5049
diff changeset
65
aa119e787246 getline cleanup. This changes the getndelim2 API: both order of arguments,
Paul Eggert <eggert@cs.ucla.edu>
parents: 5049
diff changeset
66 /* Try to add at least this many bytes when extending the buffer.
aa119e787246 getline cleanup. This changes the getndelim2 API: both order of arguments,
Paul Eggert <eggert@cs.ucla.edu>
parents: 5049
diff changeset
67 MIN_CHUNK must be no greater than GETNDELIM2_MAXIMUM. */
4460
1892b6732a40 New module 'getnline'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
68 #define MIN_CHUNK 64
1892b6732a40 New module 'getnline'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
69
4463
7564fca8961e New module 'getndelim2'.
Bruno Haible <bruno@clisp.org>
parents: 4460
diff changeset
70 ssize_t
5062
aa119e787246 getline cleanup. This changes the getndelim2 API: both order of arguments,
Paul Eggert <eggert@cs.ucla.edu>
parents: 5049
diff changeset
71 getndelim2 (char **lineptr, size_t *linesize, size_t offset, size_t nmax,
aa119e787246 getline cleanup. This changes the getndelim2 API: both order of arguments,
Paul Eggert <eggert@cs.ucla.edu>
parents: 5049
diff changeset
72 int delim1, int delim2, FILE *stream)
4460
1892b6732a40 New module 'getnline'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
73 {
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10028
diff changeset
74 size_t nbytes_avail; /* Allocated but unused bytes in *LINEPTR. */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10028
diff changeset
75 char *read_pos; /* Where we're reading into *LINEPTR. */
5062
aa119e787246 getline cleanup. This changes the getndelim2 API: both order of arguments,
Paul Eggert <eggert@cs.ucla.edu>
parents: 5049
diff changeset
76 ssize_t bytes_stored = -1;
aa119e787246 getline cleanup. This changes the getndelim2 API: both order of arguments,
Paul Eggert <eggert@cs.ucla.edu>
parents: 5049
diff changeset
77 char *ptr = *lineptr;
aa119e787246 getline cleanup. This changes the getndelim2 API: both order of arguments,
Paul Eggert <eggert@cs.ucla.edu>
parents: 5049
diff changeset
78 size_t size = *linesize;
10028
bd5f3690f627 Fix computation of newsize during reallocation.
Bruno Haible <bruno@clisp.org>
parents: 10027
diff changeset
79 bool found_delimiter;
4460
1892b6732a40 New module 'getnline'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
80
5062
aa119e787246 getline cleanup. This changes the getndelim2 API: both order of arguments,
Paul Eggert <eggert@cs.ucla.edu>
parents: 5049
diff changeset
81 if (!ptr)
4460
1892b6732a40 New module 'getnline'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
82 {
5062
aa119e787246 getline cleanup. This changes the getndelim2 API: both order of arguments,
Paul Eggert <eggert@cs.ucla.edu>
parents: 5049
diff changeset
83 size = nmax < MIN_CHUNK ? nmax : MIN_CHUNK;
aa119e787246 getline cleanup. This changes the getndelim2 API: both order of arguments,
Paul Eggert <eggert@cs.ucla.edu>
parents: 5049
diff changeset
84 ptr = malloc (size);
aa119e787246 getline cleanup. This changes the getndelim2 API: both order of arguments,
Paul Eggert <eggert@cs.ucla.edu>
parents: 5049
diff changeset
85 if (!ptr)
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10028
diff changeset
86 return -1;
4460
1892b6732a40 New module 'getnline'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
87 }
1892b6732a40 New module 'getnline'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
88
5062
aa119e787246 getline cleanup. This changes the getndelim2 API: both order of arguments,
Paul Eggert <eggert@cs.ucla.edu>
parents: 5049
diff changeset
89 if (size < offset)
aa119e787246 getline cleanup. This changes the getndelim2 API: both order of arguments,
Paul Eggert <eggert@cs.ucla.edu>
parents: 5049
diff changeset
90 goto done;
4460
1892b6732a40 New module 'getnline'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
91
5062
aa119e787246 getline cleanup. This changes the getndelim2 API: both order of arguments,
Paul Eggert <eggert@cs.ucla.edu>
parents: 5049
diff changeset
92 nbytes_avail = size - offset;
aa119e787246 getline cleanup. This changes the getndelim2 API: both order of arguments,
Paul Eggert <eggert@cs.ucla.edu>
parents: 5049
diff changeset
93 read_pos = ptr + offset;
4460
1892b6732a40 New module 'getnline'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
94
5062
aa119e787246 getline cleanup. This changes the getndelim2 API: both order of arguments,
Paul Eggert <eggert@cs.ucla.edu>
parents: 5049
diff changeset
95 if (nbytes_avail == 0 && nmax <= size)
aa119e787246 getline cleanup. This changes the getndelim2 API: both order of arguments,
Paul Eggert <eggert@cs.ucla.edu>
parents: 5049
diff changeset
96 goto done;
4460
1892b6732a40 New module 'getnline'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
97
10019
e435c0a7bace Optimize getndelim2 to use block operations when possible.
Eric Blake <ebb9@byu.net>
parents: 10006
diff changeset
98 /* Normalize delimiters, since memchr2 doesn't handle EOF. */
e435c0a7bace Optimize getndelim2 to use block operations when possible.
Eric Blake <ebb9@byu.net>
parents: 10006
diff changeset
99 if (delim1 == EOF)
e435c0a7bace Optimize getndelim2 to use block operations when possible.
Eric Blake <ebb9@byu.net>
parents: 10006
diff changeset
100 delim1 = delim2;
e435c0a7bace Optimize getndelim2 to use block operations when possible.
Eric Blake <ebb9@byu.net>
parents: 10006
diff changeset
101 else if (delim2 == EOF)
e435c0a7bace Optimize getndelim2 to use block operations when possible.
Eric Blake <ebb9@byu.net>
parents: 10006
diff changeset
102 delim2 = delim1;
e435c0a7bace Optimize getndelim2 to use block operations when possible.
Eric Blake <ebb9@byu.net>
parents: 10006
diff changeset
103
10006
b0a275071b2c Test getndelim2.
Eric Blake <ebb9@byu.net>
parents: 9309
diff changeset
104 flockfile (stream);
b0a275071b2c Test getndelim2.
Eric Blake <ebb9@byu.net>
parents: 9309
diff changeset
105
10028
bd5f3690f627 Fix computation of newsize during reallocation.
Bruno Haible <bruno@clisp.org>
parents: 10027
diff changeset
106 found_delimiter = false;
bd5f3690f627 Fix computation of newsize during reallocation.
Bruno Haible <bruno@clisp.org>
parents: 10027
diff changeset
107 do
4460
1892b6732a40 New module 'getnline'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
108 {
10027
8849272e39e8 Add comments.
Bruno Haible <bruno@clisp.org>
parents: 10024
diff changeset
109 /* Here always ptr + size == read_pos + nbytes_avail.
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10028
diff changeset
110 Also nbytes_avail > 0 || size < nmax. */
4460
1892b6732a40 New module 'getnline'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
111
10024
3c66797099ef avoid a warning from gcc
Jim Meyering <meyering@redhat.com>
parents: 10019
diff changeset
112 int c IF_LINT (= 0);
10019
e435c0a7bace Optimize getndelim2 to use block operations when possible.
Eric Blake <ebb9@byu.net>
parents: 10006
diff changeset
113 const char *buffer;
e435c0a7bace Optimize getndelim2 to use block operations when possible.
Eric Blake <ebb9@byu.net>
parents: 10006
diff changeset
114 size_t buffer_len;
e435c0a7bace Optimize getndelim2 to use block operations when possible.
Eric Blake <ebb9@byu.net>
parents: 10006
diff changeset
115
e435c0a7bace Optimize getndelim2 to use block operations when possible.
Eric Blake <ebb9@byu.net>
parents: 10006
diff changeset
116 buffer = freadptr (stream, &buffer_len);
e435c0a7bace Optimize getndelim2 to use block operations when possible.
Eric Blake <ebb9@byu.net>
parents: 10006
diff changeset
117 if (buffer)
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10028
diff changeset
118 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10028
diff changeset
119 if (delim1 != EOF)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10028
diff changeset
120 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10028
diff changeset
121 const char *end = memchr2 (buffer, delim1, delim2, buffer_len);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10028
diff changeset
122 if (end)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10028
diff changeset
123 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10028
diff changeset
124 buffer_len = end - buffer + 1;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10028
diff changeset
125 found_delimiter = true;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10028
diff changeset
126 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10028
diff changeset
127 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10028
diff changeset
128 }
10019
e435c0a7bace Optimize getndelim2 to use block operations when possible.
Eric Blake <ebb9@byu.net>
parents: 10006
diff changeset
129 else
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10028
diff changeset
130 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10028
diff changeset
131 c = getc (stream);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10028
diff changeset
132 if (c == EOF)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10028
diff changeset
133 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10028
diff changeset
134 /* Return partial line, if any. */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10028
diff changeset
135 if (read_pos == ptr)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10028
diff changeset
136 goto unlock_done;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10028
diff changeset
137 else
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10028
diff changeset
138 break;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10028
diff changeset
139 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10028
diff changeset
140 if (c == delim1 || c == delim2)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10028
diff changeset
141 found_delimiter = true;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10028
diff changeset
142 buffer_len = 1;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10028
diff changeset
143 }
4460
1892b6732a40 New module 'getnline'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
144
5062
aa119e787246 getline cleanup. This changes the getndelim2 API: both order of arguments,
Paul Eggert <eggert@cs.ucla.edu>
parents: 5049
diff changeset
145 /* We always want at least one byte left in the buffer, since we
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10028
diff changeset
146 always (unless we get an error while reading the first byte)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10028
diff changeset
147 NUL-terminate the line buffer. */
4460
1892b6732a40 New module 'getnline'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
148
10028
bd5f3690f627 Fix computation of newsize during reallocation.
Bruno Haible <bruno@clisp.org>
parents: 10027
diff changeset
149 if (nbytes_avail < buffer_len + 1 && size < nmax)
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10028
diff changeset
150 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10028
diff changeset
151 /* Grow size proportionally, not linearly, to avoid O(n^2)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10028
diff changeset
152 running time. */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10028
diff changeset
153 size_t newsize = size < MIN_CHUNK ? size + MIN_CHUNK : 2 * size;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10028
diff changeset
154 char *newptr;
5062
aa119e787246 getline cleanup. This changes the getndelim2 API: both order of arguments,
Paul Eggert <eggert@cs.ucla.edu>
parents: 5049
diff changeset
155
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10028
diff changeset
156 /* Increase newsize so that it becomes
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10028
diff changeset
157 >= (read_pos - ptr) + buffer_len. */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10028
diff changeset
158 if (newsize - (read_pos - ptr) < buffer_len + 1)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10028
diff changeset
159 newsize = (read_pos - ptr) + buffer_len + 1;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10028
diff changeset
160 /* Respect nmax. This handles possible integer overflow. */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10028
diff changeset
161 if (! (size < newsize && newsize <= nmax))
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10028
diff changeset
162 newsize = nmax;
4460
1892b6732a40 New module 'getnline'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
163
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10028
diff changeset
164 if (GETNDELIM2_MAXIMUM < newsize - offset)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10028
diff changeset
165 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10028
diff changeset
166 size_t newsizemax = offset + GETNDELIM2_MAXIMUM + 1;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10028
diff changeset
167 if (size == newsizemax)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10028
diff changeset
168 goto unlock_done;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10028
diff changeset
169 newsize = newsizemax;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10028
diff changeset
170 }
4460
1892b6732a40 New module 'getnline'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
171
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10028
diff changeset
172 nbytes_avail = newsize - (read_pos - ptr);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10028
diff changeset
173 newptr = realloc (ptr, newsize);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10028
diff changeset
174 if (!newptr)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10028
diff changeset
175 goto unlock_done;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10028
diff changeset
176 ptr = newptr;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10028
diff changeset
177 size = newsize;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10028
diff changeset
178 read_pos = size - nbytes_avail + ptr;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10028
diff changeset
179 }
4460
1892b6732a40 New module 'getnline'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
180
10027
8849272e39e8 Add comments.
Bruno Haible <bruno@clisp.org>
parents: 10024
diff changeset
181 /* Here, if size < nmax, nbytes_avail >= buffer_len + 1.
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10028
diff changeset
182 If size == nmax, nbytes_avail > 0. */
10027
8849272e39e8 Add comments.
Bruno Haible <bruno@clisp.org>
parents: 10024
diff changeset
183
10019
e435c0a7bace Optimize getndelim2 to use block operations when possible.
Eric Blake <ebb9@byu.net>
parents: 10006
diff changeset
184 if (1 < nbytes_avail)
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10028
diff changeset
185 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10028
diff changeset
186 size_t copy_len = nbytes_avail - 1;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10028
diff changeset
187 if (buffer_len < copy_len)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10028
diff changeset
188 copy_len = buffer_len;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10028
diff changeset
189 if (buffer)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10028
diff changeset
190 memcpy (read_pos, buffer, copy_len);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10028
diff changeset
191 else
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10028
diff changeset
192 *read_pos = c;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10028
diff changeset
193 read_pos += copy_len;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10028
diff changeset
194 nbytes_avail -= copy_len;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10028
diff changeset
195 }
10027
8849272e39e8 Add comments.
Bruno Haible <bruno@clisp.org>
parents: 10024
diff changeset
196
8849272e39e8 Add comments.
Bruno Haible <bruno@clisp.org>
parents: 10024
diff changeset
197 /* Here still nbytes_avail > 0. */
8849272e39e8 Add comments.
Bruno Haible <bruno@clisp.org>
parents: 10024
diff changeset
198
10019
e435c0a7bace Optimize getndelim2 to use block operations when possible.
Eric Blake <ebb9@byu.net>
parents: 10006
diff changeset
199 if (buffer && freadseek (stream, buffer_len))
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 10028
diff changeset
200 goto unlock_done;
4460
1892b6732a40 New module 'getnline'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
201 }
10028
bd5f3690f627 Fix computation of newsize during reallocation.
Bruno Haible <bruno@clisp.org>
parents: 10027
diff changeset
202 while (!found_delimiter);
4460
1892b6732a40 New module 'getnline'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
203
5062
aa119e787246 getline cleanup. This changes the getndelim2 API: both order of arguments,
Paul Eggert <eggert@cs.ucla.edu>
parents: 5049
diff changeset
204 /* Done - NUL terminate and return the number of bytes read.
4460
1892b6732a40 New module 'getnline'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
205 At this point we know that nbytes_avail >= 1. */
1892b6732a40 New module 'getnline'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
206 *read_pos = '\0';
1892b6732a40 New module 'getnline'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
207
5062
aa119e787246 getline cleanup. This changes the getndelim2 API: both order of arguments,
Paul Eggert <eggert@cs.ucla.edu>
parents: 5049
diff changeset
208 bytes_stored = read_pos - (ptr + offset);
aa119e787246 getline cleanup. This changes the getndelim2 API: both order of arguments,
Paul Eggert <eggert@cs.ucla.edu>
parents: 5049
diff changeset
209
10006
b0a275071b2c Test getndelim2.
Eric Blake <ebb9@byu.net>
parents: 9309
diff changeset
210 unlock_done:
b0a275071b2c Test getndelim2.
Eric Blake <ebb9@byu.net>
parents: 9309
diff changeset
211 funlockfile (stream);
b0a275071b2c Test getndelim2.
Eric Blake <ebb9@byu.net>
parents: 9309
diff changeset
212
5062
aa119e787246 getline cleanup. This changes the getndelim2 API: both order of arguments,
Paul Eggert <eggert@cs.ucla.edu>
parents: 5049
diff changeset
213 done:
aa119e787246 getline cleanup. This changes the getndelim2 API: both order of arguments,
Paul Eggert <eggert@cs.ucla.edu>
parents: 5049
diff changeset
214 *lineptr = ptr;
aa119e787246 getline cleanup. This changes the getndelim2 API: both order of arguments,
Paul Eggert <eggert@cs.ucla.edu>
parents: 5049
diff changeset
215 *linesize = size;
10006
b0a275071b2c Test getndelim2.
Eric Blake <ebb9@byu.net>
parents: 9309
diff changeset
216 return bytes_stored ? bytes_stored : -1;
4460
1892b6732a40 New module 'getnline'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
217 }