/* * Removes grep part from *cmd* and returns newly allocated string * with reshaped grep expression. * * Function converts multiple twiddle expressions into internal representation. * For example: * converts "~str1~str2~str3~?" into "?&str1,str2,str3" */ static char *preprocess_filter_expr(char *cmd, const char *quotes) { char *p1, *p2, *ns = NULL; const char *strsep = "&"; int len; int i; p1 = find_next_intgrep (cmd, quotes); if (!p1) { return NULL; } len = strlen (p1); if (len > 4 && r_str_endswith (p1, "~?") && p1[len - 3] != '\\') { p1[len - 2] = '\0'; ns = r_str_append (ns, "?"); } *p1 = '\0'; // remove grep part from cmd i = 0; // parse words between '~' while ((p2 = find_next_intgrep (p1 + 1, quotes))) { ns = r_str_append (ns, strsep); ns = r_str_appendlen (ns, p1 + 1, (int)(p2 - p1 - 1)); p1 = p2; strsep = ","; i++; } if (i > 0) { ns = r_str_append (ns, ","); } ns = r_str_append (ns, p1 + 1); return ns; }
R_API int r_reg_set_profile_string(RReg *reg, const char *str) { char *tok[PARSER_MAX_TOKENS]; char tmp[128]; int i, j, l; const char *p = str; if (!reg || !str) { return false; } // Same profile, no need to change if (reg->reg_profile_str && !strcmp (reg->reg_profile_str, str)) { return true; } // we should reset all the arenas before setting the new reg profile r_reg_arena_pop (reg); // Purge the old registers r_reg_free_internal (reg, true); r_reg_arena_shrink (reg); // Cache the profile string reg->reg_profile_str = strdup (str); // Line number l = 0; // For every line do { // Increment line number l++; // Skip comment lines if (*p == '#') { const char *q = p; while (*q != '\n') { q++; } reg->reg_profile_cmt = r_str_appendlen ( reg->reg_profile_cmt, p, (int)(q - p) + 1); p = q; continue; } j = 0; // For every word while (*p) { // Skip the whitespace while (*p == ' ' || *p == '\t') { p++; } // Skip the rest of the line is a comment is encountered if (*p == '#') { while (*p != '\n') { p++; } } // EOL ? if (*p == '\n') { break; } // Gather a handful of chars // Use isgraph instead of isprint because the latter considers ' ' printable for (i = 0; isgraph ((const unsigned char)*p) && i < sizeof (tmp) - 1;) { tmp[i++] = *p++; } tmp[i] = '\0'; // Limit the number of tokens if (j > PARSER_MAX_TOKENS - 1) { break; } // Save the token tok[j++] = strdup (tmp); } // Empty line, eww if (j) { // Do the actual parsing char *first = tok[0]; // Check whether it's defining an alias or a register const char *r = (*first == '=') ? parse_alias (reg, tok, j) : parse_def (reg, tok, j); // Clean up for (i = 0; i < j; i++) { free (tok[i]); } // Warn the user if something went wrong if (r) { eprintf ("%s: Parse error @ line %d (%s)\n", __FUNCTION__, l, r); //eprintf ("(%s)\n", str); // Clean up r_reg_free_internal (reg, false); return false; } } } while (*p++); reg->size = 0; for (i = 0; i < R_REG_TYPE_LAST; i++) { RRegSet *rs = ®->regset[i]; //eprintf ("* arena %s size %d\n", r_reg_get_type (i), rs->arena->size); reg->size += rs->arena->size; } // Align to byte boundary if needed //if (reg->size & 7) { // reg->size += 8 - (reg->size & 7); //} //reg->size >>= 3; // bits to bytes (divide by 8) r_reg_fit_arena (reg); // dup the last arena to allow regdiffing r_reg_arena_push (reg); r_reg_reindex (reg); // reset arenas return true; }