source: trunk/emx/src/libomflib/omflibcp.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: 5.7 KB
Line 
1/* omflibcp.c (emx+gcc) -- Copyright (c) 1993-1996 by Eberhard Mattes */
2
3/* Copy a module from one OMFLIB to another OMFLIB. */
4
5#include <stdio.h>
6#include <stdlib.h>
7#include <string.h>
8#include "omflib0.h"
9#include <sys/omflib.h>
10
11
12static struct omflib *pubdef_dst_lib;
13static word pubdef_page;
14
15
16static int add_pubdef (const char *name, char *error);
17
18
19int omflib_copy_module (struct omflib *dst_lib, FILE *dst_file,
20 struct omflib *src_lib, FILE *src_file,
21 const char *mod_name, char *error)
22{
23 struct omf_rec rec;
24 word page;
25 long long_page, pos;
26 char theadr_name[256];
27 char libmod_name[256];
28 char caller_name[256];
29 byte buf[1024], buf2[256+6];
30 enum omf_state state;
31 enum {RT_THEADR, RT_OTHER} cur_rt, prev_rt;
32 int copy;
33
34 theadr_name[0] = 0; libmod_name[0] = 0;
35 if (mod_name == NULL)
36 caller_name[0] = 0;
37 else
38 omflib_module_name (caller_name, mod_name);
39 if (dst_lib != NULL)
40 {
41 long_page = ftell (dst_file) / dst_lib->page_size;
42 if (long_page > 65535)
43 {
44 strcpy (error, "Library too big -- increase page size");
45 return -1;
46 }
47 page = (word)long_page;
48 }
49 else
50 page = 0;
51 state = OS_EMPTY; prev_rt = RT_OTHER;
52 do
53 {
54 if (fread (&rec, sizeof (rec), 1, src_file) != 1)
55 goto failure_src;
56 if (rec.rec_len > sizeof (buf))
57 {
58 strcpy (error, "Record too long");
59 return -1;
60 }
61 if (fread (buf, rec.rec_len, 1, src_file) != 1)
62 goto failure_src;
63 copy = TRUE; cur_rt = RT_OTHER;
64 switch (rec.rec_type)
65 {
66 case THEADR:
67 if (rec.rec_len == 0 || buf[0] + 1 > rec.rec_len)
68 {
69 strcpy (error, "Truncated THEADR record");
70 return -1;
71 }
72 buf[1+buf[0]] = 0;
73 omflib_module_name (theadr_name, buf + 1);
74 state = OS_EMPTY; cur_rt = RT_THEADR;
75 break;
76
77 case PUBDEF:
78 case PUBDEF|REC32:
79 if (dst_lib != NULL)
80 {
81 pubdef_dst_lib = dst_lib;
82 pubdef_page = page;
83 if (omflib_pubdef (&rec, buf, page, add_pubdef, error) != 0)
84 return -1;
85 }
86 state = OS_OTHER;
87 break;
88
89 case ALIAS:
90 if (dst_lib != NULL)
91 {
92 pubdef_dst_lib = dst_lib;
93 pubdef_page = page;
94 if (omflib_alias (&rec, buf, page, add_pubdef, error) != 0)
95 return -1;
96 }
97 state = (state == OS_EMPTY ? OS_SIMPLE : OS_OTHER);
98 break;
99
100 case COMENT:
101 if (rec.rec_len >= 3 && buf[1] == IMPDEF_CLASS
102 && buf[2] == IMPDEF_SUBTYPE)
103 {
104 if (dst_lib != NULL)
105 {
106 pubdef_dst_lib = dst_lib;
107 pubdef_page = page;
108 if (omflib_impdef (&rec, buf, page, add_pubdef, error) != 0)
109 return -1;
110 }
111 state = (state == OS_EMPTY ? OS_SIMPLE : OS_OTHER);
112 }
113 else if (rec.rec_len >= 2 && buf[1] == LIBMOD_CLASS)
114 {
115 if (dst_lib == NULL || mod_name != NULL)
116 copy = FALSE;
117 if (rec.rec_len < 3 || buf[2] + 3 > rec.rec_len)
118 {
119 strcpy (error, "Truncated LIBMOD record");
120 return -1;
121 }
122 buf[3+buf[2]] = 0;
123 omflib_module_name (libmod_name, buf + 3);
124 state = OS_OTHER;
125 }
126 else
127 state = OS_OTHER;
128 break;
129
130 case MODEND:
131 case MODEND|REC32:
132 /* Don't change STATE. */
133 break;
134
135 default:
136 state = OS_OTHER;
137 }
138
139 if (prev_rt == RT_THEADR && dst_lib != NULL && mod_name != NULL)
140 {
141 if (state == OS_SIMPLE)
142 cur_rt = RT_THEADR; /* Check again after next record */
143 else if (strcmp (caller_name, theadr_name) != 0)
144 {
145 buf2[0] = 0;
146 buf2[1] = LIBMOD_CLASS;
147 buf2[2] = strlen (caller_name);
148 memcpy (buf2 + 3, caller_name, buf2[2]);
149 if (omflib_write_record (dst_lib, COMENT, buf2[2] + 3, buf2,
150 TRUE, error) != 0)
151 return -1;
152 }
153 }
154 if (copy && dst_file != NULL)
155 {
156 if (fwrite (&rec, sizeof (rec), 1, dst_file) != 1
157 || fwrite (buf, rec.rec_len, 1, dst_file) != 1)
158 return omflib_set_error (error);
159 }
160 prev_rt = cur_rt;
161 } while (rec.rec_type != MODEND && rec.rec_type != (MODEND|REC32));
162 if (src_lib != NULL)
163 {
164 pos = ftell (src_file);
165 if (pos % src_lib->page_size != 0)
166 fseek (src_file, src_lib->page_size - pos % src_lib->page_size,
167 SEEK_CUR);
168 }
169 if (dst_lib != NULL)
170 {
171 /* Don't use PUBDEF for the module name for modules that contain
172 only an alias or an import definition. */
173
174 if (state != OS_SIMPLE)
175 {
176 if (caller_name[0] != 0)
177 strcpy (buf2, caller_name);
178 else if (libmod_name[0] != 0)
179 strcpy (buf2, libmod_name);
180 else
181 strcpy (buf2, theadr_name);
182 strcat (buf2, "!");
183 if (omflib_add_pub (dst_lib, buf2, page, error) != 0)
184 return -1;
185 }
186 if (dst_file != NULL
187 && omflib_pad (dst_file, dst_lib->page_size, FALSE, error) != 0)
188 return -1;
189 }
190 return 0;
191
192failure_src:
193 if (ferror (src_file))
194 return omflib_set_error (error);
195 strcpy (error, "Unexpected end of file");
196 return -1;
197}
198
199
200static int add_pubdef (const char *name, char *error)
201{
202 return omflib_add_pub (pubdef_dst_lib, name, pubdef_page, error);
203}
Note: See TracBrowser for help on using the repository browser.