Formatting: kill off "stealth whitespace"
[platform/upstream/nasm.git] / rdoff / rdflib.c
1 /* rdflib - manipulate RDOFF library files (.rdl) */
2
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.
7  *
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'.
12  *
13  *
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'.
19  *
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.
24  */
25
26 #include "compiler.h"
27
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>
35
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
43  */
44
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";
54
55 /* Library signature */
56 const char *rdl_signature = "RDLIB2", *sig_modname = ".sig";
57
58 char **_argv;
59
60 #define _ENDIANNESS 0           /* 0 for little, 1 for big */
61
62 static void int32_ttolocal(int32_t *l)
63 {
64 #if _ENDIANNESS
65     uint8_t t;
66     uint8_t *p = (uint8_t *)l;
67
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
77 }
78
79 char copybytes(FILE * fp, FILE * fp2, int n)
80 {
81     int i, t = 0;
82
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);
89         }
90         if (fp2)
91             if (fputc(t, fp2) == EOF) {
92                 fprintf(stderr, "rdflib: write error\n");
93                 exit(1);
94             }
95     }
96     return (char)t;             /* return last char read */
97 }
98
99 int32_t copyint32_t(FILE * fp, FILE * fp2)
100 {
101     int32_t l;
102     int i, t;
103     uint8_t *p = (uint8_t *)&l;
104
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);
111         }
112         if (fp2)
113             if (fputc(t, fp2) == EOF) {
114                 fprintf(stderr, "rdflib: write error\n");
115                 exit(1);
116             }
117         *p++ = t;
118     }
119     int32_ttolocal(&l);
120     return l;
121 }
122
123 int main(int argc, char **argv)
124 {
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];
131
132     _argv = argv;
133
134     if (argc < 3 || !strncmp(argv[1], "-h", 2)
135         || !strncmp(argv[1], "--h", 3)) {
136         printf(usage);
137         exit(1);
138     }
139
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);
147         }
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;
155
156     case 'a':                  /* add module */
157         if (argc < 5) {
158             fprintf(stderr, "rdflib: required parameter missing\n");
159             exit(1);
160         }
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);
166         }
167
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);
173         }
174
175         p = argv[4];
176         do {
177             if (fputc(*p, fp) == EOF) {
178                 fprintf(stderr, "rdflib: write error\n");
179                 exit(1);
180             }
181         } while (*p++);
182
183         while (!feof(fp2)) {
184             i = fgetc(fp2);
185             if (i == EOF) {
186                 break;
187             }
188
189             if (fputc(i, fp) == EOF) {
190                 fprintf(stderr, "rdflib: write error\n");
191                 exit(1);
192             }
193         }
194         fclose(fp2);
195         fclose(fp);
196         break;
197
198     case 'x':
199         if (argc < 5) {
200             fprintf(stderr, "rdflib: required parameter missing\n");
201             exit(1);
202         }
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);
209         }
210
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;
218
219             if (feof(fp))
220                 break;
221
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);
232                     }
233                 }
234             } else
235                 printf("%-40s ", buf);
236
237             /* step over the RDOFF file, extracting type information for
238              * the listing, and copying it if fp2 != NULL */
239
240             if (buf[0] == '.') {
241
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);
247
248                 l = copyint32_t(fp, fp2);
249
250                 if (argv[1][0] == 't')
251                     printf("   %"PRId32" bytes content\n", l);
252
253                 copybytes(fp, fp2, l);
254             } else if ((c = copybytes(fp, fp2, 6)) >= '2') {    /* version 2 or above */
255                 l = copyint32_t(fp, fp2);
256
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");
263                 /*
264                  * version 1 object, so we don't have an object content
265                  * length field.
266                  */
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 */
270             }
271
272             if (fp2)
273                 break;
274         }
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);
282         }
283         break;
284
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);
291         }
292
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);
298         }
299
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);
306             }
307         }
308
309         fptmp = tmpfile();
310         if (!fptmp) {
311             fprintf(stderr, "rdflib: could not open temporary file\n");
312             perror("rdflib");
313             exit(1);
314         }
315
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);
323
324         while (!feof(fptmp)) {
325             /* read name */
326             p = buf;
327             while ((*(p++) = (char)fgetc(fptmp)))
328                 if (feof(fptmp))
329                     break;
330
331             if (feof(fptmp))
332                 break;
333
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 */
345                 }
346             }
347         }
348
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);
356                 }
357             } while (*p++);
358
359             while (!feof(fp2)) {
360                 i = fgetc(fp2);
361                 if (i == EOF) {
362                     break;
363                 }
364                 if (fputc(i, fp) == EOF) {
365                     fprintf(stderr, "rdflib: write error\n");
366                     exit(1);
367                 }
368             }
369             fclose(fp2);
370         }
371
372         /* copy rest of library if any */
373         while (!feof(fptmp)) {
374             i = fgetc(fptmp);
375             if (i == EOF) {
376                 break;
377             }
378
379             if (fputc(i, fp) == EOF) {
380                 fprintf(stderr, "rdflib: write error\n");
381                 exit(1);
382             }
383         }
384
385         fclose(fp);
386         fclose(fptmp);
387         break;
388
389     default:
390         fprintf(stderr, "rdflib: command '%c' not recognized\n",
391                 argv[1][0]);
392         exit(1);
393     }
394     return 0;
395 }