struct idset *idset_decode (const char *str) { struct idset *idset; char *cpy = NULL; char *tok, *saveptr, *a1; int saved_errno; if (!str) { errno = EINVAL; return NULL; } if (!(idset = idset_create (0, IDSET_FLAG_AUTOGROW))) return NULL; if (!(cpy = strdup (str))) goto error; a1 = trim_brackets (cpy); saveptr = NULL; while ((tok = strtok_r (a1, ",", &saveptr))) { unsigned int hi, lo, i; if (parse_range (tok, &hi, &lo) < 0) goto inval; /* Count backwards so that idset_set() can grow the * idset to the maximum size on the first access, * rather than possibly doing it multiple times. */ for (i = hi; i >= lo && i != UINT_MAX; i--) { if (idset_set (idset, i) < 0) goto error; } a1 = NULL; } free (cpy); return idset; inval: errno = EINVAL; error: saved_errno = errno; idset_destroy (idset); free (cpy); errno = saved_errno; return NULL; }
F_NODE *recursion_create_node(char *str, int start, int len) { F_NODE *f_node = NULL; int index; real value; int trim_num; // adjust start len. trim_brackets(str, &start, &len); STR_TYPE_INFO type; if (get_str_type(str, start, len, &type) != 0) { // error TODO return NULL; } if (type.type == STR_TYPE_DIG) { value = atof(str + start); f_node = malloc_f_node(); f_node->node_type = NODE_TYPE_NUM; f_node->num = value; return f_node; } if (type.type == STR_TYPE_SYM) { f_node = malloc_f_node(); f_node->node_type = NODE_TYPE_SYM; copy_str(f_node->sym, str + start, len, MAX_SYMBOL_LEN); return f_node; } char fun_name[16]; int para_num; int para_sep_index[4]; int i; if (type.type == STR_TYPE_FUN) { get_fun_name(fun_name, str, start, len); para_num = get_para_sep_index(para_sep_index, str, start, len); f_node = malloc_f_node(); f_node->node_type = NODE_TYPE_FUN; f_node->fun = get_fun_pointer(fun_name); for ( i = 0; i < para_num; i++) { f_node->child[i] = recursion_create_node(str, start + para_sep_index[i] + 1, para_sep_index[i + 1] - para_sep_index[i] - 1); } return f_node; } index = type.index; if (type.type == STR_TYPE_ADD) { return normal_math_node(add_wrapper, str, start, len, index); } if (type.type == STR_TYPE_MIN) { return normal_math_node(min_wrapper, str, start, len, index); } if (type.type == STR_TYPE_MUL) { return normal_math_node(mul_wrapper, str, start, len, index); } if (type.type == STR_TYPE_DIV){ return normal_math_node(div_wrapper, str, start, len, index); } // error return f_node; }
// Inputs: arr_len, names, locations_in, ffs_in, directions_in, cycles_in. // Outputs: locations_out, ffs_out, directions_out, cycles_out. // Note that this function allocates memory for the output arrays. void process_template(int arr_len, char* names, char* locations_in, char* ffs_in, char* directions_in, char* cycles_in, char** locations_out, char** ffs_out, char** directions_out, char** cycles_out) { // Inputs arrive as "[token1, token2, ...]" const char s[2] = ","; char *token; int index; // Remove brackets from strings. trim_brackets(names); trim_brackets(locations_in); trim_brackets(ffs_in); trim_brackets(directions_in); trim_brackets(cycles_in); // If no data, just set all output buffers to NULL. if (arr_len == 0) { locations_out = NULL; ffs_out = NULL; directions_out = NULL; cycles_out = NULL; return; } // Pin locations. locations_out = (char**) calloc(arr_len, LOCATION_SIZE); assert(locations_out != NULL); token = strtok(locations_in, s); index = 0; while(token != NULL && strcmp(token, "null") != 0) { locations_out[index] = token; index += LOCATION_SIZE; token = strtok(NULL, s); } // Force-formats. ffs_out = (char**) calloc(arr_len, BIT_SIZE); assert(ffs_out != NULL); token = strtok(ffs_in, s); index = 0; while(token != NULL && strcmp(token, "null") != 0) { ffs_out[index] = token; index += BIT_SIZE; token = strtok(NULL, s); } // Pin directions. directions_out = (char**) calloc(arr_len, BIT_SIZE); assert(directions_out != NULL); token = strtok(directions_in, s); index = 0; while(token != NULL && strcmp(token, "null") != 0) { ffs_out[index] = token; index += BIT_SIZE; token = strtok(NULL, s); } // Test cycles. cycles_out = (char**) calloc(arr_len, BIT_SIZE); assert(cycles_out != NULL); token = strtok(cycles_in, s); index = 0; while(token != NULL && strcmp(token, "null") != 0) { cycles_out[index] = token; index += BIT_SIZE; token = strtok(NULL, s); } }
/** * Constructs the expression tree. */ void Filter::parse(const char* exp, int32_t len, Node *node, bool debug) { if (debug) { std::cerr << "parsing \""; for (int32_t i=0; i<len; ++i) std::cerr << exp[i] ; std::cerr << "\" " << len << "\n"; } //****************************** //trim white spaces and brackets //****************************** while (*exp==' ') ++exp; while (exp[len-1]==' ') --len; trim_brackets(exp, len); //this is a literal if (is_literal(exp, len)) { //will not recurse any further return parse_literal(exp, len, node, debug); } //this is guaranteed to be decomposed unless there is an error in the expression else { const char* p = exp; //points to end of first part const char* q = exp; //points to start of second part const char* r = exp; //for iteration int32_t type = INT_MAX; while(r-exp!=len) { fwd_to_closing_bracket(r, len); int32_t oplen = -1; int32_t ctype = peek_op(r, len, oplen, debug); if(ctype!=-1) { if (ctype<type) { if (debug) std::cerr<< "\tupdating type\n"; type = ctype; p = r-1; q = r+oplen; } r += oplen-1; } ++r; } if (type==-1) { kstring_t s = {0,0,0}; kputsn(exp, len, &s); fprintf(stderr, "[%s:%d %s] expression not correct %s\n", __FILE__, __LINE__, __FUNCTION__, s.s); if (s.m) free(s.s); exit(1); } node->type = type; node->left = new Node(); parse(exp, p-exp+1, node->left, debug); node->right = new Node(); parse(q, len-(q-exp), node->right, debug); } }
/** * Trim brackets from an expression. */ void Filter::trim_brackets(const char* &exp, int32_t &len) { if (*exp=='(' && exp[len-1]==')') { int32_t opened_brackets = 1; bool nested = true; int32_t j=1; while(j<len-1) { if(exp[j]=='(') { if (opened_brackets<0) { kstring_t s = {0,0,0}; kputsn(exp, len, &s); fprintf(stderr, "[%s:%d %s] brackets not correct %s\n", __FILE__, __LINE__, __FUNCTION__, s.s); if (s.m) free(s.s); exit(1); } ++opened_brackets; } else if (exp[j]==')') { if (opened_brackets<=0) { kstring_t s = {0,0,0}; kputsn(exp, len, &s); fprintf(stderr, "[%s:%d %s] brackets not correct %s\n", __FILE__, __LINE__, __FUNCTION__, s.s); if (s.m) free(s.s); exit(1); } --opened_brackets; } if (opened_brackets==0) { nested = false; break; } ++j; } if (nested) { if (opened_brackets == 1) { ++exp; len -=2; trim_brackets(exp, len); } else { std::cerr << "Illegal expression: brackets not correct\n"; } } } }