source: trunk/libs/newlib/src/newlib/libc/stdio/getdelim.c @ 450

Last change on this file since 450 was 444, checked in by satin@…, 6 years ago

add newlib,libalmos-mkh, restructure shared_syscalls.h and mini-libc

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