home *** CD-ROM | disk | FTP | other *** search
/ Graphics 16,000 / graphics-16000.iso / msdos / animutil / pvquan / animdat / animdat.c next >
C/C++ Source or Header  |  1992-11-30  |  11KB  |  403 lines

  1. /*--------------------------------------------------------------*/
  2. /*            ANIMDAT 1.1                */
  3. /*        copyright 1992 - TODD SANKEY            */
  4. /*                                */
  5. /*  The author hereby grants permission for the use and sharing    */
  6. /* of both source code end executable versions of this software    */
  7. /* at no charge. This software is not for sale and no other    */
  8. /* shall charge for it without the expressed consent of the    */
  9. /* author.                            */
  10. /*                                */
  11. /*  The source code can be freely modified, but it must retain    */
  12. /* the original copyright notice, and the author must be    */
  13. /* notified of these changes if the altered code is to be    */
  14. /* distributed.                            */
  15. /*--------------------------------------------------------------*/
  16.  
  17.  
  18. /*--------------------------------------------------------------*/
  19. /* animdat.c        Main file for animdat program.        */
  20. /*--------------------------------------------------------------*/
  21.  
  22. #include <stdlib.h>
  23. #include <stdio.h>
  24. #include <string.h>
  25. #include <ctype.h>
  26. #include <math.h>
  27. #include "common.h"
  28.  
  29. /*  This definition controls what filenames are used for the generated    */
  30. /* files. If LONG_FILENAMES is not defined, then the generated files    */
  31. /* are named SCENEnnn.DAT where nnn is the number of the scene. If    */
  32. /* LONG_FILENAMES is defined, the generated filenames use the root name    */
  33. /* given on the command line and add _nnn.DAT .                */
  34. /*  This option is given because DOS machines have the limit of 8    */
  35. /* characters in the filename, so LONG_FILENAMES should not be used.    */
  36. #define    LONG_FILENAMES
  37.  
  38. #ifdef LONG_FILENAMES
  39. #define MAX_FNAME_SIZE 100
  40. #else
  41. #define MAX_FNAME_SIZE 13
  42. #endif
  43.  
  44. #define NAMELEN 20
  45. #define NUMLEN 20
  46. #define MAXSCENES 100
  47. #define VARCHAR '@'
  48. #define GATECHAR '&'
  49. #define MAX_LINE_SIZE 256
  50.  
  51.  
  52. /* Globals used in other modules */
  53. int        numscenes = -1;
  54. sym_ptr        symbol_table = NULL;
  55. char        cur_line[MAX_LINE_SIZE];
  56. char        *cur_file = NULL;
  57. unsigned int    cur_line_num = 0;
  58.  
  59.  
  60. /* Used within animdat.c */
  61. static sym_ptr    x_symbol = NULL;
  62. static sym_ptr    cur_sc_symbol = NULL;
  63. static sym_ptr    num_sc_symbol = NULL;
  64. static char    *cur_symbol = NULL;
  65. static int    gate_closed = 0;
  66.  
  67.  
  68. /*--------------------------------------------------------------*/
  69. /* parse_equation    Attaches a binary tree representation    */
  70. /*            of a mathematical expression to a symbol*/
  71. /*            given that the scanner module is    */
  72. /*            initialized to the first token in the    */
  73. /*            expression.                */
  74. /*--------------------------------------------------------------*/
  75. void parse_equation(sym_ptr new_symbol)
  76. {
  77.  new_symbol->sym_info = (void *)expression();
  78.  new_symbol->sym_type = SYM_DOUBLE;
  79.  if (token == COMMA) {
  80.     double sign_flag = 1.0;
  81.     get_token();
  82.     if (token == MINUS) {
  83.         sign_flag = (-1.0);
  84.         get_token();
  85.         }
  86.     else if (token == PLUS)
  87.         get_token();
  88.  
  89.     if (token == NUMBER)
  90.         new_symbol->cur_val = sign_flag * literal_value;
  91.     else
  92.         error(SYNTAX_ERROR,cur_line);
  93.     }
  94.  
  95. }
  96.  
  97.  
  98.  
  99. /*--------------------------------------------------------------*/
  100. /* parse_filename    Attaches a file pointer to a symbol.    */
  101. /*--------------------------------------------------------------*/
  102. void parse_filename(sym_ptr new_symbol)
  103. {
  104.  get_token();
  105.  new_symbol->sym_type = SYM_FILE;
  106.  new_symbol->sym_info = (void *)fopen(word_string,"r");
  107.  if (new_symbol->sym_info == NULL)
  108.     error(FILE_ERROR,word_string);
  109.  get_token();
  110. }
  111.  
  112.  
  113. /*--------------------------------------------------------------*/
  114. /* parse_string        Attaches a string pointer to a symbol.    */
  115. /*--------------------------------------------------------------*/
  116. void parse_string(sym_ptr new_symbol)
  117. {
  118.  char *quote;
  119.  
  120.  quote=(char *)malloc(strlen(word_string)+1);
  121.  if (quote == NULL)
  122.     error(FAILED_MALLOC,NULL);
  123.  
  124.  strcpy(quote,word_string);
  125.  new_symbol->sym_type = SYM_STRING;
  126.  new_symbol->sym_info = (void *)quote;
  127.  get_token();
  128. }
  129.  
  130.  
  131.  
  132.  
  133. /*--------------------------------------------------------------*/
  134. /* parsevarfile        Attempts to parse a file as a sequence    */
  135. /*            of lines each containing a symbol name    */
  136. /*            and a definition.            */
  137. /*--------------------------------------------------------------*/
  138. void parsevarfile(FILE *varfile)
  139. {
  140.  int i;
  141.  sym_ptr new_symbol;
  142.  
  143.  cur_line_num = 0;
  144.  while (!feof(varfile)) {
  145.     /* Read the current line of the file into a buffer */
  146.     if (fgets(cur_line,MAX_LINE_SIZE,varfile) != NULL) {
  147.         cur_line_num++;
  148.         for (i=0; i<MAX_LINE_SIZE && cur_line[i]!='\0'; i++);
  149.         if (cur_line[i]!='\0' || i>=MAX_LINE_SIZE)
  150.             error(LINE_TOO_LONG,cur_line);
  151.  
  152.         init_scanner(cur_line);
  153.  
  154.         if (token == IDENTIFIER) {
  155.             new_symbol = add_symbol(&symbol_table, word_string);
  156.             get_token();
  157.             if (token != EQUAL)
  158.                 error(SYNTAX_ERROR,cur_line);
  159.             get_token();
  160.             switch (token) {
  161.                 case POUND : parse_filename(new_symbol);break;
  162.                 case QUOTE : parse_string(new_symbol);    break;
  163.                 default    : parse_equation(new_symbol);
  164.                 }
  165.             }
  166.         else if (token == NUMSCENE) {
  167.             get_token();
  168.             if (token != EQUAL)
  169.                 error(SYNTAX_ERROR,cur_line);
  170.             get_token();
  171.             if (token != NUMBER)
  172.                 error(SYNTAX_ERROR,cur_line);
  173.             numscenes = (int)literal_value;
  174.             get_token();
  175.             }
  176.         else if (token != END_OF_FILE)
  177.             error(SYNTAX_ERROR,cur_line);
  178.         }
  179.     }
  180.  
  181.  cur_line_num = 0;
  182. }
  183.  
  184.  
  185. /*--------------------------------------------------------------*/
  186. /* add_system_variables        Creates the predefined symbols    */
  187. /*                but leaves them undefined.    */
  188. /*--------------------------------------------------------------*/
  189. void add_system_variables(void)
  190. {
  191.  num_sc_symbol = add_symbol(&symbol_table,"num_scenes");
  192.  x_symbol = add_symbol(&symbol_table,"x");
  193.  cur_sc_symbol = add_symbol(&symbol_table,"cur_scene");
  194. }
  195.  
  196.  
  197.  
  198.  
  199. /*--------------------------------------------------------------*/
  200. /* update_system_variables    Defines the system variables.    */
  201. /*--------------------------------------------------------------*/
  202. void update_system_variables(void)
  203. {
  204.  char eq[MAX_LINE_SIZE];
  205.  double xinc;
  206.  
  207.  xinc = 1.0 / ((double)numscenes);
  208.  sprintf(eq,"x + %lf \0",xinc);
  209.  init_scanner(eq);
  210.  x_symbol->sym_info = (void *)expression();
  211.  x_symbol->cur_val = 0.0;
  212.  x_symbol->sym_type = SYM_DOUBLE;
  213.  
  214.  sprintf(eq,"cur_scene + 1 \0");
  215.  init_scanner(eq);
  216.  cur_sc_symbol->sym_info = (void *)expression();
  217.  cur_sc_symbol->cur_val = 0.0;
  218.  cur_sc_symbol->sym_type = SYM_DOUBLE;
  219.  
  220.  sprintf(eq,"%d \0",numscenes);
  221.  init_scanner(eq);
  222.  num_sc_symbol->sym_info = (void *)expression();
  223.  num_sc_symbol->cur_val = (double)numscenes;
  224.  num_sc_symbol->sym_type = SYM_DOUBLE;
  225. }
  226.  
  227.  
  228.  
  229.  
  230.  
  231. /*--------------------------------------------------------------*/
  232. /* check_btree        Scans a binary tree representation    */
  233. /*            of a mathematical expression checking    */
  234. /*            for undefined symbols.            */
  235. /*--------------------------------------------------------------*/
  236. void check_btree(btree_node_ptr bnode)
  237. {
  238.  if (bnode->node_type == NAMEDVAR) {
  239.     if (search_symtab(symbol_table,bnode->node_data.name) == NULL) {
  240.         sprintf(cur_line,"%s in definition of %s",bnode->node_data.name,cur_symbol);
  241.         error(UNDEFINED_SYMBOL,cur_line);
  242.         }
  243.     }
  244. }
  245.  
  246.  
  247.  
  248.  
  249. /*--------------------------------------------------------------*/
  250. /* check_symbol        Verifies the definition of a symbol.    */
  251. /*--------------------------------------------------------------*/
  252. void check_symbol(sym_ptr symbol)
  253. {
  254.  cur_symbol = symbol->name;
  255.  if (symbol->sym_type == SYM_DOUBLE)
  256.     traverse_btree((btree_node_ptr)(symbol->sym_info),check_btree);
  257. }
  258.  
  259.  
  260.  
  261.  
  262. /*--------------------------------------------------------------*/
  263. /* reset_flags        Clears the flag in a symbol which    */
  264. /*            indicates that the symbol value has    */
  265. /*            already been evaluated for this scene.    */
  266. /*--------------------------------------------------------------*/
  267. void reset_flags(sym_ptr symbol)
  268. {
  269.  symbol->update_flag = 0;
  270. }
  271.  
  272.  
  273.  
  274.  
  275. void main(int argc,char **argv)
  276. {
  277.  int    curscene,inchar,i;
  278.  char    varname[MAX_LINE_SIZE];
  279.  FILE    *datfile,*curscenefile,*varfile;
  280.  char    dat_name[MAX_FNAME_SIZE];
  281.  char    var_name[MAX_FNAME_SIZE];
  282.  char    scene_name[MAX_FNAME_SIZE];
  283.  
  284.  if (argc != 2) {
  285.     printf("ANIMDAT <root file>\n");
  286.     printf("  where rootfile.dat is the template file\n");
  287.     printf("  and   rootfile.var is the variable definition file\n");
  288.     exit(1);
  289.     }
  290.  
  291.  strcpy(dat_name, argv[1]);
  292.  strcat(dat_name,".pov");
  293.  datfile=fopen(dat_name,"r");
  294.  if (datfile == NULL) {
  295.     printf(" Could not open datfile: %s\n", dat_name);
  296.     exit(1);
  297.     }
  298.  
  299.  strcpy(var_name, argv[1]);
  300.  strcat(var_name, ".var");
  301.  varfile=fopen(var_name,"r");
  302.  if (varfile == NULL) {
  303.     printf(" Could not open varfile: %s\n", var_name);
  304.     exit(1);
  305.     }
  306.  
  307.  cur_file = var_name;
  308.  add_system_variables();
  309.  parsevarfile(varfile);
  310.  fclose(varfile);
  311.  update_system_variables();
  312.  traverse_symtab(symbol_table,check_symbol);
  313.  
  314.  if (numscenes<=0)
  315.     error(NO_NUMSCENE,NULL);
  316.  
  317.  cur_file = dat_name;
  318.  cur_line_num = 1;
  319.  
  320. #ifndef LONG_FILENAMES
  321.  strcpy(scene_name,"scene000.dat");
  322. #endif
  323.  
  324.  for (curscene=1;curscene<=numscenes;curscene++) {
  325.  
  326. #ifdef LONG_FILENAMES
  327.     sprintf(scene_name,"%s_%d.pov",argv[1],curscene - 1);
  328. #else
  329.     sprintf(scene_name,"scene%03d.pov",curscene - 1);
  330. #endif
  331.  
  332.     curscenefile=fopen(scene_name,"w");
  333.  
  334.     if (curscenefile==NULL) {
  335.         printf("Could not open file %s\n",scene_name);
  336.         exit(1);
  337.         }
  338.  
  339.     rewind(datfile);
  340.     traverse_symtab(symbol_table,reset_flags);
  341.  
  342.     gate_closed = 0;
  343.     while (!feof(datfile)) {
  344.         inchar=fgetc(datfile);
  345.  
  346.         switch (inchar) {
  347.         case VARCHAR :
  348.             if (!gate_closed) {
  349.                 i = 0;
  350.                 do {
  351.                     inchar=fgetc(datfile);
  352.                     if (inchar != VARCHAR) {
  353.                         varname[i] = inchar;
  354.                         i++;
  355.                         }
  356.                     } while ( i < (MAX_LINE_SIZE - 1) && inchar !=VARCHAR);
  357.  
  358.                 varname[i] = '\0';
  359.                 if (inchar!=VARCHAR)
  360.                     fprintf(curscenefile,"%c%s",VARCHAR,varname);
  361.                 else
  362.                     print_symbol(curscenefile,varname);
  363.                 }
  364.             break;
  365.  
  366.         case GATECHAR :
  367.             inchar = fgetc(datfile);
  368.             if (isalpha(inchar)) {    /* Assume start of gate */
  369.                 i = 0;
  370.                 do {
  371.                     varname[i] = inchar;
  372.                     i++;
  373.                     inchar = fgetc(datfile);
  374.                     } while (i < (MAX_LINE_SIZE - 1) && (isalnum(inchar) || inchar == '_'));
  375.                 varname[i] = '\0';
  376.                 if ( (eval_symbol(varname) <= 0.0) || gate_closed)
  377.                     gate_closed++;
  378.                 }
  379.  
  380.             else if (gate_closed)
  381.                 gate_closed--; /* End of gate */
  382.             break;
  383.  
  384.         case EOF :
  385.             break;
  386.  
  387.         default:
  388.             if (!gate_closed) {
  389.                 fputc(inchar,curscenefile);
  390.                 if (inchar == '\n')
  391.                     cur_line_num++;
  392.                 }
  393.  
  394.  
  395.  
  396.             }
  397.         }
  398.  
  399.     fclose(curscenefile);
  400.     }
  401.  
  402. }
  403.