/*
* This file is part of ltrace.
- * Copyright (C) 2011,2012,2013 Petr Machata, Red Hat Inc.
+ * Copyright (C) 2011,2012,2013,2014 Petr Machata, Red Hat Inc.
* Copyright (C) 1998,1999,2003,2007,2008,2009 Juan Cespedes
* Copyright (C) 2006 Ian Wienand
* Copyright (C) 2006 Steve Fink
return xstrndup(ident, *str - ident);
}
-/*
- Returns position in string at the left parenthesis which starts the
- function's argument signature. Returns NULL on error.
-*/
-static char *
-start_of_arg_sig(char *str) {
- char *pos;
- int stacked = 0;
-
- if (!strlen(str))
- return NULL;
-
- pos = &str[strlen(str)];
- do {
- pos--;
- if (pos < str)
- return NULL;
- while ((pos > str) && (*pos != ')') && (*pos != '('))
- pos--;
-
- if (*pos == ')')
- stacked++;
- else if (*pos == '(')
- stacked--;
- else
- return NULL;
-
- } while (stacked > 0);
-
- return (stacked == 0) ? pos : NULL;
-}
-
static int
parse_int(struct locus *loc, char **str, long *ret)
{
return 0;
struct arg_type_info *ninfo = malloc(sizeof(*ninfo));
- if (ninfo == NULL) {
+ if (ninfo == NULL || type_clone(ninfo, *infop) < 0) {
report_error(loc->filename, loc->line_no,
"malloc: %s", strerror(errno));
+ free(ninfo);
return -1;
}
- *ninfo = **infop;
*infop = ninfo;
*ownp = 1;
return 0;
struct expr_node *node = malloc(sizeof(*node));
if (node == NULL) {
free(*packp);
+ *packp = NULL;
return -1;
}
{
size_t len = strlen(kwd);
if (strncmp(*str, kwd, len) == 0
- && !isalnum(CTYPE_CONV((*str)[len]))) {
+ && !isalnum(CTYPE_CONV((*str)[len]))
+ && (*str)[len] != '_') {
(*str) += len;
return 0;
}
return -1;
}
-/* XXX extra_param and param_num are a kludge to get in
+/* XXX EXTRA_PARAM and PARAM_NUM are a kludge to get in
* backward-compatible support for "format" parameter type. The
* latter is only valid if the former is non-NULL, which is only in
* top-level context. */
process_line(struct protolib *plib, struct locus *loc, char *buf)
{
char *str = buf;
- char *tmp;
debug(3, "Reading line %d of `%s'", loc->line_no, loc->filename);
eat_spaces(&str);
struct prototype fun;
prototype_init(&fun);
+ struct param *extra_param = NULL;
char *proto_name = NULL;
int own;
fun.return_info = parse_lens(plib, loc, &str, NULL, 0, &own, NULL);
if (fun.return_info == NULL) {
err:
debug(3, " Skipping line %d", loc->line_no);
+
+ if (extra_param != NULL) {
+ param_destroy(extra_param);
+ free(extra_param);
+ }
+
prototype_destroy(&fun);
free(proto_name);
return -1;
debug(4, " return_type = %d", fun.return_info->type);
eat_spaces(&str);
- tmp = start_of_arg_sig(str);
- if (tmp == NULL) {
- report_error(loc->filename, loc->line_no, "syntax error");
+ proto_name = parse_ident(loc, &str);
+ if (proto_name == NULL)
goto err;
- }
- *tmp = '\0';
- proto_name = strdup(str);
- if (proto_name == NULL) {
- oom:
- report_error(loc->filename, loc->line_no,
- "%s", strerror(errno));
+ eat_spaces(&str);
+ if (parse_char(loc, &str, '(') < 0)
goto err;
- }
-
- str = tmp + 1;
debug(3, " name = %s", proto_name);
- struct param *extra_param = NULL;
int have_stop = 0;
while (1) {
if (have_stop == 0) {
struct param param;
param_init_stop(¶m);
- if (prototype_push_param(&fun, ¶m) < 0)
- goto oom;
+ if (prototype_push_param(&fun, ¶m) < 0) {
+ oom:
+ report_error(loc->filename,
+ loc->line_no,
+ "%s", strerror(errno));
+ goto err;
+ }
have_stop = 1;
}
str++;
if (extra_param != NULL) {
prototype_push_param(&fun, extra_param);
free(extra_param);
+ extra_param = NULL;
}
if (protolib_add_prototype(plib, proto_name, 1, &fun) < 0) {