NASM 2.00rc1
[nasm.git] / rdoff / rdflib.c
blob852920ed572c04b4f4cffe828005cc6be2442237
1 /* rdflib - manipulate RDOFF library files (.rdl) */
3 /*
4 * an rdoff library is simply a sequence of RDOFF object files, each
5 * preceded by the name of the module, an ASCII string of up to 255
6 * characters, terminated by a zero.
8 * When a library is being created, special signature block is placed
9 * in the beginning of the file. It is a string 'RDLIB' followed by a
10 * version number, then int32_t content size and a int32_t time stamp.
11 * The module name of the signature block is '.sig'.
14 * There may be an optional directory placed on the end of the file.
15 * The format of the directory will be 'RDLDD' followed by a version
16 * number, followed by the length of the directory, and then the
17 * directory, the format of which has not yet been designed.
18 * The module name of the directory must be '.dir'.
20 * All module names beginning with '.' are reserved for possible future
21 * extensions. The linker ignores all such modules, assuming they have
22 * the format of a six uint8_t type & version identifier followed by int32_t
23 * content size, followed by data.
26 #include "compiler.h"
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <errno.h>
31 #include <string.h>
32 #include <inttypes.h>
33 #include <time.h>
34 #include <inttypes.h>
36 /* functions supported:
37 * create a library (no extra operands required)
38 * add a module from a library (requires filename and name to give mod.)
39 * replace a module in a library (requires given name and filename)
40 * delete a module from a library (requires given name)
41 * extract a module from the library (requires given name and filename)
42 * list modules
45 const char *usage =
46 "usage:\n"
47 " rdflib x libname [extra operands]\n\n"
48 " where x is one of:\n"
49 " c - create library\n"
50 " a - add module (operands = filename module-name)\n"
51 " x - extract (module-name filename)\n"
52 " r - replace (module-name filename)\n"
53 " d - delete (module-name)\n" " t - list\n";
55 /* Library signature */
56 const char *rdl_signature = "RDLIB2", *sig_modname = ".sig";
58 char **_argv;
60 #define _ENDIANNESS 0 /* 0 for little, 1 for big */
62 static void int32_ttolocal(int32_t *l)
64 #if _ENDIANNESS
65 uint8_t t;
66 uint8_t *p = (uint8_t *)l;
68 t = p[0];
69 p[0] = p[3];
70 p[3] = t;
71 t = p[1];
72 p[1] = p[2];
73 p[2] = p[1];
74 #else
75 (void)l; /* placate optimizers */
76 #endif
79 char copybytes(FILE * fp, FILE * fp2, int n)
81 int i, t = 0;
83 for (i = 0; i < n; i++) {
84 t = fgetc(fp);
85 if (t == EOF) {
86 fprintf(stderr, "rdflib: premature end of file in '%s'\n",
87 _argv[2]);
88 exit(1);
90 if (fp2)
91 if (fputc(t, fp2) == EOF) {
92 fprintf(stderr, "rdflib: write error\n");
93 exit(1);
96 return (char)t; /* return last char read */
99 int32_t copyint32_t(FILE * fp, FILE * fp2)
101 int32_t l;
102 int i, t;
103 uint8_t *p = (uint8_t *)&l;
105 for (i = 0; i < 4; i++) { /* skip magic no */
106 t = fgetc(fp);
107 if (t == EOF) {
108 fprintf(stderr, "rdflib: premature end of file in '%s'\n",
109 _argv[2]);
110 exit(1);
112 if (fp2)
113 if (fputc(t, fp2) == EOF) {
114 fprintf(stderr, "rdflib: write error\n");
115 exit(1);
117 *p++ = t;
119 int32_ttolocal(&l);
120 return l;
123 int main(int argc, char **argv)
125 FILE *fp, *fp2 = NULL, *fptmp;
126 char *p, buf[256], c;
127 int i;
128 int32_t l;
129 time_t t;
130 char rdbuf[10];
132 _argv = argv;
134 if (argc < 3 || !strncmp(argv[1], "-h", 2)
135 || !strncmp(argv[1], "--h", 3)) {
136 printf(usage);
137 exit(1);
140 switch (argv[1][0]) {
141 case 'c': /* create library */
142 fp = fopen(argv[2], "wb");
143 if (!fp) {
144 fprintf(stderr, "rdflib: could not open '%s'\n", argv[2]);
145 perror("rdflib");
146 exit(1);
148 fwrite(sig_modname, 1, strlen(sig_modname) + 1, fp);
149 fwrite(rdl_signature, 1, strlen(rdl_signature), fp);
150 l = sizeof(t = time(NULL));
151 fwrite(&l, sizeof(l), 1, fp);
152 fwrite(&t, 1, l, fp);
153 fclose(fp);
154 break;
156 case 'a': /* add module */
157 if (argc < 5) {
158 fprintf(stderr, "rdflib: required parameter missing\n");
159 exit(1);
161 fp = fopen(argv[2], "ab");
162 if (!fp) {
163 fprintf(stderr, "rdflib: could not open '%s'\n", argv[2]);
164 perror("rdflib");
165 exit(1);
168 fp2 = fopen(argv[3], "rb");
169 if (!fp2) {
170 fprintf(stderr, "rdflib: could not open '%s'\n", argv[3]);
171 perror("rdflib");
172 exit(1);
175 p = argv[4];
176 do {
177 if (fputc(*p, fp) == EOF) {
178 fprintf(stderr, "rdflib: write error\n");
179 exit(1);
181 } while (*p++);
183 while (!feof(fp2)) {
184 i = fgetc(fp2);
185 if (i == EOF) {
186 break;
189 if (fputc(i, fp) == EOF) {
190 fprintf(stderr, "rdflib: write error\n");
191 exit(1);
194 fclose(fp2);
195 fclose(fp);
196 break;
198 case 'x':
199 if (argc < 5) {
200 fprintf(stderr, "rdflib: required parameter missing\n");
201 exit(1);
203 case 't':
204 fp = fopen(argv[2], "rb");
205 if (!fp) {
206 fprintf(stderr, "rdflib: could not open '%s'\n", argv[2]);
207 perror("rdflib");
208 exit(1);
211 fp2 = NULL;
212 while (!feof(fp)) {
213 /* read name */
214 p = buf;
215 while ((*(p++) = (char)fgetc(fp)))
216 if (feof(fp))
217 break;
219 if (feof(fp))
220 break;
222 fp2 = NULL;
223 if (argv[1][0] == 'x') {
224 /* check against desired name */
225 if (!strcmp(buf, argv[3])) {
226 fp2 = fopen(argv[4], "wb");
227 if (!fp2) {
228 fprintf(stderr, "rdflib: could not open '%s'\n",
229 argv[4]);
230 perror("rdflib");
231 exit(1);
234 } else
235 printf("%-40s ", buf);
237 /* step over the RDOFF file, extracting type information for
238 * the listing, and copying it if fp2 != NULL */
240 if (buf[0] == '.') {
242 if (argv[1][0] == 't')
243 for (i = 0; i < 6; i++)
244 printf("%c", copybytes(fp, fp2, 1));
245 else
246 copybytes(fp, fp2, 6);
248 l = copyint32_t(fp, fp2);
250 if (argv[1][0] == 't')
251 printf(" %"PRId32" bytes content\n", l);
253 copybytes(fp, fp2, l);
254 } else if ((c = copybytes(fp, fp2, 6)) >= '2') { /* version 2 or above */
255 l = copyint32_t(fp, fp2);
257 if (argv[1][0] == 't')
258 printf("RDOFF%c %"PRId32" bytes content\n", c, l);
259 copybytes(fp, fp2, l); /* entire object */
260 } else {
261 if (argv[1][0] == 't')
262 printf("RDOFF1\n");
264 * version 1 object, so we don't have an object content
265 * length field.
267 copybytes(fp, fp2, copyint32_t(fp, fp2)); /* header */
268 copybytes(fp, fp2, copyint32_t(fp, fp2)); /* text */
269 copybytes(fp, fp2, copyint32_t(fp, fp2)); /* data */
272 if (fp2)
273 break;
275 fclose(fp);
276 if (fp2)
277 fclose(fp2);
278 else if (argv[1][0] == 'x') {
279 fprintf(stderr, "rdflib: module '%s' not found in '%s'\n",
280 argv[3], argv[2]);
281 exit(1);
283 break;
285 case 'r': /* replace module */
286 argc--;
287 case 'd': /* delete module */
288 if (argc < 4) {
289 fprintf(stderr, "rdflib: required parameter missing\n");
290 exit(1);
293 fp = fopen(argv[2], "rb");
294 if (!fp) {
295 fprintf(stderr, "rdflib: could not open '%s'\n", argv[2]);
296 perror("rdflib");
297 exit(1);
300 if (argv[1][0] == 'r') {
301 fp2 = fopen(argv[4], "rb");
302 if (!fp2) {
303 fprintf(stderr, "rdflib: could not open '%s'\n", argv[4]);
304 perror("rdflib");
305 exit(1);
309 fptmp = tmpfile();
310 if (!fptmp) {
311 fprintf(stderr, "rdflib: could not open temporary file\n");
312 perror("rdflib");
313 exit(1);
316 /* copy library into temporary file */
317 fseek(fp, 0, SEEK_END); /* get file length */
318 l = ftell(fp);
319 fseek(fp, 0, SEEK_SET);
320 copybytes(fp, fptmp, l);
321 rewind(fptmp);
322 freopen(argv[2], "wb", fp);
324 while (!feof(fptmp)) {
325 /* read name */
326 p = buf;
327 while ((*(p++) = (char)fgetc(fptmp)))
328 if (feof(fptmp))
329 break;
331 if (feof(fptmp))
332 break;
334 /* check against desired name */
335 if (!strcmp(buf, argv[3])) {
336 fread(p = rdbuf, 1, sizeof(rdbuf), fptmp);
337 l = *(int32_t *)(p + 6);
338 fseek(fptmp, l, SEEK_CUR);
339 break;
340 } else {
341 fwrite(buf, 1, strlen(buf) + 1, fp); /* module name */
342 if ((c = copybytes(fptmp, fp, 6)) >= '2') {
343 l = copyint32_t(fptmp, fp); /* version 2 or above */
344 copybytes(fptmp, fp, l); /* entire object */
349 if (argv[1][0] == 'r') {
350 /* copy new module into library */
351 p = argv[3];
352 do {
353 if (fputc(*p, fp) == EOF) {
354 fprintf(stderr, "rdflib: write error\n");
355 exit(1);
357 } while (*p++);
359 while (!feof(fp2)) {
360 i = fgetc(fp2);
361 if (i == EOF) {
362 break;
364 if (fputc(i, fp) == EOF) {
365 fprintf(stderr, "rdflib: write error\n");
366 exit(1);
369 fclose(fp2);
372 /* copy rest of library if any */
373 while (!feof(fptmp)) {
374 i = fgetc(fptmp);
375 if (i == EOF) {
376 break;
379 if (fputc(i, fp) == EOF) {
380 fprintf(stderr, "rdflib: write error\n");
381 exit(1);
385 fclose(fp);
386 fclose(fptmp);
387 break;
389 default:
390 fprintf(stderr, "rdflib: command '%c' not recognized\n",
391 argv[1][0]);
392 exit(1);
394 return 0;