/******************************************************************** * FUNCTION handle_alias_parm * * alias def * alias def=def-value * * Handle the alias command, based on the parameter * * INPUTS: * varstr == alias command line * setonly == TRUE if expecting set version only; ignore show alias * FALSE if expecting show alias or set alias * loginfo == TRUE if log-level=info should be used * FALSE if log-level=debug2 should be used * RETURNS: * status *********************************************************************/ static status_t handle_alias_parm (const xmlChar *varstr, boolean setonly, boolean loginfo) { const xmlChar *valptr = NULL; uint32 nlen = 0; status_t res; res = parse_alias(varstr, &nlen, &valptr); if (res == NO_ERR) { if (valptr) { /* setting an alias */ alias_cb_t *alias = find_alias(varstr, nlen); if (alias) { if (LOGDEBUG3) { log_debug3("\nAbout to replace alias '%s'" "\n old value: '%s'" "\n new value: '%s'", alias->name, alias->value ? alias->value : EMPTY_STRING, valptr); } /* modify an existing alias */ res = set_alias(alias, valptr); if (res == NO_ERR) { if (loginfo) { log_info("\nUpdated alias '%s'\n", alias->name); } else { log_debug2("\nUpdated alias '%s'", alias->name); } } else { log_error("\nError: invalid alias value '%s'\n", valptr); } } else { /* create a new alias */ alias = new_alias(varstr, nlen); if (alias == NULL) { res = ERR_INTERNAL_MEM; } else { res = set_alias(alias, valptr); if (res == NO_ERR) { res = add_alias(alias); if (res == NO_ERR) { if (loginfo) { log_info("\nAdded alias '%s'\n", alias->name); } else { log_debug2("\nAdded alias '%s'", alias->name); } } else { log_error("\nError: alias was not added '%s'\n", get_error_string(res)); } } else { log_error("\nError: invalid alias value '%s'\n", valptr); free_alias(alias); } } } } else if (!setonly) { /* just provided a name; show alias */ show_alias_name(varstr, nlen); } else if (LOGDEBUG) { log_debug("\nSkipping alias '%s' because no value set", varstr); } } else if (res == ERR_NCX_INVALID_NAME) { log_error("\nError: invalid alias (%s)", get_error_string(res)); } else { log_error("\nError: invalid alias '%s' (%s)", varstr, get_error_string(res)); } return res; } /* handle_alias_parm */
static struct arg_type_info * parse_nonpointer_type(struct protolib *plib, struct locus *loc, char **str, struct param **extra_param, size_t param_num, int *ownp, int *forwardp) { const char *orig_str = *str; enum arg_type type; if (parse_arg_type(str, &type) < 0) { struct arg_type_info *type; if (parse_alias(plib, loc, str, &type, ownp, extra_param, param_num) < 0) return NULL; else if (type != NULL) return type; *ownp = 0; if ((type = parse_typedef_name(plib, str)) == NULL) report_error(loc->filename, loc->line_no, "unknown type around '%s'", orig_str); return type; } /* For some types that's all we need. */ switch (type) { case ARGTYPE_VOID: case ARGTYPE_INT: case ARGTYPE_UINT: case ARGTYPE_LONG: case ARGTYPE_ULONG: case ARGTYPE_CHAR: case ARGTYPE_SHORT: case ARGTYPE_USHORT: case ARGTYPE_FLOAT: case ARGTYPE_DOUBLE: *ownp = 0; return type_get_simple(type); case ARGTYPE_ARRAY: case ARGTYPE_STRUCT: break; case ARGTYPE_POINTER: /* Pointer syntax is not based on keyword, so we * should never get this type. */ assert(type != ARGTYPE_POINTER); abort(); } struct arg_type_info *info = malloc(sizeof(*info)); if (info == NULL) { report_error(loc->filename, loc->line_no, "malloc: %s", strerror(errno)); return NULL; } *ownp = 1; if (type == ARGTYPE_ARRAY) { if (parse_array(plib, loc, str, info) < 0) { fail: free(info); return NULL; } } else { assert(type == ARGTYPE_STRUCT); if (parse_struct(plib, loc, str, info, forwardp) < 0) goto fail; } return info; }
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; }
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; // Purge the old registers r_reg_free_internal (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 == '#') { while (*p != '\n') p++; 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); return false; } } } while (*p++); // 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); return true; }