]> git.neil.brown.name Git - wiggle.git/blob - load.c
Removed malloc.h, fixed off-by-one in bestmatch.c, it was silent in Linux and deadly...
[wiggle.git] / load.c
1 /*
2  * wiggle - apply rejected patches
3  *
4  * Copyright (C) 2003 Neil Brown <neilb@cse.unsw.edu.au>
5  *
6  *
7  *    This program is free software; you can redistribute it and/or modify
8  *    it under the terms of the GNU General Public License as published by
9  *    the Free Software Foundation; either version 2 of the License, or
10  *    (at your option) any later version.
11  *
12  *    This program is distributed in the hope that it will be useful,
13  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *    GNU General Public License for more details.
16  *
17  *    You should have received a copy of the GNU General Public License
18  *    along with this program; if not, write to the Free Software Foundation, Inc.,
19  *    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  *    Author: Neil Brown
22  *    Email: <neilb@suse.de>
23  */
24
25 /*
26  * read in files
27  *
28  * Files are read in whole and stored in a
29  * struct stream {char*, len}
30  *
31  *
32  * loading the file "-" reads from stdin which might require
33  * reading into several buffers
34  */
35
36 #include        "wiggle.h"
37 #include        <sys/types.h>
38 #include        <sys/stat.h>
39 #include        <unistd.h>
40 #include        <fcntl.h>
41 #include        <stdlib.h>
42
43 static void join_streams(struct stream list[], int cnt)
44 {
45         /* join all the streams in the list (upto body=NULL)
46          * into one by re-allocing list[0].body and copying
47          */
48         int len = 0;
49         int i;
50         char *c;
51
52         for (i = 0; i < cnt ; i++)
53                 len += list[i].len;
54
55         c = realloc(list[0].body, len+1);
56         if (c == NULL)
57                 die();
58
59         list[0].body = c;
60         c  += list[0].len;
61         list[0].len = len;
62         for (i = 1; i < cnt; i++) {
63                 memcpy(c, list[i].body, list[i].len);
64                 c += list[i].len;
65                 list[i].len = 0;
66         }
67         c[0] = 0;
68 }
69
70 static struct stream load_regular(int fd)
71 {
72         struct stat stb;
73         struct stream s;
74         fstat(fd, &stb);
75
76         s.len = stb.st_size;
77         s.body = malloc(s.len+1);
78         if (s.body) {
79                 if (read(fd, s.body, s.len) != s.len) {
80                         free(s.body);
81                         s.body = NULL;
82                 }
83         } else
84                 die();
85         s.body[s.len] = 0;
86         return s;
87 }
88
89 static struct stream load_other(int fd)
90 {
91
92         struct stream list[10];
93         int i = 0;
94
95         while (1) {
96                 list[i].body = malloc(8192);
97                 if (!list[i].body)
98                         die();
99                 list[i].len = read(fd, list[i].body, 8192);
100                 if (list[i].len < 0)
101                         die();
102                 if (list[i].len == 0)
103                         break;
104                 i++;
105                 if (i == 10) {
106                         join_streams(list, i);
107                         i = 1;
108                 }
109         }
110         join_streams(list, i);
111         return list[0];
112 }
113
114 struct stream load_file(char *name)
115 {
116         struct stream s;
117         struct stat stb;
118         int fd;
119
120         s.body = NULL;
121         s.len = 0;
122         if (strcmp(name, "-") == 0)
123                 fd = 0;
124         else {
125                 fd = open(name, O_RDONLY);
126                 if (fd < 0)
127                         return s;
128         }
129
130         if (fstat(fd, &stb) == 0) {
131
132                 if (S_ISREG(stb.st_mode))
133                         s = load_regular(fd);
134                 else
135                         s = load_other(fd);
136         }
137         close(fd);
138         return s;
139 }
140