[Ltrace-devel] r60 - in ltrace/trunk: . etc testsuite/ltrace.main

Ian Wienand ianw-guest at costa.debian.org
Mon Aug 7 03:53:20 UTC 2006


Author: ianw-guest
Date: 2006-08-07 03:53:19 +0000 (Mon, 07 Aug 2006)
New Revision: 60

Modified:
   ltrace/trunk/ChangeLog
   ltrace/trunk/display_args.c
   ltrace/trunk/etc/ltrace.conf
   ltrace/trunk/ltrace.h
   ltrace/trunk/read_config_file.c
   ltrace/trunk/testsuite/ltrace.main/parameters-lib.c
   ltrace/trunk/testsuite/ltrace.main/parameters.c
   ltrace/trunk/testsuite/ltrace.main/parameters.conf
   ltrace/trunk/testsuite/ltrace.main/parameters.exp
Log:
enumerate parameters


Modified: ltrace/trunk/ChangeLog
===================================================================
--- ltrace/trunk/ChangeLog	2006-08-07 02:55:24 UTC (rev 59)
+++ ltrace/trunk/ChangeLog	2006-08-07 03:53:19 UTC (rev 60)
@@ -1,5 +1,13 @@
 2006-08-07  Steve Fink <sphink at gmail.com>
 
+	* display_args.c, etc/ltrace.conf, ltrace.h, read_config_file.c,
+	testsuite/ltrace.main/parameters-lib.c,
+	testsuite/ltrace.main/parameters.c,
+	testsuite/ltrace.main/parameters.conf,
+	testsuite/ltrace.main/parameters.exp: implement enumerated parameters
+
+2006-08-07  Steve Fink <sphink at gmail.com>
+
 	* testsuite/ltrace.main/Makefile.in :  update testsuite for
 	new parameters
 	* testsuite/ltrace.main/parameters-lib.c : added

Modified: ltrace/trunk/display_args.c
===================================================================
--- ltrace/trunk/display_args.c	2006-08-07 02:55:24 UTC (rev 59)
+++ ltrace/trunk/display_args.c	2006-08-07 03:53:19 UTC (rev 60)
@@ -42,6 +42,18 @@
       return display_value(type, proc, pointed_to, inner);
 }
 
+static int display_enum(enum tof type, struct process *proc,
+                        arg_type_info* info, long value)
+{
+    int ii;
+    for (ii = 0; ii < info->u.enum_info.entries; ++ii) {
+	if (info->u.enum_info.values[ii] == value)
+	    return fprintf(output, "%s", info->u.enum_info.keys[ii]);
+    }
+
+    return display_unknown(type, proc, value);
+}
+
 /* Args:
    type - syscall or shared library function or memory
    proc - information about the traced process
@@ -94,6 +106,8 @@
 		return display_string(type, proc, (void*) value,
 				      get_length(type, proc,
 						 info->u.string_n_info.size_spec));
+        case ARGTYPE_ENUM:
+		return display_enum(type, proc, info, value);
 	case ARGTYPE_POINTER:
 		return display_pointer(type, proc, value, info);
  	case ARGTYPE_UNKNOWN:

Modified: ltrace/trunk/etc/ltrace.conf
===================================================================
--- ltrace/trunk/etc/ltrace.conf	2006-08-07 02:55:24 UTC (rev 59)
+++ ltrace/trunk/etc/ltrace.conf	2006-08-07 03:53:19 UTC (rev 60)
@@ -24,11 +24,20 @@
 ; string[N]     == (char *)             [N>0]   [show only up to N bytes]
 ; ignore	== (any)			[ignore arg, output blank]
 ; type*		== (type *)			[pointer to any other type]
+; enum (key=value,key=value,...)		[enumeration, see below]
 
 ; Backwards-compatibility:
 ; string0	== (char *)			[same as string[retval]]
 ; stringN	== (char *)		[N>0]	[same as string[argN]]
 
+; Enumerations
+;
+; The syntax is a parenthesized list of key=value assignments, like so:
+;   enum (F_DUPFD=0,F_GETFD=1,F_SETFD=2)
+; an example usage might look like
+;   int fcntl(int,enum (F_DUPFD=0,F_GETFD=1,F_SETFD=2))
+;
+
 ; arpa/inet.h
 int inet_aton(string,addr);
 string inet_ntoa(addr);			; It isn't a ADDR but an hexa number...

Modified: ltrace/trunk/ltrace.h
===================================================================
--- ltrace/trunk/ltrace.h	2006-08-07 02:55:24 UTC (rev 59)
+++ ltrace/trunk/ltrace.h	2006-08-07 03:53:19 UTC (rev 60)
@@ -42,6 +42,7 @@
 	ARGTYPE_FORMAT,		/* printf-like format */
 	ARGTYPE_STRING,		/* NUL-terminated string */
 	ARGTYPE_STRING_N,	/* String of known maxlen */
+        ARGTYPE_ENUM,		/* Enumeration */
         ARGTYPE_IGNORE,		/* Leave parameter blank */
         ARGTYPE_POINTER,	/* Pointer to some other type */
         ARGTYPE_COUNT		/* number of ARGTYPE_* values */
@@ -50,6 +51,13 @@
 typedef struct arg_type_info_t {
     enum arg_type type;
     union {
+	// ARGTYPE_ENUM
+	struct {
+	    size_t entries;
+	    char **keys;
+	    int *values;
+	} enum_info;
+
 	// ARGTYPE_STRING_N
 	struct {
 	    int size_spec;

Modified: ltrace/trunk/read_config_file.c
===================================================================
--- ltrace/trunk/read_config_file.c	2006-08-07 02:55:24 UTC (rev 59)
+++ ltrace/trunk/read_config_file.c	2006-08-07 03:53:19 UTC (rev 60)
@@ -11,6 +11,10 @@
 #include "output.h"
 #include "debug.h"
 
+static int line_no;
+static char *filename;
+static int error_count = 0;
+
 struct function *list_of_functions = NULL;
 
 static struct list_of_pt_t {
@@ -29,6 +33,7 @@
 	"file", ARGTYPE_FILE}, {
 	"format", ARGTYPE_FORMAT}, {
 	"string", ARGTYPE_STRING}, {
+	"enum", ARGTYPE_ENUM}, {
 	"ignore", ARGTYPE_IGNORE}, {
 	NULL, ARGTYPE_UNKNOWN}	/* Must finish with NULL */
 };
@@ -46,6 +51,7 @@
 	{ ARGTYPE_FORMAT },
 	{ ARGTYPE_STRING },
 	{ ARGTYPE_STRING_N },
+	{ ARGTYPE_ENUM },
 	{ ARGTYPE_IGNORE },
 	{ ARGTYPE_POINTER },
 	{ ARGTYPE_UNKNOWN }
@@ -81,6 +87,32 @@
 	}
 }
 
+static char *xstrndup(char *str, size_t len)
+{
+    char *ret = (char *) malloc(len + 1);
+    strncpy(ret, str, len);
+    ret[len] = 0;
+    return ret;
+}
+
+static char *parse_ident(char **str)
+{
+    char *ident = *str;
+
+    if (!isalnum(**str) && **str != '_') {
+	output_line(0, "Syntax error in `%s', line %d: Bad identifier",
+		    filename, line_no);
+	error_count++;
+	return NULL;
+    }
+
+    while (**str && (isalnum(**str) || **str == '_')) {
+	++(*str);
+    }
+
+    return xstrndup(ident, *str - ident);
+}
+
 /*
   Returns position in string at the left parenthesis which starts the
   function's argument signature. Returns NULL on error.
@@ -119,12 +151,17 @@
 */
 static int simple_type(enum arg_type at)
 {
+    switch (at) {
+    case ARGTYPE_STRING:
+    case ARGTYPE_STRING_N:
+    case ARGTYPE_ENUM:
+	return 0;
+
+    default:
 	return 1;
+    }
 }
 
-static int line_no;
-static char *filename;
-
 static int parse_int(char **str)
 {
     char *end;
@@ -132,6 +169,7 @@
     if (end == *str) {
 	output_line(0, "Syntax error in `%s', line %d: Bad number",
 		    filename, line_no);
+	error_count++;
 	return 0;
     }
 
@@ -191,6 +229,73 @@
 
 	switch (info->type) {
 
+	// Syntax: enum ( keyname=value,keyname=value,... )
+	case ARGTYPE_ENUM:{
+	    struct enum_opt {
+		char *key;
+		int value;
+		struct enum_opt *next;
+	    };
+	    struct enum_opt *list = NULL;
+	    struct enum_opt *p;
+	    int entries = 0;
+	    int ii;
+
+	    eat_spaces(str);
+	    (*str)++;		// Get past open paren
+	    eat_spaces(str);
+
+	    while (**str && **str != ')') {
+		p = (struct enum_opt *) malloc(sizeof(*p));
+		eat_spaces(str);
+		p->key = parse_ident(str);
+		if (error_count) {
+		    free(p);
+		    return NULL;
+		}
+		eat_spaces(str);
+		if (**str != '=') {
+		    free(p->key);
+		    free(p);
+		    output_line(0,
+				"Syntax error in `%s', line %d: expected '=', got '%c'",
+				filename, line_no, **str);
+		    error_count++;
+		    return NULL;
+		}
+		++(*str);
+		eat_spaces(str);
+		p->value = parse_int(str);
+		p->next = list;
+		list = p;
+		++entries;
+
+		// Skip comma
+		eat_spaces(str);
+		if (**str == ',') {
+		    (*str)++;
+		    eat_spaces(str);
+		}
+	    }
+
+	    info->u.enum_info.entries = entries;
+	    info->u.enum_info.keys =
+		(char **) malloc(entries * sizeof(char *));
+	    info->u.enum_info.values =
+		(int *) malloc(entries * sizeof(int));
+	    for (ii = 0, p = NULL; list; ++ii, list = list->next) {
+		if (p)
+		    free(p);
+		info->u.enum_info.keys[ii] = list->key;
+		info->u.enum_info.values[ii] = list->value;
+		p = list;
+	    }
+	    if (p)
+		free(p);
+
+	    return info;
+	}
+
 	case ARGTYPE_STRING:
 	    if (!isdigit(**str) && **str != '[') {
 		/* Oops, was just a simple string after all */
@@ -217,6 +322,7 @@
 		output_line(0, "Syntax error in `%s', line %d: Unknown type encountered",
 			    filename, line_no);
 		free(info);
+		error_count++;
 		return NULL;
 	}
 }
@@ -258,6 +364,7 @@
 	if (!tmp) {
 		output_line(0, "Syntax error in `%s', line %d", filename,
 			    line_no);
+		error_count++;
 		return NULL;
 	}
 	*tmp = '\0';
@@ -281,6 +388,7 @@
 			output_line(0, "Syntax error in `%s', line %d"
                                     ": unknown argument type",
 				    filename, line_no);
+			error_count++;
 			return NULL;
 		}
 		eat_spaces(&str);
@@ -294,6 +402,7 @@
 				str[strlen(str) - 1] = '\0';
 			output_line(0, "Syntax error in `%s', line %d at ...\"%s\"",
 				    filename, line_no, str);
+			error_count++;
 			return NULL;
 		}
 	}
@@ -318,8 +427,11 @@
 	}
 	line_no = 0;
 	while (fgets(buf, 1024, stream)) {
-		struct function *tmp = process_line(buf);
+		struct function *tmp;
 
+		error_count = 0;
+		tmp = process_line(buf);
+
 		if (tmp) {
 			debug(2, "New function: `%s'", tmp->name);
 			tmp->next = list_of_functions;

Modified: ltrace/trunk/testsuite/ltrace.main/parameters-lib.c
===================================================================
--- ltrace/trunk/testsuite/ltrace.main/parameters-lib.c	2006-08-07 02:55:24 UTC (rev 59)
+++ ltrace/trunk/testsuite/ltrace.main/parameters-lib.c	2006-08-07 03:53:19 UTC (rev 60)
@@ -36,3 +36,8 @@
 {
 	printf("%s\n", *sP);
 }
+
+void func_enum(int x)
+{
+	printf("enum: %d\n", x);
+}

Modified: ltrace/trunk/testsuite/ltrace.main/parameters.c
===================================================================
--- ltrace/trunk/testsuite/ltrace.main/parameters.c	2006-08-07 02:55:24 UTC (rev 59)
+++ ltrace/trunk/testsuite/ltrace.main/parameters.c	2006-08-07 03:53:19 UTC (rev 60)
@@ -20,6 +20,15 @@
 void func_ppp(int***);
 void func_stringp(char**);
 
+typedef enum {
+  RED,
+  GREEN,
+  BLUE,
+  CHARTREUSE,
+  PETUNIA
+} color_t;
+void func_enum(color_t);
+
 int 
 main ()
 {
@@ -27,18 +36,27 @@
   int *xP, **xPP;
   char buf[200];
   char *s;
+
   func_ignore(1, 2, 3);
+
   func_intptr(&x);
+
   func_intptr_ret(&x);
+
   func_strlen(buf);
   printf("%s\n", buf);
+
   func_strfixed(buf);
   printf("%s\n", buf);
+
   x = 80;
   xP = &x;
   xPP = &xP;
   func_ppp(&xPP);
+
   s = (char*) malloc(100);
   strcpy(s, "Dude");
   func_stringp(&s);
+
+  func_enum(BLUE);
 }

Modified: ltrace/trunk/testsuite/ltrace.main/parameters.conf
===================================================================
--- ltrace/trunk/testsuite/ltrace.main/parameters.conf	2006-08-07 02:55:24 UTC (rev 59)
+++ ltrace/trunk/testsuite/ltrace.main/parameters.conf	2006-08-07 03:53:19 UTC (rev 60)
@@ -5,3 +5,4 @@
 void func_strfixed(string[4])
 void func_ppp(int***)
 void func_stringp(string*)
+void func_enum(enum (RED=0,GREEN=1,BLUE=2,CHARTREUSE=3,PETUNIA=4))

Modified: ltrace/trunk/testsuite/ltrace.main/parameters.exp
===================================================================
--- ltrace/trunk/testsuite/ltrace.main/parameters.exp	2006-08-07 02:55:24 UTC (rev 59)
+++ ltrace/trunk/testsuite/ltrace.main/parameters.exp	2006-08-07 03:53:19 UTC (rev 60)
@@ -50,3 +50,5 @@
 ltrace_verify_output ${srcdir}/${subdir}/${testfile}.ltrace $pattern 1
 set pattern "func_stringp(\\\"Dude\\\")"
 ltrace_verify_output ${srcdir}/${subdir}/${testfile}.ltrace $pattern 1
+set pattern "func_enum(BLUE)"
+ltrace_verify_output ${srcdir}/${subdir}/${testfile}.ltrace $pattern 1




More information about the Ltrace-devel mailing list