New LGPL implementation of getline() and getdelim()
Showing
2 changed files
with
92 additions
and
132 deletions
1 | /* getline.c -- Replacement for GNU C library function getline | 1 | /* GNU mailutils - a suite of utilities for electronic mail |
2 | Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc. | ||
2 | 3 | ||
3 | Copyright (C) 1993, 1996, 2001 Free Software Foundation, Inc. | 4 | This program is free software; you can redistribute it and/or modify |
5 | it under the terms of the GNU General Library Public License as published by | ||
6 | the Free Software Foundation; either version 2, or (at your option) | ||
7 | any later version. | ||
4 | 8 | ||
5 | This program is free software; you can redistribute it and/or | 9 | This program is distributed in the hope that it will be useful, |
6 | modify it under the terms of the GNU General Public License as | 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
7 | published by the Free Software Foundation; either version 2 of the | 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
8 | License, or (at your option) any later version. | 12 | GNU Library General Public License for more details. |
9 | 13 | ||
10 | This program is distributed in the hope that it will be useful, but | 14 | You should have received a copy of the GNU Library General Public License |
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | 15 | along with this program; if not, write to the Free Software |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 16 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ |
13 | General Public License for more details. | ||
14 | 17 | ||
15 | You should have received a copy of the GNU General Public License | 18 | /* First implementation by Alain Magloire */ |
16 | along with this program; if not, write to the Free Software | ||
17 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ | ||
18 | 19 | ||
19 | /* Written by Jan Brittenson, bson@gnu.ai.mit.edu. */ | 20 | #ifdef HAVE_CONFIG_H |
20 | |||
21 | #if HAVE_CONFIG_H | ||
22 | # include <config.h> | 21 | # include <config.h> |
23 | #endif | 22 | #endif |
24 | 23 | ||
25 | /* The `getdelim' function is only declared if the following symbol | ||
26 | is defined. */ | ||
27 | #define _GNU_SOURCE 1 | ||
28 | #include <stdio.h> | 24 | #include <stdio.h> |
29 | #include <sys/types.h> | 25 | #include <stdlib.h> |
30 | 26 | #include <string.h> | |
31 | #if defined __GNU_LIBRARY__ && HAVE_GETDELIM | ||
32 | 27 | ||
33 | ssize_t | 28 | ssize_t |
34 | getline (lineptr, n, stream) | 29 | getline (char **lineptr, size_t *n, FILE *stream) |
35 | char **lineptr; | ||
36 | size_t *n; | ||
37 | FILE *stream; | ||
38 | { | 30 | { |
39 | return getdelim (lineptr, n, '\n', stream); | 31 | return getdelim (lineptr, n, '\n', stream); |
40 | } | 32 | } |
41 | 33 | ||
34 | #ifndef HAVE_GETDELIM | ||
42 | 35 | ||
43 | #else /* ! have getdelim */ | 36 | /* Default value for line length. */ |
44 | 37 | static const int line_size = 128; | |
45 | # define NDEBUG | ||
46 | # include <assert.h> | ||
47 | |||
48 | # if STDC_HEADERS | ||
49 | # include <stdlib.h> | ||
50 | # else | ||
51 | char *malloc (), *realloc (); | ||
52 | # endif | ||
53 | |||
54 | /* Always add at least this many bytes when extending the buffer. */ | ||
55 | # define MIN_CHUNK 64 | ||
56 | |||
57 | /* Read up to (and including) a TERMINATOR from STREAM into *LINEPTR | ||
58 | + OFFSET (and null-terminate it). *LINEPTR is a pointer returned from | ||
59 | malloc (or NULL), pointing to *N characters of space. It is realloc'd | ||
60 | as necessary. Return the number of characters read (not including the | ||
61 | null terminator), or -1 on error or EOF. */ | ||
62 | 38 | ||
63 | ssize_t | 39 | ssize_t |
64 | getstr (lineptr, n, stream, terminator, offset) | 40 | getdelim (char **lineptr, size_t *n, int delim, FILE *stream) |
65 | char **lineptr; | ||
66 | size_t *n; | ||
67 | FILE *stream; | ||
68 | char terminator; | ||
69 | size_t offset; | ||
70 | { | 41 | { |
71 | int nchars_avail; /* Allocated but unused chars in *LINEPTR. */ | 42 | int indx = 0; |
72 | char *read_pos; /* Where we're reading into *LINEPTR. */ | 43 | int c; |
73 | int ret; | ||
74 | 44 | ||
75 | if (!lineptr || !n || !stream) | 45 | /* Sanity checks. */ |
46 | if (lineptr == NULL || n == NULL || stream == NULL) | ||
76 | return -1; | 47 | return -1; |
77 | 48 | ||
78 | if (!*lineptr) | 49 | /* Allocate the line the first time. */ |
50 | if (*lineptr == NULL) | ||
79 | { | 51 | { |
80 | *n = MIN_CHUNK; | 52 | *lineptr = malloc (line_size); |
81 | *lineptr = malloc (*n); | 53 | if (*lineptr == NULL) |
82 | if (!*lineptr) | ||
83 | return -1; | 54 | return -1; |
55 | *n = line_size; | ||
84 | } | 56 | } |
85 | 57 | ||
86 | nchars_avail = *n - offset; | 58 | while ((c = getc (stream)) != EOF) |
87 | read_pos = *lineptr + offset; | ||
88 | |||
89 | for (;;) | ||
90 | { | 59 | { |
91 | register int c = getc (stream); | 60 | /* Check if more memory is needed. */ |
92 | 61 | if (indx >= *n) | |
93 | /* We always want at least one char left in the buffer, since we | ||
94 | always (unless we get an error while reading the first char) | ||
95 | NUL-terminate the line buffer. */ | ||
96 | |||
97 | assert(*n - nchars_avail == read_pos - *lineptr); | ||
98 | if (nchars_avail < 2) | ||
99 | { | 62 | { |
100 | if (*n > MIN_CHUNK) | 63 | *lineptr = realloc (*lineptr, *n + line_size); |
101 | *n *= 2; | 64 | if (*lineptr == NULL) |
102 | else | ||
103 | *n += MIN_CHUNK; | ||
104 | |||
105 | nchars_avail = *n + *lineptr - read_pos; | ||
106 | *lineptr = realloc (*lineptr, *n); | ||
107 | if (!*lineptr) | ||
108 | return -1; | 65 | return -1; |
109 | read_pos = *n - nchars_avail + *lineptr; | 66 | *n += line_size; |
110 | assert(*n - nchars_avail == read_pos - *lineptr); | ||
111 | } | 67 | } |
112 | 68 | ||
113 | if (c == EOF || ferror (stream)) | 69 | /* Push the result in the line. */ |
114 | { | 70 | (*lineptr)[indx++] = c; |
115 | /* Return partial line, if any. */ | ||
116 | if (read_pos == *lineptr) | ||
117 | return -1; | ||
118 | else | ||
119 | break; | ||
120 | } | ||
121 | |||
122 | *read_pos++ = c; | ||
123 | nchars_avail--; | ||
124 | 71 | ||
125 | if (c == terminator) | 72 | /* Bail out. */ |
126 | /* Return the line. */ | 73 | if (c == delim) |
127 | break; | 74 | break; |
128 | } | 75 | } |
129 | 76 | ||
130 | /* Done - NUL terminate and return the number of chars read. */ | 77 | /* Make room for the null character. */ |
131 | *read_pos = '\0'; | 78 | if (indx >= *n) |
79 | { | ||
80 | *lineptr = realloc (*lineptr, *n + line_size); | ||
81 | if (*lineptr == NULL) | ||
82 | return -1; | ||
83 | *n += line_size; | ||
84 | } | ||
132 | 85 | ||
133 | ret = read_pos - (*lineptr + offset); | 86 | /* Null terminate the buffer. */ |
134 | return ret; | 87 | (*lineptr)[indx++] = 0; |
135 | } | ||
136 | 88 | ||
137 | ssize_t | 89 | /* The last line may not have the delimiter, we have to |
138 | getline (lineptr, n, stream) | 90 | * return what we got and the error will be seen on the |
139 | char **lineptr; | 91 | * next iteration. */ |
140 | size_t *n; | 92 | return (c == EOF && (indx - 1) == 0) ? -1 : indx - 1; |
141 | FILE *stream; | ||
142 | { | ||
143 | return getstr (lineptr, n, stream, '\n', 0); | ||
144 | } | 93 | } |
145 | 94 | ||
146 | ssize_t | 95 | #endif /* HAVE_GETDELIM */ |
147 | getdelim (lineptr, n, delimiter, stream) | 96 | |
148 | char **lineptr; | 97 | |
149 | size_t *n; | 98 | #ifdef STANDALONE |
150 | int delimiter; | 99 | int main(void) |
151 | FILE *stream; | ||
152 | { | 100 | { |
153 | return getstr (lineptr, n, stream, delimiter, 0); | 101 | FILE * fp; |
102 | char * line = NULL; | ||
103 | size_t len = 0; | ||
104 | ssize_t read; | ||
105 | fp = fopen("/etc/passwd", "r"); | ||
106 | if (fp == NULL) | ||
107 | exit(EXIT_FAILURE); | ||
108 | while ((read = getline(&line, &len, fp)) != -1) { | ||
109 | printf("Retrieved line of length %zu :\n", read); | ||
110 | printf("%s", line); | ||
111 | } | ||
112 | if (line) | ||
113 | free(line); | ||
114 | return EXIT_SUCCESS; | ||
154 | } | 115 | } |
155 | #endif | 116 | #endif | ... | ... |
1 | /* Copyright (C) 1995 Free Software Foundation, Inc. | 1 | /* GNU mailutils - a suite of utilities for electronic mail |
2 | Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc. | ||
2 | 3 | ||
3 | This program is free software; you can redistribute it and/or modify | 4 | This program is free software; you can redistribute it and/or modify |
4 | it under the terms of the GNU General Public License as published by | 5 | it under the terms of the GNU General Library Public License as published by |
5 | the Free Software Foundation; either version 2, or (at your option) | 6 | the Free Software Foundation; either version 2, or (at your option) |
6 | any later version. | 7 | any later version. |
7 | 8 | ||
8 | This program is distributed in the hope that it will be useful, | 9 | This program is distributed in the hope that it will be useful, |
9 | but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
11 | GNU General Public License for more details. | 12 | GNU Library General Public License for more details. |
12 | 13 | ||
13 | You should have received a copy of the GNU General Public License | 14 | You should have received a copy of the GNU Library General Public License |
14 | along with this program; if not, write to the Free Software | 15 | along with this program; if not, write to the Free Software |
15 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ | 16 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ |
16 | 17 | ||
17 | #ifndef GETLINE_H_ | 18 | #ifndef _GETLINE_H_ |
18 | # define GETLINE_H_ 1 | 19 | # define _GETLINE_H_ 1 |
19 | 20 | ||
20 | # include <stdio.h> | 21 | # include <stdio.h> |
21 | 22 | ||
... | @@ -27,10 +28,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ | ... | @@ -27,10 +28,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ |
27 | # endif | 28 | # endif |
28 | # endif | 29 | # endif |
29 | 30 | ||
30 | int | 31 | extern int getline PARAMS ((char **_lineptr, size_t *_n, FILE *_stream)); |
31 | getline PARAMS ((char **_lineptr, size_t *_n, FILE *_stream)); | ||
32 | 32 | ||
33 | int | 33 | extern int getdelim PARAMS ((char **_lineptr, size_t *_n, int _delimiter, FILE *_stream)); |
34 | getdelim PARAMS ((char **_lineptr, size_t *_n, int _delimiter, FILE *_stream)); | ||
35 | 34 | ||
36 | #endif /* not GETLINE_H_ */ | 35 | #endif /* ! _GETLINE_H_ */ | ... | ... |
-
Please register or sign in to post a comment