Tizen 2.0 Release
[framework/graphics/cairo.git] / util / cairo-missing / getline.c
1 /* cairo - a vector graphics library with display and print output
2  *
3  * Copyright © 2006 Red Hat, Inc.
4  * Copyright © 2011 Andrea Canciani
5  *
6  * Permission to use, copy, modify, distribute, and sell this software
7  * and its documentation for any purpose is hereby granted without
8  * fee, provided that the above copyright notice appear in all copies
9  * and that both that copyright notice and this permission notice
10  * appear in supporting documentation, and that the name of the
11  * copyright holders not be used in advertising or publicity
12  * pertaining to distribution of the software without specific,
13  * written prior permission. The copyright holders make no
14  * representations about the suitability of this software for any
15  * purpose.  It is provided "as is" without express or implied
16  * warranty.
17  *
18  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
19  * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
20  * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
21  * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
22  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
23  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
24  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
25  * SOFTWARE.
26  *
27  * Authors: Carl Worth <cworth@cworth.org>
28  *          Andrea Canciani <ranma42@gmail.com>
29  */
30
31 #include "cairo-missing.h"
32
33 #ifndef HAVE_GETLINE
34 #include "cairo-malloc-private.h"
35
36 #define GETLINE_MIN_BUFFER_SIZE 128
37 ssize_t
38 getline (char   **lineptr,
39          size_t  *n,
40          FILE    *stream)
41 {
42     char *line, *tmpline;
43     size_t len, offset;
44     ssize_t ret;
45
46     offset = 0;
47     len = *n;
48     line = *lineptr;
49     if (len < GETLINE_MIN_BUFFER_SIZE) {
50         len = GETLINE_MIN_BUFFER_SIZE;
51         line = NULL;
52     }
53
54     if (line == NULL) {
55         line = (char *) _cairo_malloc (len);
56         if (unlikely (line == NULL))
57             return -1;
58     }
59
60     while (1) {
61         if (offset + 1 == len) {
62             tmpline = (char *) _cairo_realloc_ab (line, len, 2);
63             if (unlikely (tmpline == NULL)) {
64                 if (line != *lineptr)
65                     free (line);
66                 return -1;
67             }
68             len *= 2;
69             line = tmpline;
70         }
71
72         ret = getc (stream);
73         if (ret == -1)
74             break;
75
76         line[offset++] = ret;
77         if (ret == '\n') {
78             ret = offset;
79             break;
80         }
81     }
82
83     line[offset++] = '\0';
84     *lineptr = line;
85     *n = len;
86
87     return ret;
88 }
89 #undef GETLINE_BUFFER_SIZE
90 #endif