aboutsummaryrefslogtreecommitdiff
path: root/display_args.c
diff options
context:
space:
mode:
authorJuan Cespedes <cespedes@debian.org>1998-04-25 14:31:58 +0200
committerJuan Cespedes <cespedes@debian.org>1998-04-25 14:31:58 +0200
commitac3db297f7c6f08b02a7edfb32e441875fd7c1d7 (patch)
tree8e0f7fce638eab7af22db3ec4c74f4e9679bcb78 /display_args.c
parent28f60197b93b45422a73e5d1a6aa581584d6c4a5 (diff)
downloadltrace-ac3db297f7c6f08b02a7edfb32e441875fd7c1d7.tar.gz
Version: 0.3.0
* Preliminary autoconf support * Switched to getopt() * New option: -C (demangle C++ names) * New options: --help, --version * Display "format" (printf-like) argument types * Updated manual page * New option: -e
Diffstat (limited to 'display_args.c')
-rw-r--r--display_args.c78
1 files changed, 76 insertions, 2 deletions
diff --git a/display_args.c b/display_args.c
index b3ce31e..796b3bc 100644
--- a/display_args.c
+++ b/display_args.c
@@ -5,10 +5,11 @@
#include "ltrace.h"
#include "options.h"
-static int display_char(char what);
+static int display_char(int what);
static int display_string(enum tof type, struct process * proc, int arg_num);
static int display_stringN(int arg2, enum tof type, struct process * proc, int arg_num);
static int display_unknown(enum tof type, struct process * proc, int arg_num);
+static int display_format(enum tof type, struct process * proc, int arg_num);
int display_arg(enum tof type, struct process * proc, int arg_num, enum param_type rt)
{
@@ -37,6 +38,7 @@ int display_arg(enum tof type, struct process * proc, int arg_num, enum param_ty
return fprintf(output, "0x%08x", (unsigned)arg);
}
case LT_PT_FORMAT:
+ return display_format(type, proc, arg_num);
case LT_PT_STRING:
return display_string(type, proc, arg_num);
case LT_PT_STRING0:
@@ -54,7 +56,7 @@ int display_arg(enum tof type, struct process * proc, int arg_num, enum param_ty
return fprintf(output, "?");
}
-static int display_char(char what)
+static int display_char(int what)
{
switch(what) {
case -1: return fprintf(output, "EOF");
@@ -131,3 +133,75 @@ static int display_unknown(enum tof type, struct process * proc, int arg_num)
return fprintf(output, "0x%08lx", tmp);
}
}
+
+static int display_format(enum tof type, struct process * proc, int arg_num)
+{
+ void * addr;
+ char * str1;
+ int i;
+ int len=0;
+
+ addr = (void *)gimme_arg(type, proc, arg_num);
+ if (!addr) {
+ return fprintf(output, "NULL");
+ }
+
+ str1 = malloc(MIN(opt_s,string_maxlength)+3);
+ if (!str1) {
+ return fprintf(output, "???");
+ }
+ umovestr(proc, addr, MIN(opt_s,string_maxlength)+1, str1);
+ len = fprintf(output, "\"");
+ for(i=0; len<MIN(opt_s,string_maxlength)+1; i++) {
+ if (str1[i]) {
+ len += display_char(str1[i]);
+ } else {
+ break;
+ }
+ }
+ len += fprintf(output, "\"");
+ if (str1[i] && (opt_s <= string_maxlength)) {
+ len += fprintf(output, "...");
+ }
+ for(i=0; str1[i]; i++) {
+ if (str1[i]=='%') {
+ while(1) {
+ char c = str1[++i];
+ if (c == '%') {
+ break;
+ } else if (!c) {
+ break;
+ } else if ((c=='d') || (c=='i')) {
+ len += fprintf(output, ", %d", (int)gimme_arg(type, proc, ++arg_num));
+ break;
+ } else if (c=='u') {
+ len += fprintf(output, ", %u", (int)gimme_arg(type, proc, ++arg_num));
+ break;
+ } else if (c=='o') {
+ len += fprintf(output, ", 0%o", (int)gimme_arg(type, proc, ++arg_num));
+ break;
+ } else if ((c=='x') || (c=='X')) {
+ len += fprintf(output, ", 0x%x", (int)gimme_arg(type, proc, ++arg_num));
+ break;
+ } else if (c=='c') {
+ len += fprintf(output, ", '");
+ len += display_char((int)gimme_arg(type, proc, ++arg_num));
+ len += fprintf(output, "'");
+ break;
+ } else if (c=='s') {
+ len += fprintf(output, ", ");
+ len += display_string(type, proc, ++arg_num);
+ break;
+ } else if ((c=='e') || (c=='E') || (c=='f') || (c=='g')) {
+ len += fprintf(output, ", ...");
+ str1[i+1]='\0';
+ break;
+ } else if (c=='*') {
+ len += fprintf(output, ", %d", (int)gimme_arg(type, proc, ++arg_num));
+ }
+ }
+ }
+ }
+ free(str1);
+ return len;
+}