semantics.c

Mon, 31 Dec 2001 07:44:23 +0000

author
eric
date
Mon, 31 Dec 2001 07:44:23 +0000
changeset 21
2bb19d98d928
parent 20
a1cd8cb9d09e
child 22
198616589af5
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       new_output_context->first_bookmark = NULL;
   179       new_output_context->last_bookmark = NULL;
   180     }
   181   else
   182     {
   183       memset (new_output_context, 0, sizeof (output_context_t));
   184       first_output_context = new_output_context;
   185     }
   187   new_output_context->parent = last_output_context;
   188   last_output_context = new_output_context;
   189 };
   191 void output_pop_context (void)
   192 {
   193   if (! last_output_context)
   194     {
   195       fprintf (stderr, "failed to pop an output context\n");
   196       return;
   197     }
   199   last_output_context = last_output_context->parent;
   200 };
   202 void output_clone (void)
   203 {
   204   output_context_t *new_output_context;
   206   if (! last_output_context->page_count)
   207     return;
   209   new_output_context = malloc (sizeof (output_context_t));
   210   if (! new_output_context)
   211     {
   212       fprintf (stderr, "failed to malloc an output context\n");
   213       return;
   214     }
   216   memcpy (new_output_context, last_output_context, sizeof (output_context_t));
   217   new_output_context->page_count = 0;
   218   last_output_context->next = new_output_context;
   219 }
   221 void output_set_file (char *name)
   222 {
   223   output_clone ();
   224   last_output_context->output_file = name;
   225 };
   227 void output_set_bookmark (char *name)
   228 {
   229   bookmark_t *new_bookmark;
   231   /* As the language is defined (parser.y), a bookmark can only appear
   232      at the beginning of a context! */
   233   if (last_output_context->page_count)
   234     {
   235       fprintf (stderr, "internal error, bookmark not at beginning of context\n");
   236       exit (2);
   237     }
   239   new_bookmark = calloc (1, sizeof (bookmark_t));
   240   if (! new_bookmark)
   241     {
   242       fprintf (stderr, "failed to calloc a bookmark\n");
   243       return;
   244     }
   246   new_bookmark->name = name;
   247   if (last_output_context->first_bookmark)
   248     last_output_context->last_bookmark->next = new_bookmark;
   249   else
   250     last_output_context->first_bookmark = new_bookmark;
   251   last_output_context->last_bookmark = new_bookmark;
   252 }
   254 void output_set_page_number_format (char *format)
   255 {
   256   output_clone ();
   257   last_output_context->page_number_format = format;
   258 }
   260 void increment_output_page_count (int count)
   261 {
   262   output_context_t *context;
   264   for (context = last_output_context; context; context = context->parent)
   265     context->page_count += count;
   266 }
   269 void output_pages (range_t range)
   270 {
   271   output_page_t *new_page;
   272   output_context_t *context;
   273   int count = ((range.last - range.first) + 1);
   275 #ifdef SEMANTIC_DEBUG
   276   if (range.first == range.last)
   277     SDBG(("page %d\n", range.first));
   278   else
   279     SDBG(("pages %d..%d\n", range.first, range.last));
   280 #endif /* SEMANTIC_DEBUG */
   282   new_page = calloc (1, sizeof (output_page_t));
   283   if (! new_page)
   284     {
   285       fprintf (stderr, "failed to malloc an output page struct\n");
   286       return;
   287     }
   288   if (first_output_page)
   289     {
   290       last_output_page->next = new_page;
   291       last_output_page = new_page;
   292     }
   293   else
   294     {
   295       first_output_page = last_output_page = new_page;
   296     }
   297   new_page->range = range;
   298   new_page->output_context = last_output_context;
   300   /* transfer bookmarks from context(s) to page */
   301   for (context = last_output_context; context; context = context->parent)
   302     if (context->first_bookmark)
   303       {
   304 	context->last_bookmark->next = new_page->bookmark_list;
   305 	new_page->bookmark_list = context->first_bookmark;
   306 	context->first_bookmark = NULL;
   307 	context->last_bookmark = NULL;
   308       }
   310   increment_output_page_count (count);
   311 }
   314 void yyerror (char *s)
   315 {
   316   fprintf (stderr, "%d: %s\n", line, s);
   317 }
   320 char *get_input_file (input_context_t *context)
   321 {
   322   for (; context; context = context->parent)
   323     if (context->input_file)
   324       return (context->input_file);
   325   fprintf (stderr, "no input file name found\n");
   326   exit (2);
   327 }
   329 int get_input_rotation (input_context_t *context, input_modifier_type_t type)
   330 {
   331   for (; context; context = context->parent)
   332     {
   333       if (context->modifiers [type].has_rotation)
   334 	return (context->modifiers [type].rotation);
   335       if (context->modifiers [INPUT_MODIFIER_ALL].has_rotation)
   336 	return (context->modifiers [INPUT_MODIFIER_ALL].rotation);
   337     }
   338   return (0);  /* default */
   339 }
   341 char *get_output_file (output_context_t *context)
   342 {
   343   for (; context; context = context->parent)
   344     if (context->output_file)
   345       return (context->output_file);
   346   fprintf (stderr, "no output file name found\n");
   347   exit (2);
   348 }
   350 char *get_output_page_number_format (output_context_t *context)
   351 {
   352   for (; context; context = context->parent)
   353     if (context->page_number_format)
   354       return (context->page_number_format);
   355   return (NULL);  /* default */
   356 }
   359 #ifdef SEMANTIC_DEBUG
   360 void dump_input_tree (void)
   361 {
   362   input_image_t *image;
   363   int i;
   365   printf ("input images:\n");
   366   for (image = first_input_image; image; image = image->next)
   367     for (i = image->range.first; i <= image->range.last; i++)
   368       {
   369 	input_modifier_type_t parity = (i % 2) ? INPUT_MODIFIER_ODD : INPUT_MODIFIER_EVEN;
   370 	printf ("file '%s' image %d, rotation %d\n",
   371 	        get_input_file (image->input_context),
   372 		i, 
   373 		get_input_rotation (image->input_context, parity));
   374       }
   375 }
   377 void dump_output_tree (void)
   378 {
   379   int i;
   380   output_page_t *page;
   381   bookmark_t *bookmark;
   383   printf ("output pages:\n");
   384   for (page = first_output_page; page; page = page->next)
   385     {
   386       if (page->bookmark_list)
   387 	{
   388 	  for (bookmark = page->bookmark_list; bookmark; bookmark = bookmark->next)
   389 	    printf ("bookmark '%s' ", bookmark->name);
   390 	  printf ("\n");
   391 	}
   392       for (i = page->range.first; i <= page->range.last; i++)
   393 	{
   394 	  printf ("file '%s' ", get_output_file (page->output_context));
   395 	  printf ("format '%s' ", get_output_page_number_format (page->output_context));
   396 	  printf ("page %d\n", i);
   397 	}
   398     }
   399 }
   400 #endif /* SEMANTIC_DEBUG */
   402 boolean parse_spec_file (char *fn)
   403 {
   404   boolean result = 0;
   406   yyin = fopen (fn, "r");
   407   if (! yyin)
   408     {
   409       fprintf (stderr, "can't open spec file '%s'\n", fn);
   410       goto fail;
   411     }
   413   line = 1;
   415   input_push_context ();  /* create root input context */
   416   input_push_context ();  /* create inital input context */
   418   output_push_context ();  /* create root output context */
   419   output_push_context ();  /* create initial output context */
   421   yyparse ();
   423   if (first_input_context->image_count != first_output_context->page_count)
   424     {
   425       fprintf (stderr, "input image count %d != output page count %d\n",
   426 	       first_input_context->image_count,
   427 	       first_output_context->page_count);
   428       goto fail;
   429     }
   431   fprintf (stderr, "%d pages specified\n", first_input_context->image_count);
   433   result = 1;
   435 #ifdef SEMANTIC_DEBUG
   436   dump_input_tree ();
   437   dump_output_tree ();
   438 #endif /* SEMANTIC_DEBUG */
   440  fail:
   441   if (yyin)
   442     fclose (yyin);
   444   return (result);
   445 }