Mercurial > libpst
comparison src/readpstlog.c @ 36:6fe121a971c9 stable-0-5-7
valgrind fixes
author | carl |
---|---|
date | Thu, 09 Aug 2007 15:46:34 -0700 |
parents | c508ee15dfca |
children | f6db1f060a95 |
comparison
equal
deleted
inserted
replaced
35:b2f247463b83 | 36:6fe121a971c9 |
---|---|
18 size_t get(void * buf, int size, unsigned int count, FILE *fp); | 18 size_t get(void * buf, int size, unsigned int count, FILE *fp); |
19 int split_args(char *args, int **targ); | 19 int split_args(char *args, int **targ); |
20 int is_in(int a, int *b, int c); | 20 int is_in(int a, int *b, int c); |
21 | 21 |
22 int main(int argc, char** argv) { | 22 int main(int argc, char** argv) { |
23 int *i=NULL, x, ptr, stop=0, flag; | 23 int level = 0; |
24 char *fname, *buf, format, rec_type; | 24 int *i=NULL, x, ptr, stop=0, flag; |
25 unsigned char version; | 25 char *fname, *buf, rec_type; |
26 int *show_type=NULL, show_size=0; | 26 unsigned char version; |
27 int *ex_type=NULL, ex_size=0; | 27 int *show_type=NULL, show_size=0; |
28 unsigned int funcname, filename, text, end, dtype, line, c; | 28 int *ex_type=NULL, ex_size=0; |
29 FILE *fp; | 29 unsigned int funcname, filename, text, end, dtype, line, c; |
30 struct _debug_file_rec_m mfile_rec; | 30 FILE *fp; |
31 struct _debug_file_rec_l lfile_rec; | 31 struct _debug_file_rec_m mfile_rec; |
32 | 32 struct _debug_file_rec_l lfile_rec; |
33 while ((c = getopt(argc, argv, "f:t:x:")) != -1) { | 33 char format = 'D'; // default |
34 switch(c) { | 34 while ((c = getopt(argc, argv, "f:t:x:")) != -1) { |
35 case 'f': | 35 switch(c) { |
36 // change the output format | 36 case 'f': |
37 format = toupper(optarg[0]); | 37 // change the output format |
38 break; | 38 format = toupper(optarg[0]); |
39 case 't': | 39 break; |
40 //change the type of statements shown | 40 case 't': |
41 show_size = split_args(optarg, &show_type); | 41 //change the type of statements shown |
42 // type = atoi(optarg); | 42 show_size = split_args(optarg, &show_type); |
43 break; | 43 // type = atoi(optarg); |
44 case 'x': | 44 break; |
45 // change the type of statements excluded | 45 case 'x': |
46 ex_size = split_args(optarg, &ex_type); | 46 // change the type of statements excluded |
47 break; | 47 ex_size = split_args(optarg, &ex_type); |
48 } | 48 break; |
49 } | 49 } |
50 if (argc > optind) { | 50 } |
51 fname = argv[optind++]; | 51 if (argc > optind) { |
52 } else { | 52 fname = argv[optind++]; |
53 usage(); | 53 } else { |
54 exit(2); | 54 usage(); |
55 } | 55 exit(2); |
56 | 56 } |
57 fp = fopen(fname, "rb"); | 57 |
58 if (fp == NULL) { | 58 fp = fopen(fname, "rb"); |
59 printf("Error. couldn't open debug file\n"); | 59 if (fp == NULL) { |
60 return 2; | 60 printf("Error. couldn't open debug file\n"); |
61 } | 61 return 2; |
62 if (get(&version, sizeof(char), 1, fp)==0) { | 62 } |
63 printf("Error. could not read version byte from front of file"); | 63 if (get(&version, sizeof(char), 1, fp)==0) { |
64 return 3; | 64 printf("Error. could not read version byte from front of file"); |
65 } | 65 return 3; |
66 | 66 } |
67 if (version > DEBUG_VERSION) { | 67 |
68 printf("Version number is higher than the format I know about."); | 68 if (version > DEBUG_VERSION) { |
69 return 4; | 69 printf("Version number is higher than the format I know about."); |
70 } | 70 return 4; |
71 | 71 } |
72 buf = (char*) xmalloc(BUF_SIZE); | 72 |
73 | 73 buf = (char*) xmalloc(BUF_SIZE); |
74 while (!stop) { | 74 |
75 if (fread(&x, sizeof(int), 1, fp)<=0) { | 75 while (!stop) { |
76 break; | 76 if (fread(&x, sizeof(int), 1, fp)<=0) break; |
77 } | 77 ptr = 0; |
78 ptr = 0; | 78 if (x > 0) { |
79 if (x > 0) { | 79 if (i) free(i); |
80 if (i != NULL) | 80 i = (int*)xmalloc(sizeof(int)*(x+1)); |
81 free(i); | 81 // plus 1 cause we want to read the offset of the next index |
82 i = (int*)xmalloc(sizeof(int)*(x+1)); | 82 if (get(i, sizeof(int), x+1, fp)==0) { |
83 // plus 1 cause we want to read the offset of the next index | 83 // we have reached the end of the debug file |
84 if (get(i, sizeof(int), x+1, fp)==0) { | 84 printf("oh dear. we must now end\n"); |
85 // we have reached the end of the debug file | 85 break; |
86 printf("oh dear. we must now end\n"); | 86 } |
87 break; | 87 while (ptr < x) { |
88 } | 88 fseek(fp,i[ptr++], SEEK_SET); |
89 while (ptr < x) { | 89 get(&rec_type, 1, sizeof(char), fp); |
90 fseek(fp,i[ptr++], SEEK_SET); | 90 if (rec_type == 'L') { |
91 get(&rec_type, 1, sizeof(char), fp); | 91 get(&lfile_rec, sizeof(lfile_rec), 1, fp); |
92 if (rec_type == 'L') { | 92 funcname=lfile_rec.funcname; |
93 get(&lfile_rec, sizeof(lfile_rec), 1, fp); | 93 filename=lfile_rec.filename; |
94 funcname=lfile_rec.funcname; | 94 text = lfile_rec.text; |
95 filename=lfile_rec.filename; | 95 end = lfile_rec.end; |
96 text = lfile_rec.text; | 96 dtype = lfile_rec.type; |
97 end = lfile_rec.end; | 97 line = lfile_rec.line; |
98 dtype = lfile_rec.type; | 98 } else if (rec_type == 'M') { |
99 line = lfile_rec.line; | 99 get(&mfile_rec, sizeof(mfile_rec), 1, fp); |
100 } else if (rec_type == 'M') { | 100 funcname = mfile_rec.funcname; |
101 get(&mfile_rec, sizeof(mfile_rec), 1, fp); | 101 filename = mfile_rec.filename; |
102 funcname = mfile_rec.funcname; | 102 text = mfile_rec.text; |
103 filename = mfile_rec.filename; | 103 end = mfile_rec.end; |
104 text = mfile_rec.text; | 104 dtype = mfile_rec.type; |
105 end = mfile_rec.end; | 105 line = mfile_rec.line; |
106 dtype = mfile_rec.type; | 106 } |
107 line = mfile_rec.line; | 107 if (dtype == DEBUG_FUNCENT_NO) level++; |
108 } | 108 if ((show_type == NULL || is_in(dtype, show_type, show_size)) && |
109 if ((show_type == NULL || is_in(dtype, show_type, show_size)) | 109 (ex_type == NULL || !is_in(dtype, ex_type, ex_size))) { |
110 && (ex_type == NULL || !is_in(dtype, ex_type, ex_size))) { | 110 c = 0; flag = 0; |
111 c = 0; flag = 0; | 111 while (c < end) { |
112 while (c < end) { | 112 int ii = (level-1) * 4; |
113 if (c + (BUF_SIZE-1) < end) { | 113 if (ii < 0) ii = 0; |
114 get(buf, 1, BUF_SIZE-1, fp); | 114 if (ii > 64) ii = 64; |
115 buf[BUF_SIZE-1] = '\0'; | 115 char indent[ii+1]; |
116 c += BUF_SIZE-1; | 116 memset(indent, ' ', ii); |
117 } else { | 117 indent[ii] = '\0'; |
118 get(buf, 1, end-c, fp); | 118 if (c + (BUF_SIZE-1) < end) { |
119 buf[end-c] = '\0'; | 119 get(buf, 1, BUF_SIZE-1, fp); |
120 c = end; | 120 buf[BUF_SIZE-1] = '\0'; |
121 } | 121 c += BUF_SIZE-1; |
122 if (flag == 0) { | 122 } else { |
123 if (format=='T') { // text format | 123 get(buf, 1, end-c, fp); |
124 printf("%s[%d]: %s", &buf[funcname], line, &buf[text]); | 124 buf[end-c] = '\0'; |
125 } else { | 125 c = end; |
126 printf("Type: %d\nFile[line]: %s[%d]\nFunction:%s\nText:%s", dtype, | 126 } |
127 &buf[filename], line, &buf[funcname], &buf[text]); | 127 if (flag == 0) { |
128 } | 128 if (format == 'I') { // indented text format |
129 flag = 1; | 129 char *b = buf+text; |
130 } else { | 130 printf("%s %s/%s[%d]: ", indent, &buf[filename], &buf[funcname], line); |
131 printf("%s", buf); | 131 while (b) { |
132 } | 132 char *p = strchr(b, '\n'); |
133 } | 133 if (p) { |
134 printf("\n"); | 134 *p = '\0'; |
135 } | 135 printf("%s\n%s ", b, indent); |
136 } | 136 b = p + 1; |
137 if (fseek(fp, i[ptr], SEEK_SET)==-1) { | 137 } |
138 printf("finished\n"); | 138 else { |
139 break; | 139 printf("%s", b); |
140 } | 140 b = NULL; |
141 } else { | 141 } |
142 printf("...no more items\n"); | 142 } |
143 break; | 143 } |
144 } | 144 else if (format == 'T') { // text format |
145 } | 145 printf("%s/%s[%d]: %s", &buf[filename], &buf[funcname], line, &buf[text]); |
146 free(buf); | 146 } else { |
147 fclose(fp); | 147 printf("Type: %d\nFile[line]: %s[%d]\nFunction:%s\nText:%s", dtype, |
148 return 0; | 148 &buf[filename], line, &buf[funcname], &buf[text]); |
149 } | 149 } |
150 | 150 flag = 1; |
151 } else { | |
152 if (format == 'I') { | |
153 char *b = buf; | |
154 while (b) { | |
155 char *p = strchr(b, '\n'); | |
156 if (p) { | |
157 *p = '\0'; | |
158 printf("%s\n%s ", b, indent); | |
159 b = p + 1; | |
160 } | |
161 else { | |
162 printf("%s", b); | |
163 b = NULL; | |
164 } | |
165 } | |
166 } | |
167 else printf("%s", buf); | |
168 } | |
169 } | |
170 printf("\n"); | |
171 } | |
172 if (dtype == DEBUG_FUNCRET_NO) level--; | |
173 } | |
174 if (fseek(fp, i[ptr], SEEK_SET)==-1) { | |
175 printf("finished\n"); | |
176 break; | |
177 } | |
178 } else { | |
179 printf("...no more items\n"); | |
180 break; | |
181 } | |
182 } | |
183 free(buf); | |
184 fclose(fp); | |
185 return 0; | |
186 } | |
187 | |
151 size_t get(void * buf, int size, unsigned int count, FILE *fp) { | 188 size_t get(void * buf, int size, unsigned int count, FILE *fp) { |
152 size_t z; | 189 size_t z; |
153 if ((z=fread(buf,size, count, fp)) < count) { | 190 if ((z=fread(buf,size, count, fp)) < count) { |
154 printf("Read Failed! (size=%d, count=%d,z=%ld)\n", size, count, (long)z); | 191 printf("Read Failed! (size=%d, count=%d,z=%ld)\n", size, count, (long)z); |
155 exit(1); | 192 exit(1); |
156 } | 193 } |
157 return z; | 194 return z; |
158 } | 195 } |
159 | 196 |
160 int usage() { | 197 int usage() { |
161 printf("readlog -t[show_type] -x[exclude_type] -f[format] filename\n"); | 198 printf("readlog -t[show_type] -x[exclude_type] -f[format] filename\n"); |
162 printf("\tformat:\n\t\tt: Text log format\n"); | 199 printf("\tformat:\n\t\tt: text log format\n"); |
163 printf("\tshow_type:\n\t\tcomma separated list of types to show " | 200 printf("\t\ti: indented text log format\n"); |
164 "[ie, 2,4,1,6]\n"); | 201 printf("\tshow_type:\n\t\tcomma separated list of types to show " |
165 printf("\texclude_type:\n\t\tcomma separated list of types to exclude " | 202 "[ie, 2,4,1,6]\n"); |
166 "[ie, 1,5,3,7]\n"); | 203 printf("\texclude_type:\n\t\tcomma separated list of types to exclude " |
167 return 0; | 204 "[ie, 1,5,3,7]\n"); |
168 } | 205 return 0; |
206 } | |
207 | |
169 | 208 |
170 int split_args(char *args, int **targ) { | 209 int split_args(char *args, int **targ) { |
171 int count = 1, *i, x, z; | 210 int count = 1, *i, x, z; |
172 char *tmp = args, *y; | 211 char *tmp = args, *y; |
173 if (*targ != NULL) { | 212 if (*targ != NULL) { |
174 free(*targ); | 213 free(*targ); |
175 } | 214 } |
176 // find the number of tokens in the string. Starting | 215 // find the number of tokens in the string. Starting |
177 // from 1 cause there will always be one | 216 // from 1 cause there will always be one |
178 while ((tmp = strchr(tmp, ',')) != NULL) { | 217 while ((tmp = strchr(tmp, ',')) != NULL) { |
179 tmp++; count++; | 218 tmp++; count++; |
180 } | 219 } |
181 *targ = (int*)xmalloc(count * sizeof(int)); | 220 *targ = (int*)xmalloc(count * sizeof(int)); |
182 i = *targ; // for convienience | 221 i = *targ; // for convienience |
183 tmp = args; | 222 tmp = args; |
184 z = 0; | 223 z = 0; |
185 for (x = 0; x < count; x++) { | 224 for (x = 0; x < count; x++) { |
186 y = strtok(tmp, ","); | 225 y = strtok(tmp, ","); |
187 tmp = NULL; // must be done after first call | 226 tmp = NULL; // must be done after first call |
188 if (y != NULL) { | 227 if (y != NULL) { |
189 i[x] = atoi(y); | 228 i[x] = atoi(y); |
190 z++; | 229 z++; |
191 } | 230 } |
192 } | 231 } |
193 return z; | 232 return z; |
194 } | 233 } |
234 | |
195 | 235 |
196 // checks to see if the first arg is in the array of the second arg, | 236 // checks to see if the first arg is in the array of the second arg, |
197 // the size of which is specified with the third arg. If the second | 237 // the size of which is specified with the third arg. If the second |
198 // arg is NULL, then it is obvious that it ain't there. | 238 // arg is NULL, then it is obvious that it is not there. |
199 int is_in(int a, int *b, int c){ | 239 int is_in(int a, int *b, int c){ |
200 int d = 0; | 240 int d = 0; |
201 if (b == NULL || c == 0) { // no array or no items in array | 241 if (b == NULL || c == 0) { // no array or no items in array |
202 return 0; | 242 return 0; |
203 } | 243 } |
204 while (d < c) { | 244 while (d < c) { |
205 if (a == b[d]) | 245 if (a == b[d]) return 1; |
206 return 1; | 246 d++; |
207 d++; | 247 } |
208 } | 248 return 0; |
209 return 0; | 249 } |
210 } |