data.cpp
上传用户:lhwx1029
上传日期:2013-03-07
资源大小:1173k
文件大小:32k
源码类别:

3D图形编程

开发平台:

Visual C++

  1. /** 3DGPL *************************************************
  2.  * ()                                                     *
  3.  * Interpreting ascii data description, constructing a    *
  4.  * data structure in memory, atempting to do correct      *
  5.  * alignment for items in the structs.                    *
  6.  *                                                        *
  7.  * Defines:                                               *
  8.  *  D_data                   Getting a specified export.  *
  9.  *                                                        *
  10.  * Internals:                                             *
  11.  *  DI_char                  Next char of the source;     *
  12.  *  DI_token                 Next token of the stream;    *
  13.  *  DI_type                  Interpreting type;           *
  14.  *  DI_var                   Interpreting var list;       *
  15.  *  DI_length                Length of type in bytes.     *
  16.  *                                                        *
  17.  * (c) 1995-98 Sergei Savchenko, (savs@cs.mcgill.ca)      *
  18. **********************************************************/
  19. #include "RayTracing.h"           /* HW_error */
  20. #include "data.h"                   /* self definition */
  21. #include <stdio.h>                          /* FILE etc. */
  22. #include <string.h>                         /* cmpstr etc. */
  23. #include <stdlib.h>                         /* malloc etc. */
  24. #define D_MAX_TOKEN_LENGTH 100              /* token taken from the source */
  25. #define D_NAME_LENGTH       32              /* names gotta be this long */
  26. #define D_BUFFER_LENGTH    256              /* chars being read */
  27. enum D_token_type                           /* enumerates all tokens */
  28. {
  29.  D_EOF,                                     /* end of file */
  30.  D_NAME,                                    /* starting from the letter */
  31.  D_NUMBER,                                  /* starting from a number */
  32.  D_NUMBERF,                                 /* starting from a float number */
  33.  D_BASE_INT,                                /* base types */
  34.  D_BASE_FLOAT,
  35.  D_BASE_SHORT,
  36.  D_BASE_BYTE,
  37.  D_BASE_PTR,                                /* typeless pointer */
  38.  D_DEREF,                                   /* dereferencing symbol */
  39.  D_OPEN_SQ,                                 /* describes an array */
  40.  D_CLOSE_SQ,
  41.  D_OPEN_CURL,                               /* describes a structure */
  42.  D_CLOSE_CURL,
  43.  D_OPEN_RAW,                                /* describes a raw data array */
  44.  D_CLOSE_RAW,
  45.  D_STATE_TYPE,                              /* statements */
  46.  D_STATE_VAR,                               /* "name" */
  47.  D_STATE_EXPORT
  48. };
  49. struct D_token                              /* describes a token */
  50. {
  51.  char d_description[D_MAX_TOKEN_LENGTH];    /* actual text of a token */
  52.  enum D_token_type d_type;                  /* enumeration of this token */
  53. };
  54. struct D_token D_tokens[]=                  /* what is in the grammer */
  55. {
  56. {"int"   ,D_BASE_INT},                     /* base types */
  57. {"float" ,D_BASE_FLOAT},
  58. {"short" ,D_BASE_SHORT},
  59. {"byte"  ,D_BASE_BYTE},
  60. {"ptr"   ,D_BASE_PTR},
  61. {"@"     ,D_DEREF},                        /* dereferencing symbol */
  62. {"["     ,D_OPEN_SQ},                      /* array */
  63. {"]"     ,D_CLOSE_SQ},
  64. {"{"     ,D_OPEN_CURL},                    /* structure */
  65. {"}"     ,D_CLOSE_CURL},
  66. {"<"     ,D_OPEN_RAW},                     /* raw array */
  67. {">"     ,D_CLOSE_RAW},
  68. {"type"  ,D_STATE_TYPE},                   /* statements */
  69. {"var"   ,D_STATE_VAR},
  70. {"export",D_STATE_EXPORT},
  71. {""      ,(D_token_type)0}                               /* tagging the last one */
  72. };
  73. char D_terminators[]=" nr@[]{}<>xff";    /* expression terminators */
  74. char D_filters[]=" nr";                   /* characters which are ignored */
  75. int D_current;                              /* char being read */
  76. int D_last;                                 /* how many chars are there */
  77. int D_line;                                 /* number of lines read */
  78. char *D_buffer;                             /* the chars being read */
  79. FILE *D_file;                               /* handle to the input */
  80. char D_fname[D_NAME_LENGTH];                /* name of the current file */
  81. struct D_int_alignment_struct { char d_char; int d_int; } D_int_check;
  82. struct D_float_alignment_struct { char d_char; float d_float; } D_float_check;
  83. struct D_short_alignment_struct { char d_char; short d_short; } D_short_check;
  84. struct D_ptr_alignment_struct { char d_char; char *d_ptr; } D_ptr_check;
  85. int D_int_alignment;                        /* alignment type for int */
  86. int D_float_alignment;                      /* alignment type for int */
  87. int D_short_alignment;                      /* alignment type for int */
  88. int D_ptr_alignment;                        /* gotta be same as int but... */
  89. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  90.  * Stream of chars from the script file.                 *
  91.  *                                                       *
  92.  * RETURNS: Next character from the script stream.       *
  93.  * --------                                              *
  94. * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  95. char DI_char(void)
  96. {
  97.  if(D_current<D_last)                       /* as long as have something */
  98.  {
  99.   return(D_buffer[D_current++]);            /* current char */
  100.  }
  101.  else
  102.  {
  103.   if((D_last=fread(D_buffer,sizeof(char),D_BUFFER_LENGTH,D_file))==0)
  104.    return('xff');                          /* end of the source */
  105.   D_current=0;                              /* starting from the first one */
  106.   return(D_buffer[D_current++]);
  107.  }
  108. }
  109. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  110.  * Tokenizer. token is defined as a text between         *
  111.  * a filter ( ignored ) and a terminator. token might    *
  112.  * be a terminator.                                      *
  113.  *                                                       *
  114.  * RETURNS: Type of the current token.                   *
  115.  * --------                                              *
  116.  * SETS: D_token_text,D_token_number for some kinds of   *
  117.  * ----- tokens, D_line would have number of n read.    *
  118. * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  119. char D_token_text[D_MAX_TOKEN_LENGTH];      /* set after DI_token */
  120. int D_token_number;
  121. float D_token_numberf;
  122. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  123. enum D_token_type DI_token(void)
  124. {
  125.  int i,lng=0;                               /* empty yet */
  126.  char c;
  127.  for(;;)                                    /* ignore preceding filters */
  128.  {
  129.   c=DI_char();
  130.   if(c=='xff')                             /* end of input strem */
  131.   {
  132.    D_token_text[lng]=0;                     /* no text associated here */
  133.    return(D_EOF);                           /* end of the source */
  134.   }
  135.   for(i=0;D_filters[i]!=0;i++)
  136.    if(c==D_filters[i]) break;               /* yes, filter current symbol */
  137.   if(D_filters[i]==0)
  138.   {
  139.    D_current--;                             /* process further */
  140.    break;                                   /* nope, none of filters */
  141.   }
  142.   if(D_filters[i]=='n') D_line++;          /* counter of lines read */
  143.  }
  144.  for(;;)                                    /* copy until the terminator */
  145.  {
  146.   c=DI_char();
  147.   for(i=0;D_terminators[i]!=0;i++)
  148.    if(c==D_terminators[i]) break;           /* yes, terminate on this one */
  149.   if(D_terminators[i]==0)                   /* not a terminator */
  150.   {
  151.    D_token_text[lng++]=c;                   /* char in the token */
  152.   }
  153.   else                                      /* yes a terminator */
  154.   {
  155.    D_token_text[lng]=0;                     /* end of line */
  156.    D_current--;                             /* process a terminator further */
  157.    break;                                   /* finished composing a token */
  158.   }
  159.  }
  160.  if(lng==0)                                 /* checking tokens/terminators */
  161.  {
  162.   for(i=0;strlen(D_tokens[i].d_description)!=0;i++)
  163.    if(strncmp(D_tokens[i].d_description,&c,1)==0)
  164.    {
  165.     D_current++;                            /* don't process on the next step */
  166.     return(D_tokens[i].d_type);
  167.    }
  168.  }
  169.  for(i=0;strlen(D_tokens[i].d_description)!=0;i++)
  170.   if(strcmp(D_tokens[i].d_description,D_token_text)==0)
  171.    return(D_tokens[i].d_type);              /* command token */
  172.  if(strchr(D_token_text,'.')!=NULL)
  173.  {
  174.   if(sscanf(D_token_text,"%f",&D_token_numberf)==1)
  175.    return(D_NUMBERF);                       /* is floating point */
  176.  }
  177.  if((lng>2)&&(D_token_text[0]=='0')&&
  178.              (D_token_text[1]=='x'))        /* 0x0 hexadecimal */
  179.  {
  180.   if(sscanf(D_token_text+2,"%x",&D_token_number)==1)
  181.    return(D_NUMBER);                        /* is hexadecimal */
  182.  }
  183.  if(sscanf(D_token_text,"%d",&D_token_number)==1)
  184.   return(D_NUMBER);                         /* is decimal */
  185.  return(D_NAME);                            /* can be only a name */
  186. }
  187. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  188.  * The processing of the token stream from the moment    *
  189.  * the function is called should relate to type          *
  190.  * description as follows:                               *
  191.  *                                                       *
  192.  * type = <int> | <float> | <short> | <byte> | <ptr> |   *
  193.  *      | <[>number<]>type | <{> type {type} <}>         *
  194.  *                                                       *
  195.  * RETURNS: Number of the type just created.             *
  196.  * --------                                              *
  197. * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  198. struct D_type_name                          /* relates type name and number */
  199. {
  200.  char d_name[D_NAME_LENGTH];                /* type name */
  201.  int d_type;                                /* type number */
  202. };
  203. struct D_type                               /* describes a type */
  204. {
  205.  int d_array;                               /* number of elements or -1 */
  206.  int d_next;                                /* next item or -1 */
  207.  int d_current;                             /* this type */
  208. };
  209. struct D_var_name                           /* description of a variable */
  210. {
  211.  char d_name[D_NAME_LENGTH];                /* name of a variable */
  212.  char *d_data;                              /* allocated data */
  213.  int d_type;                                /* type of a variable */
  214. };
  215. #define D_SINGULAR    0                     /* not an array type */
  216. #define D_NONE       -1                     /* kinda internal NULL */
  217. #define D_TYPE_INT   -2                     /* base types: integer */
  218. #define D_TYPE_FLOAT -3
  219. #define D_TYPE_SHORT -4
  220. #define D_TYPE_BYTE  -5                     /* byte */
  221. #define D_TYPE_PTR   -6                     /* and pointer */
  222. #define D_MAX_TYPES      512                /* sizes for tables */
  223. #define D_MAX_VAR_NAMES  512
  224. #define D_MAX_TYPE_NAMES 512
  225. struct D_type_name *D_type_names;           /* relates names to numbers */
  226. int D_no_type_names;                        /* number of names */
  227. struct D_type *D_types;                     /* all types */
  228. int D_no_types;                             /* number of all types */
  229. struct D_var_name *D_var_names;             /* all variable names */
  230. int D_no_var_names;                         /* number of variables */
  231. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  232. int DI_type(void)
  233. {
  234.  int prev,orig=0,tp,i;
  235.  switch(DI_token())
  236.  {
  237.   case D_NAME:      for(i=0;i<D_no_type_names;i++)
  238.                      if(strcmp(D_token_text,D_type_names[i].d_name)==0)
  239.                       return(D_type_names[i].d_type);
  240.                     HW_error("(%s:%d) Unknown type name: %sn",D_fname,D_line,D_token_text);
  241.                     break;
  242.   case D_BASE_INT:  return(D_TYPE_INT);     /* base type int */
  243.   case D_BASE_FLOAT: return(D_TYPE_FLOAT);  /* base type float */
  244.   case D_BASE_SHORT:return(D_TYPE_SHORT);   /* base type short */
  245.   case D_BASE_BYTE: return(D_TYPE_BYTE);    /* byte type byte */
  246.   case D_BASE_PTR:  return(D_TYPE_PTR);     /* base type typeless ptr */
  247.   case D_OPEN_SQ:   if(DI_token()!=D_NUMBER)/* array [N] */
  248.                      HW_error("(%s:%d) Number expected.n",D_fname,D_line);
  249.                     D_types[D_no_types].d_array=D_token_number;
  250.                     D_types[tp=D_no_types++].d_next=-1;
  251.                     if(D_no_types>=D_MAX_TYPES)
  252.                      HW_error("(Data) No space in type list.n");
  253.                     if(DI_token()!=D_CLOSE_SQ)
  254.                      HW_error("(%s:%d) Closing bracket expected.n",
  255.                               D_fname,D_line
  256.                              );
  257.                     D_types[tp].d_current=DI_type();
  258.                     return(tp);             /* was an array type */
  259.   case D_OPEN_CURL: prev=D_NONE;            /* no first in the chain yet */
  260.                     while((tp=DI_type())!=D_NONE)
  261.                     {
  262.                      D_types[D_no_types].d_array=D_SINGULAR;
  263.                      D_types[D_no_types].d_current=tp;
  264.                      tp=D_no_types++;       /* just created type is */
  265.                      if(D_no_types>=D_MAX_TYPES)
  266.                       HW_error("(Data) No space in type list.n");
  267.                      if(prev!=D_NONE)       /* extending the chain */
  268.                       D_types[prev].d_next=tp;
  269.                      else
  270.                       orig=tp;              /* head of the chain */
  271.                      prev=tp;               /* to allow extention further */
  272.                     }
  273.                     D_types[prev].d_next=D_NONE;
  274.                     return(orig);           /* head of the chain */
  275.   case D_CLOSE_CURL:return(D_NONE);         /* no more types in the list */
  276.   default:          HW_error("(%s:%d) Type defenition expected.n",
  277.                              D_fname,D_line
  278.                             );
  279.  }
  280.  return(D_NONE);                            /* would never happen, actually */
  281. }
  282. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  283.  * The processing of the token stream from the moment    *
  284.  * the function is called should correspond to passed    *
  285.  * type and relate to variable defenition as follows:    *
  286.  *                                                       *
  287.  * var = number | reference | @reference | file_name |   *
  288.  *     | <[> var {var} <]> | <{> var {var} <}>           *
  289.  *                                                       *
  290.  * RETURNS: Number of bytes filled by the definition.    *
  291.  * --------                                              *
  292. * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  293. int DI_var(int type,char* space)
  294. {
  295.  enum D_token_type tp;
  296.  char *orig_space=space;                    /* where the start was */
  297.  int i;
  298.  if(type==D_TYPE_BYTE)                      /* base type byte */
  299.  {
  300.   switch(DI_token())                        /* number or @name */
  301.   {
  302.    case D_NUMBER: *(char*)space=(char)D_token_number;
  303.                   return(sizeof(char));
  304.    case D_DEREF:  DI_token();               /* getting name */
  305.                   for(i=0;i<D_no_var_names;i++)
  306.                    if(strcmp(D_token_text,D_var_names[i].d_name)==0) break;
  307.                   if(i==D_no_var_names)
  308.                    HW_error("(%s:%d) Unknown name %s.n",
  309.                             D_fname,D_line,D_token_text
  310.                            );
  311.                   if(D_var_names[i].d_type!=D_TYPE_BYTE)
  312.                    HW_error("(%s:%d) %s Expected to be a constant.n",
  313.                             D_fname,D_line,D_token_text
  314.                            );
  315.                   *(char*)space=*(char*)D_var_names[i].d_data;
  316.                   return(sizeof(char));
  317.    default:       HW_error("(%s:%d) Constant expected.n",D_fname,D_line);
  318.   }
  319.  }
  320.  if(type==D_TYPE_SHORT)                     /* base type short */
  321.  {
  322.   if(((long)space)%D_short_alignment!=0)
  323.    space+=D_short_alignment-((long)space)%D_short_alignment;
  324.   switch(DI_token())                        /* number of @name */
  325.   {
  326.    case D_NUMBER: *(short*)space=(short)D_token_number;
  327.                   space+=sizeof(short);
  328.                   return(space-orig_space); /* pointer difference */
  329.    case D_DEREF:  DI_token();               /* getting name */
  330.                   for(i=0;i<D_no_var_names;i++)
  331.                    if(strcmp(D_token_text,D_var_names[i].d_name)==0) break;
  332.                   if(i==D_no_var_names)
  333.                    HW_error("(%s:%d) Unknown name %s.n",
  334.                             D_fname,D_line,D_token_text
  335.                            );
  336.                   if(D_var_names[i].d_type!=D_TYPE_SHORT)
  337.                    HW_error("(%s:%d) %s Expected to be a constant.n",
  338.                             D_fname,D_line,D_token_text
  339.                            );
  340.                   *(short*)space=*(short*)D_var_names[i].d_data;
  341.                   space+=sizeof(short);
  342.                   return(space-orig_space); /* pointer difference */
  343.    default:       HW_error("(%s:%d) Constant expected.n",D_fname,D_line);
  344.   }
  345.  }
  346.  if(type==D_TYPE_INT)                       /* base type int */
  347.  {
  348.   if(((long)space)%D_int_alignment!=0)
  349.    space+=D_int_alignment-((long)space)%D_int_alignment;
  350.   switch(DI_token())                        /* number of @name */
  351.   {
  352.    case D_NUMBER: *(int*)space=D_token_number;
  353.                   space+=sizeof(int);
  354.                   return(space-orig_space); /* pointer difference */
  355.    case D_DEREF:  DI_token();               /* getting name */
  356.                   for(i=0;i<D_no_var_names;i++)
  357.                    if(strcmp(D_token_text,D_var_names[i].d_name)==0) break;
  358.                   if(i==D_no_var_names)
  359.                    HW_error("(%s:%d) Unknown name %s.n",
  360.                             D_fname,D_line,D_token_text
  361.                            );
  362.                   if(D_var_names[i].d_type!=D_TYPE_INT)
  363.                    HW_error("(%s:%d) %s Expected to be a constant.n",
  364.                             D_fname,D_line,D_token_text
  365.                            );
  366.                   *(int*)space=*(int*)D_var_names[i].d_data;
  367.                   space+=sizeof(int);
  368.                   return(space-orig_space); /* pointer difference */
  369.    default:       HW_error("(%s:%d) Constant expected.n",D_fname,D_line);
  370.   }
  371.  }
  372.  if(type==D_TYPE_FLOAT)                     /* base type float */
  373.  {
  374.   if(((long)space)%D_float_alignment!=0)
  375.    space+=D_float_alignment-((long)space)%D_float_alignment;
  376.   switch(DI_token())                        /* number of @name */
  377.   {
  378.    case D_NUMBERF:*(float*)space=D_token_numberf;
  379.                   space+=sizeof(float);
  380.                   return(space-orig_space); /* pointer difference */
  381.    case D_NUMBER: *(float*)space=(float)D_token_number;
  382.                   space+=sizeof(float);
  383.                   return(space-orig_space); /* pointer difference */
  384.    case D_DEREF:  DI_token();               /* getting name */
  385.                   for(i=0;i<D_no_var_names;i++)
  386.                    if(strcmp(D_token_text,D_var_names[i].d_name)==0) break;
  387.                   if(i==D_no_var_names)
  388.                    HW_error("(%s:%d) Unknown name %s.n",
  389.                             D_fname,D_line,D_token_text
  390.                            );
  391.                   if(D_var_names[i].d_type!=D_TYPE_FLOAT)
  392.                    HW_error("(%s:%d) %s Expected to be a constant.n",
  393.                             D_fname,D_line,D_token_text
  394.                            );
  395.                   *(float*)space=*(float*)D_var_names[i].d_data;
  396.                   space+=sizeof(float);
  397.                   return(space-orig_space); /* pointer difference */
  398.    default:       HW_error("(%s:%d) Constant expected.n",D_fname,D_line);
  399.   }
  400.  }
  401.  if(type==D_TYPE_PTR)                       /* base type pointer */
  402.  {
  403.   if(((long)space)%D_ptr_alignment!=0)
  404.    space+=D_ptr_alignment-((long)space)%D_ptr_alignment;
  405.   switch(DI_token())                        /* 0 or @name or name */
  406.   {
  407.    case D_NUMBER: if(D_token_number!=0)
  408.                    HW_error("(%s:%d) Only "0" allowed as a pointer.n",
  409.                             D_fname,D_line
  410.                            );
  411.                   *(char**)space=NULL;      /* 0 == NULL */
  412.                   space+=sizeof(char*);
  413.                   return(space-orig_space); /* pointer difference */
  414.    case D_NAME:   for(i=0;i<D_no_var_names;i++)
  415.                    if(strcmp(D_token_text,D_var_names[i].d_name)==0) break;
  416.                   if(i==D_no_var_names)     /* not a name, a file? */
  417.                   {
  418.                    int DD_current=D_current;/* stack of globals for */
  419.                    int DD_last=D_last;      /* recursive call to D_data */
  420.                    int DD_line=D_line;
  421.                    char *DD_buffer=D_buffer;
  422.                    FILE *DD_file=D_file;
  423.                    struct D_type_name *DD_type_names=D_type_names;
  424.                    int DD_no_type_names=D_no_type_names;
  425.                    struct D_type *DD_types=D_types;
  426.                    int DD_no_types=D_no_types;
  427.                    struct D_var_name *DD_var_names=D_var_names;
  428.                    int DD_no_var_names=D_no_var_names;
  429.                    char DD_fname[D_NAME_LENGTH];
  430.                    strncpy(DD_fname,D_fname,D_NAME_LENGTH);
  431.                    if(strcmp(DD_fname,D_token_text)==0)
  432.                     HW_error("(%s:%d) Can't recurse files, think about it.n",
  433.                              D_fname,D_line
  434.                             );
  435.                    *(char**)space=(char *)D_data(D_token_text);
  436.                    strncpy(D_fname,DD_fname,D_NAME_LENGTH);
  437.                    D_no_var_names=DD_no_var_names;
  438.                    D_var_names=DD_var_names;
  439.                    D_no_types=DD_no_types;
  440.                    D_types=DD_types;
  441.                    D_no_type_names=DD_no_type_names;
  442.                    D_type_names=DD_type_names;
  443.                    D_file=DD_file;
  444.                    D_buffer=DD_buffer;
  445.                    D_line=DD_line;
  446.                    D_last=DD_last;
  447.                    D_current=DD_current;    /* restoring globals from stack */
  448.                   }
  449.                   else                      /* a name */
  450.                   {
  451.                    *(char**)space=D_var_names[i].d_data;
  452.                   }
  453.                   space+=sizeof(char*);
  454.                   return(space-orig_space); /* pointer difference */
  455.    case D_DEREF:  DI_token();               /* getting name */
  456.                   for(i=0;i<D_no_var_names;i++)
  457.                    if(strcmp(D_token_text,D_var_names[i].d_name)==0) break;
  458.                   if(i==D_no_var_names)
  459.                    HW_error("(%s:%d) Unknown name %s.n",
  460.                             D_fname,D_line,D_token_text
  461.                            );
  462.                   if(D_var_names[i].d_type!=D_TYPE_PTR)
  463.                    HW_error("(%s:%d) %s Expected to be a constant pointer.n",
  464.                             D_fname,D_line,D_token_text
  465.                            );
  466.                   *(char**)space=*(char**)D_var_names[i].d_data;
  467.                   space+=sizeof(char*);
  468.                   return(space-orig_space); /* pointer difference */
  469.    default:       HW_error("(%s:%d) Name or "0" expected.n",D_fname,D_line);
  470.   }
  471.  }
  472.  if(D_types[type].d_array!=D_SINGULAR)      /* type is an array */
  473.  {
  474.   tp=DI_token();
  475.   if(tp==D_OPEN_RAW)                        /* raw byte array */
  476.   {
  477.    if(D_types[type].d_current!=D_TYPE_BYTE) /* raw array starts with "<" */
  478.     HW_error("(%s:%d) Raw array is allowed only for bytes.n",D_fname,D_line);
  479.    for(i=0;i<D_types[type].d_array;i++,space++)
  480.     *space=DI_char();
  481.    if(DI_token()!=D_CLOSE_RAW)              /* raw array ends with ">" */
  482.     HW_error("(%s:%d) Closing bracket expected.n",D_fname,D_line);
  483.    return(space-orig_space);                /* pointer difference */
  484.   }
  485.   else
  486.   {
  487.    if(tp!=D_OPEN_SQ)                        /* array starts with "[" */
  488.     HW_error("(%s:%d) Opening bracket expected.n",D_fname,D_line);
  489.    for(i=0;i<D_types[type].d_array;i++)     /* processing elements */
  490.     space+=DI_var(D_types[type].d_current,space);
  491.    if(DI_token()!=D_CLOSE_SQ)               /* array ends with "]" */
  492.     HW_error("(%s:%d) Closing bracket expected.n",D_fname,D_line);
  493.    return(space-orig_space);                /* pointer difference */
  494.   }
  495.  }
  496.  if(D_types[type].d_next!=D_NONE)           /* a structure? */
  497.  {
  498.   if(DI_token()!=D_OPEN_CURL)               /* struct starts with "{" */
  499.    HW_error("(%s:%d) Opening bracket expected.n",D_fname,D_line);
  500.   for(;type!=D_NONE;type=D_types[type].d_next)
  501.    space+=DI_var(D_types[type].d_current,space);
  502.   if(DI_token()!=D_CLOSE_CURL)              /* struct ends with "}" */
  503.    HW_error("(%s:%d) Closing bracket expected.n",D_fname,D_line);
  504.   return(space-orig_space);                 /* pointer difference */
  505.  }
  506.  return(space-orig_space);                  /* pointer difference */
  507. }
  508. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  509.  * Size of a type defined in types table.                *
  510.  *                                                       *
  511.  * RETURNS: Length in bytes of the requested type.       *
  512.  * --------                                              *
  513. * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  514. int DI_length(int type,int current_length)
  515. {
  516.  int alignment,lng=0;
  517.  if(type==D_TYPE_BYTE) return(sizeof(char));/* base types */
  518.  if(type==D_TYPE_SHORT)
  519.  {
  520.   if(current_length%D_short_alignment==0) alignment=0;
  521.   else alignment=D_short_alignment-current_length%D_short_alignment;
  522.   return(sizeof(short)+alignment);
  523.  }
  524.  if(type==D_TYPE_INT)
  525.  {
  526.   if(current_length%D_int_alignment==0) alignment=0;
  527.   else alignment=D_int_alignment-current_length%D_int_alignment;
  528.   return(sizeof(int)+alignment);
  529.  }
  530.  if(type==D_TYPE_FLOAT)
  531.  {
  532.   if(current_length%D_float_alignment==0) alignment=0;
  533.   else alignment=D_float_alignment-current_length%D_float_alignment;
  534.   return(sizeof(float)+alignment);
  535.  }
  536.  if(type==D_TYPE_PTR)
  537.  {
  538.   if(current_length%D_ptr_alignment==0) alignment=0;
  539.   else alignment=D_ptr_alignment-current_length%D_ptr_alignment;
  540.   return(sizeof(char*)+alignment);
  541.  }
  542.  if(D_types[type].d_array!=D_SINGULAR)      /* type is an array */
  543.  {                                          /* first item might be aligned */
  544.   alignment=DI_length(D_types[type].d_current,current_length);
  545.   return((D_types[type].d_array-1)*DI_length(D_types[type].d_current,0)+
  546.          alignment
  547.         );
  548.  }
  549.  if(D_types[type].d_next!=D_NONE)           /* a structure? */
  550.  {
  551.   for(;type!=D_NONE;type=D_types[type].d_next)
  552.    lng+=DI_length(D_types[type].d_current,lng);
  553.  }
  554.  return(lng);
  555. }
  556. /*********************************************************
  557.  * Processing specified input file remembering type info *
  558.  * in <type> statements, constructing variables on <var> *
  559.  * statements processing stops on first export statement.*
  560.  *                                                       *
  561.  * source = <type> name type |                           *
  562.  *        | <var> type name var |                        *
  563.  *        | <export> name                                *
  564.  *                                                       *
  565.  * RETURNS: Pointer to data specified in first export.   *
  566.  * --------                                              *
  567. *********************************************************/
  568. void* D_data(char *name)
  569. {
  570.  char *data=NULL;                           /* pointer to be returned */
  571.  int tp,i,quit=0;                           /* flag when to quit */
  572.  long lng;
  573.  D_int_alignment=((char*)&D_int_check.d_int)-((char*)&D_int_check.d_char);
  574.  D_float_alignment=((char*)&D_float_check.d_float)-((char*)&D_float_check.d_char);
  575.  D_short_alignment=((char*)&D_short_check.d_short)-((char*)&D_short_check.d_char);
  576.  D_ptr_alignment=((char*)&D_ptr_check.d_ptr)-((char*)&D_ptr_check.d_char);
  577.  strncpy(D_fname,name,D_NAME_LENGTH);       /* for error messages */
  578.  if((D_file=fopen(name,"rb"))==NULL)        /* where to take data from */
  579.   HW_error("(Data) Can't open %s.n",D_fname);
  580.  D_current=D_last=0;                        /* the buffer is empty */
  581.  D_line=1;                                  /* initally at first line */
  582.  D_buffer=(char*)malloc(D_BUFFER_LENGTH*sizeof(char));
  583.  if(D_buffer==NULL) HW_error("(Data) Not enough memory.n");
  584.  D_type_names=(struct D_type_name*)malloc(D_MAX_TYPE_NAMES*
  585.                sizeof(struct D_type_name));
  586.  D_types=(struct D_type*)malloc(D_MAX_TYPES*sizeof(struct D_type));
  587.  D_var_names=(struct D_var_name*)malloc(D_MAX_VAR_NAMES*
  588.               sizeof(struct D_var_name));
  589.  if((D_type_names==NULL)||(D_types==NULL)||(D_var_names==NULL))
  590.   HW_error("(Data) Not enough memory.n");
  591.  D_no_type_names=D_no_types=D_no_var_names=0;/* all tables are empty */
  592.  do
  593.  {
  594.   switch(DI_token())
  595.   {
  596.    case D_STATE_TYPE:  if(DI_token()!=D_NAME)
  597.                         HW_error("(%s:%d) Name expected.n",D_fname,D_line);
  598.                        for(i=0;i<D_no_type_names;i++)
  599.                         if(strcmp(D_token_text,D_type_names[i].d_name)==0)
  600.                          HW_error("(%s:%d) Duplicate type name %s.n",
  601.                                   D_fname,D_line,D_token_text
  602.                                  );
  603.                        strncpy(D_type_names[D_no_type_names].d_name,
  604.                                D_token_text,D_NAME_LENGTH
  605.                               );
  606.                        D_type_names[D_no_type_names++].d_type=DI_type();
  607.                        if(D_no_type_names>=D_MAX_TYPE_NAMES)
  608.                         HW_error("(Data) No space in type table.n");
  609.                        break;
  610.    case D_STATE_VAR:   D_var_names[D_no_var_names].d_data=(char*)
  611.                        malloc(lng=sizeof(char)*DI_length(tp=DI_type(),0));
  612.                        if(D_var_names[D_no_var_names].d_data==NULL)
  613.                         HW_error("(Data) Not enough memory %ld.n",lng);
  614.                        D_var_names[D_no_var_names].d_type=tp;
  615.                        if(DI_token()!=D_NAME)
  616.                         HW_error("(%s:%d) Name expected.n",D_fname,D_line);
  617.                        for(i=0;i<D_no_var_names;i++)
  618.                         if(strcmp(D_token_text,D_var_names[i].d_name)==0)
  619.                          HW_error("(%s:%d) Duplicate variable name %s.n",
  620.                                   D_fname,D_line,D_token_text
  621.                                  );
  622.                        strncpy(D_var_names[D_no_var_names].d_name,
  623.                                D_token_text,D_NAME_LENGTH
  624.                               );
  625.                        DI_var(tp,D_var_names[D_no_var_names++].d_data);
  626.                        if(D_no_var_names>=D_MAX_VAR_NAMES)
  627.                         HW_error("(Data) No space in var table.n");
  628.                        break;
  629.    case D_STATE_EXPORT:if(DI_token()!=D_NAME)
  630.                         HW_error("(%s:%d) Name expected.n",D_fname,D_line);
  631.                        for(i=0;i<D_no_var_names;i++)
  632.                         if(strcmp(D_token_text,D_var_names[i].d_name)==0) break;
  633.                        if(i==D_no_var_names)
  634.                         HW_error("(%s:%d) Unknown variable name %s.n",
  635.                                  D_fname,D_line,D_token_text
  636.                                 );
  637.                        data=D_var_names[i].d_data;
  638.                        quit=1;              /* quit processing */
  639.                        break;
  640.    default:            HW_error("(%s:%d) No such statement %s.n",
  641.                                 D_fname,D_line,D_token_text
  642.                                );
  643.   }
  644.  } while(!quit);
  645.  fclose(D_file);
  646.  free(D_buffer);                            /* getting rid of all tables */
  647.  free(D_type_names);
  648.  free(D_types);
  649.  free(D_var_names);
  650.  return(data);                              /* constructed structure */
  651. }
  652. /**********************************************************/