~ubuntu-branches/ubuntu/jaunty/ghostscript/jaunty-updates

« back to all changes in this revision

Viewing changes to src/mkromfs.c

  • Committer: Bazaar Package Importer
  • Author(s): Till Kamppeter
  • Date: 2009-01-20 16:40:45 UTC
  • mfrom: (1.1.10 upstream)
  • Revision ID: james.westby@ubuntu.com-20090120164045-lnfhi0n30o5lwhwa
Tags: 8.64.dfsg.1~svn9377-0ubuntu1
* New upstream release (SVN rev 9377)
   o Fixes many bugs concerning PDF rendering, to make the PDF printing
     workflow correctly working.
   o Fixes long-standing bugs in many drivers, like input paper tray and
     duplex options not working for the built-in PCL 4, 5, 5c, 5e, and
     6/XL drivers, PDF input not working for bjc600, bjc800, and cups
     output devices, several options not working and uninitialized
     memory with cups output device.
   o Merged nearly all patches of the Ubuntu and Debian packages upstream.
   o Fixes LP: #317810, LP: #314439, LP: #314018.
* debian/patches/03_libpaper_support.dpatch,
  debian/patches/11_gs-cjk_font_glyph_handling_fix.dpatch,
  debian/patches/12_gs-cjk_vertical_writing_metrics_fix.dpatch,
  debian/patches/13_gs-cjk_cjkps_examples.dpatch,
  debian/patches/20_bbox_segv_fix.dpatch,
  debian/patches/21_brother_7x0_gdi_fix.dpatch,
  debian/patches/22_epsn_margin_workaround.dpatch,
  debian/patches/24_gs_man_fix.dpatch,
  debian/patches/25_toolbin_insecure_tmp_usage_fix.dpatch,
  debian/patches/26_assorted_script_fixes.dpatch,
  debian/patches/29_gs_css_fix.dpatch,
  debian/patches/30_ps2pdf_man_improvement.dpatch,
  debian/patches/31_fix-gc-sigbus.dpatch,
  debian/patches/34_ftbfs-on-hurd-fix.dpatch,
  debian/patches/35_disable_libcairo.dpatch,
  debian/patches/38_pxl-duplex.dpatch,
  debian/patches/39_pxl-resolution.dpatch,
  debian/patches/42_gs-init-ps-delaybind-fix.dpatch,
  debian/patches/45_bjc600-bjc800-pdf-input.dpatch,
  debian/patches/48_cups-output-device-pdf-duplex-uninitialized-memory-fix.dpatch,
  debian/patches/50_lips4-floating-point-exception.dpatch,
  debian/patches/52_cups-device-logging.dpatch,
  debian/patches/55_pcl-input-slot-fix.dpatch,
  debian/patches/57_pxl-input-slot-fix.dpatch,
  debian/patches/60_pxl-cups-driver-pdf.dpatch,
  debian/patches/62_onebitcmyk-pdf.dpatch,
  debian/patches/65_too-big-temp-files-1.dpatch,
  debian/patches/67_too-big-temp-files-2.dpatch,
  debian/patches/70_take-into-account-data-in-stream-buffer-before-refill.dpatch:
  Removed, applied upstream.
* debian/patches/01_docdir_fix_for_debian.dpatch,
  debian/patches/02_gs_man_fix_debian.dpatch,
  debian/patches/01_docdir-fix-for-debian.dpatch,
  debian/patches/02_docdir-fix-for-debian.dpatch: Renamed patches to
  make merging with Debian easier.
* debian/patches/32_improve-handling-of-media-size-changes-from-gv.dpatch, 
  debian/patches/33_bad-params-to-xinitimage-on-large-bitmaps.dpatch:
  regenerated for new source directory structure.
* debian/rules: Corrected paths to remove cidfmap (it is in Resource/Init/
  in GS 8.64) and to install headers (source paths are psi/ and base/ now).
* debian/rules: Remove all fontmaps, as DeFoMa replaces them.
* debian/local/pdftoraster/pdftoraster.c,
  debian/local/pdftoraster/pdftoraster.convs, debian/rules: Removed
  added pdftoraster filter and use the one which comes with Ghostscript.
* debian/ghostscript.links: s/8.63/8.64/

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (C) 2001-2006 Artifex Software, Inc.
2
 
   All Rights Reserved.
3
 
  
4
 
   This software is provided AS-IS with no warranty, either express or
5
 
   implied.
6
 
 
7
 
   This software is distributed under license and may not be copied, modified
8
 
   or distributed except as expressly authorized under the terms of that
9
 
   license.  Refer to licensing information at http://www.artifex.com/
10
 
   or contact Artifex Software, Inc.,  7 Mt. Lassen Drive - Suite A-134,
11
 
   San Rafael, CA  94903, U.S.A., +1(415)492-9861, for further information.
12
 
*/
13
 
 
14
 
/* $Id: mkromfs.c 8022 2007-06-05 22:23:38Z giles $ */
15
 
/* Generate source data for the %rom% IODevice */
16
 
/*
17
 
 * For reasons of convenience and footprint reduction, the various postscript
18
 
 * source files, resources and fonts required by Ghostscript can be compiled
19
 
 * into the executable.
20
 
 *
21
 
 * This file takes a set of directories, and creates a compressed filesystem
22
 
 * image that can be compiled into the executable as static data and accessed
23
 
 * through the %rom% iodevice prefix
24
 
 */
25
 
/*
26
 
 *      Usage: mkromfs [-o outputfile] [options ...] paths
27
 
 *          options and paths can be interspersed and are processed in order
28
 
 *          options:
29
 
 *              -o outputfile   default: obj/gsromfs.c if this option present, must be first.
30
 
 *              -P prefix       use prefix to find path. prefix not included in %rom%
31
 
 *              -X path         exclude the path from further processing.
32
 
 *              -d string       directory in %rom file system (really just a prefix string on filename)
33
 
 *              -c              compression on
34
 
 *              -b              compression off (binary).
35
 
 *
36
 
 *          Note: The tail of any path encountered will be tested so .svn on the -X
37
 
 *                list will exclude that path in all subsequent paths enumerated.
38
 
 */ 
39
 
 
40
 
#include "stdpre.h"
41
 
#include "stdint_.h"
42
 
#include "gsiorom.h"
43
 
#include "gsmemret.h" /* for gs_memory_type_ptr_t */
44
 
#include "gsmalloc.h"
45
 
#include "gsstype.h"
46
 
#include "gp.h" 
47
 
#include <stdio.h>
48
 
#include <stdlib.h>
49
 
#include <string.h>
50
 
#include "time_.h"
51
 
 
52
 
#include <zlib.h>
53
 
 
54
 
/*
55
 
 * The rom file system is an array of pointers to nodes, terminated by a NULL
56
 
 */
57
 
/*
58
 
 * in memory structure of each node is:
59
 
 *
60
 
 *      length_of_uncompressed_file             [31-bit big-endian]
61
 
 *                                              high bit is compression flag 
62
 
 *      data_block_struct[]
63
 
 *      padded_file_name (char *)       includes as least one terminating <nul>
64
 
 *      padded_data_blocks
65
 
 */
66
 
/*
67
 
 *      data_block_struct:
68
 
 *          data_length                 (not including pad)     [32-bit big-endian]
69
 
 *          data_block_offset           (start of each block)   [32-bit big-endian]
70
 
 */
71
 
 
72
 
typedef struct romfs_inode_s {
73
 
    unsigned long length;               /* blocks is (length+ROMFS_BLOCKSIZE-1)/ROMFS_BLOCKSIZE */
74
 
    char *name;                         /* nul terminated */
75
 
    unsigned long *data_lengths;        /* this could be short if ROMFS_BLOCKSIZE */
76
 
                                        /* is < 64k, but the cost is small to use int */
77
 
    unsigned char **data;
78
 
} romfs_inode;
79
 
 
80
 
typedef struct Xlist_element_s {
81
 
        void *next;
82
 
        char *path;
83
 
    } Xlist_element;
84
 
 
85
 
byte *minimal_alloc_bytes(gs_memory_t * mem, uint size, client_name_t cname);
86
 
byte *minimal_alloc_byte_array(gs_memory_t * mem, uint num_elements,
87
 
                             uint elt_size, client_name_t cname);
88
 
void *minimal_alloc_struct(gs_memory_t * mem, gs_memory_type_ptr_t pstype,
89
 
               client_name_t cname);
90
 
void minimal_free_object(gs_memory_t * mem, void * data, client_name_t cname);
91
 
void minimal_free_string(gs_memory_t * mem, byte * data, uint nbytes, client_name_t cname);
92
 
 
93
 
/*******************************************************************************
94
 
 * The following is a REALLY minimal gs_memory_t for use by the gp_ functions
95
 
 *******************************************************************************/
96
 
byte *
97
 
minimal_alloc_bytes(gs_memory_t * mem, uint size, client_name_t cname)
98
 
{
99
 
    return malloc(size);
100
 
}
101
 
 
102
 
byte *
103
 
minimal_alloc_byte_array(gs_memory_t * mem, uint num_elements,
104
 
                             uint elt_size, client_name_t cname)
105
 
{
106
 
    return malloc(num_elements * elt_size);
107
 
}
108
 
 
109
 
void *
110
 
minimal_alloc_struct(gs_memory_t * mem, gs_memory_type_ptr_t pstype,
111
 
               client_name_t cname)
112
 
{
113
 
    return malloc(pstype->ssize);
114
 
}
115
 
 
116
 
void
117
 
minimal_free_object(gs_memory_t * mem, void * data, client_name_t cname)
118
 
{
119
 
    free(data);
120
 
    return;
121
 
}
122
 
 
123
 
void
124
 
minimal_free_string(gs_memory_t * mem, byte * data, uint nbytes, client_name_t cname)
125
 
{
126
 
    free(data);
127
 
    return;
128
 
}
129
 
 
130
 
void basic_enum_ptrs(void);
131
 
void basic_reloc_ptrs(void);
132
 
 
133
 
void basic_enum_ptrs() {
134
 
    printf("basic_enum_ptrs is only called by a GC. Abort.\n");
135
 
    exit(1);
136
 
}
137
 
 
138
 
void basic_reloc_ptrs() {
139
 
    printf("basic_reloc_ptrs is only called by a GC. Abort.\n");
140
 
    exit(1);
141
 
}
142
 
 
143
 
 
144
 
const gs_malloc_memory_t minimal_memory = {
145
 
    (gs_memory_t *)&minimal_memory, /* stable */
146
 
    { minimal_alloc_bytes, /* alloc_bytes_immovable */
147
 
      NULL, /* resize_object */
148
 
      minimal_free_object, /* free_object */
149
 
      NULL, /* stable */
150
 
      NULL, /* status */
151
 
      NULL, /* free_all */
152
 
      NULL, /* consolidate_free */
153
 
      minimal_alloc_bytes, /* alloc_bytes */ 
154
 
      minimal_alloc_struct, /* alloc_struct */
155
 
      minimal_alloc_struct, /* alloc_struct_immovable */
156
 
      minimal_alloc_byte_array, /* alloc_byte_array */
157
 
      minimal_alloc_byte_array, /* alloc_byte_array_immovable */
158
 
      NULL, /* alloc_struct_array */
159
 
      NULL, /* alloc_struct_array_immovable */
160
 
      NULL, /* object_size */
161
 
      NULL, /* object_type */
162
 
      minimal_alloc_bytes, /* alloc_string */
163
 
      minimal_alloc_bytes, /* alloc_string_immovable */
164
 
      NULL, /* resize_string */
165
 
      minimal_free_string, /* free_string */
166
 
      NULL, /* register_root */ 
167
 
      NULL, /* unregister_root */
168
 
      NULL /* enable_free */ 
169
 
    },    
170
 
    NULL, /* gs_lib_ctx */
171
 
    NULL, /* head */
172
 
    NULL, /* non_gc_memory */
173
 
    0, /* allocated */
174
 
    0, /* limit */ 
175
 
    0, /* used */ 
176
 
    0  /* max used */
177
 
};
178
 
 
179
 
void put_uint32(FILE *out, const unsigned int q);
180
 
void put_bytes_padded(FILE *out, unsigned char *p, unsigned int len);
181
 
void inode_clear(romfs_inode* node);
182
 
void inode_write(FILE *out, romfs_inode *node, int compression, int inode_count, int*totlen);
183
 
void process_path(char *path, const char *prefix, const char *add_prefix, Xlist_element *Xlist_head, int compression,
184
 
        int *inode_count, int *totlen, FILE *out);
185
 
 
186
 
/* put 4 byte integer, big endian */
187
 
void put_uint32(FILE *out, const unsigned int q)
188
 
{
189
 
#if ARCH_IS_BIG_ENDIAN
190
 
    fprintf (out, "0x%08x,", q);
191
 
#else
192
 
    fprintf (out, "0x%02x%02x%02x%02x,", q & 0xff, (q>>8) & 0xff, (q>>16) & 0xff, (q>>24) & 0xff);
193
 
#endif
194
 
}
195
 
 
196
 
/* write string as 4 character chunks, padded to 4 byte words. */
197
 
void put_bytes_padded(FILE *out, unsigned char *p, unsigned int len)
198
 
{
199
 
    int i, j=0;
200
 
    union {
201
 
        uint32_t w;
202
 
        struct {
203
 
            unsigned char c1;
204
 
            unsigned char c2;
205
 
            unsigned char c3;
206
 
            unsigned char c4;
207
 
        } c;
208
 
    } w2c;
209
 
 
210
 
    for (i=0; i<(len/4); i++) {
211
 
        j = i*4;
212
 
        w2c.c.c1 = p[j++];
213
 
        w2c.c.c2 = p[j++];
214
 
        w2c.c.c3 = p[j++];
215
 
        w2c.c.c4 = p[j++];
216
 
        fprintf(out, "0x%08x,", w2c.w);
217
 
        if ((i & 7) == 7)
218
 
            fprintf(out, "\n\t");
219
 
    }
220
 
    w2c.w = 0;
221
 
    switch (len - j) {
222
 
      case 3:
223
 
        w2c.c.c3 = p[j+2];
224
 
      case 2:
225
 
        w2c.c.c2 = p[j+1];
226
 
      case 1:
227
 
        w2c.c.c1 = p[j];
228
 
        fprintf(out, "0x%08x,", w2c.w);
229
 
      default: ;
230
 
    }
231
 
    fprintf(out, "\n\t");
232
 
}
233
 
 
234
 
/* clear the internal memory of an inode */
235
 
void inode_clear(romfs_inode* node)
236
 
{
237
 
    int i, blocks = (node->length+ROMFS_BLOCKSIZE-1)/ROMFS_BLOCKSIZE;
238
 
    
239
 
    if (node) {
240
 
        if (node->data) {
241
 
            for (i = 0; i < blocks; i++) {
242
 
                if (node->data[i]) free(node->data[i]);
243
 
            }
244
 
            free(node->data);
245
 
        }
246
 
        if (node->data_lengths) free(node->data_lengths);
247
 
    }
248
 
}
249
 
 
250
 
/* write out and inode and its file data */
251
 
void
252
 
inode_write(FILE *out, romfs_inode *node, int compression, int inode_count, int *totlen)
253
 
{
254
 
    int i, offset;
255
 
    int blocks = (node->length+ROMFS_BLOCKSIZE-1)/ROMFS_BLOCKSIZE;
256
 
    int namelen = strlen(node->name) + 1;       /* include terminating <nul> */
257
 
    
258
 
    /* write the node header */
259
 
    fprintf(out,"    static uint32_t node_%d[] = {\n\t", inode_count);
260
 
    /* 4 byte file length + compression flag in high bit */
261
 
    put_uint32(out, node->length | (compression ? 0x80000000 : 0));
262
 
    fprintf(out, "\t/* compression_flag_bit + file length */\n\t");
263
 
    
264
 
    printf("writing node '%s' len=%ld", node->name, node->length);
265
 
#ifdef DEBUG
266
 
    printf(" %ld blocks %s", blocks, compression ? "compressed" : "binary");
267
 
#endif
268
 
    printf("\n");
269
 
    
270
 
    /* write out data block structures */
271
 
    offset = 4 + (8*blocks) + ((namelen+3) & ~3);
272
 
    *totlen += offset;                  /* add in the header size */
273
 
    for (i = 0; i < blocks; i++) {
274
 
        put_uint32(out, node->data_lengths[i]);
275
 
        put_uint32(out, offset);
276
 
        offset += (node->data_lengths[i]+3) & ~3;
277
 
        fprintf(out, "\t/* data_block_length, offset to data_block */\n\t");
278
 
    }
279
 
    /* write file name (path) padded to 4 byte multiple */
280
 
    fprintf(out, "\t/* file name '%s' */\n\t", node->name);
281
 
    put_bytes_padded(out, node->name, namelen);
282
 
    
283
 
    /* write out data */
284
 
    for (i = 0; i < blocks; i++) {
285
 
        put_bytes_padded(out, node->data[i], node->data_lengths[i]);
286
 
        *totlen += (node->data_lengths[i]+3) & ~3;      /* padded block length */
287
 
    }
288
 
    fprintf(out, "\t0 };\t/* end-of-node */\n");
289
 
}
290
 
 
291
 
 
292
 
/* This relies on the gp_enumerate_* which should not return directories, nor */
293
 
/* should it recurse into directories (unlike Adobe's implementation)         */
294
 
void process_path(char *path, const char *prefix, const char *add_prefix, Xlist_element *Xlist_head,
295
 
                int compression, int *inode_count, int *totlen, FILE *out)
296
 
{
297
 
    int namelen, excluded, save_count=*inode_count;
298
 
    Xlist_element *Xlist_scan;
299
 
    char *prefixed_path;
300
 
    char *found_path, *rom_filename;
301
 
    file_enum *pfenum;
302
 
    int ret, block, blocks;
303
 
    romfs_inode *node;
304
 
    unsigned char *ubuf, *cbuf;
305
 
    unsigned long ulen, clen;
306
 
    FILE *in;
307
 
 
308
 
    prefixed_path = malloc(1024);
309
 
    found_path = malloc(1024);
310
 
    rom_filename = malloc(1024);
311
 
    ubuf = malloc(ROMFS_BLOCKSIZE);
312
 
    cbuf = malloc(ROMFS_CBUFSIZE);
313
 
    if (ubuf == NULL || cbuf == NULL || prefixed_path == NULL ||
314
 
                found_path == NULL || rom_filename == NULL) {
315
 
        printf("malloc fail in process_path\n");
316
 
        exit(1);
317
 
    }
318
 
    prefixed_path[0] = 0;       /* empty string */
319
 
    strcat(prefixed_path, prefix);
320
 
    strcat(prefixed_path, path);
321
 
    strcat(prefixed_path, "*");
322
 
    strcpy(rom_filename, add_prefix);
323
 
#ifdef __WIN32__
324
 
    {
325
 
        int i;
326
 
 
327
 
        /* On Windows, the paths may (will) have '\' instead of '/' so we translate them */
328
 
        for (i=0; i<strlen(prefixed_path); i++)
329
 
            if (prefixed_path[i] == '\\')
330
 
                prefixed_path[i] = '/';
331
 
        for (i=0; i<strlen(rom_filename); i++)
332
 
            if (rom_filename[i] == '\\')
333
 
                rom_filename[i] = '/';
334
 
    }
335
 
#endif
336
 
    /* check for the file on the Xlist */
337
 
    pfenum = gp_enumerate_files_init(prefixed_path, strlen(prefixed_path),
338
 
                        (gs_memory_t *)&minimal_memory);
339
 
    if (pfenum == NULL) {
340
 
        printf("gp_enumerate_files_init failed.\n");
341
 
        exit(1);
342
 
    }
343
 
    while ((namelen=gp_enumerate_files_next(pfenum, found_path, 1024)) >= 0) {
344
 
        excluded = 0;
345
 
        found_path[namelen] = 0;                /* terminate the string */
346
 
        /* check to see if the tail of the path we found matches one on the exclusion list */
347
 
        for (Xlist_scan = Xlist_head; Xlist_scan != NULL; Xlist_scan = Xlist_scan->next) {
348
 
            if (strlen(found_path) >= strlen(Xlist_scan->path)) {
349
 
                if (strcmp(Xlist_scan->path, found_path+strlen(found_path)-strlen(Xlist_scan->path)) == 0) {
350
 
                    excluded = 1;
351
 
                    break;
352
 
                }
353
 
            }
354
 
        }
355
 
        if (excluded)
356
 
            continue;
357
 
 
358
 
        /* process a file */
359
 
        node = calloc(1, sizeof(romfs_inode));
360
 
        /* get info for this file */
361
 
        in = fopen(found_path, "rb");
362
 
        if (in == NULL) {
363
 
            printf("unable to open file for processing: %s\n", found_path);
364
 
            continue;
365
 
        }
366
 
        /* rom_filename + strlen(add_prefix) is first char after the new prefix we want to add */
367
 
        /* found_path + strlen(prefix) is the file name after the -P prefix */
368
 
        rom_filename[strlen(add_prefix)] = 0;           /* truncate afater prefix */
369
 
        strcat(rom_filename, found_path + strlen(prefix));
370
 
        node->name = rom_filename;      /* without -P prefix, with -d add_prefix */
371
 
        fseek(in, 0, SEEK_END);
372
 
        node->length = ftell(in);
373
 
        blocks = (node->length+ROMFS_BLOCKSIZE-1) / ROMFS_BLOCKSIZE + 1;
374
 
        node->data_lengths = calloc(blocks, sizeof(*node->data_lengths));
375
 
        node->data = calloc(blocks, sizeof(*node->data));
376
 
        fclose(in);
377
 
        in = fopen(found_path, "rb");
378
 
        block = 0;
379
 
        while (!feof(in)) {
380
 
            ulen = fread(ubuf, 1, ROMFS_BLOCKSIZE, in);
381
 
            if (!ulen) break;
382
 
            clen = ROMFS_CBUFSIZE;
383
 
            if (compression) {
384
 
                /* compress data here */
385
 
                ret = compress(cbuf, &clen, ubuf, ulen);
386
 
                if (ret != Z_OK) {
387
 
                    printf("error compressing data block!\n");
388
 
                    exit(1);
389
 
                }
390
 
            } else {
391
 
                memcpy(cbuf, ubuf, ulen);
392
 
                clen = ulen;
393
 
            }
394
 
            node->data_lengths[block] = clen; 
395
 
            node->data[block] = malloc(clen);
396
 
            memcpy(node->data[block], cbuf, clen);
397
 
            block++;
398
 
        }
399
 
        fclose(in);
400
 
        /* write out data for this file */
401
 
        inode_write(out, node, compression, *inode_count, totlen);
402
 
        /* clean up */
403
 
        inode_clear(node);
404
 
        free(node);
405
 
        (*inode_count)++;
406
 
    }
407
 
    free(cbuf);
408
 
    free(ubuf);
409
 
    free(found_path);
410
 
    free(prefixed_path);
411
 
    if (save_count == *inode_count) {
412
 
        printf("warning: no files found from path '%s%s'\n", prefix, path);
413
 
    }
414
 
}
415
 
 
416
 
int
417
 
main(int argc, char *argv[])
418
 
{
419
 
    int i;
420
 
    int inode_count = 0, totlen = 0;
421
 
    FILE *out;
422
 
    const char *outfilename = "obj/gsromfs.c";
423
 
    const char *prefix = "";
424
 
    const char *add_prefix = "";
425
 
    int atarg = 1;
426
 
    int compression = 1;                        /* default to doing compression */
427
 
    Xlist_element *Xlist_scan, *Xlist_head = NULL;
428
 
    
429
 
    if (argc < 2) {
430
 
        printf("\n"
431
 
                "       Usage: mkromfs [-o outputfile] [options ...] paths\n"
432
 
                "           options and paths can be interspersed and are processed in order\n"
433
 
                "           options:\n"
434
 
                "               -o outputfile   default: obj/gsromfs.c if this option present, must be first.\n"
435
 
                "               -P prefix       use prefix to find path. prefix not included in %%rom%%\n"
436
 
                "               -X path         exclude the path from further processing.\n"
437
 
                "               -d string       directory in %%rom file system (just a prefix string on filename)\n"
438
 
                "               -c              compression on\n"
439
 
                "               -b              compression off (binary).\n"
440
 
                "\n"
441
 
                "           Note: The tail of any path encountered will be tested so .svn on the -X\n"
442
 
                "                 list will exclude that path in all subsequent paths enumerated.\n"
443
 
            );
444
 
        exit(1);
445
 
    }
446
 
 
447
 
#ifdef DEBUG
448
 
    printf("compression will use %d byte blocksize (zlib output buffer %d bytes)\n",
449
 
        ROMFS_BLOCKSIZE, ROMFS_CBUFSIZE);
450
 
#endif /* DEBUG */
451
 
    
452
 
    if (argc > 3 && argv[1][0] == '-' && argv[1][1] == 'o') {
453
 
        /* process -o option for outputfile */
454
 
        outfilename = argv[2];
455
 
        atarg += 2;
456
 
    }
457
 
#ifdef DEBUG
458
 
    printf("   writing romfs data to '%s'\n", outfilename);
459
 
#endif /* DEBUG */
460
 
    out = fopen(outfilename, "w");
461
 
 
462
 
    fprintf(out,"\t/* Generated data for %%rom%% device, see mkromfs.c */\n");
463
 
#if ARCH_IS_BIG_ENDIAN
464
 
    fprintf(out,"\t/* this code assumes a big endian target platform */\n");
465
 
#else
466
 
    fprintf(out,"\t/* this code assumes a little endian target platform */\n");
467
 
#endif
468
 
    fprintf(out,"\n#include \"stdint_.h\"\n");
469
 
    fprintf(out,"\n#include \"time_.h\"\n\n");
470
 
    fprintf(out,"    time_t gs_romfs_buildtime = %ld;\n\n", time(NULL));
471
 
 
472
 
    /* process the remaining arguments (options interspersed with paths) */
473
 
    for (; atarg < argc; atarg++) {  
474
 
        if (argv[atarg][0] == '-') {
475
 
            /* process an option */
476
 
            switch (argv[atarg][1]) {
477
 
              case 'b':
478
 
                compression = 0;
479
 
                break;
480
 
              case 'c':
481
 
                compression = 1;
482
 
                break;
483
 
              case 'd':
484
 
                if (++atarg == argc) {
485
 
                    printf("   option %s missing required argument\n", argv[atarg-1]);
486
 
                    exit(1);
487
 
                }
488
 
                add_prefix = argv[atarg];
489
 
                break;
490
 
              case 'P':
491
 
                if (++atarg == argc) {
492
 
                    printf("   option %s missing required argument\n", argv[atarg-1]);
493
 
                    exit(1);
494
 
                }
495
 
                prefix = argv[atarg];
496
 
                break;
497
 
              case 'X':
498
 
                if (++atarg == argc) {
499
 
                    printf("   option %s missing required argument\n", argv[atarg-1]);
500
 
                    exit(1);
501
 
                }
502
 
                Xlist_scan = malloc(sizeof(Xlist_element));
503
 
                if (Xlist_scan == NULL) {
504
 
                    exit(1);
505
 
                }
506
 
                Xlist_scan->next = Xlist_head;
507
 
                Xlist_head = Xlist_scan;
508
 
                Xlist_head->path = argv[atarg];
509
 
                break;
510
 
              default:
511
 
                printf("  unknown option: %s \n", argv[atarg]);
512
 
            }
513
 
            continue;
514
 
        }
515
 
        /* process a path */
516
 
        process_path(argv[atarg], prefix, add_prefix, Xlist_head, compression, &inode_count, &totlen, out);
517
 
    }
518
 
    /* now write out the array of nodes */
519
 
    fprintf(out, "    uint32_t *gs_romfs[] = {\n");
520
 
    for (i=0; i<inode_count; i++)
521
 
        fprintf(out, "\tnode_%d,\n", i);
522
 
    fprintf(out, "\t0 };\n");
523
 
    
524
 
    fclose(out);
525
 
 
526
 
    printf("Total %%rom%% structure size is %d bytes.\n", totlen);
527
 
    
528
 
    return 0;
529
 
}
530