/* * Check for a common mount option that manipulates s_flags. */ static int vfs_parse_sb_flag(struct fs_context *fc, const char *key) { unsigned int token; unsigned int i; for (i = 0; i < ARRAY_SIZE(forbidden_sb_flag); i++) if (strcmp(key, forbidden_sb_flag[i]) == 0) return -EINVAL; token = lookup_constant(common_set_sb_flag, key, 0); if (token) { fc->sb_flags |= token; fc->sb_flags_mask |= token; return 0; } token = lookup_constant(common_clear_sb_flag, key, 0); if (token) { fc->sb_flags &= ~token; fc->sb_flags_mask |= token; return 0; } return -ENOPARAM; }
double _parse(gchar *args, struct global_vars *gvars) { gchar mul_char = '*'; gdouble minus_one = -1.0; gchar null = 0; gint args_len = strlen(args); struct stack *arguments = stack_init(sizeof(gdouble)); struct stack *operators = stack_init(sizeof(gchar)); gint i = 0; gint j = 0; gint local_nest_level = 0; gint8 last_p = 0; /** priority of last parsed operator */ gboolean coef_flag = FALSE; /** set if value might preceed a bracket and thus become a coefficient */ gboolean func_flag = FALSE; /** set if result of next bracket is to be passed as an argument to function <symbol> */ gboolean nest_flag = FALSE; /** indicates characters are being collected and not parsed */ gboolean nest_init_flag = FALSE; /** necessary to skip first character '(' during string collection */ gboolean neg_flag = TRUE; /** set if next '-' will make number signed and not be an operator */ gboolean frac_flag = FALSE; //char nested_term[100] = { 0 }; /** collector string for contents of nested term */ GString *nested_term = g_string_new(&null); //char symbol[100] = { 0 }; /** collector string for symbol name */ GString *symbol = g_string_new(&null); for (i=0; i < args_len; i++) { if (nest_init_flag) {nest_init_flag = FALSE;} /** lock computing by raising nest level, substitute '*' if coefficient exists */ if (args[i] == '(') { if (!nest_flag) /** nested interpreting is just about to be initialized */ { if (coef_flag) {stack_push(operators, &mul_char); last_p = priority(mul_char);} coef_flag = TRUE; nest_flag = TRUE; nest_init_flag = TRUE; gvars->nest_level += 1; nested_term = g_string_new(&null); } else /** nested interpreting is in progress */ { local_nest_level += 1; } } else if (args[i] == ')') { if (nest_flag && local_nest_level == 0) /** nesting has reached end */ { nest_flag = FALSE; gdouble nested_term_result = _parse(nested_term->str, gvars); gvars->nest_level -= 1; g_string_free(nested_term, TRUE); nested_term = g_string_new(&null); if (func_flag) { gdouble compute_function_results = compute_function(symbol->str, nested_term_result, gvars); stack_push(arguments, &compute_function_results); func_flag = FALSE; g_string_free(symbol, TRUE); symbol = g_string_new(&null); } else {stack_push(arguments, &nested_term_result);} } else /** nested interpreting is in progress, passing by uninterpreted ')' */ { local_nest_level -= 1; } } if (!nest_flag) { if (args[i] == '.' || args[i] == ',') { if (g_ascii_isdigit(char_at(args,i+1))) {frac_flag = TRUE;} else {gvars->error_type = 3; return 0;} } else if (g_ascii_isdigit(args[i])) /** parse number */ { if (gvars->debug) {for (j=0;j<gvars->nest_level;j++) {g_printf(" ");} g_printf("args[%d] is digit\n", i);} gint8 dig = to_d(args[i]); stack_push(gvars->digits, &dig); if (frac_flag) {gvars->frac_point -= 1;} /** check if there is more than one digit or fractal part */ if (!(g_ascii_isdigit(char_at(args, i+1)) || char_at(args, i+1) == '.' || char_at(args, i+1) == ',')) { if (coef_flag) {stack_push(operators, &mul_char); last_p = priority(mul_char);} gdouble joined_dig = join_digits(gvars->digits, gvars->frac_point); stack_push(arguments, &joined_dig); neg_flag = FALSE; coef_flag = TRUE; frac_flag = FALSE; gvars->frac_point = 0; } } else if (isoperator(args[i])) /** parse operators */ { if (gvars->debug) {for (j=0;j<gvars->nest_level;j++) {g_printf(" ");} g_printf("args[%d] is operator\n", i);} if (neg_flag && args[i] == '-') /** check if preceeding minus changes sign of next symbol */ { neg_flag = FALSE; stack_push(arguments, &minus_one); stack_push(operators, &mul_char); last_p = priority(mul_char); } else { if (stack_length(arguments) <= stack_length(operators)) {gvars->error_type = 4; break;} /** check beforehand if lower priority operator is encountered */ if (priority(args[i]) < last_p) {compute(arguments, operators, gvars);} last_p = priority(args[i]); stack_push(operators, &args[i]); coef_flag = FALSE; neg_flag = TRUE; } } else if (g_ascii_isalpha(args[i])) /** parse letters */ { if (gvars->debug) {for (j=0;j<gvars->nest_level;j++) {g_printf(" ");} printf("args[%d] is letter\n", i);} if (coef_flag) {coef_flag = FALSE; stack_push(operators, &mul_char); last_p = priority(mul_char);} if (neg_flag) {neg_flag = FALSE;} g_string_append_c(symbol, args[i]); if (char_at(args,i+1) == '(') { compute_function(symbol->str, 1.337, gvars); if (gvars->error_type != 0) { gvars->error_type = 0; gdouble looked_up_c = lookup_constant(symbol->str, gvars); stack_push(arguments, &looked_up_c); //+symbol = ""; g_string_free(symbol, TRUE); symbol = g_string_new(&null); coef_flag = TRUE; } else {func_flag = TRUE;} } else if (!g_ascii_isalpha(char_at(args,i+1))) { gdouble looked_up_c = lookup_constant(symbol->str, gvars); stack_push(arguments, &looked_up_c); g_string_free(symbol, TRUE); symbol = g_string_new(&null); coef_flag = TRUE; } } } else if (!nest_init_flag) /** this collector block needs to be skipped once so the first '(' isn't collected */ { g_string_append_c(nested_term, args[i]); } if (args[i] == ' ') {coef_flag = FALSE;} if (char_at(args,i) == '#') {break;} /** failsafe, in case array bounds are left */ } if (gvars->debug) {printf("<args>\n");stack_dump(arguments, 'd');printf("<ops>\n");stack_dump(operators, 'c');printf("<>\n");} if (local_nest_level != 0 && gvars->error_type == 0) {gvars->error_type = 1;} if (neg_flag && gvars->error_type == 0) {gvars->error_type = 4;} if (gvars->error_type == 0) {compute(arguments, operators, gvars);} if (stack_length(arguments) > 1 && gvars->error_type == 0) {gvars->error_type = 4;printf("no2\n");} gdouble return_value = 0; if (gvars->error_type == 0) {stack_pop(arguments, &return_value);} stack_destroy(arguments); stack_destroy(operators); return return_value; }