00001
00002 #include "define.h"
00003
00004 #define BUF_SIZE 4096
00005
00006 void usage();
00007 size_t get(void * buf, int size, unsigned int count, FILE *fp);
00008 int split_args(char *args, int **targ);
00009 int is_in(int a, int *b, int c);
00010
00011 int main(int argc, char* const* argv) {
00012 int identity = 0;
00013 int level = 0;
00014 int x, ptr, stop=0, flag;
00015 char *fname, *buf, rec_type;
00016 unsigned char version;
00017 int *show_type=NULL, show_size=0;
00018 int *ex_type=NULL, ex_size=0;
00019 unsigned int funcname=0, filename=0, text=0, end=0, dtype=0, line=0;
00020 int c;
00021 char ch;
00022 FILE *fp;
00023 struct pst_debug_file_rec_m mfile_rec;
00024 struct pst_debug_file_rec_l lfile_rec;
00025 char format = 'D';
00026 while ((c = getopt(argc, argv, "f:t:x:")) != -1) {
00027 ch = c;
00028 switch(ch) {
00029 case 'f':
00030
00031 format = toupper(optarg[0]);
00032 break;
00033 case 't':
00034
00035 show_size = split_args(optarg, &show_type);
00036
00037 break;
00038 case 'x':
00039
00040 ex_size = split_args(optarg, &ex_type);
00041 break;
00042 }
00043 }
00044 if (argc > optind) {
00045 fname = argv[optind++];
00046 } else {
00047 usage();
00048 exit(2);
00049 }
00050
00051 fp = fopen(fname, "rb");
00052 if (fp == NULL) {
00053 printf("Error. couldn't open debug file\n");
00054 return 2;
00055 }
00056 if (get(&version, sizeof(char), 1, fp)==0) {
00057 printf("Error. could not read version byte from front of file");
00058 return 3;
00059 }
00060
00061 if (version > DEBUG_VERSION) {
00062 printf("Version number is higher than the format I know about.");
00063 return 4;
00064 }
00065
00066 buf = (char*) xmalloc(BUF_SIZE);
00067
00068 while (!stop) {
00069 int64_t temp;
00070 if (fread(&temp, sizeof(int64_t), 1, fp)<=0) break;
00071 x = (int)temp;
00072 ptr = 0;
00073 if (x > 0) {
00074 int64_t i[x+1];
00075 if (get(i, sizeof(int64_t), x+1, fp)==0) {
00076
00077 printf("oh dear. we must now end\n");
00078 break;
00079 }
00080 while (ptr < x) {
00081 fseeko(fp, i[ptr++], SEEK_SET);
00082 get(&rec_type, 1, sizeof(char), fp);
00083 if (rec_type == 'L') {
00084 get(&lfile_rec, sizeof(lfile_rec), 1, fp);
00085 funcname=lfile_rec.funcname;
00086 filename=lfile_rec.filename;
00087 text = lfile_rec.text;
00088 end = lfile_rec.end;
00089 dtype = lfile_rec.type;
00090 line = lfile_rec.line;
00091 } else if (rec_type == 'M') {
00092 get(&mfile_rec, sizeof(mfile_rec), 1, fp);
00093 funcname = mfile_rec.funcname;
00094 filename = mfile_rec.filename;
00095 text = mfile_rec.text;
00096 end = mfile_rec.end;
00097 dtype = mfile_rec.type;
00098 line = mfile_rec.line;
00099 }
00100 if (dtype == DEBUG_FUNCENT_NO) level++;
00101 if ((show_type == NULL || is_in(dtype, show_type, show_size)) &&
00102 (ex_type == NULL || !is_in(dtype, ex_type, ex_size))) {
00103 unsigned int c = 0;
00104 flag = 0;
00105 while (c < end) {
00106 int ii = (level-1) * 4;
00107 if (ii < 0) ii = 0;
00108 if (ii > 64) ii = 64;
00109 char indent[ii+1];
00110 memset(indent, ' ', ii);
00111 indent[ii] = '\0';
00112 if (c + (BUF_SIZE-1) < end) {
00113 get(buf, 1, BUF_SIZE-1, fp);
00114 buf[BUF_SIZE-1] = '\0';
00115 c += BUF_SIZE-1;
00116 } else {
00117 get(buf, 1, end-c, fp);
00118 buf[end-c] = '\0';
00119 c = end;
00120 }
00121 if (flag == 0) {
00122 if (format == 'I') {
00123 char *b = buf+text;
00124 identity++;
00125
00126 printf("%s %s/%s[%d]: ", indent, &buf[filename], &buf[funcname], line);
00127 while (b) {
00128 char *p = strchr(b, '\n');
00129 if (p) {
00130 *p = '\0';
00131 printf("%s\n%s ", b, indent);
00132 b = p + 1;
00133 }
00134 else {
00135 printf("%s", b);
00136 b = NULL;
00137 }
00138 }
00139 }
00140 else if (format == 'T') {
00141 printf("%s/%s[%d]: %s", &buf[filename], &buf[funcname], line, &buf[text]);
00142 } else {
00143 printf("Type: %d\nFile[line]: %s[%d]\nFunction:%s\nText:%s", dtype,
00144 &buf[filename], line, &buf[funcname], &buf[text]);
00145 }
00146 flag = 1;
00147 } else {
00148 if (format == 'I') {
00149 char *b = buf;
00150 while (b) {
00151 char *p = strchr(b, '\n');
00152 if (p) {
00153 *p = '\0';
00154 printf("%s\n%s ", b, indent);
00155 b = p + 1;
00156 }
00157 else {
00158 printf("%s", b);
00159 b = NULL;
00160 }
00161 }
00162 }
00163 else printf("%s", buf);
00164 }
00165 }
00166 printf("\n");
00167 }
00168 if (dtype == DEBUG_FUNCRET_NO) level--;
00169 }
00170 if (fseeko(fp, i[ptr], SEEK_SET)==-1) {
00171 printf("finished\n");
00172 break;
00173 }
00174 } else {
00175 printf("...no more items\n");
00176 break;
00177 }
00178 }
00179 free(buf);
00180 fclose(fp);
00181 if (format == 'I') printf("final indent level = %i\n", level);
00182 return 0;
00183 }
00184
00185 size_t get(void *buf, int size, unsigned int count, FILE *fp) {
00186 size_t z;
00187 if ((z=fread(buf, size, count, fp)) < count) {
00188 printf("Read Failed! (size=%d, count=%d,z=%ld)\n", size, count, (long)z);
00189 exit(1);
00190 }
00191 return z;
00192 }
00193
00194 void usage() {
00195 printf("readlog -t[show_type] -x[exclude_type] -f[format] filename\n");
00196 printf("\tformat:\n\t\tt: text log format\n");
00197 printf("\t\ti: indented text log format\n");
00198 printf("\tshow_type:\n\t\tcomma separated list of types to show "
00199 "[ie, 2,4,1,6]\n");
00200 printf("\texclude_type:\n\t\tcomma separated list of types to exclude "
00201 "[ie, 1,5,3,7]\n");
00202 }
00203
00204
00205 int split_args(char *args, int **targ) {
00206 int count = 1, *i, x, z;
00207 char *tmp = args, *y;
00208 if (*targ != NULL) {
00209 free(*targ);
00210 }
00211
00212
00213 while ((tmp = strchr(tmp, ',')) != NULL) {
00214 tmp++; count++;
00215 }
00216 *targ = (int*)xmalloc(count * sizeof(int));
00217 i = *targ;
00218 tmp = args;
00219 z = 0;
00220 for (x = 0; x < count; x++) {
00221 y = strtok(tmp, ",");
00222 tmp = NULL;
00223 if (y != NULL) {
00224 i[x] = atoi(y);
00225 z++;
00226 }
00227 }
00228 return z;
00229 }
00230
00231
00232
00233
00234
00235 int is_in(int a, int *b, int c){
00236 int d = 0;
00237 if (b == NULL || c == 0) {
00238 return 0;
00239 }
00240 while (d < c) {
00241 if (a == b[d]) return 1;
00242 d++;
00243 }
00244 return 0;
00245 }