semantics.c

Mon, 31 Dec 2001 07:44:23 +0000

author
eric
date
Mon, 31 Dec 2001 07:44:23 +0000
changeset 21
2bb19d98d928
parent 20
a1cd8cb9d09e
child 22
198616589af5
permissions
-rw-r--r--

*** empty log message ***

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