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

« back to all changes in this revision

Viewing changes to base/gendev.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: gendev.c 8368 2007-11-14 23:03:22Z giles $ */
 
15
/* Generate .dev configuration files */
 
16
#include "stdpre.h"
 
17
#include <ctype.h>
 
18
#include <stdio.h>
 
19
#include <stdlib.h>             /* for calloc */
 
20
#include <string.h>
 
21
 
 
22
/*
 
23
 * This program generates .dev configuration files.
 
24
 *
 
25
 * Usage:
 
26
 *      gendev [-Z] [-n [<name_prefix> | -]] [-C [<dir> | -]]
 
27
 *        (-d <devfile> | -m <modfile> | -a <modfile>)
 
28
 *        (-<category> | <item>)*
 
29
 *
 
30
 * The name_prefix is for device[2], font, init, and iodev resources.
 
31
 * ****** DOESN'T HANDLE -replace YET ******
 
32
 * ****** DOESN'T MERGE device AND device2 ******
 
33
 */
 
34
 
 
35
#define DEFAULT_NAME_PREFIX "gs_"
 
36
#define INITIAL_CATEGORY "obj"
 
37
 
 
38
typedef struct config_s {
 
39
    /* Set once */
 
40
    FILE *out;
 
41
    bool debug;
 
42
    const char *name_prefix;
 
43
    const char *file_prefix;
 
44
    ulong file_id;              /* for uniq_last detection */
 
45
    /* Updated dynamically */
 
46
#define ITEM_ID_BITS 5
 
47
    uint item_id;
 
48
    bool any_scan_items;
 
49
    bool in_res_scan;
 
50
    bool in_category;           /* in_category implies in_res_scan */
 
51
    const char *current_category;
 
52
} config;
 
53
static const config init_config =
 
54
{
 
55
    0,                          /* out */
 
56
    0,                          /* debug */
 
57
    DEFAULT_NAME_PREFIX,        /* name_prefix */
 
58
    "",                         /* file_prefix */
 
59
    0,                          /* file_id */
 
60
    0,                          /* item_id */
 
61
    0,                          /* any_scan_items */
 
62
    0,                          /* in_res_scan */
 
63
    0,                          /* in_category */
 
64
    ""                          /* current_category */
 
65
};
 
66
 
 
67
static const char *indent_INCLUDED = "\t\t\t\t";
 
68
static const char *indent_RES_SCAN = "   ";
 
69
static const char *indent_category = "\t";
 
70
static const char *indent_SEEN = "\t    ";
 
71
static const char *indent_include = "   ";
 
72
static const char *indent_scan_item = "\t";
 
73
static const char *indent_item = "";
 
74
 
 
75
/* Forward definitions */
 
76
void add_entry(config *, const char *, const char *, bool);
 
77
 
 
78
main(int argc, char *argv[])
 
79
{
 
80
    config conf;
 
81
    int i, j;
 
82
    bool dev, append;
 
83
    const char *category = INITIAL_CATEGORY;
 
84
    const char *fnarg;
 
85
    FILE *out;
 
86
    long pos;
 
87
 
 
88
    conf = init_config;
 
89
    /* Process command line arguments. */
 
90
    for (i = 1; i < argc; i++) {
 
91
        const char *arg = argv[i];
 
92
 
 
93
        if (*arg != '-') {
 
94
            fprintf(stderr, "-d|m|a must precede non-switches.\n", arg);
 
95
            exit(1);
 
96
        }
 
97
        switch (arg[1]) {
 
98
            case 'C':           /* change directory, by analogy with make */
 
99
                conf.file_prefix =
 
100
                    (argv[i + 1][0] == '-' ? "" : argv[i + 1]);
 
101
                ++i;
 
102
                continue;
 
103
            case 'n':
 
104
                conf.name_prefix =
 
105
                    (argv[i + 1][0] == '-' ? "" : argv[i + 1]);
 
106
                ++i;
 
107
                continue;
 
108
            case 'a':
 
109
                dev = false, append = true;
 
110
                break;
 
111
            case 'd':
 
112
                dev = true, append = false;
 
113
                break;
 
114
            case 'm':
 
115
                dev = false, append = false;
 
116
                break;
 
117
            case 'Z':
 
118
                conf.debug = true;
 
119
                continue;
 
120
            default:
 
121
                fprintf(stderr, "Unknown switch %s.\n", argv[i]);
 
122
                exit(1);
 
123
        }
 
124
        break;
 
125
    }
 
126
    if (i == argc - 1) {
 
127
        fprintf(stderr, "No output file name given, last argument is %s.\n",
 
128
                argv[i]);
 
129
        exit(1);
 
130
    }
 
131
    /* Must be the output file. */
 
132
    fnarg = argv[++i];
 
133
    {
 
134
        char fname[100];
 
135
 
 
136
        strcpy(fname, fnarg);
 
137
        strcat(fname, ".dev");
 
138
        out = fopen(fname, (append ? "a" : "w"));
 
139
        if (out == 0) {
 
140
            fprintf(stderr, "Can't open %s for output.\n", fname);
 
141
            exit(1);
 
142
        }
 
143
        if (!append)
 
144
            fprintf(out,
 
145
                    "/*\n * File %s created automatically by gendev.\n */\n",
 
146
                    fname);
 
147
    }
 
148
    conf.out = out;
 
149
    pos = ftell(out);
 
150
    /* We need a separate _INCLUDED flag for each batch of definitions. */
 
151
    fprintf(out, "\n#%sifndef %s_%ld_INCLUDED\n",
 
152
            indent_INCLUDED, fnarg, pos);
 
153
    fprintf(out, "#%s  define %s_%ld_INCLUDED\n",
 
154
            indent_INCLUDED, fnarg, pos);
 
155
    /* Create a "unique" hash for the output file. */
 
156
    for (j = 0; fnarg[j] != 0; ++j)
 
157
        conf.file_id = conf.file_id * 41 + fnarg[j];
 
158
    conf.item_id <<= ITEM_ID_BITS;
 
159
    /* Add the real entries. */
 
160
    if (dev)
 
161
        add_entry(&conf, "dev", fnarg, false);
 
162
    for (j = i + 1; j < argc; ++j) {
 
163
        const char *arg = argv[j];
 
164
 
 
165
        if (arg[0] == '-')
 
166
            category = arg + 1;
 
167
        else
 
168
            add_entry(&conf, category, arg, false);
 
169
    }
 
170
    if (conf.in_category)
 
171
        fprintf(out, "#%sendif /* -%s */\n",
 
172
                indent_category, conf.current_category);
 
173
    /* Add the scanning entries, if any. */
 
174
    if (conf.any_scan_items) {
 
175
        if (conf.in_res_scan)
 
176
            fprintf(out, "#%selse /* RES_SCAN */\n", indent_RES_SCAN);
 
177
        else
 
178
            fprintf(out, "#%sifdef RES_SCAN\n", indent_RES_SCAN);
 
179
        conf.in_res_scan = true;
 
180
        category = INITIAL_CATEGORY;
 
181
        conf.item_id = 0;
 
182
        for (j = i + 1; j < argc; ++j) {
 
183
            const char *arg = argv[j];
 
184
 
 
185
            if (arg[0] == '-')
 
186
                category = arg + 1;
 
187
            else
 
188
                add_entry(&conf, category, arg, true);
 
189
        }
 
190
    }
 
191
    if (conf.in_res_scan)
 
192
        fprintf(out, "#%sendif /* RES_SCAN */\n", indent_RES_SCAN);
 
193
    fprintf(out, "#%sendif /* !%s_%ld_INCLUDED */\n",
 
194
            indent_INCLUDED, fnarg, pos);
 
195
    fclose(out);
 
196
    exit(0);
 
197
}
 
198
 
 
199
/* Add an entry to the output. */
 
200
typedef enum {
 
201
    uniq_none = 0,
 
202
    uniq_first,
 
203
    uniq_last
 
204
} uniq_mode;
 
205
void
 
206
write_item(config * pconf, const char *str, const char *category,
 
207
           const char *item, uniq_mode mode)
 
208
{
 
209
    FILE *out = pconf->out;
 
210
    char cati[80];
 
211
 
 
212
    if (!pconf->in_res_scan) {
 
213
        fprintf(out, "#%sifndef RES_SCAN\n", indent_RES_SCAN);
 
214
        pconf->in_res_scan = true;
 
215
    }
 
216
    if (strcmp(pconf->current_category, category)) {
 
217
        const char *paren = strchr(str, '(');
 
218
 
 
219
        if (pconf->in_category)
 
220
            fprintf(out, "#%sendif /* -%s */\n",
 
221
                    indent_category, pconf->current_category);
 
222
        fprintf(out, "#%sifdef ", indent_category);
 
223
        fwrite(str, sizeof(char), paren - str, out);
 
224
 
 
225
        fprintf(out, "\n");
 
226
        pconf->current_category = category;
 
227
        pconf->in_category = true;
 
228
    }
 
229
    sprintf(cati, "%s_%s_", category, item);
 
230
    switch (mode) {
 
231
        case uniq_none:
 
232
            fprintf(out, "%s%s\n", indent_item, str);
 
233
            break;
 
234
        case uniq_first:
 
235
            fprintf(out, "#%sifndef %sSEEN\n", indent_SEEN, cati);
 
236
            fprintf(out, "#%s  define %sSEEN\n", indent_SEEN, cati);
 
237
            write_item(pconf, str, category, item, uniq_none);
 
238
            fprintf(out, "#%sendif\n", indent_SEEN, cati);
 
239
            break;
 
240
        case uniq_last:
 
241
            fprintf(out, "#%sif %sSEEN == %lu\n", indent_SEEN, cati,
 
242
                    pconf->file_id + pconf->item_id++);
 
243
            write_item(pconf, str, category, item, uniq_none);
 
244
            fprintf(out, "#%sendif\n", indent_SEEN, cati);
 
245
            pconf->any_scan_items = true;
 
246
            break;
 
247
    }
 
248
}
 
249
void
 
250
write_scan_item(config * pconf, const char *str, const char *category,
 
251
                const char *item, uniq_mode mode)
 
252
{
 
253
    FILE *out = pconf->out;
 
254
    char cati[80];
 
255
 
 
256
    sprintf(cati, "%s_%s_", category, item);
 
257
    switch (mode) {
 
258
        case uniq_none:
 
259
            break;
 
260
        case uniq_first:
 
261
            break;
 
262
        case uniq_last:
 
263
            fprintf(out, "#%sundef %sSEEN\n", indent_scan_item, cati);
 
264
            fprintf(out, "#%s  define %sSEEN %lu\n", indent_scan_item, cati,
 
265
                    pconf->file_id + pconf->item_id++);
 
266
    }
 
267
}
 
268
void
 
269
add_entry(config * pconf, const char *category, const char *item, bool scan)
 
270
{
 
271
    char str[80];
 
272
    uniq_mode mode = uniq_first;
 
273
 
 
274
    if (pconf->debug && !scan)
 
275
        printf("Adding %s %s;\n", category, item);
 
276
    str[0] = 0;
 
277
    switch (category[0]) {      /* just an accelerator */
 
278
#define is_cat(str) !strcmp(category, str)
 
279
        case 'd':
 
280
            if (is_cat("dev"))
 
281
                sprintf(str, "device_(%s%s_device)\n",
 
282
                        pconf->name_prefix, item);
 
283
            else if (is_cat("dev2"))
 
284
                sprintf(str, "device2_(%s%s_device)\n",
 
285
                        pconf->name_prefix, item);
 
286
            break;
 
287
        case 'e':
 
288
            if (is_cat("emulator"))
 
289
                sprintf(str, "emulator_(\"%s\",%d)",
 
290
                        item, strlen(item));
 
291
            break;
 
292
        case 'f':
 
293
            if (is_cat("font"))
 
294
                sprintf(str, "font_(\"0.font_%s\",%sf_%s,zf_%s)",
 
295
                        item, pconf->name_prefix, item, item);
 
296
            break;
 
297
        case 'i':
 
298
            if (is_cat("include")) {
 
299
                int len = strlen(item);
 
300
 
 
301
                if (scan)
 
302
                    return;
 
303
                if (strcmp(pconf->current_category, category)) {
 
304
                    if (pconf->in_category) {
 
305
                        fprintf(pconf->out, "#%sendif /* -%s */\n",
 
306
                                indent_category, pconf->current_category);
 
307
                        pconf->in_category = false;
 
308
                    }
 
309
                    pconf->current_category = category;
 
310
                }
 
311
                if (pconf->in_res_scan) {
 
312
                    fprintf(pconf->out, "#%sendif /* RES_SCAN */\n",
 
313
                            indent_RES_SCAN);
 
314
                    pconf->in_res_scan = false;
 
315
                }
 
316
                if (len < 5 || strcmp(item + len - 4, ".dev"))
 
317
                    fprintf(pconf->out, "#%sinclude \"%s.dev\"\n",
 
318
                            indent_include, item);
 
319
                else
 
320
                    fprintf(pconf->out, "#%sinclude \"%s\"\n",
 
321
                            indent_include, item);
 
322
                return;
 
323
            } else if (is_cat("init"))
 
324
                sprintf(str, "init_(%s%s_init)", pconf->name_prefix, item);
 
325
            else if (is_cat("iodev"))
 
326
                sprintf(str, "io_device_(%siodev_%s)", pconf->name_prefix, item);
 
327
            break;
 
328
        case 'l':
 
329
            if (is_cat("lib")) {
 
330
                sprintf(str, "lib_(%s)", item);
 
331
                mode = uniq_last;
 
332
            }
 
333
            break;
 
334
        case 'o':
 
335
            if (is_cat("obj"))
 
336
                sprintf(str, "obj_(%s%s)", pconf->file_prefix, item);
 
337
            else if (is_cat("oper"))
 
338
                sprintf(str, "oper_(%s_op_defs)", item);
 
339
            break;
 
340
        case 'p':
 
341
            if (is_cat("ps"))
 
342
                sprintf(str, "psfile_(\"%s.ps\",%d)",
 
343
                        item, strlen(item) + 3);
 
344
            break;
 
345
#undef is_cat
 
346
        default:
 
347
            ;
 
348
    }
 
349
    if (str[0] == 0) {
 
350
        fprintf(stderr, "Unknown category %s.\n", category);
 
351
        exit(1);
 
352
    }
 
353
    if (scan)
 
354
        write_scan_item(pconf, str, category, item, mode);
 
355
    else
 
356
        write_item(pconf, str, category, item, mode);
 
357
}