home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Graphics 16,000
/
graphics-16000.iso
/
msdos
/
animutil
/
pvquan
/
animdat
/
animdat.c
next >
Wrap
C/C++ Source or Header
|
1992-11-30
|
11KB
|
403 lines
/*--------------------------------------------------------------*/
/* ANIMDAT 1.1 */
/* copyright 1992 - TODD SANKEY */
/* */
/* The author hereby grants permission for the use and sharing */
/* of both source code end executable versions of this software */
/* at no charge. This software is not for sale and no other */
/* shall charge for it without the expressed consent of the */
/* author. */
/* */
/* The source code can be freely modified, but it must retain */
/* the original copyright notice, and the author must be */
/* notified of these changes if the altered code is to be */
/* distributed. */
/*--------------------------------------------------------------*/
/*--------------------------------------------------------------*/
/* animdat.c Main file for animdat program. */
/*--------------------------------------------------------------*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
#include "common.h"
/* This definition controls what filenames are used for the generated */
/* files. If LONG_FILENAMES is not defined, then the generated files */
/* are named SCENEnnn.DAT where nnn is the number of the scene. If */
/* LONG_FILENAMES is defined, the generated filenames use the root name */
/* given on the command line and add _nnn.DAT . */
/* This option is given because DOS machines have the limit of 8 */
/* characters in the filename, so LONG_FILENAMES should not be used. */
#define LONG_FILENAMES
#ifdef LONG_FILENAMES
#define MAX_FNAME_SIZE 100
#else
#define MAX_FNAME_SIZE 13
#endif
#define NAMELEN 20
#define NUMLEN 20
#define MAXSCENES 100
#define VARCHAR '@'
#define GATECHAR '&'
#define MAX_LINE_SIZE 256
/* Globals used in other modules */
int numscenes = -1;
sym_ptr symbol_table = NULL;
char cur_line[MAX_LINE_SIZE];
char *cur_file = NULL;
unsigned int cur_line_num = 0;
/* Used within animdat.c */
static sym_ptr x_symbol = NULL;
static sym_ptr cur_sc_symbol = NULL;
static sym_ptr num_sc_symbol = NULL;
static char *cur_symbol = NULL;
static int gate_closed = 0;
/*--------------------------------------------------------------*/
/* parse_equation Attaches a binary tree representation */
/* of a mathematical expression to a symbol*/
/* given that the scanner module is */
/* initialized to the first token in the */
/* expression. */
/*--------------------------------------------------------------*/
void parse_equation(sym_ptr new_symbol)
{
new_symbol->sym_info = (void *)expression();
new_symbol->sym_type = SYM_DOUBLE;
if (token == COMMA) {
double sign_flag = 1.0;
get_token();
if (token == MINUS) {
sign_flag = (-1.0);
get_token();
}
else if (token == PLUS)
get_token();
if (token == NUMBER)
new_symbol->cur_val = sign_flag * literal_value;
else
error(SYNTAX_ERROR,cur_line);
}
}
/*--------------------------------------------------------------*/
/* parse_filename Attaches a file pointer to a symbol. */
/*--------------------------------------------------------------*/
void parse_filename(sym_ptr new_symbol)
{
get_token();
new_symbol->sym_type = SYM_FILE;
new_symbol->sym_info = (void *)fopen(word_string,"r");
if (new_symbol->sym_info == NULL)
error(FILE_ERROR,word_string);
get_token();
}
/*--------------------------------------------------------------*/
/* parse_string Attaches a string pointer to a symbol. */
/*--------------------------------------------------------------*/
void parse_string(sym_ptr new_symbol)
{
char *quote;
quote=(char *)malloc(strlen(word_string)+1);
if (quote == NULL)
error(FAILED_MALLOC,NULL);
strcpy(quote,word_string);
new_symbol->sym_type = SYM_STRING;
new_symbol->sym_info = (void *)quote;
get_token();
}
/*--------------------------------------------------------------*/
/* parsevarfile Attempts to parse a file as a sequence */
/* of lines each containing a symbol name */
/* and a definition. */
/*--------------------------------------------------------------*/
void parsevarfile(FILE *varfile)
{
int i;
sym_ptr new_symbol;
cur_line_num = 0;
while (!feof(varfile)) {
/* Read the current line of the file into a buffer */
if (fgets(cur_line,MAX_LINE_SIZE,varfile) != NULL) {
cur_line_num++;
for (i=0; i<MAX_LINE_SIZE && cur_line[i]!='\0'; i++);
if (cur_line[i]!='\0' || i>=MAX_LINE_SIZE)
error(LINE_TOO_LONG,cur_line);
init_scanner(cur_line);
if (token == IDENTIFIER) {
new_symbol = add_symbol(&symbol_table, word_string);
get_token();
if (token != EQUAL)
error(SYNTAX_ERROR,cur_line);
get_token();
switch (token) {
case POUND : parse_filename(new_symbol);break;
case QUOTE : parse_string(new_symbol); break;
default : parse_equation(new_symbol);
}
}
else if (token == NUMSCENE) {
get_token();
if (token != EQUAL)
error(SYNTAX_ERROR,cur_line);
get_token();
if (token != NUMBER)
error(SYNTAX_ERROR,cur_line);
numscenes = (int)literal_value;
get_token();
}
else if (token != END_OF_FILE)
error(SYNTAX_ERROR,cur_line);
}
}
cur_line_num = 0;
}
/*--------------------------------------------------------------*/
/* add_system_variables Creates the predefined symbols */
/* but leaves them undefined. */
/*--------------------------------------------------------------*/
void add_system_variables(void)
{
num_sc_symbol = add_symbol(&symbol_table,"num_scenes");
x_symbol = add_symbol(&symbol_table,"x");
cur_sc_symbol = add_symbol(&symbol_table,"cur_scene");
}
/*--------------------------------------------------------------*/
/* update_system_variables Defines the system variables. */
/*--------------------------------------------------------------*/
void update_system_variables(void)
{
char eq[MAX_LINE_SIZE];
double xinc;
xinc = 1.0 / ((double)numscenes);
sprintf(eq,"x + %lf \0",xinc);
init_scanner(eq);
x_symbol->sym_info = (void *)expression();
x_symbol->cur_val = 0.0;
x_symbol->sym_type = SYM_DOUBLE;
sprintf(eq,"cur_scene + 1 \0");
init_scanner(eq);
cur_sc_symbol->sym_info = (void *)expression();
cur_sc_symbol->cur_val = 0.0;
cur_sc_symbol->sym_type = SYM_DOUBLE;
sprintf(eq,"%d \0",numscenes);
init_scanner(eq);
num_sc_symbol->sym_info = (void *)expression();
num_sc_symbol->cur_val = (double)numscenes;
num_sc_symbol->sym_type = SYM_DOUBLE;
}
/*--------------------------------------------------------------*/
/* check_btree Scans a binary tree representation */
/* of a mathematical expression checking */
/* for undefined symbols. */
/*--------------------------------------------------------------*/
void check_btree(btree_node_ptr bnode)
{
if (bnode->node_type == NAMEDVAR) {
if (search_symtab(symbol_table,bnode->node_data.name) == NULL) {
sprintf(cur_line,"%s in definition of %s",bnode->node_data.name,cur_symbol);
error(UNDEFINED_SYMBOL,cur_line);
}
}
}
/*--------------------------------------------------------------*/
/* check_symbol Verifies the definition of a symbol. */
/*--------------------------------------------------------------*/
void check_symbol(sym_ptr symbol)
{
cur_symbol = symbol->name;
if (symbol->sym_type == SYM_DOUBLE)
traverse_btree((btree_node_ptr)(symbol->sym_info),check_btree);
}
/*--------------------------------------------------------------*/
/* reset_flags Clears the flag in a symbol which */
/* indicates that the symbol value has */
/* already been evaluated for this scene. */
/*--------------------------------------------------------------*/
void reset_flags(sym_ptr symbol)
{
symbol->update_flag = 0;
}
void main(int argc,char **argv)
{
int curscene,inchar,i;
char varname[MAX_LINE_SIZE];
FILE *datfile,*curscenefile,*varfile;
char dat_name[MAX_FNAME_SIZE];
char var_name[MAX_FNAME_SIZE];
char scene_name[MAX_FNAME_SIZE];
if (argc != 2) {
printf("ANIMDAT <root file>\n");
printf(" where rootfile.dat is the template file\n");
printf(" and rootfile.var is the variable definition file\n");
exit(1);
}
strcpy(dat_name, argv[1]);
strcat(dat_name,".pov");
datfile=fopen(dat_name,"r");
if (datfile == NULL) {
printf(" Could not open datfile: %s\n", dat_name);
exit(1);
}
strcpy(var_name, argv[1]);
strcat(var_name, ".var");
varfile=fopen(var_name,"r");
if (varfile == NULL) {
printf(" Could not open varfile: %s\n", var_name);
exit(1);
}
cur_file = var_name;
add_system_variables();
parsevarfile(varfile);
fclose(varfile);
update_system_variables();
traverse_symtab(symbol_table,check_symbol);
if (numscenes<=0)
error(NO_NUMSCENE,NULL);
cur_file = dat_name;
cur_line_num = 1;
#ifndef LONG_FILENAMES
strcpy(scene_name,"scene000.dat");
#endif
for (curscene=1;curscene<=numscenes;curscene++) {
#ifdef LONG_FILENAMES
sprintf(scene_name,"%s_%d.pov",argv[1],curscene - 1);
#else
sprintf(scene_name,"scene%03d.pov",curscene - 1);
#endif
curscenefile=fopen(scene_name,"w");
if (curscenefile==NULL) {
printf("Could not open file %s\n",scene_name);
exit(1);
}
rewind(datfile);
traverse_symtab(symbol_table,reset_flags);
gate_closed = 0;
while (!feof(datfile)) {
inchar=fgetc(datfile);
switch (inchar) {
case VARCHAR :
if (!gate_closed) {
i = 0;
do {
inchar=fgetc(datfile);
if (inchar != VARCHAR) {
varname[i] = inchar;
i++;
}
} while ( i < (MAX_LINE_SIZE - 1) && inchar !=VARCHAR);
varname[i] = '\0';
if (inchar!=VARCHAR)
fprintf(curscenefile,"%c%s",VARCHAR,varname);
else
print_symbol(curscenefile,varname);
}
break;
case GATECHAR :
inchar = fgetc(datfile);
if (isalpha(inchar)) { /* Assume start of gate */
i = 0;
do {
varname[i] = inchar;
i++;
inchar = fgetc(datfile);
} while (i < (MAX_LINE_SIZE - 1) && (isalnum(inchar) || inchar == '_'));
varname[i] = '\0';
if ( (eval_symbol(varname) <= 0.0) || gate_closed)
gate_closed++;
}
else if (gate_closed)
gate_closed--; /* End of gate */
break;
case EOF :
break;
default:
if (!gate_closed) {
fputc(inchar,curscenefile);
if (inchar == '\n')
cur_line_num++;
}
}
}
fclose(curscenefile);
}
}