]> git.ipfire.org Git - thirdparty/cups.git/blob - cups/emit.c
Y2k copyright changes.
[thirdparty/cups.git] / cups / emit.c
1 /*
2 * "$Id: emit.c,v 1.15 2000/01/04 13:45:34 mike Exp $"
3 *
4 * PPD code emission routines for the Common UNIX Printing System (CUPS).
5 *
6 * Copyright 1997-2000 by Easy Software Products, all rights reserved.
7 *
8 * These coded instructions, statements, and computer programs are the
9 * property of Easy Software Products and are protected by Federal
10 * copyright law. Distribution and use rights are outlined in the file
11 * "LICENSE.txt" which should have been included with this file. If this
12 * file is missing or damaged please contact Easy Software Products
13 * at:
14 *
15 * Attn: CUPS Licensing Information
16 * Easy Software Products
17 * 44141 Airport View Drive, Suite 204
18 * Hollywood, Maryland 20636-3111 USA
19 *
20 * Voice: (301) 373-9603
21 * EMail: cups-info@cups.org
22 * WWW: http://www.cups.org
23 *
24 * PostScript is a trademark of Adobe Systems, Inc.
25 *
26 * Contents:
27 *
28 * ppdEmit() - Emit code for marked options to a file.
29 * ppdEmitFd() - Emit code for marked options to a file.
30 */
31
32 /*
33 * Include necessary headers...
34 */
35
36 #include "ppd.h"
37 #include <stdlib.h>
38 #include "string.h"
39
40 #if defined(WIN32) || defined(__EMX__)
41 # include <io.h>
42 #else
43 # include <unistd.h>
44 #endif /* WIN32 || __EMX__ */
45
46
47 /*
48 * Local functions...
49 */
50
51 static int ppd_sort(ppd_choice_t **c1, ppd_choice_t **c2);
52 static int ppd_collect(ppd_file_t *ppd, ppd_section_t section,
53 ppd_choice_t ***choices);
54
55
56 /*
57 * 'ppdEmit()' - Emit code for marked options to a file.
58 */
59
60 int /* O - 0 on success, -1 on failure */
61 ppdEmit(ppd_file_t *ppd, /* I - PPD file record */
62 FILE *fp, /* I - File to write to */
63 ppd_section_t section) /* I - Section to write */
64 {
65 int i, /* Looping var */
66 count; /* Number of choices */
67 ppd_choice_t **choices; /* Choices */
68 ppd_size_t *size; /* Custom page size */
69
70
71 if ((count = ppd_collect(ppd, section, &choices)) == 0)
72 return (0);
73
74 for (i = 0; i < count; i ++)
75 if (section != PPD_ORDER_EXIT && section != PPD_ORDER_JCL)
76 {
77 /*
78 * Send DSC comments with option...
79 */
80
81 if (fprintf(fp, "%%%%BeginFeature: %s %s\n",
82 ((ppd_option_t *)choices[i]->option)->keyword,
83 choices[i]->choice) < 0)
84 {
85 free(choices);
86 return (-1);
87 }
88
89 if (strcasecmp(((ppd_option_t *)choices[i]->option)->keyword, "PageSize") == 0 &&
90 strcasecmp(choices[i]->choice, "Custom") == 0)
91 {
92 /*
93 * Variable size; write out standard size options (this should
94 * eventually be changed to use the parameter positions defined
95 * in the PPD file...)
96 */
97
98 size = ppdPageSize(ppd, "Custom");
99 fprintf(fp, "%.0f %.0f 0 0 0\n", size->width, size->length);
100
101 if (choices[i]->code == NULL)
102 {
103 /*
104 * This can happen with certain buggy PPD files that don't include
105 * a CustomPageSize command sequence... We just use a generic
106 * Level 2 command sequence...
107 */
108
109 fputs("pop pop pop\n", fp);
110 fputs("<</PageSize[5 -2 roll]/ImagingBBox null>>setpagedevice\n", fp);
111 }
112 }
113
114 if (choices[i]->code != NULL && choices[i]->code[0] != '\0')
115 {
116 if (fputs(choices[i]->code, fp) < 0)
117 {
118 free(choices);
119 return (-1);
120 }
121
122 if (choices[i]->code[strlen(choices[i]->code) - 1] != '\n')
123 putc('\n', fp);
124 }
125
126 if (fputs("%%EndFeature\n", fp) < 0)
127 {
128 free(choices);
129 return (-1);
130 }
131 }
132 else if (fputs(choices[i]->code, fp) < 0)
133 {
134 free(choices);
135 return (-1);
136 }
137
138 free(choices);
139 return (0);
140 }
141
142
143 /*
144 * 'ppdEmitFd()' - Emit code for marked options to a file.
145 */
146
147 int /* O - 0 on success, -1 on failure */
148 ppdEmitFd(ppd_file_t *ppd, /* I - PPD file record */
149 int fd, /* I - File to write to */
150 ppd_section_t section) /* I - Section to write */
151 {
152 int i, /* Looping var */
153 count; /* Number of choices */
154 ppd_choice_t **choices; /* Choices */
155 char buf[1024]; /* Output buffer for feature */
156
157
158 if ((count = ppd_collect(ppd, section, &choices)) == 0)
159 return (0);
160
161 for (i = 0; i < count; i ++)
162 if (section != PPD_ORDER_EXIT && section != PPD_ORDER_JCL)
163 {
164 /*
165 * Send DSC comments with option...
166 */
167
168 sprintf(buf, "%%%%BeginFeature: %s %s\n",
169 ((ppd_option_t *)choices[i]->option)->keyword, choices[i]->choice);
170
171 if (write(fd, buf, strlen(buf)) < 1)
172 {
173 free(choices);
174 return (-1);
175 }
176
177 if (write(fd, choices[i]->code, strlen(choices[i]->code)) < 1)
178 {
179 free(choices);
180 return (-1);
181 }
182
183 if (write(fd, "%%EndFeature\n", 13) < 1)
184 {
185 free(choices);
186 return (-1);
187 }
188 }
189 else if (write(fd, choices[i]->code, strlen(choices[i]->code)) < 1)
190 {
191 free(choices);
192 return (-1);
193 }
194
195 free(choices);
196 return (0);
197 }
198
199
200 /*
201 * 'ppd_sort()' - Sort options by ordering numbers...
202 */
203
204 static int /* O - -1 if c1 < c2, 0 if equal, 1 otherwise */
205 ppd_sort(ppd_choice_t **c1, /* I - First choice */
206 ppd_choice_t **c2) /* I - Second choice */
207 {
208 if (((ppd_option_t *)(*c1)->option)->order < ((ppd_option_t *)(*c2)->option)->order)
209 return (-1);
210 else if (((ppd_option_t *)(*c1)->option)->order > ((ppd_option_t *)(*c2)->option)->order)
211 return (1);
212 else
213 return (0);
214 }
215
216
217 /*
218 * 'ppd_collect()' - Collect all marked options that reside in the specified
219 * section.
220 */
221
222 static int /* O - Number of options marked */
223 ppd_collect(ppd_file_t *ppd, /* I - PPD file data */
224 ppd_section_t section, /* I - Section to collect */
225 ppd_choice_t ***choices) /* O - Pointers to choices */
226 {
227 int i, j, k, m; /* Looping vars */
228 ppd_group_t *g, /* Current group */
229 *sg; /* Current sub-group */
230 ppd_option_t *o; /* Current option */
231 ppd_choice_t *c; /* Current choice */
232 int count; /* Number of choices collected */
233 ppd_choice_t **collect; /* Collected choices */
234
235
236 if (ppd == NULL)
237 return (0);
238
239 /*
240 * Allocate memory for up to 1000 selected choices...
241 */
242
243 count = 0;
244 collect = calloc(sizeof(ppd_choice_t *), 1000);
245
246 /*
247 * Loop through all options and add choices as needed...
248 */
249
250 for (i = ppd->num_groups, g = ppd->groups; i > 0; i --, g ++)
251 {
252 for (j = g->num_options, o = g->options; j > 0; j --, o ++)
253 if (o->section == section)
254 for (k = o->num_choices, c = o->choices; k > 0; k --, c ++)
255 if (c->marked && count < 1000)
256 {
257 collect[count] = c;
258 count ++;
259 }
260
261 for (j = g->num_subgroups, sg = g->subgroups; j > 0; j --, sg ++)
262 for (k = sg->num_options, o = sg->options; k > 0; k --, o ++)
263 if (o->section == section)
264 for (m = o->num_choices, c = o->choices; m > 0; m --, c ++)
265 if (c->marked && count < 1000)
266 {
267 collect[count] = c;
268 count ++;
269 }
270 }
271
272 /*
273 * If we have more than 1 marked choice, sort them...
274 */
275
276 if (count > 1)
277 qsort(collect, count, sizeof(ppd_choice_t *),
278 (int (*)(const void *, const void *))ppd_sort);
279
280 /*
281 * Return the array and number of choices; if 0, free the array since
282 * it isn't needed.
283 */
284
285 if (count > 0)
286 {
287 *choices = collect;
288 return (count);
289 }
290 else
291 {
292 *choices = NULL;
293 free(collect);
294 return (0);
295 }
296 }
297
298
299 /*
300 * End of "$Id: emit.c,v 1.15 2000/01/04 13:45:34 mike Exp $".
301 */