/********************************************************************
 * 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;
}
Example #3
0
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 = &reg->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;
}
Example #4
0
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;
}