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