xref: /aosp_15_r20/external/f2fs-tools/tools/f2fs_io_parse.c (revision 59bfda1f02d633cd6b8b69f31eee485d40f6eef6)
1*59bfda1fSAndroid Build Coastguard Worker /*
2*59bfda1fSAndroid Build Coastguard Worker  * f2fs IO tracer
3*59bfda1fSAndroid Build Coastguard Worker  *
4*59bfda1fSAndroid Build Coastguard Worker  * Copyright (c) 2014 Motorola Mobility
5*59bfda1fSAndroid Build Coastguard Worker  * Copyright (c) 2014 Jaegeuk Kim <[email protected]>
6*59bfda1fSAndroid Build Coastguard Worker  *
7*59bfda1fSAndroid Build Coastguard Worker  * This program is free software; you can redistribute it and/or modify
8*59bfda1fSAndroid Build Coastguard Worker  * it under the terms of the GNU General Public License version 2 as
9*59bfda1fSAndroid Build Coastguard Worker  * published by the Free Software Foundation.
10*59bfda1fSAndroid Build Coastguard Worker  */
11*59bfda1fSAndroid Build Coastguard Worker #include <stdio.h>
12*59bfda1fSAndroid Build Coastguard Worker #include <stdlib.h>
13*59bfda1fSAndroid Build Coastguard Worker #include <unistd.h>
14*59bfda1fSAndroid Build Coastguard Worker #include <string.h>
15*59bfda1fSAndroid Build Coastguard Worker #include <sys/queue.h>
16*59bfda1fSAndroid Build Coastguard Worker #include <assert.h>
17*59bfda1fSAndroid Build Coastguard Worker #include <locale.h>
18*59bfda1fSAndroid Build Coastguard Worker 
19*59bfda1fSAndroid Build Coastguard Worker #define P_NAMELEN	16
20*59bfda1fSAndroid Build Coastguard Worker 
21*59bfda1fSAndroid Build Coastguard Worker /* For global trace methods */
22*59bfda1fSAndroid Build Coastguard Worker enum show_type {
23*59bfda1fSAndroid Build Coastguard Worker 	SHOW_PID,
24*59bfda1fSAndroid Build Coastguard Worker 	SHOW_FTYPE,
25*59bfda1fSAndroid Build Coastguard Worker 	SHOW_ALL,
26*59bfda1fSAndroid Build Coastguard Worker };
27*59bfda1fSAndroid Build Coastguard Worker 
28*59bfda1fSAndroid Build Coastguard Worker enum trace_types {
29*59bfda1fSAndroid Build Coastguard Worker 	TP_PID,
30*59bfda1fSAndroid Build Coastguard Worker 	TP_IOS,
31*59bfda1fSAndroid Build Coastguard Worker 	TP_MAX,
32*59bfda1fSAndroid Build Coastguard Worker };
33*59bfda1fSAndroid Build Coastguard Worker 
34*59bfda1fSAndroid Build Coastguard Worker struct tps {
35*59bfda1fSAndroid Build Coastguard Worker 	enum trace_types type;
36*59bfda1fSAndroid Build Coastguard Worker 	const char *name;
37*59bfda1fSAndroid Build Coastguard Worker };
38*59bfda1fSAndroid Build Coastguard Worker 
39*59bfda1fSAndroid Build Coastguard Worker struct tps trace_points[] = {
40*59bfda1fSAndroid Build Coastguard Worker 	{ TP_PID,	"f2fs_trace_pid" },
41*59bfda1fSAndroid Build Coastguard Worker 	{ TP_IOS,	"f2fs_trace_ios" },
42*59bfda1fSAndroid Build Coastguard Worker };
43*59bfda1fSAndroid Build Coastguard Worker 
44*59bfda1fSAndroid Build Coastguard Worker /* For f2fs_trace_pid and f2fs_trace_ios */
45*59bfda1fSAndroid Build Coastguard Worker enum rw_type {
46*59bfda1fSAndroid Build Coastguard Worker 	READ,
47*59bfda1fSAndroid Build Coastguard Worker 	WRITE,
48*59bfda1fSAndroid Build Coastguard Worker 	MAX_RW,
49*59bfda1fSAndroid Build Coastguard Worker };
50*59bfda1fSAndroid Build Coastguard Worker 
51*59bfda1fSAndroid Build Coastguard Worker enum file_type {
52*59bfda1fSAndroid Build Coastguard Worker 	__NORMAL_FILE,
53*59bfda1fSAndroid Build Coastguard Worker 	__DIR_FILE,
54*59bfda1fSAndroid Build Coastguard Worker 	__NODE_FILE,
55*59bfda1fSAndroid Build Coastguard Worker 	__META_FILE,
56*59bfda1fSAndroid Build Coastguard Worker 	__ATOMIC_FILE,
57*59bfda1fSAndroid Build Coastguard Worker 	__VOLATILE_FILE,
58*59bfda1fSAndroid Build Coastguard Worker 	__MISC_FILE,
59*59bfda1fSAndroid Build Coastguard Worker 	__NR_FILES,
60*59bfda1fSAndroid Build Coastguard Worker };
61*59bfda1fSAndroid Build Coastguard Worker 
62*59bfda1fSAndroid Build Coastguard Worker char *file_type_string[] = {
63*59bfda1fSAndroid Build Coastguard Worker 	"User      ",
64*59bfda1fSAndroid Build Coastguard Worker 	"Dir       ",
65*59bfda1fSAndroid Build Coastguard Worker 	"Node      ",
66*59bfda1fSAndroid Build Coastguard Worker 	"Meta      ",
67*59bfda1fSAndroid Build Coastguard Worker 	"Atomic    ",
68*59bfda1fSAndroid Build Coastguard Worker 	"Voltile   ",
69*59bfda1fSAndroid Build Coastguard Worker 	"Misc      ",
70*59bfda1fSAndroid Build Coastguard Worker };
71*59bfda1fSAndroid Build Coastguard Worker 
72*59bfda1fSAndroid Build Coastguard Worker struct pid_ent {
73*59bfda1fSAndroid Build Coastguard Worker 	int pid;
74*59bfda1fSAndroid Build Coastguard Worker 	char name[P_NAMELEN];
75*59bfda1fSAndroid Build Coastguard Worker 	unsigned long long io[__NR_FILES][MAX_RW];
76*59bfda1fSAndroid Build Coastguard Worker 	unsigned long long total_io[MAX_RW];
77*59bfda1fSAndroid Build Coastguard Worker 	LIST_ENTRY(pid_ent) ptr;
78*59bfda1fSAndroid Build Coastguard Worker };
79*59bfda1fSAndroid Build Coastguard Worker 
80*59bfda1fSAndroid Build Coastguard Worker /* global variables */
81*59bfda1fSAndroid Build Coastguard Worker int major = 0, minor = 0;
82*59bfda1fSAndroid Build Coastguard Worker int show_option = SHOW_ALL;
83*59bfda1fSAndroid Build Coastguard Worker unsigned long long total_io[__NR_FILES][MAX_RW];
84*59bfda1fSAndroid Build Coastguard Worker 
85*59bfda1fSAndroid Build Coastguard Worker LIST_HEAD(plist, pid_ent) pid_info;
86*59bfda1fSAndroid Build Coastguard Worker 
87*59bfda1fSAndroid Build Coastguard Worker /* Functions */
atoh(char * str)88*59bfda1fSAndroid Build Coastguard Worker static inline int atoh(char *str)
89*59bfda1fSAndroid Build Coastguard Worker {
90*59bfda1fSAndroid Build Coastguard Worker 	int val;
91*59bfda1fSAndroid Build Coastguard Worker 	sscanf(str, "%x", &val);
92*59bfda1fSAndroid Build Coastguard Worker 	return val;
93*59bfda1fSAndroid Build Coastguard Worker }
94*59bfda1fSAndroid Build Coastguard Worker 
do_init()95*59bfda1fSAndroid Build Coastguard Worker static void do_init()
96*59bfda1fSAndroid Build Coastguard Worker {
97*59bfda1fSAndroid Build Coastguard Worker 	struct pid_ent *misc;
98*59bfda1fSAndroid Build Coastguard Worker 
99*59bfda1fSAndroid Build Coastguard Worker 	misc = calloc(1, sizeof(struct pid_ent));
100*59bfda1fSAndroid Build Coastguard Worker 	assert(misc);
101*59bfda1fSAndroid Build Coastguard Worker 
102*59bfda1fSAndroid Build Coastguard Worker 	LIST_INIT(&pid_info);
103*59bfda1fSAndroid Build Coastguard Worker 	LIST_INSERT_HEAD(&pid_info, misc, ptr);
104*59bfda1fSAndroid Build Coastguard Worker }
105*59bfda1fSAndroid Build Coastguard Worker 
show_usage()106*59bfda1fSAndroid Build Coastguard Worker void show_usage()
107*59bfda1fSAndroid Build Coastguard Worker {
108*59bfda1fSAndroid Build Coastguard Worker 	printf("\nUsage: parse.f2fs [options] log_file\n");
109*59bfda1fSAndroid Build Coastguard Worker 	printf("[options]:\n");
110*59bfda1fSAndroid Build Coastguard Worker 	printf("  -a RW sorted by pid & file types\n");
111*59bfda1fSAndroid Build Coastguard Worker 	printf("  -f RW sorted by file types\n");
112*59bfda1fSAndroid Build Coastguard Worker 	printf("  -p RW sorted by pid\n");
113*59bfda1fSAndroid Build Coastguard Worker 	printf("  -m major number\n");
114*59bfda1fSAndroid Build Coastguard Worker 	printf("  -n minor number\n");
115*59bfda1fSAndroid Build Coastguard Worker 	exit(1);
116*59bfda1fSAndroid Build Coastguard Worker }
117*59bfda1fSAndroid Build Coastguard Worker 
parse_options(int argc,char * argv[])118*59bfda1fSAndroid Build Coastguard Worker static int parse_options(int argc, char *argv[])
119*59bfda1fSAndroid Build Coastguard Worker {
120*59bfda1fSAndroid Build Coastguard Worker 	const char *option_string = "fm:n:p";
121*59bfda1fSAndroid Build Coastguard Worker 	int option = 0;
122*59bfda1fSAndroid Build Coastguard Worker 
123*59bfda1fSAndroid Build Coastguard Worker 	while ((option = getopt(argc, argv, option_string)) != EOF) {
124*59bfda1fSAndroid Build Coastguard Worker 		switch (option) {
125*59bfda1fSAndroid Build Coastguard Worker 		case 'f':
126*59bfda1fSAndroid Build Coastguard Worker 			show_option = SHOW_FTYPE;
127*59bfda1fSAndroid Build Coastguard Worker 			break;
128*59bfda1fSAndroid Build Coastguard Worker 		case 'm':
129*59bfda1fSAndroid Build Coastguard Worker 			major = atoh(optarg);
130*59bfda1fSAndroid Build Coastguard Worker 			break;
131*59bfda1fSAndroid Build Coastguard Worker 		case 'n':
132*59bfda1fSAndroid Build Coastguard Worker 			minor = atoh(optarg);
133*59bfda1fSAndroid Build Coastguard Worker 			break;
134*59bfda1fSAndroid Build Coastguard Worker 		case 'p':
135*59bfda1fSAndroid Build Coastguard Worker 			show_option = SHOW_PID;
136*59bfda1fSAndroid Build Coastguard Worker 			break;
137*59bfda1fSAndroid Build Coastguard Worker 		default:
138*59bfda1fSAndroid Build Coastguard Worker 			printf("\tError: Unknown option %c\n", option);
139*59bfda1fSAndroid Build Coastguard Worker 			show_usage();
140*59bfda1fSAndroid Build Coastguard Worker 			break;
141*59bfda1fSAndroid Build Coastguard Worker 		}
142*59bfda1fSAndroid Build Coastguard Worker 	}
143*59bfda1fSAndroid Build Coastguard Worker 	if ((optind + 1) != argc) {
144*59bfda1fSAndroid Build Coastguard Worker 		printf("\tError: Log file is not specified.\n");
145*59bfda1fSAndroid Build Coastguard Worker 		show_usage();
146*59bfda1fSAndroid Build Coastguard Worker 	}
147*59bfda1fSAndroid Build Coastguard Worker 	return optind;
148*59bfda1fSAndroid Build Coastguard Worker }
149*59bfda1fSAndroid Build Coastguard Worker 
get_pid_entry(int pid)150*59bfda1fSAndroid Build Coastguard Worker struct pid_ent *get_pid_entry(int pid)
151*59bfda1fSAndroid Build Coastguard Worker {
152*59bfda1fSAndroid Build Coastguard Worker 	struct pid_ent *entry;
153*59bfda1fSAndroid Build Coastguard Worker 
154*59bfda1fSAndroid Build Coastguard Worker 	LIST_FOREACH(entry, &pid_info, ptr) {
155*59bfda1fSAndroid Build Coastguard Worker 		if (entry->pid == pid)
156*59bfda1fSAndroid Build Coastguard Worker 			return entry;
157*59bfda1fSAndroid Build Coastguard Worker 	}
158*59bfda1fSAndroid Build Coastguard Worker 	return LIST_FIRST(&pid_info);
159*59bfda1fSAndroid Build Coastguard Worker }
160*59bfda1fSAndroid Build Coastguard Worker 
handle_tp_pid(char * ptr)161*59bfda1fSAndroid Build Coastguard Worker static void handle_tp_pid(char *ptr)
162*59bfda1fSAndroid Build Coastguard Worker {
163*59bfda1fSAndroid Build Coastguard Worker 	struct pid_ent *pent;
164*59bfda1fSAndroid Build Coastguard Worker 
165*59bfda1fSAndroid Build Coastguard Worker 	pent = calloc(1, sizeof(struct pid_ent));
166*59bfda1fSAndroid Build Coastguard Worker 	assert(pent);
167*59bfda1fSAndroid Build Coastguard Worker 
168*59bfda1fSAndroid Build Coastguard Worker 	ptr = strtok(NULL, " ");
169*59bfda1fSAndroid Build Coastguard Worker 	pent->pid = atoh(ptr);
170*59bfda1fSAndroid Build Coastguard Worker 
171*59bfda1fSAndroid Build Coastguard Worker 	ptr = strtok(NULL, " ");
172*59bfda1fSAndroid Build Coastguard Worker 	strcpy(pent->name, ptr);
173*59bfda1fSAndroid Build Coastguard Worker 
174*59bfda1fSAndroid Build Coastguard Worker 	LIST_INSERT_HEAD(&pid_info, pent, ptr);
175*59bfda1fSAndroid Build Coastguard Worker }
176*59bfda1fSAndroid Build Coastguard Worker 
handle_tp_ios(char * ptr)177*59bfda1fSAndroid Build Coastguard Worker static void handle_tp_ios(char *ptr)
178*59bfda1fSAndroid Build Coastguard Worker {
179*59bfda1fSAndroid Build Coastguard Worker 	int pid, type, rw, len;
180*59bfda1fSAndroid Build Coastguard Worker 	struct pid_ent *p;
181*59bfda1fSAndroid Build Coastguard Worker 
182*59bfda1fSAndroid Build Coastguard Worker 	ptr = strtok(NULL, " ");
183*59bfda1fSAndroid Build Coastguard Worker 	pid = atoh(ptr);
184*59bfda1fSAndroid Build Coastguard Worker 
185*59bfda1fSAndroid Build Coastguard Worker 	ptr = strtok(NULL, " ");
186*59bfda1fSAndroid Build Coastguard Worker 	ptr = strtok(NULL, " ");
187*59bfda1fSAndroid Build Coastguard Worker 	type = atoh(ptr);
188*59bfda1fSAndroid Build Coastguard Worker 
189*59bfda1fSAndroid Build Coastguard Worker 	ptr = strtok(NULL, " ");
190*59bfda1fSAndroid Build Coastguard Worker 	rw = atoh(ptr);
191*59bfda1fSAndroid Build Coastguard Worker 
192*59bfda1fSAndroid Build Coastguard Worker 	ptr = strtok(NULL, " ");
193*59bfda1fSAndroid Build Coastguard Worker 	/* int op_flags = atoh(ptr) */
194*59bfda1fSAndroid Build Coastguard Worker 	ptr = strtok(NULL, " ");
195*59bfda1fSAndroid Build Coastguard Worker 	/* unsigned long long blkaddr = atoh(ptr); */
196*59bfda1fSAndroid Build Coastguard Worker 
197*59bfda1fSAndroid Build Coastguard Worker 	ptr = strtok(NULL, " ");
198*59bfda1fSAndroid Build Coastguard Worker 	len = atoh(ptr);
199*59bfda1fSAndroid Build Coastguard Worker 
200*59bfda1fSAndroid Build Coastguard Worker 	/* update per-pid stat */
201*59bfda1fSAndroid Build Coastguard Worker 	p = get_pid_entry(pid);
202*59bfda1fSAndroid Build Coastguard Worker 	p->io[type][rw & 0x1] += len;
203*59bfda1fSAndroid Build Coastguard Worker 	p->total_io[rw & 0x1] += len;
204*59bfda1fSAndroid Build Coastguard Worker 
205*59bfda1fSAndroid Build Coastguard Worker 	/* update total stat */
206*59bfda1fSAndroid Build Coastguard Worker 	total_io[type][rw & 0x1] += len;
207*59bfda1fSAndroid Build Coastguard Worker }
208*59bfda1fSAndroid Build Coastguard Worker 
do_parse(FILE * file)209*59bfda1fSAndroid Build Coastguard Worker static void do_parse(FILE *file)
210*59bfda1fSAndroid Build Coastguard Worker {
211*59bfda1fSAndroid Build Coastguard Worker 	char line[300];
212*59bfda1fSAndroid Build Coastguard Worker 	char *ptr;
213*59bfda1fSAndroid Build Coastguard Worker 	int i;
214*59bfda1fSAndroid Build Coastguard Worker 
215*59bfda1fSAndroid Build Coastguard Worker 	while (fgets(line, sizeof(line), file) != NULL) {
216*59bfda1fSAndroid Build Coastguard Worker 		ptr = strtok(line, ":");
217*59bfda1fSAndroid Build Coastguard Worker 
218*59bfda1fSAndroid Build Coastguard Worker 		ptr = strtok(NULL, " :");
219*59bfda1fSAndroid Build Coastguard Worker 
220*59bfda1fSAndroid Build Coastguard Worker 		for (i = 0; i < TP_MAX; i++) {
221*59bfda1fSAndroid Build Coastguard Worker 			if (!strcmp(ptr, trace_points[i].name))
222*59bfda1fSAndroid Build Coastguard Worker 				break;
223*59bfda1fSAndroid Build Coastguard Worker 		}
224*59bfda1fSAndroid Build Coastguard Worker 		if (i == TP_MAX)
225*59bfda1fSAndroid Build Coastguard Worker 			continue;
226*59bfda1fSAndroid Build Coastguard Worker 		ptr = strtok(NULL, " :");
227*59bfda1fSAndroid Build Coastguard Worker 		if (major && major != atoh(ptr))
228*59bfda1fSAndroid Build Coastguard Worker 			continue;
229*59bfda1fSAndroid Build Coastguard Worker 		ptr = strtok(NULL, " :");
230*59bfda1fSAndroid Build Coastguard Worker 		if (minor && minor != atoh(ptr))
231*59bfda1fSAndroid Build Coastguard Worker 			continue;
232*59bfda1fSAndroid Build Coastguard Worker 
233*59bfda1fSAndroid Build Coastguard Worker 		switch (i) {
234*59bfda1fSAndroid Build Coastguard Worker 		case TP_PID:
235*59bfda1fSAndroid Build Coastguard Worker 			handle_tp_pid(ptr);
236*59bfda1fSAndroid Build Coastguard Worker 			break;
237*59bfda1fSAndroid Build Coastguard Worker 		case TP_IOS:
238*59bfda1fSAndroid Build Coastguard Worker 			handle_tp_ios(ptr);
239*59bfda1fSAndroid Build Coastguard Worker 			break;
240*59bfda1fSAndroid Build Coastguard Worker 		}
241*59bfda1fSAndroid Build Coastguard Worker 	}
242*59bfda1fSAndroid Build Coastguard Worker }
243*59bfda1fSAndroid Build Coastguard Worker 
__print_pid()244*59bfda1fSAndroid Build Coastguard Worker static void __print_pid()
245*59bfda1fSAndroid Build Coastguard Worker {
246*59bfda1fSAndroid Build Coastguard Worker 	struct pid_ent *entry;
247*59bfda1fSAndroid Build Coastguard Worker 	int i;
248*59bfda1fSAndroid Build Coastguard Worker 
249*59bfda1fSAndroid Build Coastguard Worker 	setlocale(LC_ALL, "");
250*59bfda1fSAndroid Build Coastguard Worker 	printf("%8s %16s %17s ||", "PID", "NAME", "R/W in 4KB");
251*59bfda1fSAndroid Build Coastguard Worker 	for (i = 0; i < __NR_FILES; i++)
252*59bfda1fSAndroid Build Coastguard Worker 		printf(" %17s |", file_type_string[i]);
253*59bfda1fSAndroid Build Coastguard Worker 	printf("\n");
254*59bfda1fSAndroid Build Coastguard Worker 
255*59bfda1fSAndroid Build Coastguard Worker 	LIST_FOREACH(entry, &pid_info, ptr) {
256*59bfda1fSAndroid Build Coastguard Worker 		printf("%8x %16s %'8lld %'8lld ||",
257*59bfda1fSAndroid Build Coastguard Worker 				entry->pid, entry->name,
258*59bfda1fSAndroid Build Coastguard Worker 				entry->total_io[READ],
259*59bfda1fSAndroid Build Coastguard Worker 				entry->total_io[WRITE]);
260*59bfda1fSAndroid Build Coastguard Worker 		for (i = 0; i < __NR_FILES; i++)
261*59bfda1fSAndroid Build Coastguard Worker 			printf(" %'8lld %'8lld |",
262*59bfda1fSAndroid Build Coastguard Worker 				entry->io[i][READ],
263*59bfda1fSAndroid Build Coastguard Worker 				entry->io[i][WRITE]);
264*59bfda1fSAndroid Build Coastguard Worker 		printf("\n");
265*59bfda1fSAndroid Build Coastguard Worker 	}
266*59bfda1fSAndroid Build Coastguard Worker }
267*59bfda1fSAndroid Build Coastguard Worker 
__print_ftype()268*59bfda1fSAndroid Build Coastguard Worker static void __print_ftype()
269*59bfda1fSAndroid Build Coastguard Worker {
270*59bfda1fSAndroid Build Coastguard Worker 	int i;
271*59bfda1fSAndroid Build Coastguard Worker 
272*59bfda1fSAndroid Build Coastguard Worker 	setlocale(LC_ALL, "");
273*59bfda1fSAndroid Build Coastguard Worker 	printf("\n===== Data R/W in 4KB according to File types =====\n");
274*59bfda1fSAndroid Build Coastguard Worker 	for (i = 0; i < __NR_FILES; i++)
275*59bfda1fSAndroid Build Coastguard Worker 		printf(" %17s |", file_type_string[i]);
276*59bfda1fSAndroid Build Coastguard Worker 	printf("\n");
277*59bfda1fSAndroid Build Coastguard Worker 
278*59bfda1fSAndroid Build Coastguard Worker 	for (i = 0; i < __NR_FILES; i++)
279*59bfda1fSAndroid Build Coastguard Worker 		printf(" %'8lld %'8lld |",
280*59bfda1fSAndroid Build Coastguard Worker 				total_io[i][READ],
281*59bfda1fSAndroid Build Coastguard Worker 				total_io[i][WRITE]);
282*59bfda1fSAndroid Build Coastguard Worker 	printf("\n");
283*59bfda1fSAndroid Build Coastguard Worker }
284*59bfda1fSAndroid Build Coastguard Worker 
do_print()285*59bfda1fSAndroid Build Coastguard Worker static void do_print()
286*59bfda1fSAndroid Build Coastguard Worker {
287*59bfda1fSAndroid Build Coastguard Worker 	switch (show_option) {
288*59bfda1fSAndroid Build Coastguard Worker 	case SHOW_PID:
289*59bfda1fSAndroid Build Coastguard Worker 		__print_pid();
290*59bfda1fSAndroid Build Coastguard Worker 		break;
291*59bfda1fSAndroid Build Coastguard Worker 	case SHOW_FTYPE:
292*59bfda1fSAndroid Build Coastguard Worker 		__print_ftype();
293*59bfda1fSAndroid Build Coastguard Worker 		break;
294*59bfda1fSAndroid Build Coastguard Worker 	case SHOW_ALL:
295*59bfda1fSAndroid Build Coastguard Worker 		__print_pid();
296*59bfda1fSAndroid Build Coastguard Worker 		printf("\n\n");
297*59bfda1fSAndroid Build Coastguard Worker 		__print_ftype();
298*59bfda1fSAndroid Build Coastguard Worker 		break;
299*59bfda1fSAndroid Build Coastguard Worker 	}
300*59bfda1fSAndroid Build Coastguard Worker }
301*59bfda1fSAndroid Build Coastguard Worker 
main(int argc,char ** argv)302*59bfda1fSAndroid Build Coastguard Worker int main(int argc, char **argv)
303*59bfda1fSAndroid Build Coastguard Worker {
304*59bfda1fSAndroid Build Coastguard Worker 	FILE *file;
305*59bfda1fSAndroid Build Coastguard Worker 	int opt;
306*59bfda1fSAndroid Build Coastguard Worker 
307*59bfda1fSAndroid Build Coastguard Worker 	opt = parse_options(argc, argv);
308*59bfda1fSAndroid Build Coastguard Worker 
309*59bfda1fSAndroid Build Coastguard Worker 	file = fopen(argv[opt], "r");
310*59bfda1fSAndroid Build Coastguard Worker 	if (!file) {
311*59bfda1fSAndroid Build Coastguard Worker 		perror("open log file");
312*59bfda1fSAndroid Build Coastguard Worker 		exit(EXIT_FAILURE);
313*59bfda1fSAndroid Build Coastguard Worker 	}
314*59bfda1fSAndroid Build Coastguard Worker 
315*59bfda1fSAndroid Build Coastguard Worker 	do_init();
316*59bfda1fSAndroid Build Coastguard Worker 
317*59bfda1fSAndroid Build Coastguard Worker 	do_parse(file);
318*59bfda1fSAndroid Build Coastguard Worker 
319*59bfda1fSAndroid Build Coastguard Worker 	do_print();
320*59bfda1fSAndroid Build Coastguard Worker 
321*59bfda1fSAndroid Build Coastguard Worker 	fclose(file);
322*59bfda1fSAndroid Build Coastguard Worker 	return 0;
323*59bfda1fSAndroid Build Coastguard Worker }
324