semantics.c

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
permissions
-rw-r--r--

*** empty log message ***

     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 #define SEMANTIC_DEBUG
    11 #ifdef SEMANTIC_DEBUG
    12 #define SDBG(x) printf x
    13 #else
    14 #define SDBG(x)
    15 #endif
    18 FILE *yyin;
    19 int line;  /* line number in spec file */
    22 input_context_t *first_input_context;
    23 input_context_t *last_input_context;
    25 input_modifier_type_t current_modifier_context;
    27 input_image_t *first_input_image;
    28 input_image_t *last_input_image;
    30 output_context_t *first_output_context;
    31 output_context_t *last_output_context;
    33 output_page_t *first_output_page;
    34 output_page_t *last_output_page;
    37 void input_push_context (void)
    38 {
    39   input_context_t *new_input_context;
    41   new_input_context = malloc (sizeof (input_context_t));
    42   if (! new_input_context)
    43     {
    44       fprintf (stderr, "failed to malloc an input context\n");
    45       return;
    46     }
    48   if (last_input_context)
    49     {
    50       memcpy (new_input_context, last_input_context, sizeof (input_context_t));
    51       new_input_context->image_count = 0;
    52     }
    53   else
    54     {
    55       memset (new_input_context, 0, sizeof (input_context_t));
    56       first_input_context = new_input_context;
    57     }
    59   new_input_context->parent = last_input_context;
    60   last_input_context = new_input_context;
    61 };
    63 void input_pop_context (void)
    64 {
    65   if (! last_input_context)
    66     {
    67       fprintf (stderr, "failed to pop an input context\n");
    68       return;
    69     }
    71   last_input_context = last_input_context->parent;
    72 };
    74 void input_set_modifier_context (input_modifier_type_t type)
    75 {
    76   current_modifier_context = type;
    77 #ifdef SEMANTIC_DEBUG
    78   SDBG(("modifier type "));
    79   switch (type)
    80     {
    81     case INPUT_MODIFIER_ALL: SDBG(("all")); break;
    82     case INPUT_MODIFIER_ODD: SDBG(("odd")); break;
    83     case INPUT_MODIFIER_EVEN: SDBG(("even")); break;
    84     default: SDBG(("unknown %d", type));
    85     }
    86   SDBG(("\n"));
    87 #endif /* SEMANTIC_DEBUG */
    88 }
    90 void input_clone (void)
    91 {
    92   input_context_t *new_input_context;
    94   if (! last_input_context->image_count)
    95     return;
    97   new_input_context = malloc (sizeof (input_context_t));
    98   if (! new_input_context)
    99     {
   100       fprintf (stderr, "failed to malloc an input context\n");
   101       return;
   102     }
   104   memcpy (new_input_context, last_input_context, sizeof (input_context_t));
   105   new_input_context->image_count = 0;
   106   last_input_context->next = new_input_context;
   107 }
   109 void input_set_file (char *name)
   110 {
   111   input_clone ();
   112   last_input_context->input_file = name;
   113 };
   115 void input_set_rotation (int rotation)
   116 {
   117   last_input_context->modifiers [current_modifier_context].has_rotation = 1;
   118   last_input_context->modifiers [current_modifier_context].rotation = rotation;
   119   SDBG(("rotation %d\n", rotation));
   120 }
   122 void increment_input_image_count (int count)
   123 {
   124   input_context_t *context;
   126   for (context = last_input_context; context; context = context->parent)
   127     context->image_count += count;
   128 }
   130 void input_images (range_t range)
   131 {
   132   input_image_t *new_image;
   133   int count = ((range.last - range.first) + 1);
   135 #ifdef SEMANTIC_DEBUG
   136   if (range.first == range.last)
   137     SDBG(("image %d\n", range.first));
   138   else
   139     SDBG(("images %d..%d\n", range.first, range.last));
   140 #endif /* SEMANTIC_DEBUG */
   142   new_image = calloc (1, sizeof (input_image_t));
   143   if (! new_image)
   144     {
   145       fprintf (stderr, "failed to malloc an input image struct\n");
   146       return;
   147     }
   148   if (first_input_image)
   149     {
   150       last_input_image->next = new_image;
   151       last_input_image = new_image;
   152     }
   153   else
   154     {
   155       first_input_image = last_input_image = new_image;
   156     }
   157   new_image->range = range;
   158   new_image->input_context = last_input_context;
   159   increment_input_image_count (count);
   160 }
   163 void output_push_context (void)
   164 {
   165   output_context_t *new_output_context;
   167   new_output_context = malloc (sizeof (output_context_t));
   168   if (! new_output_context)
   169     {
   170       fprintf (stderr, "failed to malloc an output context\n");
   171       return;
   172     }
   174   if (last_output_context)
   175     {
   176       memcpy (new_output_context, last_output_context, sizeof (output_context_t));
   177       new_output_context->page_count = 0;
   178     }
   179   else
   180     {
   181       memset (new_output_context, 0, sizeof (output_context_t));
   182       first_output_context = new_output_context;
   183     }
   185   new_output_context->parent = last_output_context;
   186   last_output_context = new_output_context;
   187 };
   189 void output_pop_context (void)
   190 {
   191   if (! last_output_context)
   192     {
   193       fprintf (stderr, "failed to pop an output context\n");
   194       return;
   195     }
   197   last_output_context = last_output_context->parent;
   198 };
   200 void output_clone (void)
   201 {
   202   output_context_t *new_output_context;
   204   if (! last_output_context->page_count)
   205     return;
   207   new_output_context = malloc (sizeof (output_context_t));
   208   if (! new_output_context)
   209     {
   210       fprintf (stderr, "failed to malloc an output context\n");
   211       return;
   212     }
   214   memcpy (new_output_context, last_output_context, sizeof (output_context_t));
   215   new_output_context->page_count = 0;
   216   last_output_context->next = new_output_context;
   217 }
   219 void output_set_file (char *name)
   220 {
   221   output_clone ();
   222   last_output_context->output_file = name;
   223 };
   225 void output_set_bookmark (char *name)
   226 {
   227   bookmark_t *new_bookmark;
   229   /* As the language is defined (parser.y), a bookmark can only appear
   230      at the beginning of a context! */
   231   if (last_output_context->page_count)
   232     {
   233       fprintf (stderr, "internal error, bookmark not at beginning of context\n");
   234       exit (2);
   235     }
   237   new_bookmark = calloc (1, sizeof (bookmark_t));
   238   if (! new_bookmark)
   239     {
   240       fprintf (stderr, "failed to calloc a bookmark\n");
   241       return;
   242     }
   244   new_bookmark->name = name;
   245   if (last_output_context->first_bookmark)
   246     last_output_context->last_bookmark->next = new_bookmark;
   247   else
   248     last_output_context->first_bookmark = new_bookmark;
   249   last_output_context->last_bookmark = new_bookmark;
   250 }
   252 void output_set_page_number_format (char *format)
   253 {
   254   output_clone ();
   255   last_output_context->page_number_format = format;
   256 }
   258 void increment_output_page_count (int count)
   259 {
   260   output_context_t *context;
   262   for (context = last_output_context; context; context = context->parent)
   263     context->page_count += count;
   264 }
   266 void output_pages (range_t range)
   267 {
   268   output_page_t *new_page;
   269   int count = ((range.last - range.first) + 1);
   271 #ifdef SEMANTIC_DEBUG
   272   if (range.first == range.last)
   273     SDBG(("page %d\n", range.first));
   274   else
   275     SDBG(("pages %d..%d\n", range.first, range.last));
   276 #endif /* SEMANTIC_DEBUG */
   278   new_page = calloc (1, sizeof (output_page_t));
   279   if (! new_page)
   280     {
   281       fprintf (stderr, "failed to malloc an output page struct\n");
   282       return;
   283     }
   284   if (first_output_page)
   285     {
   286       last_output_page->next = new_page;
   287       last_output_page = new_page;
   288     }
   289   else
   290     {
   291       first_output_page = last_output_page = new_page;
   292     }
   293   new_page->range = range;
   294   new_page->output_context = last_output_context;
   296   /* transfer bookmarks from context to page */
   297   new_page->bookmark_list = last_output_context->first_bookmark;
   298   last_output_context->first_bookmark = NULL;
   299   last_output_context->last_bookmark = NULL;
   301   increment_output_page_count (count);
   302 }
   305 void yyerror (char *s)
   306 {
   307   fprintf (stderr, "%d: %s\n", line, s);
   308 }
   311 char *get_input_file (input_context_t *context)
   312 {
   313   for (; context; context = context->parent)
   314     if (context->input_file)
   315       return (context->input_file);
   316   fprintf (stderr, "no input file name found\n");
   317   exit (2);
   318 }
   320 int get_input_rotation (input_context_t *context, input_modifier_type_t type)
   321 {
   322   for (; context; context = context->parent)
   323     {
   324       if (context->modifiers [type].has_rotation)
   325 	return (context->modifiers [type].rotation);
   326       if (context->modifiers [INPUT_MODIFIER_ALL].has_rotation)
   327 	return (context->modifiers [INPUT_MODIFIER_ALL].rotation);
   328     }
   329   return (0);  /* default */
   330 }
   332 char *get_output_file (output_context_t *context)
   333 {
   334   for (; context; context = context->parent)
   335     if (context->output_file)
   336       return (context->output_file);
   337   fprintf (stderr, "no output file name found\n");
   338   exit (2);
   339 }
   341 char *get_output_page_number_format (output_context_t *context)
   342 {
   343   for (; context; context = context->parent)
   344     if (context->page_number_format)
   345       return (context->page_number_format);
   346   return (NULL);  /* default */
   347 }
   350 #ifdef SEMANTIC_DEBUG
   351 void dump_input_tree (void)
   352 {
   353   input_image_t *image;
   354   int i;
   356   printf ("input images:\n");
   357   for (image = first_input_image; image; image = image->next)
   358     for (i = image->range.first; i <= image->range.last; i++)
   359       {
   360 	input_modifier_type_t parity = (i % 2) ? INPUT_MODIFIER_ODD : INPUT_MODIFIER_EVEN;
   361 	printf ("file '%s' image %d, rotation %d\n",
   362 	        get_input_file (image->input_context),
   363 		i, 
   364 		get_input_rotation (image->input_context, parity));
   365       }
   366 }
   368 void dump_output_tree (void)
   369 {
   370   int i;
   371   output_page_t *page;
   372   bookmark_t *bookmark;
   374   printf ("output pages:\n");
   375   for (page = first_output_page; page; page = page->next)
   376     {
   377       if (page->bookmark_list)
   378 	{
   379 	  for (bookmark = page->bookmark_list; bookmark; bookmark = bookmark->next)
   380 	    printf ("bookmark '%s' ", bookmark->name);
   381 	  printf ("\n");
   382 	}
   383       for (i = page->range.first; i <= page->range.last; i++)
   384 	{
   385 	  printf ("file '%s' ", get_output_file (page->output_context));
   386 	  printf ("format '%s' ", get_output_page_number_format (page->output_context));
   387 	  printf ("page %d\n", i);
   388 	}
   389     }
   390 }
   391 #endif /* SEMANTIC_DEBUG */
   393 boolean parse_spec_file (char *fn)
   394 {
   395   boolean result = 0;
   397   yyin = fopen (fn, "r");
   398   if (! yyin)
   399     {
   400       fprintf (stderr, "can't open spec file '%s'\n", fn);
   401       goto fail;
   402     }
   404   line = 1;
   406   input_push_context ();  /* create root input context */
   407   input_push_context ();  /* create inital input context */
   409   output_push_context ();  /* create root output context */
   410   output_push_context ();  /* create initial output context */
   412   yyparse ();
   414   if (first_input_context->image_count != first_output_context->page_count)
   415     {
   416       fprintf (stderr, "input image count %d != output page count %d\n",
   417 	       first_input_context->image_count,
   418 	       first_output_context->page_count);
   419       goto fail;
   420     }
   422   fprintf (stderr, "%d pages specified\n", first_input_context->image_count);
   424   result = 1;
   426 #ifdef SEMANTIC_DEBUG
   427   dump_input_tree ();
   428   dump_output_tree ();
   429 #endif /* SEMANTIC_DEBUG */
   431  fail:
   432   if (yyin)
   433     fclose (yyin);
   435   return (result);
   436 }