File: minimal-getline.c

package info (click to toggle)
auto-multiple-choice 1.4.0-2~exp1
  • links: PTS, VCS
  • area: main
  • in suites: experimental
  • size: 18,520 kB
  • sloc: perl: 23,839; xml: 20,920; cpp: 1,791; makefile: 472; ansic: 186; sh: 80
file content (70 lines) | stat: -rw-r--r-- 1,678 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
/*

 Copyright (C) 2011-2017 Alexis Bienvenue <paamc@passoire.fr>

 This file is part of Auto-Multiple-Choice

 Auto-Multiple-Choice is free software: you can redistribute it
 and/or modify it under the terms of the GNU General Public License
 as published by the Free Software Foundation, either version 2 of
 the License, or (at your option) any later version.

 Auto-Multiple-Choice is distributed in the hope that it will be
 useful, but WITHOUT ANY WARRANTY; without even the implied warranty
 of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with Auto-Multiple-Choice.  If not, see
 <http://www.gnu.org/licenses/>.

*/

/* This file contains a minimal getline implementation for use in AMC
   on platforms where getline is not included */

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>

ssize_t getline(char **lineptr,size_t *n,FILE *stream) {
  ssize_t i=0;
  int c;

  if(lineptr==NULL || n==NULL || stream==NULL) {
    errno=EINVAL;
    return -1;
  }

  if (*lineptr==NULL || *n==0) {
    *n = 64;
    *lineptr=(char*)realloc(*lineptr,sizeof(char)*(*n));
    if(*lineptr==NULL) {
      return(-1);
    }
  }

  flockfile(stream);

  while((c = getc_unlocked(stream)) != EOF) {
    i++;
    if(i+1 > *n) {
      *n = *n + 16;
      *lineptr=(char*)realloc(*lineptr,sizeof(char)*(*n));

      if(*lineptr==NULL) {
        funlockfile(stream);
        return(-1);
      }
    }

    (*lineptr)[i-1]=c;
    if(c=='\n') break;
  }

  funlockfile(stream);

  (*lineptr)[i]='\0';
  return(i>0 ? i : -1);
}