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