diff options
author | Juan Cespedes <cespedes@debian.org> | 1998-04-25 14:31:58 +0200 |
---|---|---|
committer | Juan Cespedes <cespedes@debian.org> | 1998-04-25 14:31:58 +0200 |
commit | ac3db297f7c6f08b02a7edfb32e441875fd7c1d7 (patch) | |
tree | 8e0f7fce638eab7af22db3ec4c74f4e9679bcb78 /display_args.c | |
parent | 28f60197b93b45422a73e5d1a6aa581584d6c4a5 (diff) | |
download | ltrace-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.c | 78 |
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; +} |