comparison src/debug.c @ 33:12cac756bc05 stable-0-5-5

enable -d option, but if not specified, don't generate a debug file
author carl
date Tue, 10 Jul 2007 20:23:55 -0700
parents b88ceb81dba2
children 07177825c91b
comparison
equal deleted inserted replaced
32:c03974357771 33:12cac756bc05
10 #ifdef _WIN32 10 #ifdef _WIN32
11 # define vsnprintf _vsnprintf 11 # define vsnprintf _vsnprintf
12 #endif 12 #endif
13 13
14 struct _debug_item { 14 struct _debug_item {
15 int type; 15 int type;
16 char * function; 16 char * function;
17 unsigned int line; 17 unsigned int line;
18 char * file; 18 char * file;
19 char * text; 19 char * text;
20 struct _debug_item *next; 20 struct _debug_item *next;
21 } *item_head=NULL, *item_tail=NULL, *item_ptr=NULL, *info_ptr=NULL, *temp_list=NULL; 21 } *item_head=NULL, *item_tail=NULL, *item_ptr=NULL, *info_ptr=NULL, *temp_list=NULL;
22 22
23
23 struct _debug_func { 24 struct _debug_func {
24 char * name; 25 char * name;
25 struct _debug_func *next; 26 struct _debug_func *next;
26 } *func_head=NULL, *func_ptr=NULL; 27 } *func_head=NULL, *func_ptr=NULL;
27 28
28 29
29 void _debug_init(char *fname); 30 void _debug_init(char *fname);
30 void _debug_msg_info (int line, char *file, int type); 31 void _debug_msg_info (int line, char *file, int type);
42 // will do a debug_write, then create a new record, and write the 43 // will do a debug_write, then create a new record, and write the
43 // text body directly to the file 44 // text body directly to the file
44 #define MAX_MESSAGE_SIZE 4096 45 #define MAX_MESSAGE_SIZE 4096
45 46
46 void _pst_debug(char *fmt, ...) { 47 void _pst_debug(char *fmt, ...) {
47 va_list ap; 48 va_list ap;
48 va_start(ap,fmt); 49 va_start(ap,fmt);
49 vfprintf(stderr, fmt, ap); 50 vfprintf(stderr, fmt, ap);
50 va_end(ap); 51 va_end(ap);
51 } 52 }
53
52 54
53 #define NUM_COL 30 55 #define NUM_COL 30
54 void _pst_debug_hexdump(FILE *out, unsigned char *buf, size_t size, int col) { 56 void _pst_debug_hexdump(FILE *out, unsigned char *buf, size_t size, int col) {
55 int off = 0, toff; 57 int off = 0, toff;
56 int count = 0; 58 int count = 0;
57 59
58 if (col == -1) { 60 if (!out) return; // no file
59 col = NUM_COL; 61 if (col == -1) col = NUM_COL;
60 } 62 fprintf(out, "\n");
61 fprintf(out, "\n"); 63 while (off < size) {
62 while (off < size) { 64 fprintf(out, "%X\t:", off);
63 fprintf(out, "%X\t:", off); 65 toff = off;
64 toff = off; 66 while (count < col && off < size) {
65 while (count < col && off < size) { 67 fprintf(out, "%02hhx ", buf[off]);
66 fprintf(out, "%02hhx ", buf[off]); 68 off++; count++;
67 off++; count++; 69 }
68 } 70 off = toff;
69 off = toff; 71 while (count < col) {
70 while (count < col) { 72 // only happens at end of block to pad the text over to the text column
71 // only happens at end of block to pad the text over to the text column 73 fprintf(out, " ");
72 fprintf(out, " "); 74 count++;
73 count++; 75 }
74 } 76 count = 0;
75 count = 0; 77 fprintf(out, ":");
76 fprintf(out, ":"); 78 while (count < col && off < size) {
77 while (count < col && off < size) { 79 fprintf(out, "%c", isgraph(buf[off])?buf[off]:'.');
78 fprintf(out, "%c", isgraph(buf[off])?buf[off]:'.'); 80 off++; count ++;
79 off++; count ++; 81 }
80 } 82
81 83 fprintf(out, "\n");
82 fprintf(out, "\n"); 84 count=0;
83 count=0; 85 }
84 } 86
85 87 fprintf(out, "\n");
86 fprintf(out, "\n"); 88 }
87 } 89
88
89 void _pst_debug_hexprint(char *data, int size) {
90 int i = 0;
91 while (i < size) {
92 fprintf(stderr, "%02hhX", data[i]);
93 i++;
94 }
95 }
96 90
97 FILE *debug_fp = NULL; 91 FILE *debug_fp = NULL;
98 unsigned int max_items=DEBUG_MAX_ITEMS, curr_items=0; 92 unsigned int max_items=DEBUG_MAX_ITEMS, curr_items=0;
99 93
94
100 void _debug_init(char* fname) { 95 void _debug_init(char* fname) {
101 unsigned char version = DEBUG_VERSION; 96 unsigned char version = DEBUG_VERSION;
102 item_head = item_tail = NULL; 97 item_head = item_tail = NULL;
103 curr_items = 0; 98 curr_items = 0;
104 if (debug_fp != NULL) 99 if (debug_fp) _debug_close();
105 _debug_close(); 100 if (!fname) return;
106 if ((debug_fp = fopen(fname, "wb")) == NULL) { 101 if ((debug_fp = fopen(fname, "wb")) == NULL) {
107 fprintf(stderr, "Opening of file %s failed\n", fname); 102 fprintf(stderr, "Opening of file %s failed\n", fname);
108 exit(1); 103 exit(1);
109 } 104 }
110 fwrite(&version, 1, sizeof(char), debug_fp); 105 fwrite(&version, 1, sizeof(char), debug_fp);
111 } 106 }
107
112 108
113 // function must be called before _debug_msg. It sets up the 109 // function must be called before _debug_msg. It sets up the
114 // structure for the function that follows 110 // structure for the function that follows
115 void _debug_msg_info(int line, char* file, int type) { 111 void _debug_msg_info(int line, char* file, int type) {
116 char *x; 112 char *x;
117 if (debug_fp == NULL) { 113 if (!debug_fp) return; // no file
118 fprintf(stderr, "debug_fp is NULL\n"); 114 info_ptr = (struct _debug_item*) xmalloc(sizeof(struct _debug_item));
119 return; 115 info_ptr->type = type;
120 } 116 info_ptr->line = line;
121 info_ptr = (struct _debug_item*) xmalloc(sizeof(struct _debug_item)); 117 x = (func_head==NULL?"No Function":func_head->name);
122 info_ptr->type = type; 118 info_ptr->function = (char*) xmalloc(strlen(x)+1);
123 info_ptr->line = line; 119 strcpy(info_ptr->function, x);
124 x = (func_head==NULL?"No Function":func_head->name); 120
125 info_ptr->function = (char*) xmalloc(strlen(x)+1); 121 info_ptr->file = (char*) xmalloc(strlen(file)+1);
126 strcpy(info_ptr->function, x); 122 strcpy(info_ptr->file, file);
127 123
128 info_ptr->file = (char*) xmalloc(strlen(file)+1); 124 //put the current record on a temp linked list
129 strcpy(info_ptr->file, file); 125 info_ptr->next = temp_list;
130 126 temp_list = info_ptr;
131 //put the current record on a temp linked list 127 }
132 info_ptr->next = temp_list; 128
133 temp_list = info_ptr;
134 }
135 129
136 void _debug_msg_text(char* fmt, ...) { 130 void _debug_msg_text(char* fmt, ...) {
137 va_list ap; 131 va_list ap;
138 int f, g; 132 int f, g;
139 char x[2]; 133 char x[2];
140 struct _debug_item *temp; 134 struct _debug_item *temp;
141 if (debug_fp == NULL) 135 if (!debug_fp) return; // no file
142 return; 136 va_start(ap, fmt);
143 va_start(ap, fmt); 137 // get the record off of the temp_list
144 // get the record off of the temp_list 138 info_ptr = temp_list;
145 info_ptr = temp_list; 139 if (info_ptr)
146 if (info_ptr != NULL) 140 temp_list = info_ptr->next;
147 temp_list = info_ptr->next; 141 else {
148 else { 142 fprintf(stderr, "NULL info_ptr. ERROR!!\n");
149 fprintf(stderr, "NULL info_ptr. ERROR!!\n"); 143 exit(-2);
150 exit(-2); 144 }
151 } 145 // according to glibc 2.1, this should return the req. number of bytes for
152 // according to glibc 2.1, this should return the req. number of bytes for 146 // the string
153 // the string 147 #ifdef _WIN32
154 #ifdef _WIN32 148 // vsnprintf trick doesn't work. must use function called _vscprintf
155 // vsnprintf trick doesn't work. must use function called _vscprintf 149 // cannot find much documentation about this on internet or anywhere.
156 // cannot find much documentation about this on internet or anywhere. 150 // I assume it isn't a standard function, but only in VisualC++
157 // I assume it isn't a standard function, but only in VisualC++ 151 f = _vscprintf(fmt, ap);
158 f = _vscprintf(fmt, ap); 152 #else
159 #else 153 f = vsnprintf(x, 1, fmt, ap);
160 f = vsnprintf(x, 1, fmt, ap); 154 #endif
161 #endif 155 va_end(ap); // must be called after vsnprintf()
162 va_end(ap); // must be called after vsnprintf() 156
163 157 if (f > 0 && f < MAX_MESSAGE_SIZE) {
164 if (f > 0 && f < MAX_MESSAGE_SIZE) { 158 info_ptr->text = (char*) xmalloc(f+1);
165 info_ptr->text = (char*) xmalloc(f+1); 159 va_start(ap, fmt);
166 va_start(ap, fmt); 160 if ((g = vsnprintf(info_ptr->text, f, fmt, ap)) == -1) {
167 if ((g = vsnprintf(info_ptr->text, f, fmt, ap)) == -1) { 161 fprintf(stderr, "_debug_msg: Dieing! vsnprintf returned -1 for format \"%s\"\n", fmt);
168 fprintf(stderr, "_debug_msg: Dieing! vsnprintf returned -1 for format \"%s\"\n", fmt); 162 exit(-2);
169 exit(-2); 163 }
170 } 164 va_end(ap);
171 va_end(ap); 165 info_ptr->text[g] = '\0';
172 info_ptr->text[g] = '\0'; 166 if (f != g) {
173 if (f != g) { 167 fprintf(stderr, "_debug_msg: f != g\n");
174 fprintf(stderr, "_debug_msg: f != g\n"); 168 }
175 } 169 } else if (f > 0) { // it is over the max_message_size then
176 } else if (f > 0) { // it is over the max_message_size then 170 f += strlen(info_ptr->file)+strlen(info_ptr->function);
177 f += strlen(info_ptr->file)+strlen(info_ptr->function); 171 temp = info_ptr;
178 temp = info_ptr; 172 _debug_write(); // dump the current messages
179 _debug_write(); // dump the current messages 173 info_ptr = temp;
180 info_ptr = temp; 174 va_start(ap, fmt);
181 va_start(ap, fmt); 175 _debug_write_msg(info_ptr, fmt, &ap, f);
182 _debug_write_msg(info_ptr, fmt, &ap, f); 176 va_end(ap);
183 va_end(ap); 177 free(info_ptr->function);
184 free(info_ptr->function); 178 free(info_ptr->file);
185 free(info_ptr->file); 179 free(info_ptr);
186 free(info_ptr); 180 info_ptr = NULL;
187 info_ptr = NULL; 181 return;
188 return; 182 } else {
189 } else { 183 fprintf(stderr, "_debug_msg: error getting requested size of debug message\n");
190 fprintf(stderr, "_debug_msg: error getting requested size of debug message\n"); 184 info_ptr->text = "ERROR Saving\n";
191 info_ptr->text = "ERROR Saving\n"; 185 }
192 } 186
193 187 if (!item_head)
194 if (item_head == NULL) 188 item_head = info_ptr;
195 item_head = info_ptr; 189
196 190 info_ptr->next = NULL;
197 info_ptr->next = NULL; 191 if (item_tail) item_tail->next = info_ptr;
198 if (item_tail != NULL) 192 item_tail = info_ptr;
199 item_tail->next = info_ptr; 193
200 item_tail = info_ptr; 194 if (++curr_items == max_items) {
201 195 // here we will jump off and save the contents
202 if (++curr_items == max_items) { 196 _debug_write();
203 // here we will jump off and save the contents 197 info_ptr = NULL;
204 _debug_write(); 198 }
205 info_ptr = NULL; 199 }
206 } 200
207 }
208 201
209 void _debug_hexdump(unsigned char *x, int y, int cols) { 202 void _debug_hexdump(unsigned char *x, int y, int cols) {
210 struct _debug_item *temp; 203 struct _debug_item *temp;
211 if (debug_fp == NULL) 204 if (!debug_fp) return; // no file
212 return; 205 info_ptr = temp_list;
213 info_ptr = temp_list; 206 if (info_ptr)
214 if (info_ptr != NULL) 207 temp_list = info_ptr->next;
215 temp_list = info_ptr->next; 208 temp = info_ptr;
216 temp = info_ptr; 209 _debug_write();
217 _debug_write(); 210 info_ptr = temp;
218 info_ptr = temp; 211 _debug_write_hex(info_ptr, x, y, cols);
219 _debug_write_hex(info_ptr, x, y, cols); 212 free(info_ptr->function);
220 free(info_ptr->function); 213 free(info_ptr->file);
221 free(info_ptr->file); 214 free(info_ptr);
222 free(info_ptr); 215 info_ptr = NULL;
223 info_ptr = NULL; 216 }
224 } 217
225 218
226 void _debug_func(char *function) { 219 void _debug_func(char *function) {
227 func_ptr = xmalloc (sizeof(struct _debug_func)); 220 func_ptr = xmalloc (sizeof(struct _debug_func));
228 func_ptr->name = xmalloc(strlen(function)+1); 221 func_ptr->name = xmalloc(strlen(function)+1);
229 strcpy(func_ptr->name, function); 222 strcpy(func_ptr->name, function);
230 func_ptr->next = func_head; 223 func_ptr->next = func_head;
231 func_head = func_ptr; 224 func_head = func_ptr;
232 } 225 }
226
233 227
234 void _debug_func_ret() { 228 void _debug_func_ret() {
235 //remove the head item 229 //remove the head item
236 func_ptr = func_head; 230 func_ptr = func_head;
237 if (func_head != NULL) { 231 if (func_head) {
238 func_head = func_head->next; 232 func_head = func_head->next;
239 free(func_ptr->name); 233 free(func_ptr->name);
240 free(func_ptr); 234 free(func_ptr);
241 } else { 235 } else {
242 DIE(("function list is empty!\n")); 236 DIE(("function list is empty!\n"));
243 } 237 }
244 } 238 }
239
245 240
246 void _debug_close(void) { 241 void _debug_close(void) {
247 _debug_write(); 242 _debug_write();
248 while (func_head != NULL) { 243 while (func_head) {
249 func_ptr = func_head; 244 func_ptr = func_head;
250 func_head = func_head->next; 245 func_head = func_head->next;
251 free(func_ptr->name); 246 free(func_ptr->name);
252 free(func_ptr); 247 free(func_ptr);
253 } 248 }
254 249
255 if (debug_fp != NULL) 250 if (debug_fp) fclose(debug_fp);
256 fclose(debug_fp); 251 debug_fp = NULL;
257 debug_fp = NULL; 252 }
258 253
259 if (func_head != NULL)
260 while (func_head != NULL) {
261 printf("function '%s' still on stack\n", func_head->name);
262 func_head = func_head->next;
263 }
264 }
265 254
266 void _debug_write() { 255 void _debug_write() {
267 size_t size, ptr, funcname, filename, text, end; 256 size_t size, ptr, funcname, filename, text, end;
268 char *buf = NULL, rec_type; 257 char *buf = NULL, rec_type;
269 long index_pos = ftell (debug_fp), file_pos = index_pos; 258 if (!debug_fp) return; // no file
270 // add 2. One for the pointer to the next index, 259 long index_pos = ftell (debug_fp), file_pos = index_pos;
271 // one for the count of this index 260 // add 2. One for the pointer to the next index,
272 int index_size = ((curr_items+2) * sizeof(int)); 261 // one for the count of this index
273 int *index; 262 int index_size = ((curr_items+2) * sizeof(int));
274 int index_ptr = 0; 263 int *index;
275 struct _debug_file_rec_m mfile_rec; 264 int index_ptr = 0;
276 struct _debug_file_rec_l lfile_rec; 265 struct _debug_file_rec_m mfile_rec;
277 266 struct _debug_file_rec_l lfile_rec;
278 if (curr_items == 0) 267
279 // no items to write. 268 if (curr_items == 0) return; // no items to write.
280 return; 269
281 index = (int*) xmalloc(index_size); 270 index = (int*) xmalloc(index_size);
282 file_pos += index_size; 271 file_pos += index_size;
283 // write the index first, we will re-write it later, but 272 // write the index first, we will re-write it later, but
284 // we want to allocate the space 273 // we want to allocate the space
285 fwrite(index, index_size, 1, debug_fp); 274 fwrite(index, index_size, 1, debug_fp);
286 index[index_ptr++] = curr_items; 275 index[index_ptr++] = curr_items;
287 276
288 item_ptr = item_head; 277 item_ptr = item_head;
289 while (item_ptr != NULL) { 278 while (item_ptr) {
290 file_pos = ftell(debug_fp); 279 file_pos = ftell(debug_fp);
291 index[index_ptr++] = file_pos; 280 index[index_ptr++] = file_pos;
292 size = strlen(item_ptr->function)+strlen(item_ptr->file)+ 281 size = strlen(item_ptr->function)+strlen(item_ptr->file)+
293 strlen(item_ptr->text) + 3; //for the three \0s 282 strlen(item_ptr->text) + 3; //for the three \0s
294 if (buf) free(buf); 283 if (buf) free(buf);
295 buf = xmalloc(size+1); 284 buf = xmalloc(size+1);
296 ptr = 0; 285 ptr = 0;
297 funcname=ptr; 286 funcname=ptr;
298 ptr += sprintf(&(buf[ptr]), "%s", item_ptr->function)+1; 287 ptr += sprintf(&(buf[ptr]), "%s", item_ptr->function)+1;
299 filename=ptr; 288 filename=ptr;
300 ptr += sprintf(&(buf[ptr]), "%s", item_ptr->file)+1; 289 ptr += sprintf(&(buf[ptr]), "%s", item_ptr->file)+1;
301 text=ptr; 290 text=ptr;
302 ptr += sprintf(&(buf[ptr]), "%s", item_ptr->text)+1; 291 ptr += sprintf(&(buf[ptr]), "%s", item_ptr->text)+1;
303 end=ptr; 292 end=ptr;
304 if (end > USHRT_MAX) { // bigger than can be stored in a short 293 if (end > USHRT_MAX) { // bigger than can be stored in a short
305 rec_type = 'L'; 294 rec_type = 'L';
306 fwrite(&rec_type, 1, sizeof(char), debug_fp); 295 fwrite(&rec_type, 1, sizeof(char), debug_fp);
307 lfile_rec.type = item_ptr->type; 296 lfile_rec.type = item_ptr->type;
308 lfile_rec.line = item_ptr->line; 297 lfile_rec.line = item_ptr->line;
309 lfile_rec.funcname = funcname; 298 lfile_rec.funcname = funcname;
310 lfile_rec.filename = filename; 299 lfile_rec.filename = filename;
311 lfile_rec.text = text; 300 lfile_rec.text = text;
312 lfile_rec.end = end; 301 lfile_rec.end = end;
313 fwrite(&lfile_rec, sizeof(lfile_rec), 1, debug_fp); 302 fwrite(&lfile_rec, sizeof(lfile_rec), 1, debug_fp);
314 } else { 303 } else {
315 rec_type = 'M'; 304 rec_type = 'M';
316 fwrite(&rec_type, 1, sizeof(char), debug_fp); 305 fwrite(&rec_type, 1, sizeof(char), debug_fp);
317 mfile_rec.type = item_ptr->type; 306 mfile_rec.type = item_ptr->type;
318 mfile_rec.line = item_ptr->line; 307 mfile_rec.line = item_ptr->line;
319 mfile_rec.funcname = funcname; 308 mfile_rec.funcname = funcname;
320 mfile_rec.filename = filename; 309 mfile_rec.filename = filename;
321 mfile_rec.text = text; 310 mfile_rec.text = text;
322 mfile_rec.end = end; 311 mfile_rec.end = end;
323 fwrite(&mfile_rec, sizeof(mfile_rec), 1, debug_fp); 312 fwrite(&mfile_rec, sizeof(mfile_rec), 1, debug_fp);
324 } 313 }
325 fwrite(buf, 1, ptr, debug_fp); 314 fwrite(buf, 1, ptr, debug_fp);
326 if (buf) free(buf); buf = NULL; 315 if (buf) free(buf); buf = NULL;
327 item_head = item_ptr->next; 316 item_head = item_ptr->next;
328 free(item_ptr->function); 317 free(item_ptr->function);
329 free(item_ptr->file); 318 free(item_ptr->file);
330 free(item_ptr->text); 319 free(item_ptr->text);
331 free(item_ptr); 320 free(item_ptr);
332 item_ptr = item_head; 321 item_ptr = item_head;
333 } 322 }
334 curr_items = 0; 323 curr_items = 0;
335 index[index_ptr] = ftell(debug_fp); 324 index[index_ptr] = ftell(debug_fp);
336 325
337 // we should now have a complete index 326 // we should now have a complete index
338 fseek(debug_fp, index_pos, SEEK_SET); 327 fseek(debug_fp, index_pos, SEEK_SET);
339 fwrite(index, index_size, 1, debug_fp); 328 fwrite(index, index_size, 1, debug_fp);
340 fseek(debug_fp, 0, SEEK_END); 329 fseek(debug_fp, 0, SEEK_END);
341 item_ptr = item_head = item_tail = NULL; 330 item_ptr = item_head = item_tail = NULL;
342 free(index); 331 free(index);
343 if (buf) free(buf); buf = NULL; 332 if (buf) free(buf); buf = NULL;
344 } 333 }
334
345 335
346 void _debug_write_msg(struct _debug_item *item, char *fmt, va_list *ap, int size) { 336 void _debug_write_msg(struct _debug_item *item, char *fmt, va_list *ap, int size) {
347 struct _debug_file_rec_l lfile_rec; 337 struct _debug_file_rec_l lfile_rec;
348 struct _debug_file_rec_m mfile_rec; 338 struct _debug_file_rec_m mfile_rec;
349 unsigned char rec_type; 339 unsigned char rec_type;
350 int index_size = 3 * sizeof(int); 340 int index_size = 3 * sizeof(int);
351 int *index = malloc(index_size); 341 int *index = malloc(index_size);
352 int index_pos, file_pos; 342 int index_pos, file_pos;
353 char zero='\0'; 343 char zero='\0';
354 unsigned int end; 344 unsigned int end;
355 index[0] = 1; //only one item in this index 345 if (!debug_fp) return; // no file
356 index_pos = ftell(debug_fp); 346 index[0] = 1; //only one item in this index
357 fwrite(index, index_size, 1, debug_fp); 347 index_pos = ftell(debug_fp);
358 348 fwrite(index, index_size, 1, debug_fp);
359 index[1] = ftell(debug_fp); 349
360 350 index[1] = ftell(debug_fp);
361 if (size > USHRT_MAX) { // bigger than can be stored in a short 351
362 rec_type = 'L'; 352 if (size > USHRT_MAX) { // bigger than can be stored in a short
363 fwrite(&rec_type, 1, sizeof(char), debug_fp); 353 rec_type = 'L';
364 lfile_rec.type = item->type; 354 fwrite(&rec_type, 1, sizeof(char), debug_fp);
365 lfile_rec.line = item->line; 355 lfile_rec.type = item->type;
366 lfile_rec.funcname = 0; 356 lfile_rec.line = item->line;
367 lfile_rec.filename = strlen(item->function)+1; 357 lfile_rec.funcname = 0;
368 lfile_rec.text = lfile_rec.filename+strlen(item->file)+1; 358 lfile_rec.filename = strlen(item->function)+1;
369 fwrite(&lfile_rec, sizeof(lfile_rec), 1, debug_fp); 359 lfile_rec.text = lfile_rec.filename+strlen(item->file)+1;
370 } else { 360 fwrite(&lfile_rec, sizeof(lfile_rec), 1, debug_fp);
371 rec_type = 'M'; 361 } else {
372 fwrite(&rec_type, 1, sizeof(char), debug_fp); 362 rec_type = 'M';
373 mfile_rec.type = item->type; 363 fwrite(&rec_type, 1, sizeof(char), debug_fp);
374 mfile_rec.line = item->line; 364 mfile_rec.type = item->type;
375 mfile_rec.funcname = 0; 365 mfile_rec.line = item->line;
376 mfile_rec.filename = strlen(item->function)+1; 366 mfile_rec.funcname = 0;
377 mfile_rec.text = mfile_rec.filename+strlen(item->file)+1; 367 mfile_rec.filename = strlen(item->function)+1;
378 fwrite(&mfile_rec, sizeof(mfile_rec), 1, debug_fp); 368 mfile_rec.text = mfile_rec.filename+strlen(item->file)+1;
379 } 369 fwrite(&mfile_rec, sizeof(mfile_rec), 1, debug_fp);
380 file_pos = ftell(debug_fp); 370 }
381 fwrite(item->function, strlen(item->function)+1, 1, debug_fp); 371 file_pos = ftell(debug_fp);
382 fwrite(item->file, strlen(item->file)+1, 1, debug_fp); 372 fwrite(item->function, strlen(item->function)+1, 1, debug_fp);
383 vfprintf(debug_fp, fmt, *ap); 373 fwrite(item->file, strlen(item->file)+1, 1, debug_fp);
384 fwrite(&zero, 1, 1, debug_fp); 374 vfprintf(debug_fp, fmt, *ap);
385 375 fwrite(&zero, 1, 1, debug_fp);
386 end = ftell(debug_fp)-file_pos; 376
387 377 end = ftell(debug_fp)-file_pos;
388 index[2] = ftell(debug_fp); 378
389 fseek(debug_fp, index_pos, SEEK_SET); 379 index[2] = ftell(debug_fp);
390 fwrite(index, index_size, 1, debug_fp); 380 fseek(debug_fp, index_pos, SEEK_SET);
391 if (size > USHRT_MAX) { 381 fwrite(index, index_size, 1, debug_fp);
392 fwrite(&rec_type, 1, sizeof(char), debug_fp); 382 if (size > USHRT_MAX) {
393 lfile_rec.end = end; 383 fwrite(&rec_type, 1, sizeof(char), debug_fp);
394 fwrite(&lfile_rec, sizeof(lfile_rec), 1, debug_fp); 384 lfile_rec.end = end;
395 } else { 385 fwrite(&lfile_rec, sizeof(lfile_rec), 1, debug_fp);
396 fwrite(&rec_type, 1, sizeof(char), debug_fp); 386 } else {
397 mfile_rec.end = end; 387 fwrite(&rec_type, 1, sizeof(char), debug_fp);
398 fwrite(&mfile_rec, sizeof(mfile_rec), 1, debug_fp); 388 mfile_rec.end = end;
399 } 389 fwrite(&mfile_rec, sizeof(mfile_rec), 1, debug_fp);
400 fseek(debug_fp, 0, SEEK_END); 390 }
401 // that should do it... 391 fseek(debug_fp, 0, SEEK_END);
402 } 392 // that should do it...
393 }
394
403 395
404 void _debug_write_hex(struct _debug_item *item, unsigned char *buf, int size, int col) { 396 void _debug_write_hex(struct _debug_item *item, unsigned char *buf, int size, int col) {
405 struct _debug_file_rec_l lfile_rec; 397 struct _debug_file_rec_l lfile_rec;
406 unsigned char rec_type; 398 unsigned char rec_type;
407 int index_size = 3 * sizeof(int); 399 int index_size = 3 * sizeof(int);
408 int *index = malloc(index_size); 400 int *index = malloc(index_size);
409 int index_pos, file_pos; 401 int index_pos, file_pos;
410 char zero='\0'; 402 char zero='\0';
411 index[0] = 1; // only one item in this index run 403 if (!debug_fp) return; // no file
412 index_pos = ftell(debug_fp); 404 index[0] = 1; // only one item in this index run
413 fwrite(index, index_size, 1, debug_fp); 405 index_pos = ftell(debug_fp);
414 index[1] = ftell(debug_fp); 406 fwrite(index, index_size, 1, debug_fp);
415 407 index[1] = ftell(debug_fp);
416 // always use the long 408
417 rec_type = 'L'; 409 // always use the long
418 fwrite(&rec_type, 1, sizeof(char), debug_fp); 410 rec_type = 'L';
419 lfile_rec.type = item->type; 411 fwrite(&rec_type, 1, sizeof(char), debug_fp);
420 lfile_rec.line = item->line; 412 lfile_rec.type = item->type;
421 lfile_rec.funcname = 0; 413 lfile_rec.line = item->line;
422 lfile_rec.filename = strlen(item->function)+1; 414 lfile_rec.funcname = 0;
423 lfile_rec.text = lfile_rec.filename+strlen(item->file)+1; 415 lfile_rec.filename = strlen(item->function)+1;
424 fwrite(&lfile_rec, sizeof(lfile_rec), 1, debug_fp); 416 lfile_rec.text = lfile_rec.filename+strlen(item->file)+1;
425 417 fwrite(&lfile_rec, sizeof(lfile_rec), 1, debug_fp);
426 file_pos = ftell(debug_fp); 418
427 fwrite(item->function, strlen(item->function)+1, 1, debug_fp); 419 file_pos = ftell(debug_fp);
428 fwrite(item->file, strlen(item->file)+1, 1, debug_fp); 420 fwrite(item->function, strlen(item->function)+1, 1, debug_fp);
429 421 fwrite(item->file, strlen(item->file)+1, 1, debug_fp);
430 _pst_debug_hexdump(debug_fp, buf, size, col); 422
431 fwrite(&zero, 1, 1, debug_fp); 423 _pst_debug_hexdump(debug_fp, buf, size, col);
432 lfile_rec.end = ftell(debug_fp)-file_pos; 424 fwrite(&zero, 1, 1, debug_fp);
433 425 lfile_rec.end = ftell(debug_fp)-file_pos;
434 index[2] = ftell(debug_fp); 426
435 fseek(debug_fp, index_pos, SEEK_SET); 427 index[2] = ftell(debug_fp);
436 fwrite(index, index_size, 1, debug_fp); 428 fseek(debug_fp, index_pos, SEEK_SET);
437 fwrite(&rec_type, 1, sizeof(char), debug_fp); 429 fwrite(index, index_size, 1, debug_fp);
438 fwrite(&lfile_rec, sizeof(lfile_rec), 1, debug_fp); 430 fwrite(&rec_type, 1, sizeof(char), debug_fp);
439 fseek(debug_fp, 0, SEEK_END); 431 fwrite(&lfile_rec, sizeof(lfile_rec), 1, debug_fp);
440 } 432 fseek(debug_fp, 0, SEEK_END);
441 433 }
434
435
442 void * xmalloc(size_t size) { 436 void * xmalloc(size_t size) {
443 void *mem = malloc(size); 437 void *mem = malloc(size);
444 if (mem == NULL) { 438 if (!mem) {
445 fprintf(stderr, "xMalloc: Out Of memory [req: %ld]\n", (long)size); 439 fprintf(stderr, "xMalloc: Out Of memory [req: %ld]\n", (long)size);
446 exit(1); 440 exit(1);
447 } 441 }
448 return mem; 442 return mem;
449 } 443 }
450 444