Update dependencies
[nasm/avx512.git] / rdoff / rdlib.c
blob97f682f3b6241f202268f75e25aaa6c19328387d
1 /*
2 * rdlib.c - routines for manipulating RDOFF libraries (.rdl)
3 */
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <string.h>
9 #define RDOFF_UTILS
11 #include "rdoff.h"
12 #include "rdlib.h"
13 #include "rdlar.h"
15 /* See Texinfo documentation about new RDOFF libraries format */
17 int rdl_error = 0;
19 char *rdl_errors[5] = {
20 "no error","could not open file", "invalid file structure",
21 "file contains modules of an unsupported RDOFF version",
22 "module not found"
25 int rdl_verify(const char * filename)
27 FILE * fp = fopen(filename, "rb");
28 char buf[257];
29 int i;
30 long length;
31 static char lastverified[256];
32 static int lastresult = -1;
34 if (lastresult != -1 && !strcmp(filename, lastverified))
35 return lastresult;
37 strcpy(lastverified, filename);
39 if (!fp)
40 return (rdl_error = lastresult = 1);
42 while (!feof(fp))
44 i = 0;
46 while (fread(buf + i,1,1,fp) == 1 && buf[i] && i < 257)
47 i++;
48 if (feof(fp)) break;
50 if (buf[0] == '.') {
52 * A special module, eg a signature block or a directory.
53 * Format of such a module is defined to be:
54 * six char type identifier
55 * long count bytes content
56 * content
57 * so we can handle it uniformaly with RDOFF2 modules.
59 fread(buf, 6, 1, fp);
60 buf[6] = 0;
61 /* Currently, nothing useful to do with signature block.. */
62 } else {
63 fread(buf, 6, 1, fp);
64 buf[6] = 0;
65 if (strncmp(buf, "RDOFF", 5)) {
66 return rdl_error = lastresult = 2;
67 } else if (buf[5] != '2') {
68 return rdl_error = lastresult = 3;
71 fread(&length, 4, 1, fp);
72 fseek(fp, length, SEEK_CUR); /* skip over the module */
74 fclose(fp);
75 return lastresult = 0; /* library in correct format */
78 int rdl_open (struct librarynode * lib, const char * name)
80 int i = rdl_verify(name);
81 if (i) return i;
83 lib->fp = NULL;
84 lib->name = strdup(name);
85 lib->referenced = 0;
86 lib->next = NULL;
87 return 0;
90 void rdl_close (struct librarynode * lib)
92 if (lib->fp)
93 fclose(lib->fp);
94 free(lib->name);
97 int rdl_searchlib (struct librarynode * lib,
98 const char * label, rdffile * f)
100 char buf[512];
101 int i, t;
102 void * hdr;
103 rdfheaderrec * r;
104 long l;
106 rdl_error = 0;
107 lib->referenced ++;
109 if (! lib->fp)
111 lib->fp = fopen(lib->name,"rb");
113 if (! lib->fp) {
114 rdl_error = 1;
115 return 0;
118 else
119 rewind(lib->fp);
121 while (! feof(lib->fp) )
124 * read the module name from the file, and prepend
125 * the library name and '.' to it.
127 strcpy(buf, lib->name);
129 i = strlen(lib->name);
130 buf[i++] = '.'; t = i;
131 while (fread(buf + i,1,1,lib->fp) == 1 && buf[i] && i < 512)
132 i++;
134 buf[i] = 0;
136 if (feof(lib->fp)) break;
137 if (!strcmp(buf + t, ".dir")) /* skip over directory */
139 fread (&l, 4, 1, lib->fp);
140 fseek (lib->fp, l, SEEK_CUR);
141 continue;
144 * open the RDOFF module
146 if ( rdfopenhere(f,lib->fp,&lib->referenced,buf) ) {
147 rdl_error = 16 * rdf_errno;
148 return 0;
151 * read in the header, and scan for exported symbols
153 hdr = malloc(f->header_len);
154 rdfloadseg(f,RDOFF_HEADER,hdr);
156 while ((r = rdfgetheaderrec(f)))
158 if (r->type != 3) /* not an export */
159 continue;
161 if (! strcmp(r->e.label, label) ) /* match! */
163 free(hdr); /* reset to 'just open' */
164 f->header_loc = NULL; /* state... */
165 f->header_fp = 0;
166 return 1;
170 /* find start of next module... */
171 i = f->eof_offset;
172 rdfclose(f);
173 fseek(lib->fp,i,SEEK_SET);
177 * close the file if nobody else is using it
179 lib->referenced --;
180 if (! lib->referenced)
182 fclose(lib->fp);
183 lib->fp = NULL;
185 return 0;
188 int rdl_openmodule (struct librarynode * lib, int moduleno, rdffile * f)
190 char buf[512];
191 int i, cmod, t;
192 long length;
194 lib->referenced++;
196 if (!lib->fp)
198 lib->fp = fopen(lib->name, "rb");
199 if (!lib->fp) {
200 lib->referenced--;
201 return (rdl_error = 1);
204 else
205 rewind(lib->fp);
207 cmod = -1;
208 while (!feof(lib->fp))
210 strcpy(buf, lib->name);
211 i = strlen(buf);
212 buf[i++] = '.'; t = i;
213 while (fread(buf + i,1,1,lib->fp) == 1 && buf[i] && i < 512)
214 i++;
215 buf[i] = 0;
216 if (feof(lib->fp)) break;
218 if (buf[t] != '.') /* special module - not counted in the numbering */
219 cmod++; /* of RDOFF modules - must be referred to by name */
221 if (cmod == moduleno) {
222 rdl_error = 16 *
223 rdfopenhere(f, lib->fp, &lib->referenced, buf);
224 lib->referenced--;
225 if (!lib->referenced) {
226 fclose(lib->fp);
227 lib->fp = NULL;
229 return rdl_error;
232 fread(buf, 6, 1, lib->fp);
233 buf[6] = 0;
234 if (buf[t] == '.') {
235 /* do nothing */
237 else if (strncmp(buf, "RDOFF", 5)) {
238 if (! --lib->referenced) {
239 fclose(lib->fp);
240 lib->fp = NULL;
242 return rdl_error = 2;
244 else if (buf[5] != '2') {
245 if (! --lib->referenced) {
246 fclose(lib->fp);
247 lib->fp = NULL;
249 return rdl_error = 3;
252 fread(&length, 4, 1, lib->fp);
253 fseek(lib->fp, length, SEEK_CUR); /* skip over the module */
255 if (! --lib->referenced) {
256 fclose(lib->fp);
257 lib->fp = NULL;
259 return rdl_error = 4; /* module not found */
262 void rdl_perror(const char *apname, const char *filename)
264 if (rdl_error >= 16)
265 rdfperror(apname, filename);
266 else
267 fprintf(stderr,"%s:%s:%s\n",apname,filename,rdl_errors[rdl_error]);