Wiggle 0.6 - first release
[wiggle/upstream.git] / load.c
bloba6ef25053806c0bdb375f2ab48c26c502673e7f6
1 /*
2 * wiggle - apply rejected patches
4 * Copyright (C) 2003 Neil Brown <neilb@cse.unsw.edu.au>
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.
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.
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
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 * Author: Neil Brown
22 * Email: <neilb@cse.unsw.edu.au>
23 * Paper: Neil Brown
24 * School of Computer Science and Engineering
25 * The University of New South Wales
26 * Sydney, 2052
27 * Australia
31 * read in files
33 * Files are read in whole and stored in a
34 * struct stream {char*, len}
37 * loading the file "-" reads from stdin which might require
38 * reading into several buffers
41 #include "wiggle.h"
42 #include <sys/types.h>
43 #include <sys/stat.h>
44 #include <unistd.h>
45 #include <fcntl.h>
46 #include <malloc.h>
48 static void join_streams(struct stream list[], int cnt)
50 /* join all the streams in the list (upto body=NULL)
51 * into one by re-allocing list[0].body and copying
53 int len=0;
54 int i;
55 char *c;
57 for (i=0; i<cnt ; i++)
58 len += list[i].len;
60 c = realloc(list[0].body, len);
61 if (c == NULL)
62 die();
64 list[0].body = c;
65 c += list[0].len;
66 list[0].len = len;
67 for (i=1; i<cnt; i++) {
68 memcpy(c, list[i].body, list[i].len);
69 c += list[i].len;
70 list[i].len = 0;
74 static struct stream load_regular(int fd)
76 struct stat stb;
77 struct stream s;
78 fstat(fd, &stb);
80 s.len = stb.st_size;
81 s.body = malloc(s.len);
82 if (s.body) {
83 if (read(fd, s.body, s.len) != s.len) {
84 free(s.body);
85 s.body = NULL;
87 } else die();
88 return s;
91 static struct stream load_other(int fd)
94 struct stream list[10];
95 int i = 0;
97 while(1) {
98 list[i].body = malloc(8192);
99 if (!list[i].body)
100 die();
101 list[i].len = read(fd, list[i].body, 8192);
102 if (list[i].len < 0)
103 die();
104 if (list[i].len == 0)
105 break;
106 i++;
107 if (i == 10) {
108 join_streams(list, i);
109 i = 1;
112 join_streams(list, i);
113 return list[0];
116 struct stream load_file(char *name)
118 struct stream s;
119 struct stat stb;
120 int fd;
122 s.body = NULL;
123 s.len = 0;
124 if (strcmp(name, "-")==0)
125 fd = 0;
126 else {
127 fd = open(name, O_RDONLY);
128 if (fd <0)
129 return s;
132 if (fstat(fd, &stb) == 0) {
134 if (S_ISREG(stb.st_mode))
135 s = load_regular(fd);
136 else
137 s = load_other(fd);
139 close(fd);
140 return s;