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

« back to all changes in this revision

Viewing changes to psi/icontext.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: icontext.c 9043 2008-08-28 22:48:19Z giles $ */
 
15
/* Context state operations */
 
16
#include "ghost.h"
 
17
#include "gsstruct.h"           /* for gxalloc.h */
 
18
#include "gxalloc.h"
 
19
#include "ierrors.h"
 
20
#include "stream.h"             /* for files.h */
 
21
#include "files.h"
 
22
#include "idict.h"
 
23
#include "igstate.h"
 
24
#include "icontext.h"
 
25
#include "interp.h"
 
26
#include "isave.h"
 
27
#include "dstack.h"
 
28
#include "estack.h"
 
29
#include "store.h"
 
30
 
 
31
/* Declare the GC descriptors for embedded objects. */
 
32
extern_st(st_gs_dual_memory);
 
33
extern_st(st_ref_stack);
 
34
extern_st(st_dict_stack);
 
35
extern_st(st_exec_stack);
 
36
extern_st(st_op_stack);
 
37
 
 
38
/* GC descriptors */
 
39
static 
 
40
CLEAR_MARKS_PROC(context_state_clear_marks)
 
41
{
 
42
    gs_context_state_t *const pcst = vptr;
 
43
 
 
44
    r_clear_attrs(&pcst->stdio[0], l_mark);
 
45
    r_clear_attrs(&pcst->stdio[1], l_mark);
 
46
    r_clear_attrs(&pcst->stdio[2], l_mark);
 
47
    r_clear_attrs(&pcst->error_object, l_mark);
 
48
    r_clear_attrs(&pcst->userparams, l_mark);
 
49
}
 
50
static 
 
51
ENUM_PTRS_WITH(context_state_enum_ptrs, gs_context_state_t *pcst) {
 
52
    index -= 6;
 
53
    if (index < st_gs_dual_memory_num_ptrs)
 
54
        return ENUM_USING(st_gs_dual_memory, &pcst->memory,
 
55
                          sizeof(pcst->memory), index);
 
56
    index -= st_gs_dual_memory_num_ptrs;
 
57
    if (index < st_dict_stack_num_ptrs)
 
58
        return ENUM_USING(st_dict_stack, &pcst->dict_stack,
 
59
                          sizeof(pcst->dict_stack), index);
 
60
    index -= st_dict_stack_num_ptrs;
 
61
    if (index < st_exec_stack_num_ptrs)
 
62
        return ENUM_USING(st_exec_stack, &pcst->exec_stack,
 
63
                          sizeof(pcst->exec_stack), index);
 
64
    index -= st_exec_stack_num_ptrs;
 
65
    return ENUM_USING(st_op_stack, &pcst->op_stack,
 
66
                      sizeof(pcst->op_stack), index);
 
67
    }
 
68
    ENUM_PTR(0, gs_context_state_t, pgs);
 
69
    case 1: ENUM_RETURN_REF(&pcst->stdio[0]);
 
70
    case 2: ENUM_RETURN_REF(&pcst->stdio[1]);
 
71
    case 3: ENUM_RETURN_REF(&pcst->stdio[2]);
 
72
    case 4: ENUM_RETURN_REF(&pcst->error_object);
 
73
    case 5: ENUM_RETURN_REF(&pcst->userparams);
 
74
ENUM_PTRS_END
 
75
static RELOC_PTRS_WITH(context_state_reloc_ptrs, gs_context_state_t *pcst);
 
76
    RELOC_PTR(gs_context_state_t, pgs);
 
77
    RELOC_USING(st_gs_dual_memory, &pcst->memory, sizeof(pcst->memory));
 
78
    /******* WHY DON'T WE CLEAR THE l_mark OF stdio? ******/
 
79
    RELOC_REF_VAR(pcst->stdio[0]);
 
80
    RELOC_REF_VAR(pcst->stdio[1]);
 
81
    RELOC_REF_VAR(pcst->stdio[2]);
 
82
    RELOC_REF_VAR(pcst->error_object);
 
83
    r_clear_attrs(&pcst->error_object, l_mark);
 
84
    RELOC_REF_VAR(pcst->userparams);
 
85
    r_clear_attrs(&pcst->userparams, l_mark);
 
86
    RELOC_USING(st_dict_stack, &pcst->dict_stack, sizeof(pcst->dict_stack));
 
87
    RELOC_USING(st_exec_stack, &pcst->exec_stack, sizeof(pcst->exec_stack));
 
88
    RELOC_USING(st_op_stack, &pcst->op_stack, sizeof(pcst->op_stack));
 
89
RELOC_PTRS_END
 
90
public_st_context_state();
 
91
 
 
92
/* Allocate the state of a context. */
 
93
int
 
94
context_state_alloc(gs_context_state_t ** ppcst,
 
95
                    const ref *psystem_dict,
 
96
                    const gs_dual_memory_t * dmem)
 
97
{
 
98
    gs_ref_memory_t *mem = dmem->space_local;
 
99
    gs_context_state_t *pcst = *ppcst;
 
100
    int code;
 
101
    int i;
 
102
 
 
103
    if (pcst == 0) {
 
104
        pcst = gs_alloc_struct((gs_memory_t *) mem, gs_context_state_t,
 
105
                               &st_context_state, "context_state_alloc");
 
106
        if (pcst == 0)
 
107
            return_error(e_VMerror);
 
108
    }
 
109
    code = gs_interp_alloc_stacks(mem, pcst);
 
110
    if (code < 0)
 
111
        goto x0;
 
112
    /*
 
113
     * We have to initialize the dictionary stack early,
 
114
     * for far-off references to systemdict.
 
115
     */
 
116
    pcst->dict_stack.system_dict = *psystem_dict;
 
117
    pcst->dict_stack.min_size = 0;
 
118
    pcst->dict_stack.userdict_index = 0;
 
119
    pcst->pgs = int_gstate_alloc(dmem);
 
120
    if (pcst->pgs == 0) {
 
121
        code = gs_note_error(e_VMerror);
 
122
        goto x1;
 
123
    }
 
124
    pcst->memory = *dmem;
 
125
    pcst->language_level = 1;
 
126
    make_false(&pcst->array_packing);
 
127
    make_int(&pcst->binary_object_format, 0);
 
128
    pcst->rand_state = rand_state_initial;
 
129
    pcst->usertime_total = 0;
 
130
    pcst->keep_usertime = false;
 
131
    pcst->in_superexec = 0;
 
132
    pcst->plugin_list = 0;
 
133
    make_t(&pcst->error_object, t__invalid);
 
134
    {   /*
 
135
         * Create an empty userparams dictionary of the right size.
 
136
         * If we can't determine the size, pick an arbitrary one.
 
137
         */
 
138
        ref *puserparams;
 
139
        uint size;
 
140
        ref *system_dict = &pcst->dict_stack.system_dict;
 
141
 
 
142
        if (dict_find_string(system_dict, "userparams", &puserparams) >= 0)
 
143
            size = dict_length(puserparams);
 
144
        else
 
145
            size = 30;
 
146
        code = dict_alloc(pcst->memory.space_local, size, &pcst->userparams);
 
147
        if (code < 0)
 
148
            goto x2;
 
149
        /* PostScript code initializes the user parameters. */
 
150
    }
 
151
    pcst->scanner_options = 0;
 
152
    pcst->LockFilePermissions = false;
 
153
    pcst->starting_arg_file = false;
 
154
    pcst->RenderTTNotdef = true;
 
155
    /* The initial stdio values are bogus.... */
 
156
    make_file(&pcst->stdio[0], a_readonly | avm_invalid_file_entry, 1,
 
157
              invalid_file_entry);
 
158
    make_file(&pcst->stdio[1], a_all | avm_invalid_file_entry, 1,
 
159
              invalid_file_entry);
 
160
    make_file(&pcst->stdio[2], a_all | avm_invalid_file_entry, 1,
 
161
              invalid_file_entry);
 
162
    for (i = countof(pcst->memory.spaces_indexed); --i >= 0;)
 
163
        if (dmem->spaces_indexed[i] != 0)
 
164
            ++(dmem->spaces_indexed[i]->num_contexts);
 
165
    *ppcst = pcst;
 
166
    return 0;
 
167
  x2:gs_state_free(pcst->pgs);
 
168
  x1:gs_interp_free_stacks(mem, pcst);
 
169
  x0:if (*ppcst == 0)
 
170
        gs_free_object((gs_memory_t *) mem, pcst, "context_state_alloc");
 
171
    return code;
 
172
}
 
173
 
 
174
/* Load the interpreter state from a context. */
 
175
int
 
176
context_state_load(gs_context_state_t * i_ctx_p)
 
177
{
 
178
    gs_ref_memory_t *lmem = iimemory_local;
 
179
    ref *system_dict = systemdict;
 
180
    uint space = r_space(system_dict);
 
181
    dict_stack_t *dstack = &idict_stack;
 
182
    int code;
 
183
 
 
184
    /*
 
185
     * Disable save checking, and space check for systemdict, while
 
186
     * copying dictionaries.
 
187
     */
 
188
    alloc_set_not_in_save(idmemory);
 
189
    r_set_space(system_dict, avm_max);
 
190
    /*
 
191
     * Switch references from systemdict to local objects.
 
192
     * userdict.localdicts holds these objects.  We could optimize this by
 
193
     * only doing it if we're changing to a different local VM relative to
 
194
     * the same global VM, but the cost is low enough relative to other
 
195
     * things that we don't bother.
 
196
     */
 
197
    {
 
198
        ref_stack_t *rdstack = &dstack->stack;
 
199
        const ref *puserdict =
 
200
            ref_stack_index(rdstack, ref_stack_count(rdstack) - 1 -
 
201
                            dstack->userdict_index);
 
202
        ref *plocaldicts;
 
203
 
 
204
        if (dict_find_string(puserdict, "localdicts", &plocaldicts) > 0 &&
 
205
            r_has_type(plocaldicts, t_dictionary)
 
206
            ) {
 
207
            dict_copy(plocaldicts, system_dict, dstack);
 
208
        }
 
209
    }
 
210
    /*
 
211
     * Set systemdict.userparams to the saved copy, and then
 
212
     * set the actual user parameters.  Note that we must disable both
 
213
     * space checking and save checking while doing this.  Also,
 
214
     * we must do this after copying localdicts (if required), because
 
215
     * userparams also appears in localdicts.
 
216
     */
 
217
    code = dict_put_string(system_dict, "userparams", &i_ctx_p->userparams,
 
218
                           dstack);
 
219
    if (code >= 0)
 
220
        code = set_user_params(i_ctx_p, &i_ctx_p->userparams);
 
221
    r_set_space(system_dict, space);
 
222
    if (lmem->save_level > 0)
 
223
        alloc_set_in_save(idmemory);
 
224
    estack_clear_cache(&iexec_stack);
 
225
    dstack_set_top(&idict_stack);
 
226
    return code;
 
227
}
 
228
 
 
229
/* Store the interpreter state in a context. */
 
230
int
 
231
context_state_store(gs_context_state_t * pcst)
 
232
{
 
233
    ref_stack_cleanup(&pcst->dict_stack.stack);
 
234
    ref_stack_cleanup(&pcst->exec_stack.stack);
 
235
    ref_stack_cleanup(&pcst->op_stack.stack);
 
236
    /*
 
237
     * The user parameters in systemdict.userparams are kept
 
238
     * up to date by PostScript code, but we still need to save
 
239
     * systemdict.userparams to get the correct l_new flag.
 
240
     */
 
241
    {
 
242
        ref *puserparams;
 
243
        /* We need i_ctx_p for access to the d_stack. */
 
244
        i_ctx_t *i_ctx_p = pcst;
 
245
 
 
246
        if (dict_find_string(systemdict, "userparams", &puserparams) < 0)
 
247
            return_error(e_Fatal);
 
248
        pcst->userparams = *puserparams;
 
249
    }
 
250
    return 0;
 
251
}
 
252
 
 
253
/* Free the contents of the state of a context, always to its local VM. */
 
254
/* Return a mask of which of its VMs, if any, we freed. */
 
255
int
 
256
context_state_free(gs_context_state_t * pcst)
 
257
{
 
258
    gs_ref_memory_t *mem = pcst->memory.space_local;
 
259
    int freed = 0;
 
260
    int i;
 
261
 
 
262
    /*
 
263
     * If this context is the last one referencing a particular VM
 
264
     * (local / global / system), free the entire VM space;
 
265
     * otherwise, just free the context-related structures.
 
266
     */
 
267
    for (i = countof(pcst->memory.spaces_indexed); --i >= 0;) {
 
268
        if (pcst->memory.spaces_indexed[i] != 0 &&
 
269
            !--(pcst->memory.spaces_indexed[i]->num_contexts)
 
270
            ) {
 
271
/****** FREE THE ENTIRE SPACE ******/
 
272
            freed |= 1 << i;
 
273
        }
 
274
    }
 
275
    /*
 
276
     * If we freed any spaces at all, we must have freed the local
 
277
     * VM where the context structure and its substructures were
 
278
     * allocated.
 
279
     */
 
280
    if (freed)
 
281
        return freed;
 
282
    {
 
283
        gs_state *pgs = pcst->pgs;
 
284
 
 
285
        gs_grestoreall(pgs);
 
286
        /* Patch the saved pointer so we can do the last grestore. */
 
287
        {
 
288
            gs_state *saved = gs_state_saved(pgs);
 
289
 
 
290
            gs_state_swap_saved(saved, saved);
 
291
        }
 
292
        gs_grestore(pgs);
 
293
        gs_state_swap_saved(pgs, (gs_state *) 0);
 
294
        gs_state_free(pgs);
 
295
    }
 
296
/****** FREE USERPARAMS ******/
 
297
    gs_interp_free_stacks(mem, pcst);
 
298
    return 0;
 
299
}