*** empty log message ***

Mon, 31 Dec 2001 07:25:08 +0000

author
eric
date
Mon, 31 Dec 2001 07:25:08 +0000
changeset 20
a1cd8cb9d09e
parent 19
e9bf1ed4f331
child 21
2bb19d98d928

*** empty log message ***

Makefile file | annotate | diff | revisions
parser.y file | annotate | diff | revisions
scanner.l file | annotate | diff | revisions
semantics.c file | annotate | diff | revisions
semantics.h file | annotate | diff | revisions
     1.1 --- a/Makefile	Mon Dec 31 02:33:50 2001 +0000
     1.2 +++ b/Makefile	Mon Dec 31 07:25:08 2001 +0000
     1.3 @@ -1,6 +1,6 @@
     1.4  # tiff2pdf: build a PDF file out of one or more TIFF Class F Group 4 files
     1.5  # Makefile
     1.6 -# $Id: Makefile,v 1.6 2001/12/29 20:16:46 eric Exp $
     1.7 +# $Id: Makefile,v 1.7 2001/12/30 23:24:50 eric Exp $
     1.8  # Copyright 2001 Eric Smith <eric@brouhaha.com>
     1.9  #
    1.10  # This program is free software; you can redistribute it and/or modify
    1.11 @@ -24,8 +24,8 @@
    1.12  YACC = bison
    1.13  YFLAGS = -d -v
    1.14  
    1.15 -SRCS = bitblt.c bitblt_test.c tiff2pdf.c
    1.16 -HDRS = type.h bitblt.h tiff2pdf.h
    1.17 +SRCS = bitblt.c bitblt_test.c tiff2pdf.c semantics.c
    1.18 +HDRS = type.h bitblt.h tiff2pdf.h semantics.h
    1.19  MISC = Makefile scanner.l parser.y
    1.20  
    1.21  TARGETS = tiff2pdf bitblt_test
    1.22 @@ -34,7 +34,7 @@
    1.23  AUTO_HDRS = parser.tab.h
    1.24  AUTO_MISC = parser.output
    1.25  
    1.26 -tiff2pdf: tiff2pdf.o scanner.o parser.tab.o
    1.27 +tiff2pdf: tiff2pdf.o scanner.o semantics.o parser.tab.o
    1.28  
    1.29  bitblt_test: bitblt_test.o bitblt.o
    1.30  
    1.31 @@ -42,6 +42,12 @@
    1.32  clean:
    1.33  	rm -f *.o *.d $(TARGETS) $(AUTO_SRCS) $(AUTO_HDRS) $(AUTO_MISC) 
    1.34  
    1.35 +wc:
    1.36 +	wc -l $(SRCS) $(HDRS) $(MISC)
    1.37 +
    1.38 +ls-lt:
    1.39 +	ls -lt $(SRCS) $(HDRS) $(MISC)
    1.40 +
    1.41  
    1.42  %.tab.c %.tab.h %.output: %.y
    1.43  	$(YACC) $(YFLAGS) $<
     2.1 --- a/parser.y	Mon Dec 31 02:33:50 2001 +0000
     2.2 +++ b/parser.y	Mon Dec 31 07:25:08 2001 +0000
     2.3 @@ -38,6 +38,7 @@
     2.4  %token RESOLUTION
     2.5  %token INPUT
     2.6  
     2.7 +%token FORMAT
     2.8  %token PAGE
     2.9  %token PAGES
    2.10  %token BOOKMARK
    2.11 @@ -69,21 +70,21 @@
    2.12  	| INTEGER { $$.first = $1; $$.last = $1; } ;
    2.13  
    2.14  image_ranges:
    2.15 -	range { input_images ($1.first, $1.last); }
    2.16 -	| image_ranges ',' range { input_images ($3.first, $3.last); } ;
    2.17 +	range { input_images ($1); }
    2.18 +	| image_ranges ',' range { input_images ($3); } ;
    2.19  
    2.20  
    2.21  input_file_clause:
    2.22  	FILE_KEYWORD STRING  ';'  { input_set_file ($2) } ;
    2.23  
    2.24  image_clause:
    2.25 -	IMAGE INTEGER ';' { input_images ($2, $2); } ;
    2.26 +	IMAGE INTEGER ';' { range_t range = { $2, $2 }; input_images (range); } ;
    2.27  
    2.28  images_clause:
    2.29  	IMAGES image_ranges ';' ;
    2.30  
    2.31  rotate_clause:
    2.32 -	ROTATE INTEGER ';' { input_set_rotation ($2) };
    2.33 +	ROTATE INTEGER ';' { input_set_rotation ($2) } ;
    2.34  
    2.35  unit:
    2.36  	/* empty */  /* default to INCH */ { $$ = 25.4; }
    2.37 @@ -125,7 +126,7 @@
    2.38  	ODD { input_set_modifier_context (INPUT_MODIFIER_ODD); }
    2.39            modifier_clause_list ';'
    2.40            { input_set_modifier_context (INPUT_MODIFIER_ALL); }
    2.41 -	| EVEN { input_set_modifier_context (INPUT_MODIFIER_ODD); }
    2.42 +	| EVEN { input_set_modifier_context (INPUT_MODIFIER_EVEN); }
    2.43  	  modifier_clause_list ';'
    2.44            { input_set_modifier_context (INPUT_MODIFIER_ALL); } ;
    2.45  
    2.46 @@ -150,24 +151,34 @@
    2.47  output_file_clause:
    2.48  	FILE_KEYWORD STRING  ';' { output_set_file ($2) } ;
    2.49  
    2.50 +format_clause:
    2.51 +	FORMAT STRING ';' { output_set_page_number_format ($2) } ;
    2.52 +
    2.53  page_ranges:
    2.54 -	range { output_pages ($1.first, $1.last); }
    2.55 -	| page_ranges ',' range { output_pages ($3.first, $3.last); } ;
    2.56 +	range { output_pages ($1); }
    2.57 +	| page_ranges ',' range { output_pages ($3); } ;
    2.58  
    2.59  page_clause:
    2.60 -	PAGE INTEGER ';' { output_pages ($2, $2); }
    2.61 -	| PAGE STRING ',' INTEGER ';' { output_pages ($4, $4); } ;
    2.62 +	PAGE INTEGER ';' { range_t range = { $2, $2 }; output_pages (range); } ;
    2.63  
    2.64  pages_clause:
    2.65 -	PAGES page_ranges ';'
    2.66 -	| PAGES STRING ',' page_ranges ';' ;
    2.67 +	PAGES page_ranges ';' ;
    2.68 +
    2.69 +bookmark_name:
    2.70 +	STRING { output_set_bookmark ($1); } ;
    2.71 +
    2.72 +bookmark_name_list:
    2.73 +	bookmark_name
    2.74 +	| bookmark_name_list ',' bookmark_name ;
    2.75  
    2.76  bookmark_clause:
    2.77 -	BOOKMARK INTEGER ',' STRING ';'
    2.78 -	| BOOKMARK STRING ';' ;
    2.79 +	BOOKMARK { output_push_context (); }
    2.80 +	bookmark_name_list
    2.81 +	output_clause_list ';' { output_pop_context (); } ;
    2.82  
    2.83  output_clause:
    2.84  	output_file_clause
    2.85 +	| format_clause
    2.86  	| page_clause | pages_clause
    2.87  	| bookmark_clause
    2.88  	| output_clause_list ;
    2.89 @@ -177,7 +188,8 @@
    2.90  	| output_clauses output_clause ;
    2.91  
    2.92  output_clause_list:
    2.93 -	'{' output_clauses '}' ;
    2.94 +	'{' { output_push_context (); }
    2.95 +	output_clauses '}' { output_pop_context (); } ;
    2.96  
    2.97  output_statement:
    2.98  	OUTPUT output_clauses ;
     3.1 --- a/scanner.l	Mon Dec 31 02:33:50 2001 +0000
     3.2 +++ b/scanner.l	Mon Dec 31 07:25:08 2001 +0000
     3.3 @@ -1,5 +1,5 @@
     3.4  /*
     3.5 -$Id: scanner.l,v 1.10 2001/12/30 09:09:08 eric Exp $
     3.6 +$Id: scanner.l,v 1.11 2001/12/30 23:25:08 eric Exp $
     3.7  */
     3.8  
     3.9  %option case-insensitive
    3.10 @@ -54,6 +54,7 @@
    3.11  crop		{ return (CROP); }
    3.12  even		{ return (EVEN); }
    3.13  file		{ return (FILE_KEYWORD); }
    3.14 +format		{ return (FORMAT); }
    3.15  image		{ return (IMAGE); }
    3.16  images		{ return (IMAGES); }
    3.17  inch		{ return (INCH); }
    3.18 @@ -68,7 +69,7 @@
    3.19  rotate		{ return (ROTATE); }
    3.20  size		{ return (SIZE); }
    3.21  
    3.22 -\".*\"		{ 
    3.23 +\"[^\n"]*\"		{ 
    3.24                    int len = strlen (yytext) - 2;
    3.25                    yylval.string = malloc (len + 1);
    3.26                    memcpy (yylval.string, yytext + 1, len);
     4.1 --- a/semantics.c	Mon Dec 31 02:33:50 2001 +0000
     4.2 +++ b/semantics.c	Mon Dec 31 07:25:08 2001 +0000
     4.3 @@ -19,12 +19,19 @@
     4.4  int line;  /* line number in spec file */
     4.5  
     4.6  
     4.7 -int input_page_count;   /* total input pages in spec */
     4.8 -int output_page_count;  /* total output pages in spec */
     4.9 +input_context_t *first_input_context;
    4.10 +input_context_t *last_input_context;
    4.11 +
    4.12 +input_modifier_type_t current_modifier_context;
    4.13  
    4.14 +input_image_t *first_input_image;
    4.15 +input_image_t *last_input_image;
    4.16  
    4.17 -input_context_t *current_input_context;
    4.18 -input_modifier_type_t current_modifier_context;
    4.19 +output_context_t *first_output_context;
    4.20 +output_context_t *last_output_context;
    4.21 +
    4.22 +output_page_t *first_output_page;
    4.23 +output_page_t *last_output_page;
    4.24  
    4.25  
    4.26  void input_push_context (void)
    4.27 @@ -34,31 +41,34 @@
    4.28    new_input_context = malloc (sizeof (input_context_t));
    4.29    if (! new_input_context)
    4.30      {
    4.31 -      fprintf (stderr, "failed to calloc an input context\n");
    4.32 +      fprintf (stderr, "failed to malloc an input context\n");
    4.33        return;
    4.34      }
    4.35  
    4.36 -  if (current_input_context)
    4.37 +  if (last_input_context)
    4.38      {
    4.39 -      memcpy (new_input_context, current_input_context, sizeof (input_context_t));
    4.40 -      new_input_context->page_count = 0;
    4.41 +      memcpy (new_input_context, last_input_context, sizeof (input_context_t));
    4.42 +      new_input_context->image_count = 0;
    4.43      }
    4.44    else
    4.45 -    memset (new_input_context, 0, sizeof (input_context_t));
    4.46 +    {
    4.47 +      memset (new_input_context, 0, sizeof (input_context_t));
    4.48 +      first_input_context = new_input_context;
    4.49 +    }
    4.50  
    4.51 -  new_input_context->parent_input_context = current_input_context;
    4.52 -  current_input_context = new_input_context;
    4.53 +  new_input_context->parent = last_input_context;
    4.54 +  last_input_context = new_input_context;
    4.55  };
    4.56  
    4.57  void input_pop_context (void)
    4.58  {
    4.59 -  if (! current_input_context)
    4.60 +  if (! last_input_context)
    4.61      {
    4.62        fprintf (stderr, "failed to pop an input context\n");
    4.63        return;
    4.64      }
    4.65  
    4.66 -  current_input_context = current_input_context->parent_input_context;
    4.67 +  last_input_context = last_input_context->parent;
    4.68  };
    4.69  
    4.70  void input_set_modifier_context (input_modifier_type_t type)
    4.71 @@ -77,46 +87,218 @@
    4.72  #endif /* SEMANTIC_DEBUG */
    4.73  }
    4.74  
    4.75 +void input_clone (void)
    4.76 +{
    4.77 +  input_context_t *new_input_context;
    4.78 +
    4.79 +  if (! last_input_context->image_count)
    4.80 +    return;
    4.81 +
    4.82 +  new_input_context = malloc (sizeof (input_context_t));
    4.83 +  if (! new_input_context)
    4.84 +    {
    4.85 +      fprintf (stderr, "failed to malloc an input context\n");
    4.86 +      return;
    4.87 +    }
    4.88 +
    4.89 +  memcpy (new_input_context, last_input_context, sizeof (input_context_t));
    4.90 +  new_input_context->image_count = 0;
    4.91 +  last_input_context->next = new_input_context;
    4.92 +}
    4.93 +
    4.94  void input_set_file (char *name)
    4.95  {
    4.96 +  input_clone ();
    4.97 +  last_input_context->input_file = name;
    4.98  };
    4.99  
   4.100  void input_set_rotation (int rotation)
   4.101  {
   4.102 -  current_input_context->modifiers [current_modifier_context].has_rotation = 1;
   4.103 -  current_input_context->modifiers [current_modifier_context].rotation = rotation;
   4.104 +  last_input_context->modifiers [current_modifier_context].has_rotation = 1;
   4.105 +  last_input_context->modifiers [current_modifier_context].rotation = rotation;
   4.106    SDBG(("rotation %d\n", rotation));
   4.107  }
   4.108  
   4.109 -void input_images (int first, int last)
   4.110 +void increment_input_image_count (int count)
   4.111  {
   4.112 -  input_page_count += ((last - first) + 1);
   4.113 +  input_context_t *context;
   4.114 +
   4.115 +  for (context = last_input_context; context; context = context->parent)
   4.116 +    context->image_count += count;
   4.117 +}
   4.118 +
   4.119 +void input_images (range_t range)
   4.120 +{
   4.121 +  input_image_t *new_image;
   4.122 +  int count = ((range.last - range.first) + 1);
   4.123 +
   4.124  #ifdef SEMANTIC_DEBUG
   4.125 -  if (first == last)
   4.126 -    SDBG(("image %d\n", first));
   4.127 +  if (range.first == range.last)
   4.128 +    SDBG(("image %d\n", range.first));
   4.129    else
   4.130 -    SDBG(("images %d..%d\n", first, last));
   4.131 +    SDBG(("images %d..%d\n", range.first, range.last));
   4.132  #endif /* SEMANTIC_DEBUG */
   4.133 +
   4.134 +  new_image = calloc (1, sizeof (input_image_t));
   4.135 +  if (! new_image)
   4.136 +    {
   4.137 +      fprintf (stderr, "failed to malloc an input image struct\n");
   4.138 +      return;
   4.139 +    }
   4.140 +  if (first_input_image)
   4.141 +    {
   4.142 +      last_input_image->next = new_image;
   4.143 +      last_input_image = new_image;
   4.144 +    }
   4.145 +  else
   4.146 +    {
   4.147 +      first_input_image = last_input_image = new_image;
   4.148 +    }
   4.149 +  new_image->range = range;
   4.150 +  new_image->input_context = last_input_context;
   4.151 +  increment_input_image_count (count);
   4.152  }
   4.153  
   4.154  
   4.155  void output_push_context (void)
   4.156  {
   4.157 +  output_context_t *new_output_context;
   4.158 +
   4.159 +  new_output_context = malloc (sizeof (output_context_t));
   4.160 +  if (! new_output_context)
   4.161 +    {
   4.162 +      fprintf (stderr, "failed to malloc an output context\n");
   4.163 +      return;
   4.164 +    }
   4.165 +
   4.166 +  if (last_output_context)
   4.167 +    {
   4.168 +      memcpy (new_output_context, last_output_context, sizeof (output_context_t));
   4.169 +      new_output_context->page_count = 0;
   4.170 +    }
   4.171 +  else
   4.172 +    {
   4.173 +      memset (new_output_context, 0, sizeof (output_context_t));
   4.174 +      first_output_context = new_output_context;
   4.175 +    }
   4.176 +
   4.177 +  new_output_context->parent = last_output_context;
   4.178 +  last_output_context = new_output_context;
   4.179  };
   4.180  
   4.181 +void output_pop_context (void)
   4.182 +{
   4.183 +  if (! last_output_context)
   4.184 +    {
   4.185 +      fprintf (stderr, "failed to pop an output context\n");
   4.186 +      return;
   4.187 +    }
   4.188 +
   4.189 +  last_output_context = last_output_context->parent;
   4.190 +};
   4.191 +
   4.192 +void output_clone (void)
   4.193 +{
   4.194 +  output_context_t *new_output_context;
   4.195 +
   4.196 +  if (! last_output_context->page_count)
   4.197 +    return;
   4.198 +
   4.199 +  new_output_context = malloc (sizeof (output_context_t));
   4.200 +  if (! new_output_context)
   4.201 +    {
   4.202 +      fprintf (stderr, "failed to malloc an output context\n");
   4.203 +      return;
   4.204 +    }
   4.205 +
   4.206 +  memcpy (new_output_context, last_output_context, sizeof (output_context_t));
   4.207 +  new_output_context->page_count = 0;
   4.208 +  last_output_context->next = new_output_context;
   4.209 +}
   4.210 +
   4.211  void output_set_file (char *name)
   4.212  {
   4.213 +  output_clone ();
   4.214 +  last_output_context->output_file = name;
   4.215  };
   4.216  
   4.217 -void output_pages (int first, int last)
   4.218 +void output_set_bookmark (char *name)
   4.219  {
   4.220 -  output_page_count += ((last - first) + 1);
   4.221 +  bookmark_t *new_bookmark;
   4.222 +
   4.223 +  /* As the language is defined (parser.y), a bookmark can only appear
   4.224 +     at the beginning of a context! */
   4.225 +  if (last_output_context->page_count)
   4.226 +    {
   4.227 +      fprintf (stderr, "internal error, bookmark not at beginning of context\n");
   4.228 +      exit (2);
   4.229 +    }
   4.230 +
   4.231 +  new_bookmark = calloc (1, sizeof (bookmark_t));
   4.232 +  if (! new_bookmark)
   4.233 +    {
   4.234 +      fprintf (stderr, "failed to calloc a bookmark\n");
   4.235 +      return;
   4.236 +    }
   4.237 +
   4.238 +  new_bookmark->name = name;
   4.239 +  if (last_output_context->first_bookmark)
   4.240 +    last_output_context->last_bookmark->next = new_bookmark;
   4.241 +  else
   4.242 +    last_output_context->first_bookmark = new_bookmark;
   4.243 +  last_output_context->last_bookmark = new_bookmark;
   4.244 +}
   4.245 +
   4.246 +void output_set_page_number_format (char *format)
   4.247 +{
   4.248 +  output_clone ();
   4.249 +  last_output_context->page_number_format = format;
   4.250 +}
   4.251 +
   4.252 +void increment_output_page_count (int count)
   4.253 +{
   4.254 +  output_context_t *context;
   4.255 +
   4.256 +  for (context = last_output_context; context; context = context->parent)
   4.257 +    context->page_count += count;
   4.258 +}
   4.259 +
   4.260 +void output_pages (range_t range)
   4.261 +{
   4.262 +  output_page_t *new_page;
   4.263 +  int count = ((range.last - range.first) + 1);
   4.264 +
   4.265  #ifdef SEMANTIC_DEBUG
   4.266 -  if (first == last)
   4.267 -    SDBG(("page %d\n", first));
   4.268 +  if (range.first == range.last)
   4.269 +    SDBG(("page %d\n", range.first));
   4.270    else
   4.271 -    SDBG(("pages %d..%d\n", first, last));
   4.272 +    SDBG(("pages %d..%d\n", range.first, range.last));
   4.273  #endif /* SEMANTIC_DEBUG */
   4.274 +
   4.275 +  new_page = calloc (1, sizeof (output_page_t));
   4.276 +  if (! new_page)
   4.277 +    {
   4.278 +      fprintf (stderr, "failed to malloc an output page struct\n");
   4.279 +      return;
   4.280 +    }
   4.281 +  if (first_output_page)
   4.282 +    {
   4.283 +      last_output_page->next = new_page;
   4.284 +      last_output_page = new_page;
   4.285 +    }
   4.286 +  else
   4.287 +    {
   4.288 +      first_output_page = last_output_page = new_page;
   4.289 +    }
   4.290 +  new_page->range = range;
   4.291 +  new_page->output_context = last_output_context;
   4.292 +
   4.293 +  /* transfer bookmarks from context to page */
   4.294 +  new_page->bookmark_list = last_output_context->first_bookmark;
   4.295 +  last_output_context->first_bookmark = NULL;
   4.296 +  last_output_context->last_bookmark = NULL;
   4.297 +
   4.298 +  increment_output_page_count (count);
   4.299  }
   4.300  
   4.301  
   4.302 @@ -126,6 +308,88 @@
   4.303  }
   4.304  
   4.305  
   4.306 +char *get_input_file (input_context_t *context)
   4.307 +{
   4.308 +  for (; context; context = context->parent)
   4.309 +    if (context->input_file)
   4.310 +      return (context->input_file);
   4.311 +  fprintf (stderr, "no input file name found\n");
   4.312 +  exit (2);
   4.313 +}
   4.314 +
   4.315 +int get_input_rotation (input_context_t *context, input_modifier_type_t type)
   4.316 +{
   4.317 +  for (; context; context = context->parent)
   4.318 +    {
   4.319 +      if (context->modifiers [type].has_rotation)
   4.320 +	return (context->modifiers [type].rotation);
   4.321 +      if (context->modifiers [INPUT_MODIFIER_ALL].has_rotation)
   4.322 +	return (context->modifiers [INPUT_MODIFIER_ALL].rotation);
   4.323 +    }
   4.324 +  return (0);  /* default */
   4.325 +}
   4.326 +
   4.327 +char *get_output_file (output_context_t *context)
   4.328 +{
   4.329 +  for (; context; context = context->parent)
   4.330 +    if (context->output_file)
   4.331 +      return (context->output_file);
   4.332 +  fprintf (stderr, "no output file name found\n");
   4.333 +  exit (2);
   4.334 +}
   4.335 +
   4.336 +char *get_output_page_number_format (output_context_t *context)
   4.337 +{
   4.338 +  for (; context; context = context->parent)
   4.339 +    if (context->page_number_format)
   4.340 +      return (context->page_number_format);
   4.341 +  return (NULL);  /* default */
   4.342 +}
   4.343 +
   4.344 +
   4.345 +#ifdef SEMANTIC_DEBUG
   4.346 +void dump_input_tree (void)
   4.347 +{
   4.348 +  input_image_t *image;
   4.349 +  int i;
   4.350 +
   4.351 +  printf ("input images:\n");
   4.352 +  for (image = first_input_image; image; image = image->next)
   4.353 +    for (i = image->range.first; i <= image->range.last; i++)
   4.354 +      {
   4.355 +	input_modifier_type_t parity = (i % 2) ? INPUT_MODIFIER_ODD : INPUT_MODIFIER_EVEN;
   4.356 +	printf ("file '%s' image %d, rotation %d\n",
   4.357 +	        get_input_file (image->input_context),
   4.358 +		i, 
   4.359 +		get_input_rotation (image->input_context, parity));
   4.360 +      }
   4.361 +}
   4.362 +
   4.363 +void dump_output_tree (void)
   4.364 +{
   4.365 +  int i;
   4.366 +  output_page_t *page;
   4.367 +  bookmark_t *bookmark;
   4.368 +
   4.369 +  printf ("output pages:\n");
   4.370 +  for (page = first_output_page; page; page = page->next)
   4.371 +    {
   4.372 +      if (page->bookmark_list)
   4.373 +	{
   4.374 +	  for (bookmark = page->bookmark_list; bookmark; bookmark = bookmark->next)
   4.375 +	    printf ("bookmark '%s' ", bookmark->name);
   4.376 +	  printf ("\n");
   4.377 +	}
   4.378 +      for (i = page->range.first; i <= page->range.last; i++)
   4.379 +	{
   4.380 +	  printf ("file '%s' ", get_output_file (page->output_context));
   4.381 +	  printf ("format '%s' ", get_output_page_number_format (page->output_context));
   4.382 +	  printf ("page %d\n", i);
   4.383 +	}
   4.384 +    }
   4.385 +}
   4.386 +#endif /* SEMANTIC_DEBUG */
   4.387 +
   4.388  boolean parse_spec_file (char *fn)
   4.389  {
   4.390    boolean result = 0;
   4.391 @@ -139,22 +403,31 @@
   4.392  
   4.393    line = 1;
   4.394  
   4.395 -  input_push_context ();  /* create initial input context */
   4.396 +  input_push_context ();  /* create root input context */
   4.397 +  input_push_context ();  /* create inital input context */
   4.398 +
   4.399 +  output_push_context ();  /* create root output context */
   4.400    output_push_context ();  /* create initial output context */
   4.401  
   4.402    yyparse ();
   4.403  
   4.404 -  if (input_page_count != output_page_count)
   4.405 +  if (first_input_context->image_count != first_output_context->page_count)
   4.406      {
   4.407 -      fprintf (stderr, "input page count %d != output page count %d\n",
   4.408 -	       input_page_count, output_page_count);
   4.409 +      fprintf (stderr, "input image count %d != output page count %d\n",
   4.410 +	       first_input_context->image_count,
   4.411 +	       first_output_context->page_count);
   4.412        goto fail;
   4.413      }
   4.414  
   4.415 -  fprintf (stderr, "%d pages specified\n", input_page_count);
   4.416 +  fprintf (stderr, "%d pages specified\n", first_input_context->image_count);
   4.417  
   4.418    result = 1;
   4.419  
   4.420 +#ifdef SEMANTIC_DEBUG
   4.421 +  dump_input_tree ();
   4.422 +  dump_output_tree ();
   4.423 +#endif /* SEMANTIC_DEBUG */
   4.424 +
   4.425   fail:
   4.426    if (yyin)
   4.427      fclose (yyin);
     5.1 --- a/semantics.h	Mon Dec 31 02:33:50 2001 +0000
     5.2 +++ b/semantics.h	Mon Dec 31 07:25:08 2001 +0000
     5.3 @@ -42,20 +42,58 @@
     5.4  
     5.5  typedef struct input_context_t
     5.6  {
     5.7 -  struct input_context_t *parent_input_context;
     5.8 +  struct input_context_t *parent;
     5.9 +  struct input_context_t *next;
    5.10  
    5.11 -  int page_count;  /* how many pages reference this context,
    5.12 +  int image_count;  /* how many pages reference this context,
    5.13  		      including those from subcontexts */
    5.14  
    5.15 +  char *input_file;
    5.16 +
    5.17    input_modifiers_t modifiers [INPUT_MODIFIER_TYPE_COUNT];
    5.18  } input_context_t;
    5.19  
    5.20  
    5.21 -extern int line;  /* line number in spec file */
    5.22 +typedef struct input_image_t
    5.23 +{
    5.24 +  struct input_image_t *next;
    5.25 +  input_context_t *input_context;
    5.26 +  range_t range;
    5.27 +} input_image_t;
    5.28 +
    5.29 +
    5.30 +typedef struct bookmark_t
    5.31 +{
    5.32 +  struct bookmark_t *next;
    5.33 +  char *name;
    5.34 +} bookmark_t;
    5.35  
    5.36  
    5.37 -extern int input_page_count;   /* total input pages in spec */
    5.38 -extern int output_page_count;  /* total output pages in spec */
    5.39 +typedef struct output_context_t
    5.40 +{
    5.41 +  struct output_context_t *parent;
    5.42 +  struct output_context_t *next;
    5.43 +
    5.44 +  int page_count;  /* how many pages reference this context,
    5.45 +		      including those from subcontexts */
    5.46 +
    5.47 +  char *output_file;
    5.48 +  bookmark_t *first_bookmark;
    5.49 +  bookmark_t *last_bookmark;
    5.50 +  char *page_number_format;
    5.51 +} output_context_t;
    5.52 +
    5.53 +
    5.54 +typedef struct output_page_t
    5.55 +{
    5.56 +  struct output_page_t *next;
    5.57 +  output_context_t *output_context;
    5.58 +  range_t range;
    5.59 +  bookmark_t *bookmark_list;
    5.60 +} output_page_t;
    5.61 +
    5.62 +
    5.63 +extern int line;  /* line number in spec file */
    5.64  
    5.65  
    5.66  boolean parse_spec_file (char *fn);
    5.67 @@ -67,8 +105,10 @@
    5.68  void input_set_modifier_context (input_modifier_type_t type);
    5.69  void input_set_file (char *name);
    5.70  void input_set_rotation (int rotation);
    5.71 -void input_images (int first, int last);
    5.72 +void input_images (range_t range);
    5.73  
    5.74  /* semantic routines for output statements */
    5.75  void output_set_file (char *name);
    5.76 -void output_pages (int first, int last);
    5.77 +void output_set_bookmark (char *name);
    5.78 +void output_set_page_number_format (char *format);
    5.79 +void output_pages (range_t range);