1.1 --- a/semantics.c Mon Dec 31 02:33:50 2001 +0000 1.2 +++ b/semantics.c Mon Dec 31 07:25:08 2001 +0000 1.3 @@ -19,12 +19,19 @@ 1.4 int line; /* line number in spec file */ 1.5 1.6 1.7 -int input_page_count; /* total input pages in spec */ 1.8 -int output_page_count; /* total output pages in spec */ 1.9 +input_context_t *first_input_context; 1.10 +input_context_t *last_input_context; 1.11 + 1.12 +input_modifier_type_t current_modifier_context; 1.13 1.14 +input_image_t *first_input_image; 1.15 +input_image_t *last_input_image; 1.16 1.17 -input_context_t *current_input_context; 1.18 -input_modifier_type_t current_modifier_context; 1.19 +output_context_t *first_output_context; 1.20 +output_context_t *last_output_context; 1.21 + 1.22 +output_page_t *first_output_page; 1.23 +output_page_t *last_output_page; 1.24 1.25 1.26 void input_push_context (void) 1.27 @@ -34,31 +41,34 @@ 1.28 new_input_context = malloc (sizeof (input_context_t)); 1.29 if (! new_input_context) 1.30 { 1.31 - fprintf (stderr, "failed to calloc an input context\n"); 1.32 + fprintf (stderr, "failed to malloc an input context\n"); 1.33 return; 1.34 } 1.35 1.36 - if (current_input_context) 1.37 + if (last_input_context) 1.38 { 1.39 - memcpy (new_input_context, current_input_context, sizeof (input_context_t)); 1.40 - new_input_context->page_count = 0; 1.41 + memcpy (new_input_context, last_input_context, sizeof (input_context_t)); 1.42 + new_input_context->image_count = 0; 1.43 } 1.44 else 1.45 - memset (new_input_context, 0, sizeof (input_context_t)); 1.46 + { 1.47 + memset (new_input_context, 0, sizeof (input_context_t)); 1.48 + first_input_context = new_input_context; 1.49 + } 1.50 1.51 - new_input_context->parent_input_context = current_input_context; 1.52 - current_input_context = new_input_context; 1.53 + new_input_context->parent = last_input_context; 1.54 + last_input_context = new_input_context; 1.55 }; 1.56 1.57 void input_pop_context (void) 1.58 { 1.59 - if (! current_input_context) 1.60 + if (! last_input_context) 1.61 { 1.62 fprintf (stderr, "failed to pop an input context\n"); 1.63 return; 1.64 } 1.65 1.66 - current_input_context = current_input_context->parent_input_context; 1.67 + last_input_context = last_input_context->parent; 1.68 }; 1.69 1.70 void input_set_modifier_context (input_modifier_type_t type) 1.71 @@ -77,46 +87,218 @@ 1.72 #endif /* SEMANTIC_DEBUG */ 1.73 } 1.74 1.75 +void input_clone (void) 1.76 +{ 1.77 + input_context_t *new_input_context; 1.78 + 1.79 + if (! last_input_context->image_count) 1.80 + return; 1.81 + 1.82 + new_input_context = malloc (sizeof (input_context_t)); 1.83 + if (! new_input_context) 1.84 + { 1.85 + fprintf (stderr, "failed to malloc an input context\n"); 1.86 + return; 1.87 + } 1.88 + 1.89 + memcpy (new_input_context, last_input_context, sizeof (input_context_t)); 1.90 + new_input_context->image_count = 0; 1.91 + last_input_context->next = new_input_context; 1.92 +} 1.93 + 1.94 void input_set_file (char *name) 1.95 { 1.96 + input_clone (); 1.97 + last_input_context->input_file = name; 1.98 }; 1.99 1.100 void input_set_rotation (int rotation) 1.101 { 1.102 - current_input_context->modifiers [current_modifier_context].has_rotation = 1; 1.103 - current_input_context->modifiers [current_modifier_context].rotation = rotation; 1.104 + last_input_context->modifiers [current_modifier_context].has_rotation = 1; 1.105 + last_input_context->modifiers [current_modifier_context].rotation = rotation; 1.106 SDBG(("rotation %d\n", rotation)); 1.107 } 1.108 1.109 -void input_images (int first, int last) 1.110 +void increment_input_image_count (int count) 1.111 { 1.112 - input_page_count += ((last - first) + 1); 1.113 + input_context_t *context; 1.114 + 1.115 + for (context = last_input_context; context; context = context->parent) 1.116 + context->image_count += count; 1.117 +} 1.118 + 1.119 +void input_images (range_t range) 1.120 +{ 1.121 + input_image_t *new_image; 1.122 + int count = ((range.last - range.first) + 1); 1.123 + 1.124 #ifdef SEMANTIC_DEBUG 1.125 - if (first == last) 1.126 - SDBG(("image %d\n", first)); 1.127 + if (range.first == range.last) 1.128 + SDBG(("image %d\n", range.first)); 1.129 else 1.130 - SDBG(("images %d..%d\n", first, last)); 1.131 + SDBG(("images %d..%d\n", range.first, range.last)); 1.132 #endif /* SEMANTIC_DEBUG */ 1.133 + 1.134 + new_image = calloc (1, sizeof (input_image_t)); 1.135 + if (! new_image) 1.136 + { 1.137 + fprintf (stderr, "failed to malloc an input image struct\n"); 1.138 + return; 1.139 + } 1.140 + if (first_input_image) 1.141 + { 1.142 + last_input_image->next = new_image; 1.143 + last_input_image = new_image; 1.144 + } 1.145 + else 1.146 + { 1.147 + first_input_image = last_input_image = new_image; 1.148 + } 1.149 + new_image->range = range; 1.150 + new_image->input_context = last_input_context; 1.151 + increment_input_image_count (count); 1.152 } 1.153 1.154 1.155 void output_push_context (void) 1.156 { 1.157 + output_context_t *new_output_context; 1.158 + 1.159 + new_output_context = malloc (sizeof (output_context_t)); 1.160 + if (! new_output_context) 1.161 + { 1.162 + fprintf (stderr, "failed to malloc an output context\n"); 1.163 + return; 1.164 + } 1.165 + 1.166 + if (last_output_context) 1.167 + { 1.168 + memcpy (new_output_context, last_output_context, sizeof (output_context_t)); 1.169 + new_output_context->page_count = 0; 1.170 + } 1.171 + else 1.172 + { 1.173 + memset (new_output_context, 0, sizeof (output_context_t)); 1.174 + first_output_context = new_output_context; 1.175 + } 1.176 + 1.177 + new_output_context->parent = last_output_context; 1.178 + last_output_context = new_output_context; 1.179 }; 1.180 1.181 +void output_pop_context (void) 1.182 +{ 1.183 + if (! last_output_context) 1.184 + { 1.185 + fprintf (stderr, "failed to pop an output context\n"); 1.186 + return; 1.187 + } 1.188 + 1.189 + last_output_context = last_output_context->parent; 1.190 +}; 1.191 + 1.192 +void output_clone (void) 1.193 +{ 1.194 + output_context_t *new_output_context; 1.195 + 1.196 + if (! last_output_context->page_count) 1.197 + return; 1.198 + 1.199 + new_output_context = malloc (sizeof (output_context_t)); 1.200 + if (! new_output_context) 1.201 + { 1.202 + fprintf (stderr, "failed to malloc an output context\n"); 1.203 + return; 1.204 + } 1.205 + 1.206 + memcpy (new_output_context, last_output_context, sizeof (output_context_t)); 1.207 + new_output_context->page_count = 0; 1.208 + last_output_context->next = new_output_context; 1.209 +} 1.210 + 1.211 void output_set_file (char *name) 1.212 { 1.213 + output_clone (); 1.214 + last_output_context->output_file = name; 1.215 }; 1.216 1.217 -void output_pages (int first, int last) 1.218 +void output_set_bookmark (char *name) 1.219 { 1.220 - output_page_count += ((last - first) + 1); 1.221 + bookmark_t *new_bookmark; 1.222 + 1.223 + /* As the language is defined (parser.y), a bookmark can only appear 1.224 + at the beginning of a context! */ 1.225 + if (last_output_context->page_count) 1.226 + { 1.227 + fprintf (stderr, "internal error, bookmark not at beginning of context\n"); 1.228 + exit (2); 1.229 + } 1.230 + 1.231 + new_bookmark = calloc (1, sizeof (bookmark_t)); 1.232 + if (! new_bookmark) 1.233 + { 1.234 + fprintf (stderr, "failed to calloc a bookmark\n"); 1.235 + return; 1.236 + } 1.237 + 1.238 + new_bookmark->name = name; 1.239 + if (last_output_context->first_bookmark) 1.240 + last_output_context->last_bookmark->next = new_bookmark; 1.241 + else 1.242 + last_output_context->first_bookmark = new_bookmark; 1.243 + last_output_context->last_bookmark = new_bookmark; 1.244 +} 1.245 + 1.246 +void output_set_page_number_format (char *format) 1.247 +{ 1.248 + output_clone (); 1.249 + last_output_context->page_number_format = format; 1.250 +} 1.251 + 1.252 +void increment_output_page_count (int count) 1.253 +{ 1.254 + output_context_t *context; 1.255 + 1.256 + for (context = last_output_context; context; context = context->parent) 1.257 + context->page_count += count; 1.258 +} 1.259 + 1.260 +void output_pages (range_t range) 1.261 +{ 1.262 + output_page_t *new_page; 1.263 + int count = ((range.last - range.first) + 1); 1.264 + 1.265 #ifdef SEMANTIC_DEBUG 1.266 - if (first == last) 1.267 - SDBG(("page %d\n", first)); 1.268 + if (range.first == range.last) 1.269 + SDBG(("page %d\n", range.first)); 1.270 else 1.271 - SDBG(("pages %d..%d\n", first, last)); 1.272 + SDBG(("pages %d..%d\n", range.first, range.last)); 1.273 #endif /* SEMANTIC_DEBUG */ 1.274 + 1.275 + new_page = calloc (1, sizeof (output_page_t)); 1.276 + if (! new_page) 1.277 + { 1.278 + fprintf (stderr, "failed to malloc an output page struct\n"); 1.279 + return; 1.280 + } 1.281 + if (first_output_page) 1.282 + { 1.283 + last_output_page->next = new_page; 1.284 + last_output_page = new_page; 1.285 + } 1.286 + else 1.287 + { 1.288 + first_output_page = last_output_page = new_page; 1.289 + } 1.290 + new_page->range = range; 1.291 + new_page->output_context = last_output_context; 1.292 + 1.293 + /* transfer bookmarks from context to page */ 1.294 + new_page->bookmark_list = last_output_context->first_bookmark; 1.295 + last_output_context->first_bookmark = NULL; 1.296 + last_output_context->last_bookmark = NULL; 1.297 + 1.298 + increment_output_page_count (count); 1.299 } 1.300 1.301 1.302 @@ -126,6 +308,88 @@ 1.303 } 1.304 1.305 1.306 +char *get_input_file (input_context_t *context) 1.307 +{ 1.308 + for (; context; context = context->parent) 1.309 + if (context->input_file) 1.310 + return (context->input_file); 1.311 + fprintf (stderr, "no input file name found\n"); 1.312 + exit (2); 1.313 +} 1.314 + 1.315 +int get_input_rotation (input_context_t *context, input_modifier_type_t type) 1.316 +{ 1.317 + for (; context; context = context->parent) 1.318 + { 1.319 + if (context->modifiers [type].has_rotation) 1.320 + return (context->modifiers [type].rotation); 1.321 + if (context->modifiers [INPUT_MODIFIER_ALL].has_rotation) 1.322 + return (context->modifiers [INPUT_MODIFIER_ALL].rotation); 1.323 + } 1.324 + return (0); /* default */ 1.325 +} 1.326 + 1.327 +char *get_output_file (output_context_t *context) 1.328 +{ 1.329 + for (; context; context = context->parent) 1.330 + if (context->output_file) 1.331 + return (context->output_file); 1.332 + fprintf (stderr, "no output file name found\n"); 1.333 + exit (2); 1.334 +} 1.335 + 1.336 +char *get_output_page_number_format (output_context_t *context) 1.337 +{ 1.338 + for (; context; context = context->parent) 1.339 + if (context->page_number_format) 1.340 + return (context->page_number_format); 1.341 + return (NULL); /* default */ 1.342 +} 1.343 + 1.344 + 1.345 +#ifdef SEMANTIC_DEBUG 1.346 +void dump_input_tree (void) 1.347 +{ 1.348 + input_image_t *image; 1.349 + int i; 1.350 + 1.351 + printf ("input images:\n"); 1.352 + for (image = first_input_image; image; image = image->next) 1.353 + for (i = image->range.first; i <= image->range.last; i++) 1.354 + { 1.355 + input_modifier_type_t parity = (i % 2) ? INPUT_MODIFIER_ODD : INPUT_MODIFIER_EVEN; 1.356 + printf ("file '%s' image %d, rotation %d\n", 1.357 + get_input_file (image->input_context), 1.358 + i, 1.359 + get_input_rotation (image->input_context, parity)); 1.360 + } 1.361 +} 1.362 + 1.363 +void dump_output_tree (void) 1.364 +{ 1.365 + int i; 1.366 + output_page_t *page; 1.367 + bookmark_t *bookmark; 1.368 + 1.369 + printf ("output pages:\n"); 1.370 + for (page = first_output_page; page; page = page->next) 1.371 + { 1.372 + if (page->bookmark_list) 1.373 + { 1.374 + for (bookmark = page->bookmark_list; bookmark; bookmark = bookmark->next) 1.375 + printf ("bookmark '%s' ", bookmark->name); 1.376 + printf ("\n"); 1.377 + } 1.378 + for (i = page->range.first; i <= page->range.last; i++) 1.379 + { 1.380 + printf ("file '%s' ", get_output_file (page->output_context)); 1.381 + printf ("format '%s' ", get_output_page_number_format (page->output_context)); 1.382 + printf ("page %d\n", i); 1.383 + } 1.384 + } 1.385 +} 1.386 +#endif /* SEMANTIC_DEBUG */ 1.387 + 1.388 boolean parse_spec_file (char *fn) 1.389 { 1.390 boolean result = 0; 1.391 @@ -139,22 +403,31 @@ 1.392 1.393 line = 1; 1.394 1.395 - input_push_context (); /* create initial input context */ 1.396 + input_push_context (); /* create root input context */ 1.397 + input_push_context (); /* create inital input context */ 1.398 + 1.399 + output_push_context (); /* create root output context */ 1.400 output_push_context (); /* create initial output context */ 1.401 1.402 yyparse (); 1.403 1.404 - if (input_page_count != output_page_count) 1.405 + if (first_input_context->image_count != first_output_context->page_count) 1.406 { 1.407 - fprintf (stderr, "input page count %d != output page count %d\n", 1.408 - input_page_count, output_page_count); 1.409 + fprintf (stderr, "input image count %d != output page count %d\n", 1.410 + first_input_context->image_count, 1.411 + first_output_context->page_count); 1.412 goto fail; 1.413 } 1.414 1.415 - fprintf (stderr, "%d pages specified\n", input_page_count); 1.416 + fprintf (stderr, "%d pages specified\n", first_input_context->image_count); 1.417 1.418 result = 1; 1.419 1.420 +#ifdef SEMANTIC_DEBUG 1.421 + dump_input_tree (); 1.422 + dump_output_tree (); 1.423 +#endif /* SEMANTIC_DEBUG */ 1.424 + 1.425 fail: 1.426 if (yyin) 1.427 fclose (yyin);