📄 parser.c
字号:
} if (i > (len - 2)) return FAILURE; *eqn_string = token + i + 1; return SUCCESS;}int parse_shape_prefix(char * token, int * id, char ** eqn_string) { int len, i, j; if (token == NULL) return FAILURE; if (eqn_string == NULL) return FAILURE; if (id == NULL) return FAILURE; len = strlen(token); if (len <= SHAPE_STRING_LENGTH) return FAILURE; i = SHAPE_STRING_LENGTH; j = 0; (*id) = 0; /* This loop grabs the integer id for this custom wave */ while ((i < len) && (token[i] >= 48) && (token[i] <= 57)) { if (j >= MAX_TOKEN_SIZE) return FAILURE; (*id) = 10*(*id) + (token[i]-48); j++; i++; } if (i > (len - 2)) return FAILURE; *eqn_string = token + i + 1; return SUCCESS;}/* Parses custom wave equations */int parse_wave(char * token, FILE * fs, preset_t * preset) { int id; char * eqn_type; char string[MAX_TOKEN_SIZE]; param_t * param; per_frame_eqn_t * per_frame_eqn; gen_expr_t * gen_expr; custom_wave_t * custom_wave; init_cond_t * init_cond; if (token == NULL) return FAILURE; if (fs == NULL) return FAILURE; if (preset == NULL) return FAILURE; /* Grab custom wave id and equation type (per frame or per point) from string token */ if (parse_wave_prefix(token, &id, &eqn_type) < 0) { //if (PARSE_DEBUG) printf("parse_wave: syntax error in custom wave prefix!\n"); return FAILURE; } /* Retrieve custom wave associated with this id */ if ((custom_wave = find_custom_wave(id, preset, TRUE)) == NULL) return FAILURE; /* per frame init equation case */ if (!strncmp(eqn_type, WAVE_INIT_STRING, WAVE_INIT_STRING_LENGTH)) { //if (PARSE_DEBUG) printf("parse_wave (per frame init): [begin] (LINE %d)\n", line_count); /* Parse the per frame equation */ if ((init_cond = parse_per_frame_init_eqn(fs, preset, custom_wave->param_tree)) == NULL) { //if (PARSE_DEBUG) printf("parse_wave (per frame init): equation parsing failed (LINE %d)\n", line_count); return PARSE_ERROR; } /* Insert the equation in the per frame equation tree */ if (splay_insert(init_cond, init_cond->param->name, custom_wave->per_frame_init_eqn_tree) < 0) { //if (PARSE_DEBUG) printf("parse_wave (per frame init): failed to add equation (ERROR)\n"); free_init_cond(init_cond); /* will free the gen expr too */ return FAILURE; } if (update_string_buffer(custom_wave->per_frame_init_eqn_string_buffer, &custom_wave->per_frame_init_eqn_string_index) < 0) return FAILURE; return SUCCESS; } /* per frame equation case */ if (!strncmp(eqn_type, PER_FRAME_STRING_NO_UNDERSCORE, PER_FRAME_STRING_NO_UNDERSCORE_LENGTH)) { //if (PARSE_DEBUG) printf("parse_wave (per_frame): [start] (custom wave id = %d)\n", custom_wave->id); if (parseToken(fs, string) != tEq) { //if (PARSE_DEBUG) printf("parse_wave (per_frame): no equal sign after string \"%s\" (LINE %d)\n", string, line_count); return PARSE_ERROR; } /* Find the parameter associated with the string in the custom wave database */ if ((param = find_param_db(string, custom_wave->param_tree, TRUE)) == NULL) { //if (PARSE_DEBUG) printf("parse_wave (per_frame): parameter \"%s\" not found or cannot be malloc'ed!!\n", string); return FAILURE; } /* Make sure parameter is writable */ if (param->flags & P_FLAG_READONLY) { //if (PARSE_DEBUG) printf("parse_wave (per_frame): parameter %s is marked as read only (LINE %d)\n", param->name, line_count); return FAILURE; } /* Parse right side of equation as an expression */ current_wave = custom_wave; if ((gen_expr = parse_gen_expr(fs, NULL, preset)) == NULL) { //if (PARSE_DEBUG) printf("parse_wave (per_frame): equation evaluated to null (LINE %d)\n", line_count); current_wave = NULL; return PARSE_ERROR; } current_wave = NULL; //if (PARSE_DEBUG) printf("parse_wave (per_frame): [finished parsing equation] (LINE %d)\n", line_count); /* Create a new per frame equation */ if ((per_frame_eqn = new_per_frame_eqn(custom_wave->per_frame_count++, param, gen_expr)) == NULL) { //if (PARSE_DEBUG) printf("parse_wave (per_frame): failed to create a new per frame eqn, out of memory?\n"); free_gen_expr(gen_expr); return FAILURE; } if (splay_insert(per_frame_eqn, &per_frame_eqn->index, custom_wave->per_frame_eqn_tree) < 0) { free_per_frame_eqn(per_frame_eqn); return FAILURE; } //if (PARSE_DEBUG) printf("parse_wave (per_frame): equation %d associated with custom wave %d [success]\n", // per_frame_eqn->index, custom_wave->id); /* Need to add stuff to string buffer so the editor can read the equations. Why not make a nice little helper function for this? - here it is: */ if (update_string_buffer(custom_wave->per_frame_eqn_string_buffer, &custom_wave->per_frame_eqn_string_index) < 0) return FAILURE; return SUCCESS; } /* per point equation case */ if (!strncmp(eqn_type, PER_POINT_STRING, PER_POINT_STRING_LENGTH)) { //if (PARSE_DEBUG) printf("parse_wave (per_point): per_pixel equation parsing start...(LINE %d)\n", line_count); if (parseToken(fs, string) != tEq) { /* parse per pixel operator name */ //if (PARSE_DEBUG) printf("parse_wave (per_point): equal operator missing after per pixel operator! (LINE %d)\n", line_count); return PARSE_ERROR; } /* Parse right side of equation as an expression */ current_wave = custom_wave; if ((gen_expr = parse_gen_expr(fs, NULL, preset)) == NULL) { //if (PARSE_DEBUG) printf("parse_wave (per_point): equation evaluated to null? (LINE %d)\n", line_count); return PARSE_ERROR; } current_wave = NULL; /* Add the per point equation */ if (add_per_point_eqn(string, gen_expr, custom_wave) < 0) { free_gen_expr(gen_expr); return PARSE_ERROR; } if (update_string_buffer(custom_wave->per_point_eqn_string_buffer, &custom_wave->per_point_eqn_string_index) < 0) return FAILURE; //if (PARSE_DEBUG) printf("parse_wave (per_point): [finished] (custom wave id = %d)\n", custom_wave->id); return SUCCESS; } /* Syntax error, return parse error */ return PARSE_ERROR;}/* Parses custom shape equations */int parse_shape(char * token, FILE * fs, preset_t * preset) { int id; char * eqn_type; char string[MAX_TOKEN_SIZE]; param_t * param; per_frame_eqn_t * per_frame_eqn; gen_expr_t * gen_expr; custom_shape_t * custom_shape; init_cond_t * init_cond; if (token == NULL) return FAILURE; if (fs == NULL) return FAILURE; if (preset == NULL) return FAILURE; /* Grab custom shape id and equation type (per frame or per point) from string token */ if (parse_shape_prefix(token, &id, &eqn_type) < 0) { //if (PARSE_DEBUG) printf("parse_shape: syntax error in custom shape prefix!\n"); return PARSE_ERROR; } /* Retrieve custom shape associated with this id */ if ((custom_shape = find_custom_shape(id, preset, TRUE)) == NULL) return FAILURE; /* per frame init equation case */ if (!strncmp(eqn_type, SHAPE_INIT_STRING, SHAPE_INIT_STRING_LENGTH)) { //if (PARSE_DEBUG) printf("parse_shape (per frame init): [begin] (LINE %d)\n", line_count); /* Parse the per frame equation */ if ((init_cond = parse_per_frame_init_eqn(fs, preset, custom_shape->param_tree)) == NULL) { //if (PARSE_DEBUG) printf("parse_shape (per frame init): equation parsing failed (LINE %d)\n", line_count); return PARSE_ERROR; } /* Insert the equation in the per frame equation tree */ if (splay_insert(init_cond, init_cond->param->name, custom_shape->per_frame_init_eqn_tree) < 0) { //if (PARSE_DEBUG) printf("parse_shape (per frame init): failed to add equation (ERROR)\n"); free_init_cond(init_cond); /* will free the gen expr too */ return ERROR; } if (update_string_buffer(custom_shape->per_frame_init_eqn_string_buffer, &custom_shape->per_frame_init_eqn_string_index) < 0) return FAILURE; return SUCCESS; } /* per frame equation case */ if (!strncmp(eqn_type, PER_FRAME_STRING_NO_UNDERSCORE, PER_FRAME_STRING_NO_UNDERSCORE_LENGTH)) { //if (PARSE_DEBUG) printf("parse_shape (per_frame): [start] (custom shape id = %d)\n", custom_shape->id); if (parseToken(fs, string) != tEq) { //if (PARSE_DEBUG) printf("parse_shape (per_frame): no equal sign after string \"%s\" (LINE %d)\n", string, line_count); return PARSE_ERROR; } /* Find the parameter associated with the string in the custom shape database */ if ((param = find_param_db(string, custom_shape->param_tree, TRUE)) == NULL) { //if (PARSE_DEBUG) printf("parse_shape (per_frame): parameter \"%s\" not found or cannot be malloc'ed!!\n", string); return FAILURE; } /* Make sure parameter is writable */ if (param->flags & P_FLAG_READONLY) { //if (PARSE_DEBUG) printf("parse_shape (per_frame): parameter %s is marked as read only (LINE %d)\n", param->name, line_count); return FAILURE; } /* Parse right side of equation as an expression */ current_shape = custom_shape; if ((gen_expr = parse_gen_expr(fs, NULL, preset)) == NULL) { //if (PARSE_DEBUG) printf("parse_shape (per_frame): equation evaluated to null (LINE %d)\n", line_count); current_shape = NULL; return PARSE_ERROR; } current_shape = NULL; //if (PARSE_DEBUG) printf("parse_shape (per_frame): [finished parsing equation] (LINE %d)\n", line_count); /* Create a new per frame equation */ if ((per_frame_eqn = new_per_frame_eqn(custom_shape->per_frame_count++, param, gen_expr)) == NULL) { //if (PARSE_DEBUG) printf("parse_shape (per_frame): failed to create a new per frame eqn, out of memory?\n"); free_gen_expr(gen_expr); return FAILURE; } if (splay_insert(per_frame_eqn, &per_frame_eqn->index, custom_shape->per_frame_eqn_tree) < 0) { free_per_frame_eqn(per_frame_eqn); return FAILURE; } //if (PARSE_DEBUG) printf("parse_shape (per_frame): equation %d associated with custom shape %d [success]\n", // per_frame_eqn->index, custom_shape->id); /* Need to add stuff to string buffer so the editor can read the equations. Why not make a nice little helper function for this? - here it is: */ if (update_string_buffer(custom_shape->per_frame_eqn_string_buffer, &custom_shape->per_frame_eqn_string_index) < 0) return FAILURE; return SUCCESS; } /* Syntax error, return parse error */ return PARSE_ERROR;}/* Helper function to update the string buffers used by the editor */int update_string_buffer(char * buffer, int * index) { int string_length; int skip_size; if (!buffer) return FAILURE; if (!index) return FAILURE; /* If the string line buffer used by the parser is already full then quit */ if (string_line_buffer_index == (STRING_LINE_SIZE-1)) return FAILURE; if ((skip_size = get_string_prefix_len(string_line_buffer)) == FAILURE) return FAILURE; string_line_buffer[string_line_buffer_index++] = '\n'; // string_length = strlen(string_line_buffer + strlen(eqn_string)+1); if (skip_size >= STRING_LINE_SIZE) return FAILURE; string_length = strlen(string_line_buffer + skip_size); if (skip_size > (STRING_LINE_SIZE-1)) return FAILURE; /* Add line to string buffer */ strncpy(buffer + (*index), string_line_buffer + skip_size, string_length); /* Buffer full, quit */ if ((*index) > (STRING_BUFFER_SIZE - 1)) { //if (PARSE_DEBUG) printf("update_string_buffer: string buffer full!\n"); return FAILURE; } /* Otherwise, increment string index by the added string length */ (*index)+=string_length; return SUCCESS; }/* Helper function: returns the length of the prefix portion in the line buffer (the passed string here). In other words, given the string 'per_frame_1 = x = ....', return the length of 'per_frame_1 = ' Returns -1 if syntax error*/int get_string_prefix_len(char * string) { int i = 0; /* Null argument check */ if (string == NULL) return FAILURE; /* First find the equal sign */ while (string[i] != '=') { if (string[i] == 0) return FAILURE; i++; } /* If the string already ends at the next char then give up */ if (string[i+1] == 0) return FAILURE; /* Move past the equal sign */ i++; /* Now found the start of the LHS variable, ie skip the spaces */ while(string[i] == ' ') { i++; } /* If this is the end of the string then its a syntax error */ if (string[i] == 0) return FAILURE; /* Finished succesfully, return the length */ return i;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -