blob: 84d9b78a1f4a855d39a45ed9367b621243caabbd [file] [log] [blame]
Juan Cespedes5e01f651998-03-08 22:31:44 +01001#include <stdio.h>
2#include <stdlib.h>
Juan Cespedes2c4a8cb1998-03-11 23:33:18 +01003#include <limits.h>
Juan Cespedes5e01f651998-03-08 22:31:44 +01004
5#include "ltrace.h"
6#include "options.h"
7
Juan Cespedesac3db291998-04-25 14:31:58 +02008static int display_char(int what);
Juan Cespedes5e01f651998-03-08 22:31:44 +01009static int display_string(enum tof type, struct process * proc, int arg_num);
10static int display_stringN(int arg2, enum tof type, struct process * proc, int arg_num);
11static int display_unknown(enum tof type, struct process * proc, int arg_num);
Juan Cespedesac3db291998-04-25 14:31:58 +020012static int display_format(enum tof type, struct process * proc, int arg_num);
Juan Cespedes5e01f651998-03-08 22:31:44 +010013
14int display_arg(enum tof type, struct process * proc, int arg_num, enum param_type rt)
15{
16 int tmp;
17 long arg;
18
19 switch(rt) {
20 case LT_PT_VOID:
21 return 0;
22 case LT_PT_INT:
23 return fprintf(output, "%d", (int)gimme_arg(type, proc, arg_num));
24 case LT_PT_UINT:
25 return fprintf(output, "%u", (unsigned)gimme_arg(type, proc, arg_num));
26 case LT_PT_OCTAL:
27 return fprintf(output, "0%o", (unsigned)gimme_arg(type, proc, arg_num));
28 case LT_PT_CHAR:
29 tmp = fprintf(output, "'");
30 tmp += display_char((int)gimme_arg(type, proc, arg_num));
31 tmp += fprintf(output, "'");
32 return tmp;
33 case LT_PT_ADDR:
34 arg = gimme_arg(type, proc, arg_num);
35 if (!arg) {
36 return fprintf(output, "NULL");
37 } else {
38 return fprintf(output, "0x%08x", (unsigned)arg);
39 }
40 case LT_PT_FORMAT:
Juan Cespedesac3db291998-04-25 14:31:58 +020041 return display_format(type, proc, arg_num);
Juan Cespedes5e01f651998-03-08 22:31:44 +010042 case LT_PT_STRING:
43 return display_string(type, proc, arg_num);
44 case LT_PT_STRING0:
45 return display_stringN(0, type, proc, arg_num);
46 case LT_PT_STRING1:
47 return display_stringN(1, type, proc, arg_num);
48 case LT_PT_STRING2:
49 return display_stringN(2, type, proc, arg_num);
50 case LT_PT_STRING3:
51 return display_stringN(3, type, proc, arg_num);
52 case LT_PT_UNKNOWN:
53 default:
54 return display_unknown(type, proc, arg_num);
55 }
56 return fprintf(output, "?");
57}
58
Juan Cespedesac3db291998-04-25 14:31:58 +020059static int display_char(int what)
Juan Cespedes5e01f651998-03-08 22:31:44 +010060{
61 switch(what) {
62 case -1: return fprintf(output, "EOF");
63 case '\r': return fprintf(output, "\\r");
64 case '\n': return fprintf(output, "\\n");
65 case '\t': return fprintf(output, "\\t");
Juan Cespedes81690ef1998-03-13 19:31:29 +010066 case '\b': return fprintf(output, "\\b");
Juan Cespedes5e01f651998-03-08 22:31:44 +010067 case '\\': return fprintf(output, "\\");
68 default:
69 if ((what<32) || (what>126)) {
Juan Cespedes81690ef1998-03-13 19:31:29 +010070 return fprintf(output, "\\%03o", (unsigned char)what);
Juan Cespedes5e01f651998-03-08 22:31:44 +010071 } else {
72 return fprintf(output, "%c", what);
73 }
74 }
75}
76
Juan Cespedes2c4a8cb1998-03-11 23:33:18 +010077static int string_maxlength=INT_MAX;
78
79#define MIN(a,b) (((a)<(b)) ? (a) : (b))
80
Juan Cespedes5e01f651998-03-08 22:31:44 +010081static int display_string(enum tof type, struct process * proc, int arg_num)
82{
83 void * addr;
84 char * str1;
85 int i;
86 int len=0;
87
88 addr = (void *)gimme_arg(type, proc, arg_num);
89 if (!addr) {
90 return fprintf(output, "NULL");
91 }
92
Juan Cespedes2c4a8cb1998-03-11 23:33:18 +010093 str1 = malloc(MIN(opt_s,string_maxlength)+3);
Juan Cespedes5e01f651998-03-08 22:31:44 +010094 if (!str1) {
95 return fprintf(output, "???");
96 }
Juan Cespedes2c4a8cb1998-03-11 23:33:18 +010097 umovestr(proc, addr, MIN(opt_s,string_maxlength)+1, str1);
Juan Cespedes5e01f651998-03-08 22:31:44 +010098 len = fprintf(output, "\"");
Juan Cespedes370c8e61998-09-06 14:29:46 +020099 for(i=0; i<MIN(opt_s,string_maxlength); i++) {
Juan Cespedes5e01f651998-03-08 22:31:44 +0100100 if (str1[i]) {
101 len += display_char(str1[i]);
102 } else {
103 break;
104 }
105 }
106 len += fprintf(output, "\"");
Juan Cespedes2c4a8cb1998-03-11 23:33:18 +0100107 if (str1[i] && (opt_s <= string_maxlength)) {
Juan Cespedes5e01f651998-03-08 22:31:44 +0100108 len += fprintf(output, "...");
109 }
110 free(str1);
111 return len;
112}
113
Juan Cespedes5e01f651998-03-08 22:31:44 +0100114static int display_stringN(int arg2, enum tof type, struct process * proc, int arg_num)
115{
Juan Cespedes2c4a8cb1998-03-11 23:33:18 +0100116 int a;
117
118 string_maxlength=gimme_arg(type, proc, arg2-1);
Juan Cespedes5e01f651998-03-08 22:31:44 +0100119 a = display_string(type, proc, arg_num);
Juan Cespedes2c4a8cb1998-03-11 23:33:18 +0100120 string_maxlength=INT_MAX;
Juan Cespedes5e01f651998-03-08 22:31:44 +0100121 return a;
122}
123
124static int display_unknown(enum tof type, struct process * proc, int arg_num)
125{
126 long tmp;
127
128 tmp = gimme_arg(type, proc, arg_num);
129
130 if (tmp<1000000 && tmp>-1000000) {
131 return fprintf(output, "%ld", tmp);
132 } else {
133 return fprintf(output, "0x%08lx", tmp);
134 }
135}
Juan Cespedesac3db291998-04-25 14:31:58 +0200136
137static int display_format(enum tof type, struct process * proc, int arg_num)
138{
139 void * addr;
140 char * str1;
141 int i;
142 int len=0;
143
144 addr = (void *)gimme_arg(type, proc, arg_num);
145 if (!addr) {
146 return fprintf(output, "NULL");
147 }
148
149 str1 = malloc(MIN(opt_s,string_maxlength)+3);
150 if (!str1) {
151 return fprintf(output, "???");
152 }
153 umovestr(proc, addr, MIN(opt_s,string_maxlength)+1, str1);
154 len = fprintf(output, "\"");
155 for(i=0; len<MIN(opt_s,string_maxlength)+1; i++) {
156 if (str1[i]) {
157 len += display_char(str1[i]);
158 } else {
159 break;
160 }
161 }
162 len += fprintf(output, "\"");
163 if (str1[i] && (opt_s <= string_maxlength)) {
164 len += fprintf(output, "...");
165 }
166 for(i=0; str1[i]; i++) {
167 if (str1[i]=='%') {
168 while(1) {
169 char c = str1[++i];
170 if (c == '%') {
171 break;
172 } else if (!c) {
173 break;
174 } else if ((c=='d') || (c=='i')) {
175 len += fprintf(output, ", %d", (int)gimme_arg(type, proc, ++arg_num));
176 break;
177 } else if (c=='u') {
178 len += fprintf(output, ", %u", (int)gimme_arg(type, proc, ++arg_num));
179 break;
180 } else if (c=='o') {
181 len += fprintf(output, ", 0%o", (int)gimme_arg(type, proc, ++arg_num));
182 break;
183 } else if ((c=='x') || (c=='X')) {
184 len += fprintf(output, ", 0x%x", (int)gimme_arg(type, proc, ++arg_num));
185 break;
186 } else if (c=='c') {
187 len += fprintf(output, ", '");
188 len += display_char((int)gimme_arg(type, proc, ++arg_num));
189 len += fprintf(output, "'");
190 break;
191 } else if (c=='s') {
192 len += fprintf(output, ", ");
193 len += display_string(type, proc, ++arg_num);
194 break;
195 } else if ((c=='e') || (c=='E') || (c=='f') || (c=='g')) {
196 len += fprintf(output, ", ...");
197 str1[i+1]='\0';
198 break;
199 } else if (c=='*') {
200 len += fprintf(output, ", %d", (int)gimme_arg(type, proc, ++arg_num));
201 }
202 }
203 }
204 }
205 free(str1);
206 return len;
207}