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