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