semantics.c

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