source: trunk/third/gettext/lib/getline.c @ 16931

Revision 16931, 3.7 KB checked in by ghudson, 23 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r16930, which included commits to RCS files with non-trunk default branches.
Line 
1/* getline.c -- Replacement for GNU C library function getline
2
3Copyright (C) 1993, 1996 Free Software Foundation, Inc.
4
5This program is free software; you can redistribute it and/or
6modify it under the terms of the GNU General Public License as
7published by the Free Software Foundation; either version 2 of the
8License, or (at your option) any later version.
9
10This program is distributed in the hope that it will be useful, but
11WITHOUT ANY WARRANTY; without even the implied warranty of
12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
18
19/* Written by Jan Brittenson, bson@gnu.ai.mit.edu.  */
20
21#if HAVE_CONFIG_H
22# include <config.h>
23#endif
24
25/* The `getdelim' function is only declared if the following symbol
26   is defined.  */
27#ifndef _GNU_SOURCE
28# define _GNU_SOURCE    1
29#endif
30#include <stdio.h>
31#include <sys/types.h>
32
33#if defined __GNU_LIBRARY__ && HAVE_GETDELIM
34
35int
36getline (lineptr, n, stream)
37     char **lineptr;
38     size_t *n;
39     FILE *stream;
40{
41  return getdelim (lineptr, n, '\n', stream);
42}
43
44#else /* ! have getdelim */
45
46# define NDEBUG
47# include <assert.h>
48
49# if HAVE_STDLIB_H
50#  include <stdlib.h>
51# else
52extern char *malloc ();
53extern char *realloc ();
54# endif
55
56/* Always add at least this many bytes when extending the buffer.  */
57# define MIN_CHUNK 64
58
59/* Read up to (and including) a TERMINATOR from STREAM into *LINEPTR
60   + OFFSET (and null-terminate it). *LINEPTR is a pointer returned from
61   malloc (or NULL), pointing to *N characters of space.  It is realloc'd
62   as necessary.  Return the number of characters read (not including the
63   null terminator), or -1 on error or EOF.
64   NOTE: There is another getstr() function declared in <curses.h>.  */
65
66static int
67getstr (lineptr, n, stream, terminator, offset)
68     char **lineptr;
69     size_t *n;
70     FILE *stream;
71     char terminator;
72     size_t offset;
73{
74  int nchars_avail;             /* Allocated but unused chars in *LINEPTR.  */
75  char *read_pos;               /* Where we're reading into *LINEPTR. */
76  int ret;
77
78  if (!lineptr || !n || !stream)
79    return -1;
80
81  if (!*lineptr)
82    {
83      *n = MIN_CHUNK;
84      *lineptr = malloc (*n);
85      if (!*lineptr)
86        return -1;
87    }
88
89  nchars_avail = *n - offset;
90  read_pos = *lineptr + offset;
91
92  for (;;)
93    {
94      register int c = getc (stream);
95
96      /* We always want at least one char left in the buffer, since we
97         always (unless we get an error while reading the first char)
98         NUL-terminate the line buffer.  */
99
100      assert(*n - nchars_avail == read_pos - *lineptr);
101      if (nchars_avail < 2)
102        {
103          if (*n > MIN_CHUNK)
104            *n *= 2;
105          else
106            *n += MIN_CHUNK;
107
108          nchars_avail = *n + *lineptr - read_pos;
109          *lineptr = realloc (*lineptr, *n);
110          if (!*lineptr)
111            return -1;
112          read_pos = *n - nchars_avail + *lineptr;
113          assert(*n - nchars_avail == read_pos - *lineptr);
114        }
115
116      if (c == EOF || ferror (stream))
117        {
118          /* Return partial line, if any.  */
119          if (read_pos == *lineptr)
120            return -1;
121          else
122            break;
123        }
124
125      *read_pos++ = c;
126      nchars_avail--;
127
128      if (c == terminator)
129        /* Return the line.  */
130        break;
131    }
132
133  /* Done - NUL terminate and return the number of chars read.  */
134  *read_pos = '\0';
135
136  ret = read_pos - (*lineptr + offset);
137  return ret;
138}
139
140int
141getline (lineptr, n, stream)
142     char **lineptr;
143     size_t *n;
144     FILE *stream;
145{
146  return getstr (lineptr, n, stream, '\n', 0);
147}
148
149int
150getdelim (lineptr, n, delimiter, stream)
151     char **lineptr;
152     size_t *n;
153     int delimiter;
154     FILE *stream;
155{
156  return getstr (lineptr, n, stream, delimiter, 0);
157}
158#endif
Note: See TracBrowser for help on using the repository browser.