source: trunk/emx/src/emxbind/utils.c@ 2446

Last change on this file since 2446 was 18, checked in by bird, 22 years ago

Initial revision

  • Property cvs2svn:cvs-rev set to 1.1
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 6.4 KB
Line 
1/* utils.c -- Utility functions
2 Copyright (c) 1991-1996 Eberhard Mattes
3
4This file is part of emxbind.
5
6emxbind is free software; you can redistribute it and/or modify it
7under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2, or (at your option)
9any later version.
10
11emxbind is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with emxbind; see the file COPYING. If not, write to
18the Free Software Foundation, 59 Temple Place - Suite 330,
19Boston, MA 02111-1307, USA. */
20
21
22#include <stdio.h>
23#include <stdlib.h>
24#include <stdarg.h>
25#include <string.h>
26#include <sys/types.h>
27#include <sys/stat.h>
28#include <fcntl.h>
29#include <io.h>
30#include "defs.h"
31#include "emxbind.h"
32
33
34static void out_of_mem (void) NORETURN2;
35
36
37/* Print an error message and abort. This function is called like
38 printf() but never returns. The message will be prefixed with
39 "emxbind: " and a newline will be added at the end. */
40
41void error (const char *fmt, ...)
42{
43 va_list arg_ptr;
44
45 va_start (arg_ptr, fmt);
46 fprintf (stderr, "emxbind: ");
47 vfprintf (stderr, fmt, arg_ptr);
48 fputc ('\n', stderr);
49 exit (2);
50}
51
52/* Print an out of memory message and abort. */
53
54static void out_of_mem (void)
55{
56 error ("out of memory");
57}
58
59
60/* Read SIZE bytes from the file F to the buffer DST. If there aren't
61 SIZE bytes at the current location of the read/write pointer, an
62 error message will be displayed and the program will be
63 terminated. */
64
65void my_read (void *dst, size_t size, struct file *f)
66{
67 if (fread (dst, 1, size, f->f) != size)
68 error ("cannot read `%s'", f->name);
69}
70
71
72/* Write SIZE bytes from SRC to the file F. */
73
74void my_write (const void *src, size_t size, struct file *f)
75{
76 if (fwrite (src, 1, size, f->f) != size)
77 error ("cannot write `%s'", f->name);
78}
79
80
81/* Open the file named NAME and let F reference that file. OMODE is
82 the open mode. The file is always opened in binary mode. */
83
84void my_open (struct file *f, const char *name, enum open_mode omode)
85{
86 const char *ms;
87
88 f->del = FALSE;
89 switch (omode)
90 {
91 case open_read:
92 ms = "rb";
93 break;
94 case open_read_write:
95 ms = "r+b";
96 break;
97 case create_write:
98 ms = "wb";
99 f->del = TRUE;
100 break;
101 default:
102 ms = NULL;
103 break;
104 }
105 f->name = name;
106 f->f = fopen (name, ms);
107 if (f->f == NULL)
108 error ("cannot open `%s'", name);
109 f->ok = TRUE;
110}
111
112
113/* Close the file F if it is open. */
114
115void my_close (struct file *f)
116{
117 if (f->ok)
118 {
119 f->ok = FALSE;
120 if (fflush (f->f) != 0)
121 error ("cannot write `%s'", f->name);
122 if (fclose (f->f) != 0)
123 error ("cannot close `%s'", f->name);
124 }
125}
126
127
128/* Close and remove the file F if it is open. */
129
130void my_remove (struct file *f)
131{
132 if (f->ok)
133 {
134 f->ok = FALSE;
135 fclose (f->f);
136 remove (f->name);
137 }
138}
139
140
141/* Set the read/write pointer of the file F to location POS. */
142
143void my_seek (struct file *f, long pos)
144{
145 if (fseek (f->f, pos, SEEK_SET) != 0)
146 error ("seek failed (`%s')", f->name);
147}
148
149
150/* Skip POS bytes of the file F. The read/write pointer is moved by
151 POS. */
152
153void my_skip (struct file *f, long pos)
154{
155 if (fseek (f->f, pos, SEEK_CUR) != 0)
156 error ("seek failed (`%s')", f->name);
157}
158
159
160/* Return the length of the file F. Note that this function moves the
161 read/write pointer to the end of the file. */
162
163long my_size (struct file *f)
164{
165 long n;
166
167 if (fseek (f->f, 0L, SEEK_END) != 0 || (n = ftell (f->f)) < 0)
168 error ("seek failed (`%s')", f->name);
169 return n;
170}
171
172
173/* Return the current location of the read/write pointer of the file
174 F. */
175
176long my_tell (struct file *f)
177{
178 long n;
179
180 n = ftell (f->f);
181 if (n < 0)
182 error ("ftell() failed (`%s')", f->name);
183 return n;
184}
185
186
187/* Truncate the file F. All data beyond the current read/write
188 pointer are discarded. */
189
190void my_trunc (struct file *f)
191{
192 fflush (f->f);
193 if (ftruncate (fileno (f->f), ftell (f->f)) != 0)
194 error ("ftruncate failed (`%s')", f->name);
195}
196
197
198/* Read a null-terminated string from the file F to the buffer DST.
199 There are SIZE bytes available at DST. */
200
201void my_read_str (byte *dst, size_t size, struct file *f)
202{
203 int c;
204
205 for (;;)
206 {
207 c = getc (f->f);
208 if (c == EOF)
209 error ("cannot read `%s'", f->name);
210 if (size <= 0)
211 error ("invalid string in `%s'", f->name);
212 *dst++ = (byte)c;
213 --size;
214 if (c == 0)
215 break;
216 }
217}
218
219
220/* Let DST reference the file referenced by SRC. If DST refers to a
221 open file, it will be closed before doing this. SRC will be
222 closed. */
223
224void my_change (struct file *dst, struct file *src)
225{
226 my_close (dst);
227 *dst = *src;
228 src->ok = src->del = FALSE;
229 my_seek (dst, 0);
230}
231
232
233/* Return true iff the file NAME is readable. */
234
235int my_readable (const char *name)
236{
237 return (access (name, 4) == 0);
238}
239
240
241/* Allocate N bytes of memory. This function never returns NULL.
242 When running out of memory, a message is displayed and the program
243 is terminated. */
244
245void *xmalloc (size_t n)
246{
247 void *q;
248
249 q = malloc (n);
250 if (q == NULL)
251 out_of_mem ();
252 return q;
253}
254
255
256/* Create a duplicate of the string P on the heap. This function
257 never returns NULL. When running out of memory, a message is
258 displayed and the program is terminated. */
259
260char *xstrdup (const char *p)
261{
262 char *q;
263
264 q = strdup (p);
265 if (q == NULL)
266 out_of_mem ();
267 return q;
268}
269
270
271/* Reallocate the block of memory P to N bytes. This function never
272 returns NULL. When running out of memory, a message is displayed
273 and the program is terminated. */
274
275void *xrealloc (void *p, size_t n)
276{
277 void *q;
278
279 q = realloc (p, n);
280 if (q == NULL)
281 out_of_mem ();
282 return q;
283}
284
285
286/* Return the string "s" if plural should be used for the number N.
287 If N is 1, return the empty string. */
288
289const char *plural_s (long n)
290{
291 return (n == 1 ? "" : "s");
292}
293
294
295/* Add SIZE bytes at SRC to the end of the growable buffer DST.
296 Expand DST as required. */
297
298void put_grow (struct grow *dst, const void *src, size_t size)
299{
300 if (dst->len + size > dst->size)
301 {
302 dst->size += 1024 * ((size + 1023) / 1024);
303 dst->data = xrealloc (dst->data, dst->size);
304 }
305 memmove (dst->data + dst->len, src, size);
306 dst->len += size;
307}
Note: See TracBrowser for help on using the repository browser.