source: trunk/emx/src/libomflib/omflibrd.c

Last change on this file 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.1 KB
Line 
1/* omflibrd.c (emx+gcc) -- Copyright (c) 1993-1996 by Eberhard Mattes */
2
3/* Read an OMFLIB. */
4
5#include <stdio.h>
6#include <stdlib.h>
7#include <string.h>
8#include <errno.h>
9#include "omflib0.h"
10#include <sys/omflib.h>
11
12
13struct omflib *omflib_open (const char *fname, char *error)
14{
15 FILE *f;
16 struct omflib *p;
17 struct lib_header hdr;
18
19 f = fopen (fname, "rb");
20 if (f == NULL)
21 goto failure;
22 if (fread (&hdr, sizeof (hdr), 1, f) != 1)
23 {
24 if (ferror (f))
25 goto failure;
26 strcpy (error, "Invalid library header");
27 fclose (f);
28 return NULL;
29 }
30 if (hdr.rec_type != LIBHDR || hdr.rec_len < 7)
31 {
32 strcpy (error, "Invalid library header");
33 fclose (f);
34 return NULL;
35 }
36 p = malloc (sizeof (struct omflib));
37 if (p == NULL)
38 {
39 errno = ENOMEM;
40 goto failure;
41 }
42 p->f = f;
43 p->page_size = hdr.rec_len + 3;
44 p->dict_offset = hdr.dict_offset;
45 p->dict_blocks = hdr.dict_blocks;
46 p->flags = hdr.flags;
47 p->mod_tab = NULL;
48 p->mod_alloc = 0;
49 p->mod_count = -1;
50 p->dict = NULL;
51 p->pub_tab = NULL;
52 p->pub_alloc = 0;
53 p->pub_count = 0;
54 p->output = FALSE;
55 p->state = OS_EMPTY;
56 p->mod_page = 0;
57 p->mod_name[0] = 0;
58 return p;
59
60failure:
61 strcpy (error, strerror (errno));
62 if (f != NULL)
63 fclose (f);
64 return NULL;
65}
66
67
68int omflib_read_dictionary (struct omflib *p, char *error)
69{
70 if (p->output)
71 {
72 strcpy (error, "Not implemented for output library");
73 return -1;
74 }
75 p->dict = malloc (512 * p->dict_blocks);
76 if (p->dict == NULL)
77 {
78 errno = ENOMEM;
79 return omflib_set_error (error);
80 }
81 fseek (p->f, p->dict_offset, SEEK_SET);
82 if (fread (p->dict, 512, p->dict_blocks, p->f) != p->dict_blocks)
83 {
84 if (ferror (p->f))
85 strcpy (error, strerror (errno));
86 else
87 strcpy (error, "Dictionary truncated");
88 free (p->dict);
89 p->dict = NULL;
90 return -1;
91 }
92 return 0;
93}
94
95
96static int mod_compare (const void *x1, const void *x2)
97{
98 word page1, page2;
99
100 page1 = ((const struct omfmod *)x1)->page;
101 page2 = ((const struct omfmod *)x2)->page;
102 if (page1 < page2)
103 return -1;
104 else if (page1 > page2)
105 return 1;
106 else
107 return 0;
108}
109
110
111int omflib_make_mod_tab (struct omflib *p, char *error)
112{
113 int block, bucket, bv, len;
114 char string[256];
115 struct omfmod *mod;
116 byte *d, *s;
117
118 if (p->dict == NULL && omflib_read_dictionary (p, error) != 0)
119 return -1;
120 p->mod_count = 0;
121 d = p->dict;
122 for (block = 0; block < p->dict_blocks; ++block, d += 512)
123 for (bucket = 0; bucket < 37; ++bucket)
124 {
125 bv = d[bucket];
126 if (bv != 0)
127 {
128 s = d + bv * 2;
129 len = *s;
130 if (s[len] == '!')
131 {
132 memcpy (string, s+1, len-1);
133 string[len-1] = 0;
134 if (p->mod_count >= p->mod_alloc)
135 {
136 p->mod_alloc += 16;
137 p->mod_tab = realloc (p->mod_tab, p->mod_alloc
138 * sizeof (struct omfmod));
139 if (p->mod_tab == NULL)
140 {
141 p->mod_count = -1;
142 p->mod_alloc = 0;
143 errno = ENOMEM;
144 return omflib_set_error (error);
145 }
146 }
147 mod = &p->mod_tab[p->mod_count];
148 mod->page = s[len+1] | (s[len+2] << 8);
149 mod->name = strdup (string);
150 mod->flags = 0;
151 if (mod->name == NULL)
152 {
153 errno = ENOMEM;
154 return omflib_set_error (error);
155 }
156 ++p->mod_count;
157 }
158 }
159 }
160 qsort (p->mod_tab, p->mod_count, sizeof (p->mod_tab[0]), mod_compare);
161 return 0;
162}
163
164
165int omflib_module_count (struct omflib *p, char *error)
166{
167 if (p->mod_count == -1 && omflib_make_mod_tab (p, error) != 0)
168 return -1;
169 return p->mod_count;
170}
171
172
173int omflib_module_info (struct omflib *p, int n, char *name, int *page,
174 char *error)
175{
176 if (p->mod_count == -1 && omflib_make_mod_tab (p, error) != 0)
177 return -1;
178 if (n < 0 || n >= p->mod_count)
179 {
180 strcpy (error, "Module number out of range");
181 return -1;
182 }
183 strcpy (name, p->mod_tab[n].name);
184 *page = p->mod_tab[n].page;
185 return 0;
186}
187
188
189int omflib_find_symbol (struct omflib *p, const char *name, char *error)
190{
191 int block_index, bucket_index;
192 int bv, len, bucket_count;
193 byte *ptr, *block, buf[257];
194 int (*compare)(const void *s1, const void *s2, size_t n);
195
196 if (p->dict == NULL && omflib_read_dictionary (p, error) != 0)
197 return -1;
198 len = strlen (name);
199 if (len > 255)
200 {
201 strcpy (error, "Symbol name too long");
202 return -1;
203 }
204 buf[0] = (byte)len;
205 memcpy (buf+1, name, len);
206 omflib_hash (p, buf);
207 block_index = p->block_index;
208 bucket_index = p->bucket_index;
209 bucket_count = 37;
210 compare = (p->flags & 1 ? memcmp : memicmp);
211 for (;;)
212 {
213 block = p->dict + 512 * block_index;
214 bv = block[bucket_index];
215 if (bv == 0)
216 {
217 if (block[37] != 0xff)
218 return 0;
219 bucket_count = 0; /* Keep bucket_index! */
220 }
221 else
222 {
223 ptr = block + 2 * bv;
224 if (*ptr == len && compare (ptr+1, buf+1, len) == 0)
225 return ptr[len+1] + (ptr[len+2] << 8);
226 bucket_index += p->bucket_index_delta;
227 if (bucket_index >= 37)
228 bucket_index -= 37;
229 --bucket_count;
230 }
231 if (bucket_count == 0)
232 {
233 block_index += p->block_index_delta;
234 if (block_index >= p->dict_blocks)
235 block_index -= p->dict_blocks;
236 if (block_index == p->block_index)
237 return 0;
238 bucket_count = 37;
239 }
240 }
241}
242
243
244int omflib_find_module (struct omflib *p, const char *name, char *error)
245{
246 char buf[256+1];
247
248 if (omflib_module_name (buf, name) != 0)
249 {
250 strcpy (error, "Module name too long");
251 return -1;
252 }
253 strcat (buf, "!");
254 return omflib_find_symbol (p, buf, error);
255}
256
257
258long omflib_page_pos (struct omflib *p, int page)
259{
260 return page * p->page_size;
261}
Note: See TracBrowser for help on using the repository browser.