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