Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
6536 serge 1
/* Copyright 2002, Red Hat Inc. - all rights reserved */
2
/*
3
FUNCTION
4
<>---read a line up to a specified line delimiter
5
 
6
INDEX
7
	getdelim
8
 
9
ANSI_SYNOPSIS
10
	#include 
11
	int getdelim(char **<[bufptr]>, size_t *<[n]>,
12
                     int <[delim]>, FILE *<[fp]>);
13
 
14
TRAD_SYNOPSIS
15
	#include 
16
	int getdelim(<[bufptr]>, <[n]>, <[delim]>, <[fp]>)
17
	char **<[bufptr]>;
18
	size_t *<[n]>;
19
	int <[delim]>;
20
	FILE *<[fp]>;
21
 
22
DESCRIPTION
23
<> reads a file <[fp]> up to and possibly including a specified
24
delimiter <[delim]>.  The line is read into a buffer pointed to
25
by <[bufptr]> and designated with size *<[n]>.  If the buffer is
26
not large enough, it will be dynamically grown by <>.
27
As the buffer is grown, the pointer to the size <[n]> will be
28
updated.
29
 
30
RETURNS
31
<> returns <<-1>> if no characters were successfully read;
32
otherwise, it returns the number of bytes successfully read.
33
At end of file, the result is nonzero.
34
 
35
PORTABILITY
36
<> is a glibc extension.
37
 
38
No supporting OS subroutines are directly required.
39
*/
40
 
41
#include <_ansi.h>
42
#include 
43
#include 
44
#include 
45
#include "local.h"
46
 
47
#define MIN_LINE_SIZE 4
48
#define DEFAULT_LINE_SIZE 128
49
 
50
ssize_t
51
_DEFUN(__getdelim, (bufptr, n, delim, fp),
52
       char **bufptr _AND
53
       size_t *n     _AND
54
       int delim     _AND
55
       FILE *fp)
56
{
57
  char *buf;
58
  char *ptr;
59
  size_t newsize, numbytes;
60
  int pos;
61
  int ch;
62
  int cont;
63
 
64
  if (fp == NULL || bufptr == NULL || n == NULL)
65
    {
66
      errno = EINVAL;
67
      return -1;
68
    }
69
 
70
  buf = *bufptr;
71
  if (buf == NULL || *n < MIN_LINE_SIZE)
72
    {
73
      buf = (char *)realloc (*bufptr, DEFAULT_LINE_SIZE);
74
      if (buf == NULL)
75
        {
76
	  return -1;
77
        }
78
      *bufptr = buf;
79
      *n = DEFAULT_LINE_SIZE;
80
    }
81
 
82
  CHECK_INIT (_REENT, fp);
83
 
84
  _newlib_flockfile_start (fp);
85
 
86
  numbytes = *n;
87
  ptr = buf;
88
 
89
  cont = 1;
90
 
91
  while (cont)
92
    {
93
      /* fill buffer - leaving room for nul-terminator */
94
      while (--numbytes > 0)
95
        {
96
          if ((ch = getc_unlocked (fp)) == EOF)
97
            {
98
	      cont = 0;
99
              break;
100
            }
101
	  else
102
            {
103
              *ptr++ = ch;
104
              if (ch == delim)
105
                {
106
                  cont = 0;
107
                  break;
108
                }
109
            }
110
        }
111
 
112
      if (cont)
113
        {
114
          /* Buffer is too small so reallocate a larger buffer.  */
115
          pos = ptr - buf;
116
          newsize = (*n << 1);
117
          buf = realloc (buf, newsize);
118
          if (buf == NULL)
119
            {
120
              cont = 0;
121
              break;
122
            }
123
 
124
          /* After reallocating, continue in new buffer */
125
          *bufptr = buf;
126
          *n = newsize;
127
          ptr = buf + pos;
128
          numbytes = newsize - pos;
129
        }
130
    }
131
 
132
  _newlib_flockfile_end (fp);
133
 
134
  /* if no input data, return failure */
135
  if (ptr == buf)
136
    return -1;
137
 
138
  /* otherwise, nul-terminate and return number of bytes read */
139
  *ptr = '\0';
140
  return (ssize_t)(ptr - buf);
141
}
142