Mon, 31 Dec 2001 07:44:23 +0000
*** empty log message ***
1 #include <stdlib.h>
2 #include <string.h>
3 #include <stdio.h>
5 #include "type.h"
6 #include "semantics.h"
7 #include "parser.tab.h"
10 #define SEMANTIC_DEBUG
11 #ifdef SEMANTIC_DEBUG
12 #define SDBG(x) printf x
13 #else
14 #define SDBG(x)
15 #endif
18 FILE *yyin;
19 int line; /* line number in spec file */
22 input_context_t *first_input_context;
23 input_context_t *last_input_context;
25 input_modifier_type_t current_modifier_context;
27 input_image_t *first_input_image;
28 input_image_t *last_input_image;
30 output_context_t *first_output_context;
31 output_context_t *last_output_context;
33 output_page_t *first_output_page;
34 output_page_t *last_output_page;
37 void input_push_context (void)
38 {
39 input_context_t *new_input_context;
41 new_input_context = malloc (sizeof (input_context_t));
42 if (! new_input_context)
43 {
44 fprintf (stderr, "failed to malloc an input context\n");
45 return;
46 }
48 if (last_input_context)
49 {
50 memcpy (new_input_context, last_input_context, sizeof (input_context_t));
51 new_input_context->image_count = 0;
52 }
53 else
54 {
55 memset (new_input_context, 0, sizeof (input_context_t));
56 first_input_context = new_input_context;
57 }
59 new_input_context->parent = last_input_context;
60 last_input_context = new_input_context;
61 };
63 void input_pop_context (void)
64 {
65 if (! last_input_context)
66 {
67 fprintf (stderr, "failed to pop an input context\n");
68 return;
69 }
71 last_input_context = last_input_context->parent;
72 };
74 void input_set_modifier_context (input_modifier_type_t type)
75 {
76 current_modifier_context = type;
77 #ifdef SEMANTIC_DEBUG
78 SDBG(("modifier type "));
79 switch (type)
80 {
81 case INPUT_MODIFIER_ALL: SDBG(("all")); break;
82 case INPUT_MODIFIER_ODD: SDBG(("odd")); break;
83 case INPUT_MODIFIER_EVEN: SDBG(("even")); break;
84 default: SDBG(("unknown %d", type));
85 }
86 SDBG(("\n"));
87 #endif /* SEMANTIC_DEBUG */
88 }
90 void input_clone (void)
91 {
92 input_context_t *new_input_context;
94 if (! last_input_context->image_count)
95 return;
97 new_input_context = malloc (sizeof (input_context_t));
98 if (! new_input_context)
99 {
100 fprintf (stderr, "failed to malloc an input context\n");
101 return;
102 }
104 memcpy (new_input_context, last_input_context, sizeof (input_context_t));
105 new_input_context->image_count = 0;
106 last_input_context->next = new_input_context;
107 }
109 void input_set_file (char *name)
110 {
111 input_clone ();
112 last_input_context->input_file = name;
113 };
115 void input_set_rotation (int rotation)
116 {
117 last_input_context->modifiers [current_modifier_context].has_rotation = 1;
118 last_input_context->modifiers [current_modifier_context].rotation = rotation;
119 SDBG(("rotation %d\n", rotation));
120 }
122 void increment_input_image_count (int count)
123 {
124 input_context_t *context;
126 for (context = last_input_context; context; context = context->parent)
127 context->image_count += count;
128 }
130 void input_images (range_t range)
131 {
132 input_image_t *new_image;
133 int count = ((range.last - range.first) + 1);
135 #ifdef SEMANTIC_DEBUG
136 if (range.first == range.last)
137 SDBG(("image %d\n", range.first));
138 else
139 SDBG(("images %d..%d\n", range.first, range.last));
140 #endif /* SEMANTIC_DEBUG */
142 new_image = calloc (1, sizeof (input_image_t));
143 if (! new_image)
144 {
145 fprintf (stderr, "failed to malloc an input image struct\n");
146 return;
147 }
148 if (first_input_image)
149 {
150 last_input_image->next = new_image;
151 last_input_image = new_image;
152 }
153 else
154 {
155 first_input_image = last_input_image = new_image;
156 }
157 new_image->range = range;
158 new_image->input_context = last_input_context;
159 increment_input_image_count (count);
160 }
163 void output_push_context (void)
164 {
165 output_context_t *new_output_context;
167 new_output_context = malloc (sizeof (output_context_t));
168 if (! new_output_context)
169 {
170 fprintf (stderr, "failed to malloc an output context\n");
171 return;
172 }
174 if (last_output_context)
175 {
176 memcpy (new_output_context, last_output_context, sizeof (output_context_t));
177 new_output_context->page_count = 0;
178 new_output_context->first_bookmark = NULL;
179 new_output_context->last_bookmark = NULL;
180 }
181 else
182 {
183 memset (new_output_context, 0, sizeof (output_context_t));
184 first_output_context = new_output_context;
185 }
187 new_output_context->parent = last_output_context;
188 last_output_context = new_output_context;
189 };
191 void output_pop_context (void)
192 {
193 if (! last_output_context)
194 {
195 fprintf (stderr, "failed to pop an output context\n");
196 return;
197 }
199 last_output_context = last_output_context->parent;
200 };
202 void output_clone (void)
203 {
204 output_context_t *new_output_context;
206 if (! last_output_context->page_count)
207 return;
209 new_output_context = malloc (sizeof (output_context_t));
210 if (! new_output_context)
211 {
212 fprintf (stderr, "failed to malloc an output context\n");
213 return;
214 }
216 memcpy (new_output_context, last_output_context, sizeof (output_context_t));
217 new_output_context->page_count = 0;
218 last_output_context->next = new_output_context;
219 }
221 void output_set_file (char *name)
222 {
223 output_clone ();
224 last_output_context->output_file = name;
225 };
227 void output_set_bookmark (char *name)
228 {
229 bookmark_t *new_bookmark;
231 /* As the language is defined (parser.y), a bookmark can only appear
232 at the beginning of a context! */
233 if (last_output_context->page_count)
234 {
235 fprintf (stderr, "internal error, bookmark not at beginning of context\n");
236 exit (2);
237 }
239 new_bookmark = calloc (1, sizeof (bookmark_t));
240 if (! new_bookmark)
241 {
242 fprintf (stderr, "failed to calloc a bookmark\n");
243 return;
244 }
246 new_bookmark->name = name;
247 if (last_output_context->first_bookmark)
248 last_output_context->last_bookmark->next = new_bookmark;
249 else
250 last_output_context->first_bookmark = new_bookmark;
251 last_output_context->last_bookmark = new_bookmark;
252 }
254 void output_set_page_number_format (char *format)
255 {
256 output_clone ();
257 last_output_context->page_number_format = format;
258 }
260 void increment_output_page_count (int count)
261 {
262 output_context_t *context;
264 for (context = last_output_context; context; context = context->parent)
265 context->page_count += count;
266 }
269 void output_pages (range_t range)
270 {
271 output_page_t *new_page;
272 output_context_t *context;
273 int count = ((range.last - range.first) + 1);
275 #ifdef SEMANTIC_DEBUG
276 if (range.first == range.last)
277 SDBG(("page %d\n", range.first));
278 else
279 SDBG(("pages %d..%d\n", range.first, range.last));
280 #endif /* SEMANTIC_DEBUG */
282 new_page = calloc (1, sizeof (output_page_t));
283 if (! new_page)
284 {
285 fprintf (stderr, "failed to malloc an output page struct\n");
286 return;
287 }
288 if (first_output_page)
289 {
290 last_output_page->next = new_page;
291 last_output_page = new_page;
292 }
293 else
294 {
295 first_output_page = last_output_page = new_page;
296 }
297 new_page->range = range;
298 new_page->output_context = last_output_context;
300 /* transfer bookmarks from context(s) to page */
301 for (context = last_output_context; context; context = context->parent)
302 if (context->first_bookmark)
303 {
304 context->last_bookmark->next = new_page->bookmark_list;
305 new_page->bookmark_list = context->first_bookmark;
306 context->first_bookmark = NULL;
307 context->last_bookmark = NULL;
308 }
310 increment_output_page_count (count);
311 }
314 void yyerror (char *s)
315 {
316 fprintf (stderr, "%d: %s\n", line, s);
317 }
320 char *get_input_file (input_context_t *context)
321 {
322 for (; context; context = context->parent)
323 if (context->input_file)
324 return (context->input_file);
325 fprintf (stderr, "no input file name found\n");
326 exit (2);
327 }
329 int get_input_rotation (input_context_t *context, input_modifier_type_t type)
330 {
331 for (; context; context = context->parent)
332 {
333 if (context->modifiers [type].has_rotation)
334 return (context->modifiers [type].rotation);
335 if (context->modifiers [INPUT_MODIFIER_ALL].has_rotation)
336 return (context->modifiers [INPUT_MODIFIER_ALL].rotation);
337 }
338 return (0); /* default */
339 }
341 char *get_output_file (output_context_t *context)
342 {
343 for (; context; context = context->parent)
344 if (context->output_file)
345 return (context->output_file);
346 fprintf (stderr, "no output file name found\n");
347 exit (2);
348 }
350 char *get_output_page_number_format (output_context_t *context)
351 {
352 for (; context; context = context->parent)
353 if (context->page_number_format)
354 return (context->page_number_format);
355 return (NULL); /* default */
356 }
359 #ifdef SEMANTIC_DEBUG
360 void dump_input_tree (void)
361 {
362 input_image_t *image;
363 int i;
365 printf ("input images:\n");
366 for (image = first_input_image; image; image = image->next)
367 for (i = image->range.first; i <= image->range.last; i++)
368 {
369 input_modifier_type_t parity = (i % 2) ? INPUT_MODIFIER_ODD : INPUT_MODIFIER_EVEN;
370 printf ("file '%s' image %d, rotation %d\n",
371 get_input_file (image->input_context),
372 i,
373 get_input_rotation (image->input_context, parity));
374 }
375 }
377 void dump_output_tree (void)
378 {
379 int i;
380 output_page_t *page;
381 bookmark_t *bookmark;
383 printf ("output pages:\n");
384 for (page = first_output_page; page; page = page->next)
385 {
386 if (page->bookmark_list)
387 {
388 for (bookmark = page->bookmark_list; bookmark; bookmark = bookmark->next)
389 printf ("bookmark '%s' ", bookmark->name);
390 printf ("\n");
391 }
392 for (i = page->range.first; i <= page->range.last; i++)
393 {
394 printf ("file '%s' ", get_output_file (page->output_context));
395 printf ("format '%s' ", get_output_page_number_format (page->output_context));
396 printf ("page %d\n", i);
397 }
398 }
399 }
400 #endif /* SEMANTIC_DEBUG */
402 boolean parse_spec_file (char *fn)
403 {
404 boolean result = 0;
406 yyin = fopen (fn, "r");
407 if (! yyin)
408 {
409 fprintf (stderr, "can't open spec file '%s'\n", fn);
410 goto fail;
411 }
413 line = 1;
415 input_push_context (); /* create root input context */
416 input_push_context (); /* create inital input context */
418 output_push_context (); /* create root output context */
419 output_push_context (); /* create initial output context */
421 yyparse ();
423 if (first_input_context->image_count != first_output_context->page_count)
424 {
425 fprintf (stderr, "input image count %d != output page count %d\n",
426 first_input_context->image_count,
427 first_output_context->page_count);
428 goto fail;
429 }
431 fprintf (stderr, "%d pages specified\n", first_input_context->image_count);
433 result = 1;
435 #ifdef SEMANTIC_DEBUG
436 dump_input_tree ();
437 dump_output_tree ();
438 #endif /* SEMANTIC_DEBUG */
440 fail:
441 if (yyin)
442 fclose (yyin);
444 return (result);
445 }