semantics.c

Mon, 31 Dec 2001 08:12:58 +0000

author
eric
date
Mon, 31 Dec 2001 08:12:58 +0000
changeset 22
198616589af5
parent 21
2bb19d98d928
child 24
6575fcfbdb1b
permissions
-rw-r--r--

moved most type declarations from semantics.h to semantics.c.
made various functions static.

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