source: trunk/emx/src/libomflib/omflibpb.c@ 3003

Last change on this file since 3003 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: 4.2 KB
Line 
1/* omflibpb.c (emx+gcc) -- Copyright (c) 1993-1995 by Eberhard Mattes */
2
3/* Call a function for all the PUBDEF, IMPDEF, and ALIAS records of an
4 OMFLIB. */
5
6#include <stdio.h>
7#include <stdlib.h>
8#include <string.h>
9#include "omflib0.h"
10#include <sys/omflib.h>
11
12
13static int omflib_get_index (struct ptr *p, int *dst, char *error);
14
15
16int omflib_pubdef_walk (struct omflib *p, word page,
17 int (*walker)(const char *name, char *error),
18 char *error)
19{
20 struct omf_rec rec;
21 byte buf[1024];
22 int ret;
23
24 fseek (p->f, page * p->page_size, SEEK_SET);
25 do
26 {
27 if (fread (&rec, sizeof (rec), 1, p->f) != 1)
28 goto failure;
29 if (rec.rec_len > sizeof (buf))
30 {
31 strcpy (error, "Record too long");
32 return -1;
33 }
34 if (fread (buf, rec.rec_len, 1, p->f) != 1)
35 goto failure;
36 if (rec.rec_type == PUBDEF || rec.rec_type == (PUBDEF|REC32))
37 {
38 ret = omflib_pubdef (&rec, buf, page, walker, error);
39 if (ret != 0) return ret;
40 }
41 else if (rec.rec_type == ALIAS)
42 {
43 ret = omflib_alias (&rec, buf, page, walker, error);
44 if (ret != 0) return ret;
45 }
46 else if (rec.rec_type == COMENT && rec.rec_len >= 2 &&
47 buf[1] == IMPDEF_CLASS && buf[2] == IMPDEF_SUBTYPE)
48 {
49 ret = omflib_impdef (&rec, buf, page, walker, error);
50 if (ret != 0) return ret;
51 }
52 } while (rec.rec_type != MODEND && rec.rec_type != (MODEND|REC32));
53 return 0;
54
55failure:
56 if (ferror (p->f))
57 return omflib_set_error (error);
58 strcpy (error, "Unexpected end of file");
59 return -1;
60}
61
62
63int omflib_pubdef (struct omf_rec *rec, byte *buf, word page,
64 int (*walker)(const char *name, char *error),
65 char *error)
66{
67 int group_index, segment_index, type_index;
68 struct ptr ptr;
69 int len, i, ret;
70 char name[256];
71
72 ptr.ptr = buf;
73 ptr.len = rec->rec_len - 1;
74 if (omflib_get_index (&ptr, &group_index, error) != 0)
75 return -1;
76 if (omflib_get_index (&ptr, &segment_index, error) != 0)
77 return -1;
78 if (segment_index == 0)
79 {
80 if (ptr.len < 2)
81 goto too_short;
82 ptr.ptr += 2; ptr.len -= 2;
83 }
84
85 while (ptr.len > 0)
86 {
87 if (ptr.len < 1)
88 goto too_short;
89 len = ptr.ptr[0];
90 ++ptr.ptr; --ptr.len;
91 if (ptr.len < len)
92 goto too_short;
93 memcpy (name, ptr.ptr, len);
94 name[len] = 0;
95 ptr.ptr += len; ptr.len -= len;
96 i = (rec->rec_type == (PUBDEF|REC32) ? 4 : 2);
97 if (ptr.len < i) goto too_short;
98 ptr.ptr += i; ptr.len -= i;
99 if (omflib_get_index (&ptr, &type_index, error) != 0)
100 return -1;
101 ret = walker (name, error);
102 if (ret != 0) return ret;
103 }
104 if (ptr.len != 0)
105 {
106 strcpy (error, "Invalid PUBDEF record");
107 return -1;
108 }
109 return 0;
110
111too_short:
112 strcpy (error, "PUBDEF record too short");
113 return -1;
114}
115
116
117int omflib_impdef (struct omf_rec *rec, byte *buf, word page,
118 int (*walker)(const char *name, char *error),
119 char *error)
120{
121 int len;
122 char name[256];
123
124 if (rec->rec_len < 5) goto too_short;
125 len = buf[4];
126 if (len + 5 > rec->rec_len) goto too_short;
127 memcpy (name, buf+5, len);
128 name[len] = 0;
129 return walker (name, error);
130
131too_short:
132 strcpy (error, "IMPDEF record too short");
133 return -1;
134}
135
136
137int omflib_alias (struct omf_rec *rec, byte *buf, word page,
138 int (*walker)(const char *name, char *error),
139 char *error)
140{
141 int len;
142 char name[256];
143
144 if (rec->rec_len < 1) goto too_short;
145 len = buf[0];
146 if (len + 2 > rec->rec_len) goto too_short;
147 memcpy (name, buf+1, len);
148 name[len] = 0;
149 return walker (name, error);
150
151too_short:
152 strcpy (error, "ALIAS record too short");
153 return -1;
154}
155
156
157static int omflib_get_index (struct ptr *p, int *dst, char *error)
158{
159 if (p->len < 1)
160 goto too_short;
161 if (p->ptr[0] <= 0x7f)
162 {
163 *dst = p->ptr[0];
164 ++p->ptr;
165 --p->len;
166 return 0;
167 }
168 else if (p->len < 2)
169 goto too_short;
170 else
171 {
172 *dst = ((p->ptr[0] & 0x7f) << 8) | p->ptr[1];
173 p->ptr += 2;
174 p->len -= 2;
175 return 0;
176 }
177
178too_short:
179 strcpy (error, "Record too short");
180 return -1;
181}
Note: See TracBrowser for help on using the repository browser.