Mercurial > libpst
diff readpstlog.c @ 0:6b1b602514db libpst_0_5
Initial revision
author | carl |
---|---|
date | Fri, 09 Jul 2004 07:26:16 -0700 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/readpstlog.c Fri Jul 09 07:26:16 2004 -0700 @@ -0,0 +1,210 @@ +#include <stdio.h> +#include <ctype.h> +#include <string.h> + +#ifndef _WIN32 +# include <unistd.h> +#endif + +#ifndef __GNUC__ +# include "XGetopt.h" +#endif + +#include "define.h" + +#define BUF_SIZE 4096 + +int usage(); +size_t get(void * buf, int size, unsigned int count, FILE *fp); +int split_args(char *args, int **targ); +int is_in(int a, int *b, int c); + +int main(int argc, char** argv) { + int *i=NULL, x, ptr, stop=0, flag; + char *fname, *buf, format, rec_type; + unsigned char version; + int *show_type=NULL, show_size=0; + int *ex_type=NULL, ex_size=0; + unsigned int funcname, filename, text, end, dtype, line, c; + FILE *fp; + struct _debug_file_rec_m mfile_rec; + struct _debug_file_rec_l lfile_rec; + + while ((c = getopt(argc, argv, "f:t:x:")) != -1) { + switch(c) { + case 'f': + // change the output format + format = toupper(optarg[0]); + break; + case 't': + //change the type of statements shown + show_size = split_args(optarg, &show_type); + // type = atoi(optarg); + break; + case 'x': + // change the type of statements excluded + ex_size = split_args(optarg, &ex_type); + break; + } + } + if (argc > optind) { + fname = argv[optind++]; + } else { + usage(); + exit(2); + } + + fp = fopen(fname, "rb"); + if (fp == NULL) { + printf("Error. couldn't open debug file\n"); + return 2; + } + if (get(&version, sizeof(char), 1, fp)==0) { + printf("Error. could not read version byte from front of file"); + return 3; + } + + if (version > DEBUG_VERSION) { + printf("Version number is higher than the format I know about."); + return 4; + } + + buf = (char*) xmalloc(BUF_SIZE); + + while (!stop) { + if (fread(&x, sizeof(int), 1, fp)<=0) { + break; + } + ptr = 0; + if (x > 0) { + if (i != NULL) + free(i); + i = (int*)xmalloc(sizeof(int)*(x+1)); + // plus 1 cause we want to read the offset of the next index + if (get(i, sizeof(int), x+1, fp)==0) { + // we have reached the end of the debug file + printf("oh dear. we must now end\n"); + break; + } + while (ptr < x) { + fseek(fp,i[ptr++], SEEK_SET); + get(&rec_type, 1, sizeof(char), fp); + if (rec_type == 'L') { + get(&lfile_rec, sizeof(lfile_rec), 1, fp); + funcname=lfile_rec.funcname; + filename=lfile_rec.filename; + text = lfile_rec.text; + end = lfile_rec.end; + dtype = lfile_rec.type; + line = lfile_rec.line; + } else if (rec_type == 'M') { + get(&mfile_rec, sizeof(mfile_rec), 1, fp); + funcname = mfile_rec.funcname; + filename = mfile_rec.filename; + text = mfile_rec.text; + end = mfile_rec.end; + dtype = mfile_rec.type; + line = mfile_rec.line; + } + if ((show_type == NULL || is_in(dtype, show_type, show_size)) + && (ex_type == NULL || !is_in(dtype, ex_type, ex_size))) { + c = 0; flag = 0; + while (c < end) { + if (c + (BUF_SIZE-1) < end) { + get(buf, 1, BUF_SIZE-1, fp); + buf[BUF_SIZE-1] = '\0'; + c += BUF_SIZE-1; + } else { + get(buf, 1, end-c, fp); + buf[end-c] = '\0'; + c = end; + } + if (flag == 0) { + if (format=='T') { // text format + printf("%s[%d]: %s", &buf[funcname], line, &buf[text]); + } else { + printf("Type: %d\nFile[line]: %s[%d]\nFunction:%s\nText:%s", dtype, + &buf[filename], line, &buf[funcname], &buf[text]); + } + flag = 1; + } else { + printf("%s", buf); + } + } + printf("\n"); + } + } + if (fseek(fp, i[ptr], SEEK_SET)==-1) { + printf("finished\n"); + break; + } + } else { + printf("...no more items\n"); + break; + } + } + free(buf); + fclose(fp); + return 0; +} + +size_t get(void * buf, int size, unsigned int count, FILE *fp) { + size_t z; + if ((z=fread(buf,size, count, fp)) < count) { + printf("Read Failed! (size=%d, count=%d,z=%ld)\n", size, count, (long)z); + exit(1); + } + return z; +} + +int usage() { + printf("readlog -t[show_type] -x[exclude_type] -f[format] filename\n"); + printf("\tformat:\n\t\tt: Text log format\n"); + printf("\tshow_type:\n\t\tcomma separated list of types to show " + "[ie, 2,4,1,6]\n"); + printf("\texclude_type:\n\t\tcomma separated list of types to exclude " + "[ie, 1,5,3,7]\n"); + return 0; +} + +int split_args(char *args, int **targ) { + int count = 1, *i, x, z; + char *tmp = args, *y; + if (*targ != NULL) { + free(*targ); + } + // find the number of tokens in the string. Starting + // from 1 cause there will always be one + while ((tmp = strchr(tmp, ',')) != NULL) { + tmp++; count++; + } + *targ = (int*)xmalloc(count * sizeof(int)); + i = *targ; // for convienience + tmp = args; + z = 0; + for (x = 0; x < count; x++) { + y = strtok(tmp, ","); + tmp = NULL; // must be done after first call + if (y != NULL) { + i[x] = atoi(y); + z++; + } + } + return z; +} + +// checks to see if the first arg is in the array of the second arg, +// the size of which is specified with the third arg. If the second +// arg is NULL, then it is obvious that it ain't there. +int is_in(int a, int *b, int c){ + int d = 0; + if (b == NULL || c == 0) { // no array or no items in array + return 0; + } + while (d < c) { + if (a == b[d]) + return 1; + d++; + } + return 0; +}