~ubuntu-branches/ubuntu/vivid/cctools/vivid

« back to all changes in this revision

Viewing changes to dttools/src/get_line.c

  • Committer: Bazaar Package Importer
  • Author(s): Michael Hanke
  • Date: 2011-05-07 09:05:00 UTC
  • Revision ID: james.westby@ubuntu.com-20110507090500-lqpmdtwndor6e7os
Tags: upstream-3.3.2
ImportĀ upstreamĀ versionĀ 3.3.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
Copyright (C) 2009- The University of Notre Dame
 
3
Originally written by Kevin Partington (27 January 2009)
 
4
This software is distributed under the GNU General Public License.
 
5
See the file COPYING for details.
 
6
*/
 
7
 
 
8
#include <stdio.h>
 
9
#include <stdlib.h>
 
10
#include <string.h>
 
11
 
 
12
#include "get_line.h"
 
13
 
 
14
char * get_line( FILE *fp )
 
15
{
 
16
        static char *other = NULL;
 
17
        static char buffer[LARGE_LINE_MAX];
 
18
 
 
19
        /* Free the other buffer, if we have used it. */
 
20
        if (other)
 
21
        {
 
22
                free(other);
 
23
                other = NULL;
 
24
        }
 
25
 
 
26
        if (!fgets(buffer, LARGE_LINE_MAX, fp))
 
27
        {
 
28
                return NULL;
 
29
        }
 
30
 
 
31
        /* If the main buffer is completely filled and there is more
 
32
           to read... (second condition is for slackers who don't put newlines
 
33
           at the end of their text files) */
 
34
        if (!strrchr(buffer, '\n') && strlen(buffer) == LARGE_LINE_MAX - 1)
 
35
        {
 
36
                int s = LARGE_LINE_MAX;
 
37
 
 
38
                /* ...use the heap buffer ("other"), doubling its size
 
39
                   repeatedly until it is filled. */
 
40
                do {
 
41
                        char *tmp = realloc(other, 2*s * sizeof(char));
 
42
 
 
43
                        if (!tmp)
 
44
                        {
 
45
                                free(other);
 
46
                                other = NULL;
 
47
                                return NULL;
 
48
                        }
 
49
                        else
 
50
                        {
 
51
                                if (!other)
 
52
                                        strncpy(tmp, buffer, strlen(buffer));
 
53
 
 
54
                                other = tmp;
 
55
                        }
 
56
 
 
57
                        /* Reusing tmp as a return value check */
 
58
                        tmp = fgets(other + s - 1, s + 1, fp);
 
59
 
 
60
                        if (!tmp)
 
61
                        {
 
62
                                /* fgets failed because there is no more to
 
63
                                   read (i.e., EOF), after a read has already
 
64
                                   occurred. This shouldn't happen if the file
 
65
                                   is properly delimited with newlines
 
66
                                   (including one on the end of the file
 
67
                                   itself). If you don't write newlines at the
 
68
                                   end of your text files, you should be
 
69
                                   ashamed of yourself! -KP
 
70
                                */
 
71
                                return other;
 
72
                        }
 
73
                        
 
74
                        s *= 2;
 
75
 
 
76
                } while (!strrchr(other, '\n'));
 
77
 
 
78
                return other;
 
79
 
 
80
        }
 
81
        else
 
82
        {
 
83
                return buffer;
 
84
        }
 
85
}