]> git.lizzy.rs Git - getline.git/blob - getline.c
Initial commit
[getline.git] / getline.c
1 /* The original code is public domain -- Will Hartung 4/9/09 */
2 /* Modifications, public domain as well, by Antti Haapala, 11/10/17
3    - Switched to getc on 5/23/19 */
4 /* Modifications, public domain, by Elias Fleckenstein 24/04/2022 */
5
6 #include <stdlib.h>
7 #include <errno.h>
8 #include "getline.h"
9
10 // if typedef doesn't exist (msvc, blah)
11 typedef intptr_t ssize_t;
12
13 ssize_t getline(char **lineptr, size_t *n, FILE *stream) {
14     size_t pos;
15     int c;
16
17     if (lineptr == NULL || stream == NULL || n == NULL) {
18         errno = EINVAL;
19         return -1;
20     }
21
22     c = getc(stream);
23     if (c == EOF) {
24         return -1;
25     }
26
27     if (*lineptr == NULL) {
28         *lineptr = malloc(128);
29         if (*lineptr == NULL) {
30             return -1;
31         }
32         *n = 128;
33     }
34
35     pos = 0;
36     while(c != EOF) {
37         if (pos + 1 >= *n) {
38             size_t new_size = *n + (*n >> 2);
39             if (new_size < 128) {
40                 new_size = 128;
41             }
42             char *new_ptr = realloc(*lineptr, new_size);
43             if (new_ptr == NULL) {
44                 return -1;
45             }
46             *n = new_size;
47             *lineptr = new_ptr;
48         }
49
50         ((unsigned char *)(*lineptr))[pos ++] = c;
51         if (c == '\n') {
52             break;
53         }
54         c = getc(stream);
55     }
56
57     (*lineptr)[pos] = '\0';
58     return pos;
59 }