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