]> git.sesse.net Git - vlc/blob - modules/visualization/galaktos/parser.c
Remove stdlib.h
[vlc] / modules / visualization / galaktos / parser.c
1 /*****************************************************************************
2  * parser.c:
3  *****************************************************************************
4  * Copyright (C) 2004 the VideoLAN team
5  * $Id$
6  *
7  * Authors: Cyril Deguet <asmax@videolan.org>
8  *          code from projectM http://xmms-projectm.sourceforge.net
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23  *****************************************************************************/
24
25
26
27 /* parser.c */
28
29 #include <stdio.h>
30 #include <string.h>
31
32 #include "common.h"
33 #include "fatal.h"
34
35 #include "splaytree_types.h"
36 #include "splaytree.h"
37 #include "tree_types.h"
38
39 #include "expr_types.h"
40 #include "eval.h"
41
42 #include "param_types.h"
43 #include "param.h"
44
45 #include "func_types.h"
46 #include "func.h"
47
48 #include "preset_types.h"
49 #include "builtin_funcs.h"
50
51 #include "per_pixel_eqn_types.h"
52 #include "per_pixel_eqn.h"
53
54 #include "init_cond_types.h"
55 #include "init_cond.h"
56
57 #include "per_frame_eqn_types.h"
58 #include "per_frame_eqn.h"
59
60 #include "parser.h"
61 #include "engine_vars.h"
62
63 #include "custom_wave_types.h"
64 #include "custom_wave.h"
65
66 #include "custom_shape_types.h"
67 #include "custom_shape.h"
68
69 /* Strings that prefix (and denote the type of) equations */
70
71
72 #define PER_FRAME_STRING "per_frame_"
73 #define PER_FRAME_STRING_LENGTH 10
74
75 #define PER_PIXEL_STRING "per_pixel_"
76 #define PER_PIXEL_STRING_LENGTH 10
77
78 #define PER_FRAME_INIT_STRING "per_frame_init_"
79 #define PER_FRAME_INIT_STRING_LENGTH 15
80
81 #define WAVECODE_STRING "wavecode_"
82 #define WAVECODE_STRING_LENGTH 9
83
84 #define WAVE_STRING "wave_"
85 #define WAVE_STRING_LENGTH 5
86
87 #define PER_POINT_STRING "per_point"
88 #define PER_POINT_STRING_LENGTH 9
89
90 #define PER_FRAME_STRING_NO_UNDERSCORE "per_frame"
91 #define PER_FRAME_STRING_NO_UNDERSCORE_LENGTH 9
92
93 #define SHAPECODE_STRING "shapecode_"
94 #define SHAPECODE_STRING_LENGTH 10
95
96 #define SHAPE_STRING "shape_"
97 #define SHAPE_STRING_LENGTH 6
98
99 #define SHAPE_INIT_STRING "init"
100 #define SHAPE_INIT_STRING_LENGTH 4
101
102 #define WAVE_INIT_STRING "init"
103 #define WAVE_INIT_STRING_LENGTH 4
104
105 /* Stores a line of a file as its being parsed */
106 char string_line_buffer[STRING_LINE_SIZE]; 
107
108 /* The current position of the string line buffer (see above) */
109 int string_line_buffer_index = 0;
110
111 /* All infix operators (except '=') are prototyped here */
112 extern infix_op_t * infix_add, * infix_minus, * infix_div, * infix_mult,
113   * infix_or, * infix_and, * infix_mod, * infix_positive, * infix_negative;
114
115 /* If the parser reads a line with a custom wave, this pointer is set to
116    the custom wave of concern */
117 custom_wave_t * current_wave = NULL;
118 custom_shape_t * current_shape = NULL;
119 /* Counts the number of lines parsed */
120 unsigned int line_count = 1;
121 int per_frame_eqn_count  = 0;
122 int per_frame_init_eqn_count = 0;
123
124 typedef enum {
125   NORMAL_LINE_MODE,
126   PER_FRAME_LINE_MODE,
127   PER_PIXEL_LINE_MODE,
128   INIT_COND_LINE_MODE,
129   CUSTOM_WAVE_PER_POINT_LINE_MODE,
130   CUSTOM_WAVE_PER_FRAME_LINE_MODE,
131   CUSTOM_WAVE_WAVECODE_LINE_MODE,
132   CUSTOM_SHAPE_SHAPECODE_LINE_MODE,
133 } line_mode_t;
134
135 line_mode_t line_mode = NORMAL_LINE_MODE;
136
137 /* Token enumeration type */
138 typedef enum {
139
140   tEOL,   /* end of a line, usually a '/n' or '/r' */
141   tEOF,   /* end of file */
142   tLPr,   /* ( */
143   tRPr,   /* ) */
144   tLBr,   /* [ */
145   tRBr,   /* ] */
146   tEq,    /* = */
147   tPlus,  /* + */
148   tMinus, /* - */
149   tMult,  /* * */
150   tMod,   /* % */
151   tDiv,   /* / */
152   tOr,    /* | */
153   tAnd,   /* & */
154   tComma, /* , */
155   tPositive, /* + as a prefix operator */
156   tNegative, /* - as a prefix operator */
157   tSemiColon, /* ; */
158   tStringTooLong, /* special token to indicate an invalid string length */
159   tStringBufferFilled /* the string buffer for this line is maxed out */
160 } token_t;
161
162
163 int get_string_prefix_len(char * string);
164 tree_expr_t * insert_gen_expr(gen_expr_t * gen_expr, tree_expr_t ** root);
165 tree_expr_t * insert_infix_op(infix_op_t * infix_op, tree_expr_t ** root);
166 token_t parseToken(FILE * fs, char * string);
167 gen_expr_t ** parse_prefix_args(FILE * fs, int num_args, struct PRESET_T * preset);
168 gen_expr_t * parse_infix_op(FILE * fs, token_t token, tree_expr_t * tree_expr, struct PRESET_T * preset);
169 gen_expr_t * parse_sign_arg(FILE * fs);
170 int parse_float(FILE * fs, double * float_ptr);
171 int parse_int(FILE * fs, int * int_ptr);
172 int insert_gen_rec(gen_expr_t * gen_expr, tree_expr_t * root);
173 int insert_infix_rec(infix_op_t * infix_op, tree_expr_t * root);
174 gen_expr_t * parse_gen_expr(FILE * fs, tree_expr_t * tree_expr, struct PRESET_T * preset);
175 per_frame_eqn_t * parse_implicit_per_frame_eqn(FILE * fs, char * param_string, int index, struct PRESET_T * preset);
176 init_cond_t * parse_per_frame_init_eqn(FILE * fs, struct PRESET_T * preset, splaytree_t * database);
177 int parse_wavecode_prefix(char * token, int * id, char ** var_string);
178 int parse_wavecode(char * token, FILE * fs, preset_t * preset);
179 int parse_wave_prefix(char * token, int * id, char ** eqn_string);
180
181 int parse_shapecode(char * eqn_string, FILE * fs, preset_t * preset);
182 int parse_shapecode_prefix(char * token, int * id, char ** var_string);
183
184 int parse_wave(char * eqn_string, FILE * fs, preset_t * preset);
185 int parse_shape(char * eqn_string, FILE * fs, preset_t * preset);
186 int parse_shape_prefix(char * token, int * id, char ** eqn_string);
187
188 int update_string_buffer(char * buffer, int * index);
189 int string_to_float(char * string, double * float_ptr);
190
191 /* Grabs the next token from the file. The second argument points
192    to the raw string */
193
194 token_t parseToken(FILE * fs, char * string) {
195   
196   char c;
197   int i;
198   
199   if (string != NULL)
200     memset(string, 0, MAX_TOKEN_SIZE);
201   
202   /* Loop until a delimiter is found, or the maximum string size is found */
203   for (i = 0; i < MAX_TOKEN_SIZE;i++) {
204     c = fgetc(fs);
205     
206     /* If the string line buffer is full, quit */
207     if (string_line_buffer_index == (STRING_LINE_SIZE - 1))
208       return tStringBufferFilled;
209     
210     /* Otherwise add this character to the string line buffer */
211     string_line_buffer[string_line_buffer_index++] = c;
212     /* Now interpret the character */
213     switch (c) {
214       
215     case '+':
216       return tPlus; 
217     case '-':
218       return tMinus;
219     case '%':
220       return tMod;
221     case '/':
222       
223       /* check for line comment here */
224       if ((c = fgetc(fs)) == '/') {
225         while(1) {
226           c = fgetc(fs);
227           if (c == EOF) {
228             line_mode = NORMAL_LINE_MODE;
229             return tEOF;                                
230           }
231           if (c == '\n') {
232             line_mode = NORMAL_LINE_MODE;
233             return tEOL;
234           }
235         }
236         
237       }
238       
239       /* Otherwise, just a regular division operator */
240       ungetc(c, fs);
241       return tDiv;
242       
243     case '*':
244       return tMult;
245     case '|':
246       return tOr;
247     case '&':
248       return tAnd;
249     case '(': 
250       return tLPr;
251     case ')':
252       return tRPr;
253     case '[': 
254       return tLBr;
255     case ']':
256       return tRBr;
257     case '=': 
258       return tEq;
259       //    case '\r':
260       //break;
261     case '\n':
262       line_count++;
263       line_mode = NORMAL_LINE_MODE;
264       return tEOL;
265     case ',':
266       return tComma;
267     case ';':
268       return tSemiColon;
269     case ' ': /* space, skip the character */
270       i--;
271       break;
272     case EOF:
273       line_count = 1;
274       line_mode = NORMAL_LINE_MODE;
275       return tEOF;
276       
277     default: 
278       if (string != NULL)
279         string[i] = c;
280     } 
281     
282   }
283   
284  /* String reached maximum length, return special token error */ 
285   return tStringTooLong;
286   
287 }
288
289 /* Parse input in the form of "exp, exp, exp, ...)" 
290    Returns a general expression list */
291
292 gen_expr_t ** parse_prefix_args(FILE * fs, int num_args, struct PRESET_T * preset) {
293
294   int i, j;
295   gen_expr_t ** expr_list; /* List of arguments to function */
296   gen_expr_t * gen_expr;
297   
298   /* Malloc the expression list */
299   expr_list =  (gen_expr_t**)malloc(sizeof(gen_expr_t*)*num_args);
300   
301   /* Malloc failed */
302   if (expr_list == NULL)
303     return NULL;
304   
305   
306   i = 0;
307
308   while (i < num_args) {
309     //if (PARSE_DEBUG) printf("parse_prefix_args: parsing argument %d...\n", i+1);
310     /* Parse the ith expression in the list */
311     if ((gen_expr = parse_gen_expr(fs, NULL, preset)) == NULL) {
312       //if (PARSE_DEBUG) printf("parse_prefix_args: failed to get parameter # %d for function (LINE %d)\n", i+1, line_count);
313       for (j = 0; j < i; j++) 
314         free_gen_expr(expr_list[j]);
315       free(expr_list);
316       return NULL;
317     }
318     /* Assign entry in expression list */
319     expr_list[i++] = gen_expr;
320   }
321   
322   //if (PARSE_DEBUG) printf("parse_prefix_args: finished parsing %d arguments (LINE %d)\n", num_args, line_count);      
323   /* Finally, return the resulting expression list */
324   return expr_list;
325   
326 }
327
328 /* Parses a comment at the top of the file. Stops when left bracket is found */
329 int parse_top_comment(FILE * fs) {
330
331   char string[MAX_TOKEN_SIZE];
332   token_t token;
333           
334   /* Process tokens until left bracket is found */
335   while ((token = parseToken(fs, string)) != tLBr) {
336     if (token == tEOF) 
337       return PARSE_ERROR;
338   }
339
340  /* Done, return success */
341  return SUCCESS; 
342 }       
343
344 /* Right Bracket is parsed by this function.
345    puts a new string into name */
346 int parse_preset_name(FILE * fs, char * name) {
347
348   token_t token;
349
350   if (name == NULL)
351         return FAILURE;
352
353   if ((token = parseToken(fs, name)) != tRBr)
354     return PARSE_ERROR;
355         
356   //if (PARSE_DEBUG) printf("parse_preset_name: parsed preset (name = \"%s\")\n", name);
357   
358   return SUCCESS;
359 }
360
361
362 /* Parses per pixel equations */
363 int parse_per_pixel_eqn(FILE * fs, preset_t * preset) {
364
365
366   char string[MAX_TOKEN_SIZE];
367   gen_expr_t * gen_expr;
368
369   if (PARSE_DEBUG) printf("parse_per_pixel: per_pixel equation parsing start...(LINE %d)\n", line_count);
370
371   if (parseToken(fs, string) != tEq) { /* parse per pixel operator  name */
372     if (PARSE_DEBUG) printf("parse_per_pixel: equal operator expected after per pixel operator \"%s\", but not found (LINE %d)\n", 
373                             string, line_count);
374     return PARSE_ERROR;
375   }
376   
377   /* Parse right side of equation as an expression */
378   if ((gen_expr = parse_gen_expr(fs, NULL, preset)) == NULL) {
379     if (PARSE_DEBUG) printf("parse_per_pixel: equation evaluated to null? (LINE %d)\n", line_count);
380     return PARSE_ERROR;
381   }
382   
383   /* Add the per pixel equation */
384   if (add_per_pixel_eqn(string, gen_expr, preset) < 0) {
385     free_gen_expr(gen_expr);
386     return PARSE_ERROR;
387   }
388
389   return SUCCESS;
390 }
391
392 /* Parses an equation line, this function is way too big, should add some helper functions */
393 int parse_line(FILE * fs, struct PRESET_T * preset) {
394
395   char eqn_string[MAX_TOKEN_SIZE];
396   token_t token;
397   init_cond_t * init_cond;
398   per_frame_eqn_t * per_frame_eqn;
399   
400   /* Clear the string line buffer */
401   memset(string_line_buffer, 0, STRING_LINE_SIZE);
402   string_line_buffer_index = 0;
403   
404   
405   switch (token = parseToken(fs, eqn_string)) {
406     
407     /* Invalid Cases */
408   case tRBr:
409   case tLPr:
410   case tRPr:
411   case tComma:
412   case tLBr:
413   case tPlus:
414   case tMinus:
415   case tMod:
416   case tMult:
417   case tOr:
418   case tAnd:
419   case tDiv:
420     
421     //    if (PARSE_DEBUG) printf("parse_line: invalid token found at start of line (LINE %d)\n", line_count);
422     /* Invalid token found, return a parse error */
423     return PARSE_ERROR;
424     
425     
426   case tEOL:  /* Empty line */
427     line_mode = NORMAL_LINE_MODE;
428     return SUCCESS;
429     
430   case tEOF: /* End of File */
431     line_mode = NORMAL_LINE_MODE;
432     line_count = 1;
433     return EOF;
434     
435   case tSemiColon: /* Indicates end of expression */
436     return SUCCESS;
437     
438     /* Valid Case, either an initial condition or equation should follow */
439   case tEq:
440     
441     /* CASE: PER FRAME INIT EQUATION */     
442     if (!strncmp(eqn_string, PER_FRAME_INIT_STRING, PER_FRAME_INIT_STRING_LENGTH)) {
443       
444       //if (PARSE_DEBUG) printf("parse_line: per frame init equation found...(LINE %d)\n", line_count);
445       
446       /* Set the line mode to normal */
447       line_mode = NORMAL_LINE_MODE;
448       
449       /* Parse the per frame equation */
450       if ((init_cond = parse_per_frame_init_eqn(fs, preset, NULL)) == NULL) {
451         //if (PARSE_DEBUG) printf("parse_line: per frame init equation parsing failed (LINE %d)\n", line_count);
452         return PARSE_ERROR;
453       } 
454       
455       /* Insert the equation in the per frame equation tree */
456       if (splay_insert(init_cond, init_cond->param->name, preset->per_frame_init_eqn_tree) < 0) {
457         //if (PARSE_DEBUG) printf("parse_line: failed to add a perframe equation (ERROR)\n");
458         free_init_cond(init_cond); /* will free the gen expr too */             
459         return ERROR;
460       }
461       
462      
463       if (update_string_buffer(preset->per_frame_init_eqn_string_buffer, 
464                                &preset->per_frame_init_eqn_string_index) < 0)
465         {       return FAILURE;}
466       
467       return SUCCESS;
468       
469     }
470
471     /* Per frame equation case */           
472     if (!strncmp(eqn_string, PER_FRAME_STRING, PER_FRAME_STRING_LENGTH)) {
473       
474       /* Sometimes per frame equations are implicitly defined without the
475          per_frame_ prefix. This informs the parser that one could follow */
476       line_mode = PER_FRAME_LINE_MODE;
477       
478       //if (PARSE_DEBUG) printf("parse_line: per frame equation found...(LINE %d)\n", line_count);
479       
480       /* Parse the per frame equation */
481       if ((per_frame_eqn = parse_per_frame_eqn(fs, ++per_frame_eqn_count, preset)) == NULL) {
482         if (PARSE_DEBUG) printf("parse_line: per frame equation parsing failed (LINE %d)\n", line_count);
483         return PARSE_ERROR;
484       } 
485       
486       /* Insert the equation in the per frame equation tree */
487       if (splay_insert(per_frame_eqn, &per_frame_eqn_count, preset->per_frame_eqn_tree) < 0) {
488         if (PARSE_DEBUG) printf("parse_line: failed to add a perframe equation (ERROR)\n");
489         free_per_frame_eqn(per_frame_eqn); /* will free the gen expr too */             
490         return ERROR;
491       }
492     
493       if (update_string_buffer(preset->per_frame_eqn_string_buffer, 
494                                &preset->per_frame_eqn_string_index) < 0)
495         return FAILURE;
496       
497       
498       
499       return SUCCESS;
500       
501     }
502     
503     /* Wavecode initial condition case */
504     if (!strncmp(eqn_string, WAVECODE_STRING, WAVECODE_STRING_LENGTH)) {
505       
506           line_mode = CUSTOM_WAVE_WAVECODE_LINE_MODE;
507
508       //if (PARSE_DEBUG) 
509       //      printf("parse_line: wavecode prefix found: \"%s\"\n", eqn_string);
510
511           //      printf("string:%d\n", 5);
512
513           //SUPER MYSTERIO-BUG - Don't Remove
514           printf("");
515           
516       return parse_wavecode(eqn_string, fs, preset);
517     }
518     
519     /* Custom Wave Prefix */
520     if ((!strncmp(eqn_string, WAVE_STRING, WAVE_STRING_LENGTH)) && 
521         ((eqn_string[5] >= 48) && (eqn_string[5] <= 57))) {
522       
523       //    if (PARSE_DEBUG) printf("parse_line wave prefix found: \"%s\"\n", eqn_string);
524       
525       return parse_wave(eqn_string, fs, preset);
526       
527     }
528     
529     
530     /* Shapecode initial condition case */
531     if (!strncmp(eqn_string, SHAPECODE_STRING, SHAPECODE_STRING_LENGTH)) {
532       
533       line_mode = CUSTOM_SHAPE_SHAPECODE_LINE_MODE;
534       
535       if (PARSE_DEBUG) printf("parse_line: shapecode prefix found: \"%s\"\n", eqn_string);
536       
537       return parse_shapecode(eqn_string, fs, preset);
538     }
539     
540     /* Custom Shape Prefix */
541     if ((!strncmp(eqn_string, SHAPE_STRING, SHAPE_STRING_LENGTH)) && 
542         ((eqn_string[6] >= 48) && (eqn_string[6] <= 57))) {
543       
544       if (PARSE_DEBUG) printf("parse_line shape prefix found: \"%s\"\n", eqn_string);
545       return parse_shape(eqn_string, fs, preset);
546       
547     }
548     
549     /* Per pixel equation case */
550     if (!strncmp(eqn_string, PER_PIXEL_STRING, PER_PIXEL_STRING_LENGTH)) {
551       line_mode = PER_PIXEL_LINE_MODE;
552       
553       if (parse_per_pixel_eqn(fs, preset) < 0)
554         return PARSE_ERROR;
555       
556       
557       if (update_string_buffer(preset->per_pixel_eqn_string_buffer, 
558                                &preset->per_pixel_eqn_string_index) < 0)
559         return FAILURE;
560       
561       if (PARSE_DEBUG) printf("parse_line: finished parsing per pixel equation (LINE %d)\n", line_count);
562       return SUCCESS;
563     } 
564     
565     /* Sometimes equations are written implicitly in milkdrop files, in the form
566        
567     per_frame_1 = p1 = eqn1; p2 = eqn2; p3 = eqn3;..; 
568     
569     which is analagous to:
570     
571     per_frame_1 = p1 = eqn1; per_frame_2 = p2 = eqn2; per_frame_3 = p3 = eqn3; ...;
572     
573     The following line mode hack allows such implicit declaration of the 
574     prefix that specifies the equation type. An alternative method
575     may be to associate each equation line as list of equations separated
576     by semicolons (and a new line ends the list). Instead, however, a global
577     variable called "line_mode" specifies the last type of equation found,
578     and bases any implicitly typed input on this fact
579     
580     Note added by Carmelo Piccione (cep@andrew.cmu.edu) 10/19/03
581     */
582     
583     /* Per frame line mode previously, try to parse the equation implicitly */
584     if (line_mode == PER_FRAME_LINE_MODE) {
585       if ((per_frame_eqn = parse_implicit_per_frame_eqn(fs, eqn_string, ++per_frame_eqn_count, preset)) == NULL)
586         return PARSE_ERROR;
587       
588       /* Insert the equation in the per frame equation tree */
589       if (splay_insert(per_frame_eqn, &per_frame_eqn_count, preset->per_frame_eqn_tree) < 0) {
590         if (PARSE_DEBUG) printf("parse_line: failed to add a perframe equation (ERROR)\n");
591         free_per_frame_eqn(per_frame_eqn); /* will free the gen expr too */             
592         return ERROR;
593       }
594       
595       
596       if (update_string_buffer(preset->per_frame_eqn_string_buffer, 
597                                &preset->per_frame_eqn_string_index) < 0)
598         return FAILURE;
599       
600       
601       
602       return SUCCESS;
603     }
604     
605     //if (PARSE_DEBUG) printf("parse_line: found initial condition: name = \"%s\" (LINE %d)\n", eqn_string, line_count);
606     
607     /* Evaluate the initial condition */
608     if ((init_cond = parse_init_cond(fs, eqn_string, preset)) == NULL) {
609        if (PARSE_DEBUG) printf("parse_line: failed to parse initial condition (LINE %d)\n", line_count);
610       return PARSE_ERROR; 
611     }   
612     
613     /* Add equation to initial condition tree */
614     if (splay_insert(init_cond, init_cond->param->name, preset->init_cond_tree) < 0) {
615       if (PARSE_DEBUG) printf("parse_line: failed to add initial condition \"%s\" to equation tree (LINE %d)\n", 
616                       init_cond->param->name, line_count);
617       free_init_cond(init_cond);
618       return FAILURE;
619     }
620     
621     /* Finished with initial condition line */
622     //    if (PARSE_DEBUG) printf("parse_line: initial condition parsed successfully\n");
623     
624     return SUCCESS;
625     
626     /* END INITIAL CONDITIONING PARSING */
627     
628     
629   default: /* an uncaught type or an error has occurred */
630     if (PARSE_DEBUG) printf("parse_line: uncaught case, token val = %d\n", token); 
631     return PARSE_ERROR;
632   }
633   
634   /* Because of the default in the case statement, 
635      control flow should never actually reach here */ 
636   return PARSE_ERROR;
637 }
638
639
640
641 /* Parses a general expression, this function is the meat of the parser */
642 gen_expr_t * parse_gen_expr (FILE * fs, tree_expr_t * tree_expr, struct PRESET_T * preset) {
643   
644   int i;
645   char string[MAX_TOKEN_SIZE];
646   token_t token;
647   gen_expr_t * gen_expr;
648   double val;
649   param_t * param = NULL;
650   func_t * func;
651   gen_expr_t ** expr_list;
652
653   switch (token = parseToken(fs,string)) {
654   /* Left Parentice Case */
655   case tLPr:
656     
657     /* CASE 1 (Left Parentice): See if the previous string before this parentice is a function name */
658     if ((func = find_func(string)) != NULL) {
659         if (PARSE_DEBUG) printf("parse_gen_expr: found prefix function (name = %s) (LINE %d)\n", func->name, line_count);
660       
661       /* Parse the functions arguments */
662       if ((expr_list = parse_prefix_args(fs, func->num_args, preset)) == NULL) {
663         if (PARSE_DEBUG) printf("parse_prefix_args: failed to generate an expresion list! (LINE %d) \n", line_count);
664         free_tree_expr(tree_expr);
665         return NULL;
666       }
667       
668       /* Convert function to expression */
669       if ((gen_expr = prefun_to_expr((void*)func->func_ptr, expr_list, func->num_args)) == NULL)  {     
670           if (PARSE_DEBUG) printf("parse_prefix_args: failed to convert prefix function to general expression (LINE %d) \n", 
671                                         line_count);
672         free_tree_expr(tree_expr);
673         for (i = 0; i < func->num_args;i++)
674           free_gen_expr(expr_list[i]);
675         free(expr_list);
676         return NULL;
677       }
678     
679       
680       
681       token = parseToken(fs, string);
682
683       if (*string != 0) {
684         if (PARSE_DEBUG) printf("parse_prefix_args: empty string expected, but not found...(LINE %d)\n", line_count);
685         /* continue anyway for now, could be implicit multiplication */                         
686       }         
687       
688       return parse_infix_op(fs, token, insert_gen_expr(gen_expr, &tree_expr), preset);
689     }
690      
691     
692     /* Case 2: (Left Parentice), a string coupled with a left parentice. Either an error or implicit 
693        multiplication operator. For now treat it as an error */
694     if (*string != 0) {
695       if (PARSE_DEBUG) printf("parse_gen_expr: implicit multiplication case unimplemented!\n");
696       free_tree_expr(tree_expr);
697       return NULL;
698     }
699     
700     /* CASE 3 (Left Parentice): the following is enclosed parentices to change order
701        of operations. So we create a new expression tree */
702     
703     if ((gen_expr = parse_gen_expr(fs, NULL, preset)) == NULL) {
704       //if (PARSE_DEBUG) printf("parse_gen_expr:  found left parentice, but failed to create new expression tree \n");
705       free_tree_expr(tree_expr);
706       return NULL;
707     }
708     
709     if (PARSE_DEBUG) printf("parse_gen_expr: finished enclosed expression tree...\n");  
710     token = parseToken(fs, string);
711     return parse_infix_op(fs, token, insert_gen_expr(gen_expr, &tree_expr), preset);
712
713     /* Plus is a prefix operator check */
714   case tPlus:
715     if (*string == 0) {
716       
717       //if (PARSE_DEBUG) printf("parse_gen_expr: plus used as prefix (LINE %d)\n", line_count);
718
719           /* Treat prefix plus as implict 0 preceding operator */
720       gen_expr = const_to_expr(0);
721
722       return parse_infix_op(fs, tPositive, insert_gen_expr(gen_expr, &tree_expr), preset);      
723     }
724     
725     /* Minus is a prefix operator check */
726   case tMinus:
727     if (*string == 0) {
728      
729       /* Use the negative infix operator, but first add an implicit zero to the operator tree */
730       gen_expr = const_to_expr(0);
731       //return parse_gen_expr(fs, insert_gen_expr(gen_expr, &tree_expr), preset);
732                 return parse_infix_op(fs, tNegative, insert_gen_expr(gen_expr, &tree_expr), preset);
733     }
734     
735     /* All the following cases are strings followed by an infix operator or terminal */
736   case tRPr:
737   case tEOL: 
738   case tEOF:
739   case tSemiColon:
740   case tComma:
741     
742     /* CASE 1 (terminal): string is empty, but not null. Not sure if this will actually happen
743        any more. */
744     if (*string == 0) {
745       //if (PARSE_DEBUG) printf("parse_gen_expr: empty string coupled with terminal (LINE %d) \n", line_count);
746       return parse_infix_op(fs, token, tree_expr, preset);
747       
748     }
749     
750   default:  
751
752     /* CASE 0: Empty string, parse error */
753     if (*string == 0) {
754       if (PARSE_DEBUG) printf("parse_gen_expr: empty string coupled with infix op (ERROR!) (LINE %d) \n", line_count);
755       free_tree_expr(tree_expr);
756       return NULL;
757     }
758
759     /* CASE 1: Check if string is a just a floating point number */
760     if (string_to_float(string, &val) != PARSE_ERROR) {
761       if ((gen_expr = const_to_expr(val)) == NULL) {
762         free_tree_expr(tree_expr);
763         return NULL;
764       }
765       
766       /* Parse the rest of the line */
767       return parse_infix_op(fs, token, insert_gen_expr(gen_expr, &tree_expr), preset);          
768     
769     }
770
771       
772     /* CASE 4: custom shape variable */
773     if (current_shape != NULL) {
774       if ((param = find_param_db(string, current_shape->param_tree, FALSE)) == NULL) {
775         if ((param = find_builtin_param(string)) == NULL)
776           if ((param = find_param_db(string, current_shape->param_tree, TRUE)) == NULL) {
777             free_tree_expr(tree_expr);
778             return NULL;
779           }
780       }
781       
782       if (PARSE_DEBUG) {
783         printf("parse_gen_expr: custom shape parameter (name = %s)... ", param->name);
784         fflush(stdout);
785       }  
786       
787       /* Convert parameter to an expression */
788       if ((gen_expr = param_to_expr(param)) == NULL) {
789         free_tree_expr(tree_expr);
790         return NULL;
791       }
792       
793       //if (PARSE_DEBUG) printf("converted to expression (LINE %d)\n", line_count);
794       
795       /* Parse the rest of the line */
796       return parse_infix_op(fs, token, insert_gen_expr(gen_expr, &tree_expr), preset);
797     }
798     
799     /* CASE 5: custom wave variable */
800     if (current_wave != NULL) {
801       if ((param = find_param_db(string, current_wave->param_tree, FALSE)) == NULL) {
802         if ((param = find_builtin_param(string)) == NULL) 
803           if ((param = find_param_db(string, current_wave->param_tree, TRUE)) == NULL) {
804             free_tree_expr(tree_expr);
805             return NULL;
806           }
807         
808       }
809
810       if (PARSE_DEBUG) {
811         printf("parse_gen_expr: custom wave parameter (name = %s)... ", param->name);
812         fflush(stdout);
813       }
814         
815         /* Convert parameter to an expression */
816         if ((gen_expr = param_to_expr(param)) == NULL) {
817           free_tree_expr(tree_expr);
818           return NULL;
819         }
820         
821         if (PARSE_DEBUG) printf("converted to expression (LINE %d)\n", line_count);
822         
823         /* Parse the rest of the line */
824         return parse_infix_op(fs, token, insert_gen_expr(gen_expr, &tree_expr), preset);
825       
826     }
827
828     /* CASE 6: regular parameter. Will be created if necessary and the string has no invalid characters */
829     if ((param = find_param(string, preset, P_CREATE)) != NULL) {
830       
831       if (PARSE_DEBUG) {
832         printf("parse_gen_expr: parameter (name = %s)... ", param->name);
833         fflush(stdout);
834       }  
835     
836                 /* Convert parameter to an expression */
837       if ((gen_expr = param_to_expr(param)) == NULL) {
838         free_tree_expr(tree_expr);
839         return NULL;
840       }
841       
842       if (PARSE_DEBUG) printf("converted to expression (LINE %d)\n", line_count);
843       
844       /* Parse the rest of the line */
845       return parse_infix_op(fs, token, insert_gen_expr(gen_expr, &tree_expr), preset);
846           
847     }
848    
849     /* CASE 7: Bad string, give up */
850     if (PARSE_DEBUG) printf("parse_gen_expr: syntax error [string = \"%s\"] (LINE %d)\n", string, line_count);
851     free_tree_expr(tree_expr);
852     return NULL;
853   }
854 }
855   
856
857
858 /* Inserts expressions into tree according to operator precedence.
859    If root is null, a new tree is created, with gen_expr as only element */
860
861 tree_expr_t * insert_infix_op(infix_op_t * infix_op, tree_expr_t **root) {
862
863   tree_expr_t * new_root;
864   
865   /* Sanity check */
866   if (infix_op == NULL)
867     return NULL;
868   
869   /* The root is null, so make this operator
870      the new root */
871   
872   if (*root == NULL) {
873     new_root = new_tree_expr(infix_op, NULL, NULL, NULL);
874     *root = new_root;
875     return new_root;            
876   }
877   
878   /* The root node is not an infix function,
879      so we make this infix operator the new root  */ 
880   
881   if ((*root)->infix_op == NULL) {
882     new_root = new_tree_expr(infix_op, NULL, *root, NULL);
883     (*root) = new_root;
884     return new_root;
885   }
886   
887   /* The root is an infix function. If the precedence
888      of the item to be inserted is greater than the root's
889      precedence, then make gen_expr the root */
890   
891   if (infix_op->precedence > (*root)->infix_op->precedence) {
892     new_root = new_tree_expr(infix_op, NULL, *root, NULL);
893     (*root) = new_root;
894       return new_root;
895   }
896   
897   /* If control flow reaches here, use a recursive helper
898      with the knowledge that the root is higher precedence
899      than the item to be inserted */
900   
901   insert_infix_rec(infix_op, *root);
902   return *root;
903   
904 }
905
906
907 tree_expr_t * insert_gen_expr(gen_expr_t * gen_expr, tree_expr_t ** root) {
908
909   tree_expr_t * new_root;
910   
911   /* If someone foolishly passes a null
912      pointer to insert, return the original tree */
913   
914   if (gen_expr == NULL) {
915     return *root;
916   }
917
918   /* If the root is null, generate a new expression tree,
919      using the passed expression as the root element */
920   
921   if (*root == NULL) {
922     new_root = new_tree_expr(NULL, gen_expr, NULL, NULL);
923     *root = new_root;
924     return new_root;
925   }
926   
927   
928   /* Otherwise. the new element definitely will not replace the current root.
929      Use a recursive helper function to do insertion */
930
931   insert_gen_rec(gen_expr, *root);
932   return *root;
933 }
934
935 /* A recursive helper function to insert general expression elements into the operator tree */
936 int insert_gen_rec(gen_expr_t * gen_expr, tree_expr_t * root) {
937   
938   /* Trivial Case: root is null */
939   
940   if (root == NULL) {
941     ////if (PARSE_DEBUG) printf("insert_gen_rec: root is null, returning failure\n");
942     return FAILURE;
943   }
944   
945   
946   /* The current node's left pointer is null, and this
947      current node is an infix operator, so insert the
948      general expression at the left pointer */
949   
950   if ((root->left == NULL) && (root->infix_op != NULL)) {
951     root->left = new_tree_expr(NULL, gen_expr, NULL, NULL);
952     return SUCCESS;
953   }
954   
955   /* The current node's right pointer is null, and this
956      current node is an infix operator, so insert the
957      general expression at the right pointer */
958   
959   if ((root->right == NULL) && (root->infix_op != NULL)) {
960     root->right = new_tree_expr(NULL, gen_expr, NULL, NULL);
961     return SUCCESS;
962   }
963   
964   /* Otherwise recurse down to the left. If
965      this succeeds then return. If it fails, try
966      recursing down to the right */
967   
968   if (insert_gen_rec(gen_expr, root->left) == FAILURE) 
969     return insert_gen_rec(gen_expr, root->right);
970
971   /* Impossible for control flow to reach here, but in
972      the world of C programming, who knows... */
973   //if (PARSE_DEBUG) printf("insert_gen_rec: should never reach here!\n");  
974   return FAILURE;       
975 }       
976
977
978 /* A recursive helper function to insert infix arguments by operator precedence */
979 int insert_infix_rec(infix_op_t * infix_op, tree_expr_t * root) {
980
981   /* Shouldn't happen, implies a parse error */
982
983   if (root == NULL)
984     return FAILURE;
985   
986   /* Also shouldn't happen, also implies a (different) parse error */
987
988   if (root->infix_op == NULL)
989     return FAILURE;
990
991   /* Left tree is empty, attach this operator to it. 
992      I don't think this will ever happen */
993   if (root->left == NULL) {
994     root->left = new_tree_expr(infix_op, NULL, root->left, NULL);
995     return SUCCESS;
996   }
997  
998   /* Right tree is empty, attach this operator to it */
999   if (root->right == NULL) {
1000     root->right = new_tree_expr(infix_op, NULL, root->right, NULL);
1001     return SUCCESS;
1002   }
1003
1004   /* The left element can now be ignored, since there is no way for this
1005      operator to use those expressions */
1006
1007   /* If the right element is not an infix operator,
1008      then insert the expression here, attaching the old right branch
1009      to the left of the new expression */
1010
1011   if (root->right->infix_op == NULL) {
1012     root->right = new_tree_expr(infix_op, NULL, root->right, NULL);
1013     return SUCCESS;
1014   }
1015   
1016   /* Traverse deeper if the inserting operator precedence is less than the
1017      the root's right operator precedence */
1018   if (infix_op->precedence < root->right->infix_op->precedence) 
1019     return insert_infix_rec(infix_op, root->right);
1020
1021   /* Otherwise, insert the operator here */
1022   
1023   root->right = new_tree_expr(infix_op, NULL, root->right, NULL);
1024   return SUCCESS;
1025
1026 }
1027
1028 /* Parses an infix operator */
1029 gen_expr_t * parse_infix_op(FILE * fs, token_t token, tree_expr_t * tree_expr, struct PRESET_T * preset) {
1030         
1031   gen_expr_t * gen_expr;
1032
1033   switch (token) {
1034         /* All the infix operators */
1035   case tPlus:
1036     //if (PARSE_DEBUG) printf("parse_infix_op: found addition operator (LINE %d)\n", line_count);
1037     return parse_gen_expr(fs, insert_infix_op(infix_add, &tree_expr), preset);
1038   case tMinus:
1039     //if (PARSE_DEBUG) printf("parse_infix_op: found subtraction operator (LINE %d)\n", line_count);
1040     return parse_gen_expr(fs, insert_infix_op(infix_minus, &tree_expr), preset);
1041   case tMult:
1042     //if (PARSE_DEBUG) printf("parse_infix_op: found multiplication operator (LINE %d)\n", line_count);
1043     return parse_gen_expr(fs, insert_infix_op(infix_mult, &tree_expr), preset);
1044   case tDiv:
1045     //if (PARSE_DEBUG) printf("parse_infix_op: found division operator (LINE %d)\n", line_count);  
1046     return parse_gen_expr(fs, insert_infix_op(infix_div, &tree_expr), preset);
1047   case tMod:
1048     //if (PARSE_DEBUG) printf("parse_infix_op: found modulo operator (LINE %d)\n", line_count);  
1049     return parse_gen_expr(fs, insert_infix_op(infix_mod, &tree_expr), preset);
1050   case tOr:  
1051     //if (PARSE_DEBUG) printf("parse_infix_op: found bitwise or operator (LINE %d)\n", line_count);       
1052     return parse_gen_expr(fs, insert_infix_op(infix_or, &tree_expr), preset);
1053   case tAnd:      
1054     //if (PARSE_DEBUG) printf("parse_infix_op: found bitwise and operator (LINE %d)\n", line_count);      
1055     return parse_gen_expr(fs, insert_infix_op(infix_and, &tree_expr), preset);
1056   case tPositive:
1057     //if (PARSE_DEBUG) printf("parse_infix_op: found positive operator (LINE %d)\n", line_count);         
1058     return parse_gen_expr(fs, insert_infix_op(infix_positive, &tree_expr), preset);
1059   case tNegative:
1060     //if (PARSE_DEBUG) printf("parse_infix_op: found negative operator (LINE %d)\n", line_count);         
1061     return parse_gen_expr(fs, insert_infix_op(infix_negative, &tree_expr), preset);
1062
1063   case tEOL:
1064   case tEOF:
1065   case tSemiColon:
1066   case tRPr:
1067   case tComma:    
1068         //if (PARSE_DEBUG) printf("parse_infix_op: terminal found (LINE %d)\n", line_count);
1069         gen_expr = new_gen_expr(TREE_T, (void*)tree_expr);
1070         return gen_expr;
1071   default:
1072     //if (PARSE_DEBUG) printf("parse_infix_op: operator or terminal expected, but not found (LINE %d)\n", line_count);
1073     free_tree_expr(tree_expr);
1074     return NULL;
1075   }  
1076
1077   /* Will never happen */
1078   return NULL;
1079   
1080 }
1081
1082 /* Parses an integer, checks for +/- prefix */
1083 int parse_int(FILE * fs, int * int_ptr) {
1084
1085 char string[MAX_TOKEN_SIZE];
1086   token_t token;
1087   int sign;
1088   char * end_ptr = " ";
1089         
1090   token = parseToken(fs, string);
1091
1092  
1093   switch (token) {
1094   case tMinus:
1095     sign = -1;
1096     token = parseToken(fs, string); 
1097     break;
1098   case tPlus:
1099     sign = 1;
1100     token = parseToken(fs, string);
1101     break;
1102   default: 
1103     sign = 1;
1104     break;
1105   }
1106
1107  
1108   if (string[0] == 0) 
1109     return PARSE_ERROR;
1110   
1111   /* Convert the string to an integer. *end_ptr
1112      should end up pointing to null terminator of 'string' 
1113      if the conversion was successful. */
1114   //  printf("STRING: \"%s\"\n", string);
1115
1116   (*int_ptr) = sign*strtol(string, &end_ptr, 10);
1117
1118   /* If end pointer is a return character or null terminator, all is well */
1119   if ((*end_ptr == '\r') || (*end_ptr == '\0')) 
1120     return SUCCESS;
1121
1122     return PARSE_ERROR;
1123   
1124 }
1125 /* Parses a floating point number */
1126 int string_to_float(char * string, double * float_ptr) {
1127
1128   char ** error_ptr;
1129
1130   if (*string == 0)
1131     return PARSE_ERROR;
1132
1133   error_ptr = malloc(sizeof(char**));
1134   
1135   (*float_ptr) = strtod(string, error_ptr);
1136  
1137   /* These imply a succesful parse of the string */
1138   if ((**error_ptr == '\0') || (**error_ptr == '\r')) {
1139     free(error_ptr);
1140     return SUCCESS;
1141   }
1142     
1143   (*float_ptr) = 0;
1144   free(error_ptr);
1145   return PARSE_ERROR;  
1146 }
1147
1148 /* Parses a floating point number */
1149 int parse_float(FILE * fs, double * float_ptr) {
1150
1151   char string[MAX_TOKEN_SIZE];
1152   char ** error_ptr;
1153   token_t token;
1154   int sign;
1155   
1156   error_ptr = malloc(sizeof(char**));
1157
1158   token = parseToken(fs, string);
1159
1160   switch (token) {
1161   case tMinus:
1162   sign = -1;
1163   token = parseToken(fs, string); 
1164   break;
1165   case tPlus:
1166   sign = 1;
1167   token = parseToken(fs, string);
1168   break;
1169   default: 
1170     sign = 1;  
1171   }
1172  
1173   if (string[0] == 0) {
1174     free(error_ptr);
1175     return PARSE_ERROR;
1176   }
1177
1178   (*float_ptr) = sign*strtod(string, error_ptr);
1179  
1180   /* No conversion was performed */
1181   if ((**error_ptr == '\0') || (**error_ptr == '\r')) {
1182     free(error_ptr);
1183     return SUCCESS;
1184   }
1185     
1186   //if (PARSE_DEBUG) printf("parse_float: double conversion failed for string \"%s\"\n", string);
1187
1188   (*float_ptr) = 0;
1189   free(error_ptr);
1190   return PARSE_ERROR;
1191   
1192
1193   
1194 }
1195
1196 /* Parses a per frame equation. That is, interprets a stream of data as a per frame equation */
1197 per_frame_eqn_t * parse_per_frame_eqn(FILE * fs, int index, struct PRESET_T * preset) {
1198   
1199   char string[MAX_TOKEN_SIZE];
1200   param_t * param;
1201   per_frame_eqn_t * per_frame_eqn;
1202   gen_expr_t * gen_expr;
1203   
1204   if (parseToken(fs, string) != tEq) {
1205     //if (PARSE_DEBUG) printf("parse_per_frame_eqn: no equal sign after string \"%s\" (LINE %d)\n", string, line_count);
1206     return NULL;                        
1207   }
1208   
1209   /* Find the parameter associated with the string, create one if necessary */
1210   if ((param = find_param(string, preset, P_CREATE)) == NULL) { 
1211     return NULL;        
1212   }
1213   
1214   /* Make sure parameter is writable */
1215   if (param->flags & P_FLAG_READONLY) {
1216       //if (PARSE_DEBUG) printf("parse_per_frame_eqn: parameter %s is marked as read only (LINE %d)\n", param->name, line_count);  
1217       return NULL;
1218   }
1219   
1220   /* Parse right side of equation as an expression */
1221   if ((gen_expr = parse_gen_expr(fs, NULL, preset)) == NULL) {
1222     //if (PARSE_DEBUG) printf("parse_per_frame_eqn: equation evaluated to null (LINE %d)\n", line_count);
1223     return NULL;
1224   }
1225   
1226   //if (PARSE_DEBUG) printf("parse_per_frame_eqn: finished per frame equation evaluation (LINE %d)\n", line_count);
1227   
1228   /* Create a new per frame equation */
1229   if ((per_frame_eqn = new_per_frame_eqn(index, param, gen_expr)) == NULL) {
1230     //if (PARSE_DEBUG) printf("parse_per_frame_eqn: failed to create a new per frame eqn, out of memory?\n");
1231     free_gen_expr(gen_expr);
1232     return NULL;
1233   }
1234   
1235   //if (PARSE_DEBUG) printf("parse_per_frame_eqn: per_frame eqn parsed succesfully\n");
1236   
1237   return per_frame_eqn;
1238 }
1239
1240 /* Parses an 'implicit' per frame equation. That is, interprets a stream of data as a per frame equation without a prefix */
1241 per_frame_eqn_t * parse_implicit_per_frame_eqn(FILE * fs, char * param_string, int index, struct PRESET_T * preset) {
1242   
1243   param_t * param;
1244   per_frame_eqn_t * per_frame_eqn;
1245   gen_expr_t * gen_expr;
1246   
1247   if (fs == NULL)
1248     return NULL;
1249   if (param_string == NULL)
1250     return NULL;
1251   if (preset == NULL)
1252     return NULL;
1253
1254   //rintf("param string: %s\n", param_string);
1255   /* Find the parameter associated with the string, create one if necessary */
1256   if ((param = find_param(param_string, preset, P_CREATE)) == NULL) { 
1257     return NULL;        
1258   }
1259   
1260   //printf("parse_implicit_per_frame_eqn: param is %s\n", param->name);
1261
1262   /* Make sure parameter is writable */
1263   if (param->flags & P_FLAG_READONLY) {
1264     //if (PARSE_DEBUG) printf("parse_implicit_per_frame_eqn: parameter %s is marked as read only (LINE %d)\n", param->name, line_count);  
1265     return NULL;
1266   }
1267   
1268   /* Parse right side of equation as an expression */
1269   if ((gen_expr = parse_gen_expr(fs, NULL, preset)) == NULL) {
1270     //if (PARSE_DEBUG) printf("parse_implicit_per_frame_eqn: equation evaluated to null (LINE %d)\n", line_count);
1271     return NULL;
1272   }
1273   
1274   //if (PARSE_DEBUG) printf("parse_implicit_per_frame_eqn: finished per frame equation evaluation (LINE %d)\n", line_count);
1275   
1276   /* Create a new per frame equation */
1277   if ((per_frame_eqn = new_per_frame_eqn(index, param, gen_expr)) == NULL) {
1278     //if (PARSE_DEBUG) printf("parse_implicit_per_frame_eqn: failed to create a new per frame eqn, out of memory?\n");
1279     free_gen_expr(gen_expr);
1280     return NULL;
1281   }
1282   
1283   //if (PARSE_DEBUG) printf("parse_implicit_per_frame_eqn: per_frame eqn parsed succesfully\n");
1284   
1285   return per_frame_eqn;
1286 }
1287
1288 /* Parses an initial condition */
1289 init_cond_t * parse_init_cond(FILE * fs, char * name, struct PRESET_T * preset) {
1290
1291   param_t * param;
1292   value_t init_val;
1293   init_cond_t * init_cond;
1294         
1295   if (name == NULL)
1296     return NULL;
1297   if (preset == NULL)
1298     return NULL;
1299   
1300   /* Search for the paramater in the database, creating it if necessary */
1301   if ((param = find_param(name, preset, P_CREATE)) == NULL) {
1302     return NULL;
1303   }
1304   
1305   //if (PARSE_DEBUG) printf("parse_init_cond: parameter = \"%s\" (LINE %d)\n", param->name, line_count);
1306   
1307   if (param->flags & P_FLAG_READONLY) {
1308     //if (PARSE_DEBUG) printf("parse_init_cond: builtin parameter \"%s\" marked as read only!\n", param->name);
1309     return NULL;
1310   }             
1311   
1312   /* At this point, a parameter has been created or was found
1313      in the database. */
1314   
1315   //if (PARSE_DEBUG) printf("parse_init_cond: parsing initial condition value... (LINE %d)\n", line_count);
1316   
1317   /* integer value (boolean is an integer in C) */
1318   if ((param->type == P_TYPE_INT) || (param->type == P_TYPE_BOOL)) {
1319     if ((parse_int(fs, (int*)&init_val.int_val)) == PARSE_ERROR) {      
1320       //if (PARSE_DEBUG) printf("parse_init_cond: error parsing integer!\n");
1321       return NULL;
1322     }
1323   }
1324   
1325   /* double value */
1326   else if (param->type == P_TYPE_DOUBLE) {
1327     if ((parse_float(fs, (double*)&init_val.double_val)) == PARSE_ERROR) {
1328       //if (PARSE_DEBUG) printf("parse_init_cond: error parsing double!\n");
1329       return NULL;
1330     }
1331   }
1332   
1333   /* Unknown value */
1334   else {
1335     //if (PARSE_DEBUG) printf("parse_init_cond: unknown parameter type!\n");
1336     return NULL;
1337   }
1338   
1339   /* Create new initial condition */
1340   if ((init_cond = new_init_cond(param, init_val)) == NULL) {
1341       //if (PARSE_DEBUG) printf("parse_init_cond: new_init_cond failed!\n");
1342       return NULL;
1343   }
1344   
1345   /* Finished */
1346   return init_cond;
1347 }
1348
1349 /* Parses a per frame init equation, not sure if this works right now */
1350 init_cond_t * parse_per_frame_init_eqn(FILE * fs, struct PRESET_T * preset, splaytree_t * database) {
1351   
1352   char name[MAX_TOKEN_SIZE];
1353   param_t * param = NULL;
1354   value_t init_val;
1355   init_cond_t * init_cond;
1356   gen_expr_t * gen_expr;
1357   double val;
1358   token_t token;
1359
1360
1361   if (preset == NULL)
1362     return NULL;
1363   if (fs == NULL)
1364     return NULL;
1365
1366   if ((token = parseToken(fs, name)) != tEq)
1367     return NULL;
1368   
1369
1370   /* If a database was specified,then use find_param_db instead */
1371   if ((database != NULL) && ((param = find_param_db(name, database, TRUE)) == NULL)) {
1372     return NULL;
1373   }
1374
1375   /* Otherwise use the builtin parameter and user databases. This is confusing. Sorry. */
1376   if ((param == NULL) && ((param = find_param(name, preset, P_CREATE)) == NULL)) {
1377     return NULL;
1378   }
1379   
1380   //if (PARSE_DEBUG) printf("parse_per_frame_init_eqn: parameter = \"%s\" (LINE %d)\n", param->name, line_count);
1381   
1382   if (param->flags & P_FLAG_READONLY) {
1383     //if (PARSE_DEBUG) printf("pars_per_frame_init_eqn: builtin parameter \"%s\" marked as read only!\n", param->name);
1384     return NULL;
1385   }             
1386   
1387   /* At this point, a parameter has been created or was found
1388      in the database. */
1389   
1390   //if (PARSE_DEBUG) printf("parse_per_frame_init_eqn: parsing right hand side of per frame init equation.. (LINE %d)\n", line_count);
1391   
1392   if ((gen_expr = parse_gen_expr(fs, NULL, preset)) == NULL) {
1393     //if (PARSE_DEBUG) printf("parse_per_frame_init_eqn: failed to parse general expresion!\n");
1394     return NULL;
1395   }
1396  
1397   /* Compute initial condition value */
1398   val = eval_gen_expr(gen_expr);
1399   
1400   /* Free the general expression now that we are done with it */
1401   free_gen_expr(gen_expr);
1402
1403   /* integer value (boolean is an integer in C) */
1404   if ((param->type == P_TYPE_INT) || (param->type == P_TYPE_BOOL)) {
1405     init_val.int_val = (int)val;
1406   }
1407   
1408   /* double value */
1409   else if (param->type == P_TYPE_DOUBLE) {
1410     init_val.double_val = val;
1411   }
1412   
1413   /* Unknown value */
1414   else {
1415     //if (PARSE_DEBUG) printf("parse_per_frame_init_eqn: unknown parameter type!\n");
1416     return NULL;
1417   }
1418   
1419
1420   /* Create new initial condition */
1421   if ((init_cond = new_init_cond(param, init_val)) == NULL) {
1422       //if (PARSE_DEBUG) printf("parse_per_frame_init_eqn: new_init_cond failed!\n");
1423       return NULL;
1424   }
1425
1426
1427   /* Finished */
1428   return init_cond;
1429 }
1430
1431 int parse_wavecode(char * token, FILE * fs, preset_t * preset) {
1432
1433   char * var_string;
1434   init_cond_t * init_cond;
1435   custom_wave_t * custom_wave;
1436   int id;
1437   value_t init_val;
1438   param_t * param;
1439
1440   /* Null argument checks */
1441   if (preset == NULL)
1442     return FAILURE;
1443   if (fs == NULL)
1444     return FAILURE;
1445   if (token == NULL)
1446     return FAILURE;
1447
1448   /* token should be in the form wavecode_N_var, such as wavecode_1_samples */
1449   
1450   /* Get id and variable name from token string */
1451   if (parse_wavecode_prefix(token, &id, &var_string) < 0)   
1452     return PARSE_ERROR;
1453   
1454   //if (PARSE_DEBUG) printf("parse_wavecode: wavecode id = %d, parameter = \"%s\"\n", id, var_string);
1455
1456   /* Retrieve custom wave information from preset. The 3rd argument
1457      if true creates a custom wave if one does not exist */
1458   if ((custom_wave = find_custom_wave(id, preset, TRUE)) == NULL) {
1459     //if (PARSE_DEBUG) printf("parse_wavecode: failed to load (or create) custom wave (id = %d)!\n", id);
1460     return FAILURE;
1461   }
1462   //if (PARSE_DEBUG) printf("parse_wavecode: custom wave found (id = %d)\n", custom_wave->id);
1463
1464   /* Retrieve parameter from this custom waves parameter db */
1465   if ((param = find_param_db(var_string, custom_wave->param_tree, TRUE)) == NULL)
1466     return FAILURE;
1467
1468   //if (PARSE_DEBUG) printf("parse_wavecode: custom wave parameter found (name = %s)\n", param->name);
1469
1470   /* integer value (boolean is an integer in C) */
1471   if ((param->type == P_TYPE_INT) || (param->type == P_TYPE_BOOL)) {
1472     if ((parse_int(fs, (int*)&init_val.int_val)) == PARSE_ERROR) {      
1473       //if (PARSE_DEBUG) printf("parse_wavecode: error parsing integer!\n");
1474       return PARSE_ERROR;
1475     }
1476   }
1477   
1478   /* double value */
1479   else if (param->type == P_TYPE_DOUBLE) {
1480     if ((parse_float(fs, (double*)&init_val.double_val)) == PARSE_ERROR) {
1481       //if (PARSE_DEBUG) printf("parse_wavecode: error parsing double!\n");
1482       return PARSE_ERROR;
1483     }
1484   }
1485   
1486   /* Unknown value */
1487   else {
1488     //if (PARSE_DEBUG) printf("parse_wavecode: unknown parameter type!\n");
1489     return PARSE_ERROR;
1490   }
1491   
1492   /* Create new initial condition */
1493   if ((init_cond = new_init_cond(param, init_val)) == NULL) {
1494       //if (PARSE_DEBUG) printf("parse_wavecode: new_init_cond failed!\n");
1495       return FAILURE;
1496   }
1497   
1498   if (splay_insert(init_cond, param->name, custom_wave->init_cond_tree) < 0) {
1499     free_init_cond(init_cond);
1500     return PARSE_ERROR;
1501   }
1502
1503   //if (PARSE_DEBUG) printf("parse_wavecode: [success]\n");
1504   return SUCCESS;
1505 }
1506
1507 int parse_shapecode(char * token, FILE * fs, preset_t * preset) {
1508
1509   char * var_string;
1510   init_cond_t * init_cond;
1511   custom_shape_t * custom_shape;
1512   int id;
1513   value_t init_val;
1514   param_t * param;
1515
1516   /* Null argument checks */
1517   if (preset == NULL)
1518     return FAILURE;
1519   if (fs == NULL)
1520     return FAILURE;
1521   if (token == NULL)
1522     return FAILURE;
1523
1524   /* token should be in the form shapecode_N_var, such as shapecode_1_samples */
1525   
1526   /* Get id and variable name from token string */
1527   if (parse_shapecode_prefix(token, &id, &var_string) < 0)   
1528     return PARSE_ERROR;
1529   
1530   //if (PARSE_DEBUG) printf("parse_shapecode: shapecode id = %d, parameter = \"%s\"\n", id, var_string);
1531
1532   /* Retrieve custom shape information from preset. The 3rd argument
1533      if true creates a custom shape if one does not exist */
1534   if ((custom_shape = find_custom_shape(id, preset, TRUE)) == NULL) {
1535     //if (PARSE_DEBUG) printf("parse_shapecode: failed to load (or create) custom shape (id = %d)!\n", id);
1536     return FAILURE;
1537   }
1538   //if (PARSE_DEBUG) printf("parse_shapecode: custom shape found (id = %d)\n", custom_shape->id);
1539
1540   /* Retrieve parameter from this custom shapes parameter db */
1541   if ((param = find_param_db(var_string, custom_shape->param_tree, TRUE)) == NULL) {
1542     //if (PARSE_DEBUG) printf("parse_shapecode: failed to create parameter.\n");
1543     return FAILURE;
1544   }
1545   //if (PARSE_DEBUG) printf("parse_shapecode: custom shape parameter found (name = %s)\n", param->name);
1546
1547   /* integer value (boolean is an integer in C) */
1548   if ((param->type == P_TYPE_INT) || (param->type == P_TYPE_BOOL)) {
1549     if ((parse_int(fs, (int*)&init_val.int_val)) == PARSE_ERROR) {      
1550       //if (PARSE_DEBUG) printf("parse_shapecode: error parsing integer!\n");
1551       return PARSE_ERROR;
1552     }
1553   }
1554   
1555   /* double value */
1556   else if (param->type == P_TYPE_DOUBLE) {
1557     if ((parse_float(fs, (double*)&init_val.double_val)) == PARSE_ERROR) {
1558       //if (PARSE_DEBUG) printf("parse_shapecode: error parsing double!\n");
1559       return PARSE_ERROR;
1560     }
1561   }
1562   
1563   /* Unknown value */
1564   else {
1565     //if (PARSE_DEBUG) printf("parse_shapecode: unknown parameter type!\n");
1566     return PARSE_ERROR;
1567   }
1568   
1569   /* Create new initial condition */
1570   if ((init_cond = new_init_cond(param, init_val)) == NULL) {
1571       //if (PARSE_DEBUG) printf("parse_shapecode: new_init_cond failed!\n");
1572       return FAILURE;
1573   }
1574  
1575   if (splay_insert(init_cond, param->name, custom_shape->init_cond_tree) < 0) {
1576     free_init_cond(init_cond);
1577     //if (PARSE_DEBUG) printf("parse_shapecode: initial condition already set, not reinserting it (param = \"%s\")\n", param->name);
1578     return PARSE_ERROR;
1579   }
1580
1581   //if (PARSE_DEBUG) printf("parse_shapecode: [success]\n");
1582   return SUCCESS;
1583 }
1584
1585
1586 int parse_wavecode_prefix(char * token, int * id, char ** var_string) {
1587
1588   int len, i, j;
1589   
1590   if (token == NULL)
1591     return FAILURE;
1592   if (*var_string == NULL)
1593     return FAILURE;
1594   if (id == NULL)
1595     return FAILURE;
1596   
1597   len = strlen(token);
1598
1599   /* Move pointer passed "wavecode_" prefix */
1600   if (len <= WAVECODE_STRING_LENGTH)
1601     return FAILURE;
1602   i = WAVECODE_STRING_LENGTH;
1603   j = 0;
1604   (*id) = 0;
1605   
1606   /* This loop grabs the integer id for this custom wave */
1607   while ((i < len) && (token[i] >=  48) && (token[i] <= 57)) {
1608     if (j >= MAX_TOKEN_SIZE)
1609       return FAILURE;
1610     
1611     (*id) = 10*(*id) + (token[i]-48);
1612     j++;
1613     i++;
1614   }
1615
1616  
1617   if (i > (len - 2))
1618     return FAILURE;
1619   
1620   *var_string = token + i + 1;
1621  
1622   return SUCCESS;
1623
1624 }
1625
1626
1627 int parse_shapecode_prefix(char * token, int * id, char ** var_string) {
1628
1629   int len, i, j;
1630   
1631   if (token == NULL)
1632     return FAILURE;
1633   if (*var_string == NULL)
1634     return FAILURE;
1635   if (id == NULL)
1636     return FAILURE;
1637   
1638   len = strlen(token);
1639
1640   /* Move pointer passed "shapecode_" prefix */
1641   if (len <= SHAPECODE_STRING_LENGTH)
1642     return FAILURE;
1643   i = SHAPECODE_STRING_LENGTH;
1644   j = 0;
1645   (*id) = 0;
1646   
1647   /* This loop grabs the integer id for this custom shape */
1648   while ((i < len) && (token[i] >=  48) && (token[i] <= 57)) {
1649     if (j >= MAX_TOKEN_SIZE)
1650       return FAILURE;
1651     
1652     (*id) = 10*(*id) + (token[i]-48);
1653     j++;
1654     i++;
1655   }
1656
1657  
1658   if (i > (len - 2))
1659     return FAILURE;
1660   
1661   *var_string = token + i + 1;
1662  
1663   return SUCCESS;
1664
1665 }
1666
1667 int parse_wave_prefix(char * token, int * id, char ** eqn_string) {
1668
1669   int len, i, j;
1670   
1671   if (token == NULL)
1672     return FAILURE;
1673   if (eqn_string == NULL)
1674     return FAILURE;
1675   if (id == NULL)
1676     return FAILURE;
1677   
1678   len = strlen(token);
1679  
1680   if (len <= WAVE_STRING_LENGTH)
1681     return FAILURE;
1682
1683
1684   i = WAVE_STRING_LENGTH;
1685   j = 0;
1686   (*id) = 0;
1687   
1688   /* This loop grabs the integer id for this custom wave */
1689   while ((i < len) && (token[i] >=  48) && (token[i] <= 57)) {
1690     if (j >= MAX_TOKEN_SIZE)
1691       return FAILURE;
1692     
1693     (*id) = 10*(*id) + (token[i]-48);
1694     j++;
1695     i++;
1696   }
1697
1698   if (i > (len - 2))
1699     return FAILURE;
1700  
1701   *eqn_string = token + i + 1;
1702  
1703   return SUCCESS;
1704
1705 }
1706
1707 int parse_shape_prefix(char * token, int * id, char ** eqn_string) {
1708
1709   int len, i, j;
1710   
1711   if (token == NULL)
1712     return FAILURE;
1713   if (eqn_string == NULL)
1714     return FAILURE;
1715   if (id == NULL)
1716     return FAILURE;
1717   
1718   len = strlen(token);
1719  
1720   if (len <= SHAPE_STRING_LENGTH)
1721     return FAILURE;
1722
1723
1724   i = SHAPE_STRING_LENGTH;
1725   j = 0;
1726   (*id) = 0;
1727   
1728   /* This loop grabs the integer id for this custom wave */
1729   while ((i < len) && (token[i] >=  48) && (token[i] <= 57)) {
1730     if (j >= MAX_TOKEN_SIZE)
1731       return FAILURE;
1732     
1733     (*id) = 10*(*id) + (token[i]-48);
1734     j++;
1735     i++;
1736   }
1737
1738   if (i > (len - 2))
1739     return FAILURE;
1740  
1741   *eqn_string = token + i + 1;
1742  
1743   return SUCCESS;
1744
1745 }
1746
1747 /* Parses custom wave equations */
1748 int parse_wave(char * token, FILE * fs, preset_t * preset) {
1749   
1750   int id;
1751   char * eqn_type;
1752   char string[MAX_TOKEN_SIZE];
1753   param_t * param;
1754   per_frame_eqn_t * per_frame_eqn;
1755   gen_expr_t * gen_expr;
1756   custom_wave_t * custom_wave;
1757   init_cond_t * init_cond;
1758
1759   if (token == NULL)
1760     return FAILURE;
1761   if (fs == NULL)
1762     return FAILURE;
1763   if (preset == NULL)
1764     return FAILURE;
1765   
1766   /* Grab custom wave id and equation type (per frame or per point) from string token */
1767   if (parse_wave_prefix(token, &id, &eqn_type) < 0) {
1768     //if (PARSE_DEBUG) printf("parse_wave: syntax error in custom wave prefix!\n");
1769     return FAILURE;
1770   }
1771   /* Retrieve custom wave associated with this id */
1772   if ((custom_wave = find_custom_wave(id, preset, TRUE)) == NULL)
1773     return FAILURE;
1774
1775
1776   /* per frame init equation case */        
1777   if (!strncmp(eqn_type, WAVE_INIT_STRING, WAVE_INIT_STRING_LENGTH)) {
1778
1779     //if (PARSE_DEBUG) printf("parse_wave (per frame init): [begin] (LINE %d)\n", line_count);
1780
1781     /* Parse the per frame equation */
1782     if ((init_cond = parse_per_frame_init_eqn(fs, preset, custom_wave->param_tree)) == NULL) {
1783       //if (PARSE_DEBUG) printf("parse_wave (per frame init): equation parsing failed (LINE %d)\n", line_count);
1784       return PARSE_ERROR;
1785     }   
1786
1787     /* Insert the equation in the per frame equation tree */
1788     if (splay_insert(init_cond, init_cond->param->name, custom_wave->per_frame_init_eqn_tree) < 0) {
1789       //if (PARSE_DEBUG) printf("parse_wave (per frame init): failed to add equation (ERROR)\n");
1790        free_init_cond(init_cond); /* will free the gen expr too */              
1791       return FAILURE;
1792     }
1793    
1794     if (update_string_buffer(custom_wave->per_frame_init_eqn_string_buffer, 
1795                              &custom_wave->per_frame_init_eqn_string_index) < 0)
1796       return FAILURE;
1797         
1798     return SUCCESS;
1799   
1800   }
1801
1802   /* per frame equation case */
1803   if (!strncmp(eqn_type, PER_FRAME_STRING_NO_UNDERSCORE, PER_FRAME_STRING_NO_UNDERSCORE_LENGTH)) {
1804
1805     //if (PARSE_DEBUG) printf("parse_wave (per_frame): [start] (custom wave id = %d)\n", custom_wave->id);
1806     
1807     if (parseToken(fs, string) != tEq) {
1808       //if (PARSE_DEBUG) printf("parse_wave (per_frame): no equal sign after string \"%s\" (LINE %d)\n", string, line_count);
1809       return PARSE_ERROR;                       
1810     }
1811   
1812     /* Find the parameter associated with the string in the custom wave database */
1813     if ((param = find_param_db(string, custom_wave->param_tree, TRUE)) == NULL) { 
1814       //if (PARSE_DEBUG) printf("parse_wave (per_frame): parameter \"%s\" not found or cannot be malloc'ed!!\n", string);
1815       return FAILURE;   
1816     }
1817   
1818     
1819     /* Make sure parameter is writable */
1820     if (param->flags & P_FLAG_READONLY) {
1821       //if (PARSE_DEBUG) printf("parse_wave (per_frame): parameter %s is marked as read only (LINE %d)\n", param->name, line_count);  
1822       return FAILURE;
1823     }
1824   
1825     /* Parse right side of equation as an expression */
1826
1827     current_wave = custom_wave;
1828     if ((gen_expr = parse_gen_expr(fs, NULL, preset)) == NULL) {
1829       //if (PARSE_DEBUG) printf("parse_wave (per_frame): equation evaluated to null (LINE %d)\n", line_count);
1830       current_wave = NULL;
1831       return PARSE_ERROR;
1832
1833     }
1834     current_wave = NULL;
1835
1836     //if (PARSE_DEBUG) printf("parse_wave (per_frame): [finished parsing equation] (LINE %d)\n", line_count);
1837   
1838     /* Create a new per frame equation */
1839     if ((per_frame_eqn = new_per_frame_eqn(custom_wave->per_frame_count++, param, gen_expr)) == NULL) {
1840       //if (PARSE_DEBUG) printf("parse_wave (per_frame): failed to create a new per frame eqn, out of memory?\n");
1841       free_gen_expr(gen_expr);
1842       return FAILURE;
1843     }
1844  
1845     if (splay_insert(per_frame_eqn, &per_frame_eqn->index, custom_wave->per_frame_eqn_tree) < 0) {
1846       free_per_frame_eqn(per_frame_eqn);
1847       return FAILURE;
1848     }
1849        
1850     //if (PARSE_DEBUG) printf("parse_wave (per_frame): equation %d associated with custom wave %d [success]\n", 
1851     //                      per_frame_eqn->index, custom_wave->id);
1852
1853     
1854     /* Need to add stuff to string buffer so the editor can read the equations. 
1855        Why not make a nice little helper function for this? - here it is: */
1856
1857    
1858     if (update_string_buffer(custom_wave->per_frame_eqn_string_buffer, &custom_wave->per_frame_eqn_string_index) < 0)
1859       return FAILURE;
1860
1861  
1862     return SUCCESS;
1863   }
1864
1865
1866   /* per point equation case */
1867   if (!strncmp(eqn_type, PER_POINT_STRING, PER_POINT_STRING_LENGTH)) {
1868
1869     //if (PARSE_DEBUG) printf("parse_wave (per_point): per_pixel equation parsing start...(LINE %d)\n", line_count);
1870
1871     if (parseToken(fs, string) != tEq) { /* parse per pixel operator  name */
1872       //if (PARSE_DEBUG) printf("parse_wave (per_point): equal operator missing after per pixel operator! (LINE %d)\n", line_count);
1873       return PARSE_ERROR;
1874     }
1875     
1876     /* Parse right side of equation as an expression */
1877     current_wave = custom_wave;
1878     if ((gen_expr = parse_gen_expr(fs, NULL, preset)) == NULL) {
1879       //if (PARSE_DEBUG) printf("parse_wave (per_point): equation evaluated to null? (LINE %d)\n", line_count);
1880       return PARSE_ERROR;
1881     }
1882     current_wave = NULL;
1883
1884     /* Add the per point equation */
1885     if (add_per_point_eqn(string, gen_expr, custom_wave) < 0) {
1886       free_gen_expr(gen_expr);
1887       return PARSE_ERROR;
1888     }
1889
1890    
1891     if (update_string_buffer(custom_wave->per_point_eqn_string_buffer, &custom_wave->per_point_eqn_string_index) < 0)
1892       return FAILURE;
1893
1894     //if (PARSE_DEBUG) printf("parse_wave (per_point): [finished] (custom wave id = %d)\n", custom_wave->id);
1895     return SUCCESS;
1896   }
1897
1898
1899   /* Syntax error, return parse error */
1900   return PARSE_ERROR;
1901 }
1902
1903
1904
1905 /* Parses custom shape equations */
1906 int parse_shape(char * token, FILE * fs, preset_t * preset) {
1907   
1908   int id;
1909   char * eqn_type;
1910   char string[MAX_TOKEN_SIZE];
1911   param_t * param;
1912   per_frame_eqn_t * per_frame_eqn;
1913   gen_expr_t * gen_expr;
1914   custom_shape_t * custom_shape;
1915   init_cond_t * init_cond;
1916
1917   if (token == NULL)
1918
1919     return FAILURE;
1920   if (fs == NULL)
1921     return FAILURE;
1922   if (preset == NULL)
1923     return FAILURE;
1924   
1925   /* Grab custom shape id and equation type (per frame or per point) from string token */
1926   if (parse_shape_prefix(token, &id, &eqn_type) < 0) {
1927     //if (PARSE_DEBUG) printf("parse_shape: syntax error in custom shape prefix!\n");
1928     return PARSE_ERROR;
1929   }
1930   /* Retrieve custom shape associated with this id */
1931   if ((custom_shape = find_custom_shape(id, preset, TRUE)) == NULL)
1932     return FAILURE;
1933
1934
1935   /* per frame init equation case */        
1936   if (!strncmp(eqn_type, SHAPE_INIT_STRING, SHAPE_INIT_STRING_LENGTH)) {
1937
1938     //if (PARSE_DEBUG) printf("parse_shape (per frame init): [begin] (LINE %d)\n", line_count);
1939
1940     /* Parse the per frame equation */
1941     if ((init_cond = parse_per_frame_init_eqn(fs, preset, custom_shape->param_tree)) == NULL) {
1942       //if (PARSE_DEBUG) printf("parse_shape (per frame init): equation parsing failed (LINE %d)\n", line_count);
1943       return PARSE_ERROR;
1944     }   
1945     
1946     /* Insert the equation in the per frame equation tree */
1947     if (splay_insert(init_cond, init_cond->param->name, custom_shape->per_frame_init_eqn_tree) < 0) {
1948       //if (PARSE_DEBUG) printf("parse_shape (per frame init): failed to add equation (ERROR)\n");
1949       free_init_cond(init_cond); /* will free the gen expr too */               
1950       return ERROR;
1951     }
1952
1953     if (update_string_buffer(custom_shape->per_frame_init_eqn_string_buffer, 
1954                              &custom_shape->per_frame_init_eqn_string_index) < 0)
1955       return FAILURE;
1956         
1957     return SUCCESS;
1958   
1959   }
1960
1961   /* per frame equation case */
1962   if (!strncmp(eqn_type, PER_FRAME_STRING_NO_UNDERSCORE, PER_FRAME_STRING_NO_UNDERSCORE_LENGTH)) {
1963
1964     //if (PARSE_DEBUG) printf("parse_shape (per_frame): [start] (custom shape id = %d)\n", custom_shape->id);
1965     
1966     if (parseToken(fs, string) != tEq) {
1967       //if (PARSE_DEBUG) printf("parse_shape (per_frame): no equal sign after string \"%s\" (LINE %d)\n", string, line_count);
1968       return PARSE_ERROR;                       
1969     }
1970   
1971     /* Find the parameter associated with the string in the custom shape database */
1972     if ((param = find_param_db(string, custom_shape->param_tree, TRUE)) == NULL) { 
1973       //if (PARSE_DEBUG) printf("parse_shape (per_frame): parameter \"%s\" not found or cannot be malloc'ed!!\n", string);
1974       return FAILURE;   
1975     }
1976   
1977     
1978     /* Make sure parameter is writable */
1979     if (param->flags & P_FLAG_READONLY) {
1980       //if (PARSE_DEBUG) printf("parse_shape (per_frame): parameter %s is marked as read only (LINE %d)\n", param->name, line_count);  
1981       return FAILURE;
1982     }
1983   
1984     /* Parse right side of equation as an expression */
1985
1986     current_shape = custom_shape;
1987     if ((gen_expr = parse_gen_expr(fs, NULL, preset)) == NULL) {
1988       //if (PARSE_DEBUG) printf("parse_shape (per_frame): equation evaluated to null (LINE %d)\n", line_count);
1989       current_shape = NULL;
1990       return PARSE_ERROR;
1991     }
1992
1993     current_shape = NULL;
1994
1995     //if (PARSE_DEBUG) printf("parse_shape (per_frame): [finished parsing equation] (LINE %d)\n", line_count);
1996   
1997     /* Create a new per frame equation */
1998     if ((per_frame_eqn = new_per_frame_eqn(custom_shape->per_frame_count++, param, gen_expr)) == NULL) {
1999       //if (PARSE_DEBUG) printf("parse_shape (per_frame): failed to create a new per frame eqn, out of memory?\n");
2000       free_gen_expr(gen_expr);
2001       return FAILURE;
2002     }
2003  
2004     if (splay_insert(per_frame_eqn, &per_frame_eqn->index, custom_shape->per_frame_eqn_tree) < 0) {
2005       free_per_frame_eqn(per_frame_eqn);
2006       return FAILURE;
2007     }
2008        
2009     //if (PARSE_DEBUG) printf("parse_shape (per_frame): equation %d associated with custom shape %d [success]\n", 
2010     //                      per_frame_eqn->index, custom_shape->id);
2011
2012     
2013     /* Need to add stuff to string buffer so the editor can read the equations.
2014        Why not make a nice little helper function for this? - here it is: */
2015     
2016     if (update_string_buffer(custom_shape->per_frame_eqn_string_buffer, &custom_shape->per_frame_eqn_string_index) < 0)
2017       return FAILURE;
2018
2019  
2020     return SUCCESS;
2021   }
2022
2023
2024   /* Syntax error, return parse error */
2025   return PARSE_ERROR;
2026 }
2027
2028 /* Helper function to update the string buffers used by the editor */
2029 int update_string_buffer(char * buffer, int * index) {
2030
2031   int string_length;
2032   int skip_size;
2033
2034   if (!buffer)
2035     return FAILURE;
2036   if (!index)
2037     return FAILURE;
2038
2039   
2040   /* If the string line buffer used by the parser is already full then quit */
2041   if (string_line_buffer_index == (STRING_LINE_SIZE-1))
2042     return FAILURE;
2043
2044   if ((skip_size = get_string_prefix_len(string_line_buffer)) == FAILURE)
2045     return FAILURE;
2046
2047   string_line_buffer[string_line_buffer_index++] = '\n';
2048
2049   //  string_length = strlen(string_line_buffer + strlen(eqn_string)+1);
2050   if (skip_size >= STRING_LINE_SIZE)
2051     return FAILURE;
2052
2053   string_length = strlen(string_line_buffer + skip_size);
2054
2055   if (skip_size > (STRING_LINE_SIZE-1))
2056     return FAILURE;
2057
2058   /* Add line to string buffer */
2059   strncpy(buffer + (*index), 
2060           string_line_buffer + skip_size, string_length);
2061   
2062   /* Buffer full, quit */
2063   if ((*index) > (STRING_BUFFER_SIZE - 1)) {
2064     //if (PARSE_DEBUG) printf("update_string_buffer: string buffer full!\n");
2065     return FAILURE;
2066   }     
2067   
2068   /* Otherwise, increment string index by the added string length */
2069   (*index)+=string_length;
2070     
2071   return SUCCESS;
2072   
2073 }
2074
2075
2076 /* Helper function: returns the length of the prefix portion in the line
2077    buffer (the passed string here). In other words, given
2078    the string 'per_frame_1 = x = ....', return the length of 'per_frame_1 = '
2079    Returns -1 if syntax error
2080 */
2081
2082 int get_string_prefix_len(char * string) {
2083   
2084   int i = 0;
2085
2086   /* Null argument check */
2087   if (string == NULL)
2088     return FAILURE;
2089
2090   
2091   /* First find the equal sign */
2092   while (string[i] != '=') {
2093     if (string[i] == 0)
2094       return FAILURE;
2095     i++;
2096   }
2097
2098   /* If the string already ends at the next char then give up */
2099   if (string[i+1] == 0)
2100     return FAILURE;
2101
2102   /* Move past the equal sign */
2103   i++;
2104
2105   /* Now found the start of the LHS variable, ie skip the spaces */
2106   while(string[i] == ' ') {
2107     i++;
2108   }
2109
2110   /* If this is the end of the string then its a syntax error */
2111   if (string[i] == 0)
2112     return FAILURE;
2113
2114   /* Finished succesfully, return the length */
2115   return i;
2116 }