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

Last change on this file was 2673, checked in by bird, 19 years ago
  • *:

o Synced over changed from 0.6.1 bugfixing.

  • emxbind:

o #38: Fixed truncation bug writing to the LX nametable. (Yuri)
o #38: Imports and exports are limited to 255 not 127 chars. (Yuri)
o #28: Use DLL name from the .def file when present.

  • emxomf:

o #70: Demangle symbol names in debug info. (thanks to Yuri)

  • emxomfld:

o #55: delete the response file when reinit the args.
o #46: specify .map file extension to the linker.
o #34: Removed all the silliness trying to deal with truncated symbols.
o Don't display usage() on failure, just the error message.
o #20: use mkstemp + close instead of mktemp for the response file.

  • ld:

o #20: use make_temp_file instead of mktemp. This involved including

libiberty.h which required some adjustments of duplicate code to work.

o #27: Applied fix from Yuri.

  • libmoddef:

o Allow '.' and '@' in LIBRARY/NAME names.

  • Property cvs2svn:cvs-rev set to 1.1
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 6.8 KB
RevLine 
[18]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
[2673]52
53/* Print an warning message. This function is called like printf().
54 The message will be prefixed with "emxbind: warning: " and a
55 newline will be added at the end. */
56
57void warning (const char *fmt, ...)
58{
59 va_list arg_ptr;
60
61 va_start (arg_ptr, fmt);
62 fprintf (stderr, "emxbind: warning: ");
63 vfprintf (stderr, fmt, arg_ptr);
64 fputc ('\n', stderr);
65}
66
67
[18]68/* Print an out of memory message and abort. */
69
70static void out_of_mem (void)
71{
72 error ("out of memory");
73}
74
75
76/* Read SIZE bytes from the file F to the buffer DST. If there aren't
77 SIZE bytes at the current location of the read/write pointer, an
78 error message will be displayed and the program will be
79 terminated. */
80
81void my_read (void *dst, size_t size, struct file *f)
82{
83 if (fread (dst, 1, size, f->f) != size)
84 error ("cannot read `%s'", f->name);
85}
86
87
88/* Write SIZE bytes from SRC to the file F. */
89
90void my_write (const void *src, size_t size, struct file *f)
91{
92 if (fwrite (src, 1, size, f->f) != size)
93 error ("cannot write `%s'", f->name);
94}
95
96
97/* Open the file named NAME and let F reference that file. OMODE is
98 the open mode. The file is always opened in binary mode. */
99
100void my_open (struct file *f, const char *name, enum open_mode omode)
101{
102 const char *ms;
103
104 f->del = FALSE;
105 switch (omode)
106 {
107 case open_read:
108 ms = "rb";
109 break;
110 case open_read_write:
111 ms = "r+b";
112 break;
113 case create_write:
114 ms = "wb";
115 f->del = TRUE;
116 break;
117 default:
118 ms = NULL;
119 break;
120 }
121 f->name = name;
122 f->f = fopen (name, ms);
123 if (f->f == NULL)
124 error ("cannot open `%s'", name);
125 f->ok = TRUE;
126}
127
128
129/* Close the file F if it is open. */
130
131void my_close (struct file *f)
132{
133 if (f->ok)
134 {
135 f->ok = FALSE;
136 if (fflush (f->f) != 0)
137 error ("cannot write `%s'", f->name);
138 if (fclose (f->f) != 0)
139 error ("cannot close `%s'", f->name);
140 }
141}
142
143
144/* Close and remove the file F if it is open. */
145
146void my_remove (struct file *f)
147{
148 if (f->ok)
149 {
150 f->ok = FALSE;
151 fclose (f->f);
152 remove (f->name);
153 }
154}
155
156
157/* Set the read/write pointer of the file F to location POS. */
158
159void my_seek (struct file *f, long pos)
160{
161 if (fseek (f->f, pos, SEEK_SET) != 0)
162 error ("seek failed (`%s')", f->name);
163}
164
165
166/* Skip POS bytes of the file F. The read/write pointer is moved by
167 POS. */
168
169void my_skip (struct file *f, long pos)
170{
171 if (fseek (f->f, pos, SEEK_CUR) != 0)
172 error ("seek failed (`%s')", f->name);
173}
174
175
176/* Return the length of the file F. Note that this function moves the
177 read/write pointer to the end of the file. */
178
179long my_size (struct file *f)
180{
181 long n;
182
183 if (fseek (f->f, 0L, SEEK_END) != 0 || (n = ftell (f->f)) < 0)
184 error ("seek failed (`%s')", f->name);
185 return n;
186}
187
188
189/* Return the current location of the read/write pointer of the file
190 F. */
191
192long my_tell (struct file *f)
193{
194 long n;
195
196 n = ftell (f->f);
197 if (n < 0)
198 error ("ftell() failed (`%s')", f->name);
199 return n;
200}
201
202
203/* Truncate the file F. All data beyond the current read/write
204 pointer are discarded. */
205
206void my_trunc (struct file *f)
207{
208 fflush (f->f);
209 if (ftruncate (fileno (f->f), ftell (f->f)) != 0)
210 error ("ftruncate failed (`%s')", f->name);
211}
212
213
214/* Read a null-terminated string from the file F to the buffer DST.
215 There are SIZE bytes available at DST. */
216
217void my_read_str (byte *dst, size_t size, struct file *f)
218{
219 int c;
220
221 for (;;)
222 {
223 c = getc (f->f);
224 if (c == EOF)
225 error ("cannot read `%s'", f->name);
226 if (size <= 0)
227 error ("invalid string in `%s'", f->name);
228 *dst++ = (byte)c;
229 --size;
230 if (c == 0)
231 break;
232 }
233}
234
235
236/* Let DST reference the file referenced by SRC. If DST refers to a
237 open file, it will be closed before doing this. SRC will be
238 closed. */
239
240void my_change (struct file *dst, struct file *src)
241{
242 my_close (dst);
243 *dst = *src;
244 src->ok = src->del = FALSE;
245 my_seek (dst, 0);
246}
247
248
249/* Return true iff the file NAME is readable. */
250
251int my_readable (const char *name)
252{
253 return (access (name, 4) == 0);
254}
255
256
257/* Allocate N bytes of memory. This function never returns NULL.
258 When running out of memory, a message is displayed and the program
259 is terminated. */
260
261void *xmalloc (size_t n)
262{
263 void *q;
264
265 q = malloc (n);
266 if (q == NULL)
267 out_of_mem ();
268 return q;
269}
270
271
272/* Create a duplicate of the string P on the heap. This function
273 never returns NULL. When running out of memory, a message is
274 displayed and the program is terminated. */
275
276char *xstrdup (const char *p)
277{
278 char *q;
279
280 q = strdup (p);
281 if (q == NULL)
282 out_of_mem ();
283 return q;
284}
285
286
287/* Reallocate the block of memory P to N bytes. This function never
288 returns NULL. When running out of memory, a message is displayed
289 and the program is terminated. */
290
291void *xrealloc (void *p, size_t n)
292{
293 void *q;
294
295 q = realloc (p, n);
296 if (q == NULL)
297 out_of_mem ();
298 return q;
299}
300
301
302/* Return the string "s" if plural should be used for the number N.
303 If N is 1, return the empty string. */
304
305const char *plural_s (long n)
306{
307 return (n == 1 ? "" : "s");
308}
309
310
311/* Add SIZE bytes at SRC to the end of the growable buffer DST.
312 Expand DST as required. */
313
314void put_grow (struct grow *dst, const void *src, size_t size)
315{
316 if (dst->len + size > dst->size)
317 {
318 dst->size += 1024 * ((size + 1023) / 1024);
319 dst->data = xrealloc (dst->data, dst->size);
320 }
321 memmove (dst->data + dst->len, src, size);
322 dst->len += size;
323}
Note: See TracBrowser for help on using the repository browser.