semantics.c

changeset 20
a1cd8cb9d09e
parent 19
e9bf1ed4f331
child 21
2bb19d98d928
     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);