Coverage Report

Created: 2026-04-01 07:17

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ghostpdl/pcl/pl/pltop.c
Line
Count
Source
1
/* Copyright (C) 2001-2023 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,
8
   modified or distributed except as expressly authorized under the terms
9
   of the license contained in the file LICENSE in this distribution.
10
11
   Refer to licensing information at http://www.artifex.com or contact
12
   Artifex Software, Inc.,  39 Mesa Street, Suite 108A, San Francisco,
13
   CA 94129, USA, for further information.
14
*/
15
16
17
/* pltop.c */
18
/* Top-level API for interpreters */
19
20
#include "string_.h"
21
#include "gdebug.h"
22
#include "gstypes.h"
23
#include "gsmemory.h"
24
#include "gsstruct.h"
25
#include "gsdevice.h"
26
#include "pltop.h"
27
#include "gserrors.h"
28
#include "stream.h"
29
#include "strmio.h"
30
31
/* Get implementation's characteristics */
32
const pl_interp_characteristics_t *     /* always returns a descriptor */
33
pl_characteristics(const pl_interp_implementation_t * impl)      /* implementation of interpreter to alloc */
34
532k
{
35
532k
    return impl->proc_characteristics(impl);
36
532k
}
37
38
/* Do instance interpreter allocation/init. No device is set yet */
39
int                             /* ret 0 ok, else -ve error code */
40
pl_allocate_interp_instance(pl_interp_implementation_t * impl,
41
                            gs_memory_t                * mem)   /* allocator to allocate instance from */
42
113k
{
43
113k
    return impl->proc_allocate_interp_instance(impl, mem);
44
113k
}
45
46
/*
47
 * Get the allocator with which to allocate a device
48
 */
49
gs_memory_t *
50
pl_get_device_memory(pl_interp_implementation_t *impl)
51
48.5k
{
52
48.5k
    if (impl->proc_get_device_memory == NULL)
53
40.4k
        return NULL;
54
8.09k
    return impl->proc_get_device_memory(impl);
55
48.5k
}
56
57
int
58
pl_set_param(pl_interp_implementation_t *impl,
59
             gs_param_list              *plist)
60
453k
{
61
453k
    if (impl->proc_set_param == NULL)
62
388k
        return 0;
63
64
64.7k
    return impl->proc_set_param(impl, plist);
65
453k
}
66
67
int
68
pl_add_path(pl_interp_implementation_t *impl,
69
            const char                 *path)
70
0
{
71
0
    if (impl->proc_add_path == NULL)
72
0
        return 0;
73
74
0
    return impl->proc_add_path(impl, path);
75
0
}
76
77
int pl_post_args_init(pl_interp_implementation_t *impl)
78
113k
{
79
113k
    if (impl->proc_post_args_init == NULL)
80
97.1k
        return 0;
81
82
16.1k
    return impl->proc_post_args_init(impl);
83
113k
}
84
85
/* Prepare interp instance for the next "job" */
86
int                             /* ret 0 ok, else -ve error code */
87
pl_init_job(pl_interp_implementation_t * impl,     /* interp instance to start job in */
88
            gx_device                  * device) /* device to set (open or closed) */
89
39.8k
{
90
39.8k
    return impl->proc_init_job(impl, device);
91
39.8k
}
92
93
int                             /* ret 0 ok, else -ve error code */
94
pl_run_prefix_commands(pl_interp_implementation_t * impl,     /* interp instance to start job in */
95
                       const char                 * prefix)
96
22.2k
{
97
22.2k
    if (prefix == NULL)
98
22.2k
        return 0;
99
0
    if (impl->proc_run_prefix_commands == NULL)
100
0
        return -1;
101
0
    return impl->proc_run_prefix_commands(impl, prefix);
102
0
}
103
104
/* Parse a random access seekable file.
105
   This function is mutually exclusive with pl_process and pl_flush_to_eoj,
106
   and is only called if the file is seekable and the function pointer is
107
   not NULL.
108
 */
109
int
110
pl_process_file(pl_interp_implementation_t * impl, const char *filename)
111
100
{
112
100
    gs_memory_t *mem;
113
100
    int code, code1;
114
100
    stream *s;
115
116
100
    if (impl->proc_process_file != NULL)
117
100
        return impl->proc_process_file(impl, filename);
118
119
    /* We have to process the file in chunks. */
120
0
    mem = pl_get_device_memory(impl);
121
0
    code = 0;
122
123
0
    s = sfopen(filename, "r", mem);
124
0
    if (s == NULL)
125
0
        return gs_error_undefinedfilename;
126
127
0
    code = pl_process_begin(impl);
128
129
0
    while (code == gs_error_NeedInput || code >= 0) {
130
0
        if (s->cursor.r.ptr == s->cursor.r.limit && sfeof(s))
131
0
            break;
132
0
        code = s_process_read_buf(s);
133
0
        if (code < 0)
134
0
            break;
135
136
0
        code = pl_process(impl, &s->cursor.r);
137
0
        if_debug2m('I', mem, "processed (%s) job to offset %ld\n",
138
0
                   pl_characteristics(impl)->language,
139
0
                   sftell(s));
140
0
    }
141
142
0
    code1 = pl_process_end(impl);
143
0
    if (code >= 0 && code1 < 0)
144
0
        code = code1;
145
146
0
    sfclose(s);
147
148
0
    return code;
149
0
}
150
151
/* Do setup to for parsing cursor-fulls of data */
152
int
153
pl_process_begin(pl_interp_implementation_t * impl) /* interp instance to process data job in */
154
22.1k
{
155
22.1k
    return impl->proc_process_begin(impl);
156
22.1k
}
157
158
/* Parse a cursor-full of data */
159
/* The parser reads data from the input
160
 * buffer and returns either:
161
 *      >=0 - OK, more input is needed.
162
 *      e_ExitLanguage - A UEL or other return to the default parser was
163
 *      detected.
164
 *      other <0 value - an error was detected.
165
 */
166
int
167
pl_process(pl_interp_implementation_t * impl,       /* interp instance to process data job in */
168
           stream_cursor_read         * cursor)     /* data to process */
169
112k
{
170
112k
    return impl->proc_process(impl, cursor);
171
112k
}
172
173
int
174
pl_process_end(pl_interp_implementation_t * impl)   /* interp instance to process data job in */
175
23.1k
{
176
23.1k
    return impl->proc_process_end(impl);
177
23.1k
}
178
179
/* Skip to end of job ret 1 if done, 0 ok but EOJ not found, else -ve error code */
180
int
181
pl_flush_to_eoj(pl_interp_implementation_t * impl,  /* interp instance to flush for */
182
                stream_cursor_read         * cursor)/* data to process */
183
3.43k
{
184
3.43k
    return impl->proc_flush_to_eoj(impl, cursor);
185
3.43k
}
186
187
/* Parser action for end-of-file (also resets after unexpected EOF) */
188
int                             /* ret 0 or +ve if ok, else -ve error code */
189
pl_process_eof(pl_interp_implementation_t * impl)   /* interp instance to process data job in */
190
8.56k
{
191
8.56k
    return impl->proc_process_eof(impl);
192
8.56k
}
193
194
/* Report any errors after running a job */
195
int                             /* ret 0 ok, else -ve error code */
196
pl_report_errors(pl_interp_implementation_t * impl,          /* interp instance to wrap up job in */
197
                 int                          code,          /* prev termination status */
198
                 long                         file_position, /* file position of error, -1 if unknown */
199
                 bool                         force_to_cout) /* force errors to cout */
200
2.41k
{
201
2.41k
    return impl->proc_report_errors
202
2.41k
        (impl, code, file_position, force_to_cout);
203
2.41k
}
204
205
/* Wrap up interp instance after a "job" */
206
int                             /* ret 0 ok, else -ve error code */
207
pl_dnit_job(pl_interp_implementation_t * impl)     /* interp instance to wrap up job in */
208
39.8k
{
209
39.8k
    return impl->proc_dnit_job(impl);
210
39.8k
}
211
212
/* Deallocate a interpreter instance */
213
int                             /* ret 0 ok, else -ve error code */
214
pl_deallocate_interp_instance(pl_interp_implementation_t * impl)   /* instance to dealloc */
215
113k
{
216
113k
    if (impl->interp_client_data == NULL)
217
0
        return 0;
218
113k
    return impl->proc_deallocate_interp_instance(impl);
219
113k
}
220
221
int pl_reset(pl_interp_implementation_t *impl, pl_interp_reset_reason reason)
222
0
{
223
0
    if (impl->reset == NULL)
224
0
        return 0;
225
0
    return impl->reset(impl, reason);
226
0
}