semantics.c

Mon, 31 Dec 2001 08:12:58 +0000

author
eric
date
Mon, 31 Dec 2001 08:12:58 +0000
changeset 22
198616589af5
parent 21
2bb19d98d928
child 24
6575fcfbdb1b
permissions
-rw-r--r--

moved most type declarations from semantics.h to semantics.c.
made various functions static.

     1 #include <stdlib.h>
     2 #include <string.h>
     3 #include <stdio.h>
     5 #include "type.h"
     6 #include "semantics.h"
     7 #include "parser.tab.h"
    10 typedef struct
    11 {
    12   boolean has_size;
    13   page_size_t size;
    15   boolean has_rotation;
    16   int rotation;
    18   boolean has_crop;
    19   crop_t crop;
    20 } input_modifiers_t;
    23 typedef struct input_context_t
    24 {
    25   struct input_context_t *parent;
    26   struct input_context_t *next;
    28   int image_count;  /* how many pages reference this context,
    29 		      including those from subcontexts */
    31   char *input_file;
    33   input_modifiers_t modifiers [INPUT_MODIFIER_TYPE_COUNT];
    34 } input_context_t;
    37 typedef struct input_image_t
    38 {
    39   struct input_image_t *next;
    40   input_context_t *input_context;
    41   range_t range;
    42 } input_image_t;
    45 typedef struct bookmark_t
    46 {
    47   struct bookmark_t *next;
    48   char *name;
    49 } bookmark_t;
    52 typedef struct output_context_t
    53 {
    54   struct output_context_t *parent;
    55   struct output_context_t *next;
    57   int page_count;  /* how many pages reference this context,
    58 		      including those from subcontexts */
    60   char *output_file;
    61   bookmark_t *first_bookmark;
    62   bookmark_t *last_bookmark;
    63   char *page_number_format;
    64 } output_context_t;
    67 typedef struct output_page_t
    68 {
    69   struct output_page_t *next;
    70   output_context_t *output_context;
    71   range_t range;
    72   bookmark_t *bookmark_list;
    73 } output_page_t;
    76 #define SEMANTIC_DEBUG
    77 #ifdef SEMANTIC_DEBUG
    78 #define SDBG(x) printf x
    79 #else
    80 #define SDBG(x)
    81 #endif
    84 FILE *yyin;
    85 int line;  /* line number in spec file */
    88 input_context_t *first_input_context;
    89 input_context_t *last_input_context;
    91 input_modifier_type_t current_modifier_context;
    93 input_image_t *first_input_image;
    94 input_image_t *last_input_image;
    96 output_context_t *first_output_context;
    97 output_context_t *last_output_context;
    99 output_page_t *first_output_page;
   100 output_page_t *last_output_page;
   103 void input_push_context (void)
   104 {
   105   input_context_t *new_input_context;
   107   new_input_context = malloc (sizeof (input_context_t));
   108   if (! new_input_context)
   109     {
   110       fprintf (stderr, "failed to malloc an input context\n");
   111       return;
   112     }
   114   if (last_input_context)
   115     {
   116       memcpy (new_input_context, last_input_context, sizeof (input_context_t));
   117       new_input_context->image_count = 0;
   118     }
   119   else
   120     {
   121       memset (new_input_context, 0, sizeof (input_context_t));
   122       first_input_context = new_input_context;
   123     }
   125   new_input_context->parent = last_input_context;
   126   last_input_context = new_input_context;
   127 };
   129 void input_pop_context (void)
   130 {
   131   if (! last_input_context)
   132     {
   133       fprintf (stderr, "failed to pop an input context\n");
   134       return;
   135     }
   137   last_input_context = last_input_context->parent;
   138 };
   140 void input_set_modifier_context (input_modifier_type_t type)
   141 {
   142   current_modifier_context = type;
   143 #ifdef SEMANTIC_DEBUG
   144   SDBG(("modifier type "));
   145   switch (type)
   146     {
   147     case INPUT_MODIFIER_ALL: SDBG(("all")); break;
   148     case INPUT_MODIFIER_ODD: SDBG(("odd")); break;
   149     case INPUT_MODIFIER_EVEN: SDBG(("even")); break;
   150     default: SDBG(("unknown %d", type));
   151     }
   152   SDBG(("\n"));
   153 #endif /* SEMANTIC_DEBUG */
   154 }
   156 static void input_clone (void)
   157 {
   158   input_context_t *new_input_context;
   160   if (! last_input_context->image_count)
   161     return;
   163   new_input_context = malloc (sizeof (input_context_t));
   164   if (! new_input_context)
   165     {
   166       fprintf (stderr, "failed to malloc an input context\n");
   167       return;
   168     }
   170   memcpy (new_input_context, last_input_context, sizeof (input_context_t));
   171   new_input_context->image_count = 0;
   172   last_input_context->next = new_input_context;
   173 }
   175 void input_set_file (char *name)
   176 {
   177   input_clone ();
   178   last_input_context->input_file = name;
   179 };
   181 void input_set_rotation (int rotation)
   182 {
   183   last_input_context->modifiers [current_modifier_context].has_rotation = 1;
   184   last_input_context->modifiers [current_modifier_context].rotation = rotation;
   185   SDBG(("rotation %d\n", rotation));
   186 }
   188 static void increment_input_image_count (int count)
   189 {
   190   input_context_t *context;
   192   for (context = last_input_context; context; context = context->parent)
   193     context->image_count += count;
   194 }
   196 void input_images (range_t range)
   197 {
   198   input_image_t *new_image;
   199   int count = ((range.last - range.first) + 1);
   201 #ifdef SEMANTIC_DEBUG
   202   if (range.first == range.last)
   203     SDBG(("image %d\n", range.first));
   204   else
   205     SDBG(("images %d..%d\n", range.first, range.last));
   206 #endif /* SEMANTIC_DEBUG */
   208   new_image = calloc (1, sizeof (input_image_t));
   209   if (! new_image)
   210     {
   211       fprintf (stderr, "failed to malloc an input image struct\n");
   212       return;
   213     }
   214   if (first_input_image)
   215     {
   216       last_input_image->next = new_image;
   217       last_input_image = new_image;
   218     }
   219   else
   220     {
   221       first_input_image = last_input_image = new_image;
   222     }
   223   new_image->range = range;
   224   new_image->input_context = last_input_context;
   225   increment_input_image_count (count);
   226 }
   229 void output_push_context (void)
   230 {
   231   output_context_t *new_output_context;
   233   new_output_context = malloc (sizeof (output_context_t));
   234   if (! new_output_context)
   235     {
   236       fprintf (stderr, "failed to malloc an output context\n");
   237       return;
   238     }
   240   if (last_output_context)
   241     {
   242       memcpy (new_output_context, last_output_context, sizeof (output_context_t));
   243       new_output_context->page_count = 0;
   244       new_output_context->first_bookmark = NULL;
   245       new_output_context->last_bookmark = NULL;
   246     }
   247   else
   248     {
   249       memset (new_output_context, 0, sizeof (output_context_t));
   250       first_output_context = new_output_context;
   251     }
   253   new_output_context->parent = last_output_context;
   254   last_output_context = new_output_context;
   255 };
   257 void output_pop_context (void)
   258 {
   259   if (! last_output_context)
   260     {
   261       fprintf (stderr, "failed to pop an output context\n");
   262       return;
   263     }
   265   last_output_context = last_output_context->parent;
   266 };
   268 static void output_clone (void)
   269 {
   270   output_context_t *new_output_context;
   272   if (! last_output_context->page_count)
   273     return;
   275   new_output_context = malloc (sizeof (output_context_t));
   276   if (! new_output_context)
   277     {
   278       fprintf (stderr, "failed to malloc an output context\n");
   279       return;
   280     }
   282   memcpy (new_output_context, last_output_context, sizeof (output_context_t));
   283   new_output_context->page_count = 0;
   284   last_output_context->next = new_output_context;
   285 }
   287 void output_set_file (char *name)
   288 {
   289   output_clone ();
   290   last_output_context->output_file = name;
   291 };
   293 void output_set_bookmark (char *name)
   294 {
   295   bookmark_t *new_bookmark;
   297   /* As the language is defined (parser.y), a bookmark can only appear
   298      at the beginning of a context! */
   299   if (last_output_context->page_count)
   300     {
   301       fprintf (stderr, "internal error, bookmark not at beginning of context\n");
   302       exit (2);
   303     }
   305   new_bookmark = calloc (1, sizeof (bookmark_t));
   306   if (! new_bookmark)
   307     {
   308       fprintf (stderr, "failed to calloc a bookmark\n");
   309       return;
   310     }
   312   new_bookmark->name = name;
   313   if (last_output_context->first_bookmark)
   314     last_output_context->last_bookmark->next = new_bookmark;
   315   else
   316     last_output_context->first_bookmark = new_bookmark;
   317   last_output_context->last_bookmark = new_bookmark;
   318 }
   320 void output_set_page_number_format (char *format)
   321 {
   322   output_clone ();
   323   last_output_context->page_number_format = format;
   324 }
   326 static void increment_output_page_count (int count)
   327 {
   328   output_context_t *context;
   330   for (context = last_output_context; context; context = context->parent)
   331     context->page_count += count;
   332 }
   335 void output_pages (range_t range)
   336 {
   337   output_page_t *new_page;
   338   output_context_t *context;
   339   int count = ((range.last - range.first) + 1);
   341 #ifdef SEMANTIC_DEBUG
   342   if (range.first == range.last)
   343     SDBG(("page %d\n", range.first));
   344   else
   345     SDBG(("pages %d..%d\n", range.first, range.last));
   346 #endif /* SEMANTIC_DEBUG */
   348   new_page = calloc (1, sizeof (output_page_t));
   349   if (! new_page)
   350     {
   351       fprintf (stderr, "failed to malloc an output page struct\n");
   352       return;
   353     }
   354   if (first_output_page)
   355     {
   356       last_output_page->next = new_page;
   357       last_output_page = new_page;
   358     }
   359   else
   360     {
   361       first_output_page = last_output_page = new_page;
   362     }
   363   new_page->range = range;
   364   new_page->output_context = last_output_context;
   366   /* transfer bookmarks from context(s) to page */
   367   for (context = last_output_context; context; context = context->parent)
   368     if (context->first_bookmark)
   369       {
   370 	context->last_bookmark->next = new_page->bookmark_list;
   371 	new_page->bookmark_list = context->first_bookmark;
   372 	context->first_bookmark = NULL;
   373 	context->last_bookmark = NULL;
   374       }
   376   increment_output_page_count (count);
   377 }
   380 void yyerror (char *s)
   381 {
   382   fprintf (stderr, "%d: %s\n", line, s);
   383 }
   386 static char *get_input_file (input_context_t *context)
   387 {
   388   for (; context; context = context->parent)
   389     if (context->input_file)
   390       return (context->input_file);
   391   fprintf (stderr, "no input file name found\n");
   392   exit (2);
   393 }
   395 static int get_input_rotation (input_context_t *context, input_modifier_type_t type)
   396 {
   397   for (; context; context = context->parent)
   398     {
   399       if (context->modifiers [type].has_rotation)
   400 	return (context->modifiers [type].rotation);
   401       if (context->modifiers [INPUT_MODIFIER_ALL].has_rotation)
   402 	return (context->modifiers [INPUT_MODIFIER_ALL].rotation);
   403     }
   404   return (0);  /* default */
   405 }
   407 static char *get_output_file (output_context_t *context)
   408 {
   409   for (; context; context = context->parent)
   410     if (context->output_file)
   411       return (context->output_file);
   412   fprintf (stderr, "no output file name found\n");
   413   exit (2);
   414 }
   416 static char *get_output_page_number_format (output_context_t *context)
   417 {
   418   for (; context; context = context->parent)
   419     if (context->page_number_format)
   420       return (context->page_number_format);
   421   return (NULL);  /* default */
   422 }
   425 #ifdef SEMANTIC_DEBUG
   426 void dump_input_tree (void)
   427 {
   428   input_image_t *image;
   429   int i;
   431   printf ("input images:\n");
   432   for (image = first_input_image; image; image = image->next)
   433     for (i = image->range.first; i <= image->range.last; i++)
   434       {
   435 	input_modifier_type_t parity = (i % 2) ? INPUT_MODIFIER_ODD : INPUT_MODIFIER_EVEN;
   436 	printf ("file '%s' image %d, rotation %d\n",
   437 	        get_input_file (image->input_context),
   438 		i, 
   439 		get_input_rotation (image->input_context, parity));
   440       }
   441 }
   443 void dump_output_tree (void)
   444 {
   445   int i;
   446   output_page_t *page;
   447   bookmark_t *bookmark;
   449   printf ("output pages:\n");
   450   for (page = first_output_page; page; page = page->next)
   451     {
   452       if (page->bookmark_list)
   453 	{
   454 	  for (bookmark = page->bookmark_list; bookmark; bookmark = bookmark->next)
   455 	    printf ("bookmark '%s' ", bookmark->name);
   456 	  printf ("\n");
   457 	}
   458       for (i = page->range.first; i <= page->range.last; i++)
   459 	{
   460 	  printf ("file '%s' ", get_output_file (page->output_context));
   461 	  printf ("format '%s' ", get_output_page_number_format (page->output_context));
   462 	  printf ("page %d\n", i);
   463 	}
   464     }
   465 }
   466 #endif /* SEMANTIC_DEBUG */
   468 boolean parse_spec_file (char *fn)
   469 {
   470   boolean result = 0;
   472   yyin = fopen (fn, "r");
   473   if (! yyin)
   474     {
   475       fprintf (stderr, "can't open spec file '%s'\n", fn);
   476       goto fail;
   477     }
   479   line = 1;
   481   input_push_context ();  /* create root input context */
   482   input_push_context ();  /* create inital input context */
   484   output_push_context ();  /* create root output context */
   485   output_push_context ();  /* create initial output context */
   487   yyparse ();
   489   if (first_input_context->image_count != first_output_context->page_count)
   490     {
   491       fprintf (stderr, "input image count %d != output page count %d\n",
   492 	       first_input_context->image_count,
   493 	       first_output_context->page_count);
   494       goto fail;
   495     }
   497   fprintf (stderr, "%d pages specified\n", first_input_context->image_count);
   499   result = 1;
   501 #ifdef SEMANTIC_DEBUG
   502   dump_input_tree ();
   503   dump_output_tree ();
   504 #endif /* SEMANTIC_DEBUG */
   506  fail:
   507   if (yyin)
   508     fclose (yyin);
   510   return (result);
   511 }