1*437bfbebSnyanmisaka /* SPDX-License-Identifier: Apache-2.0 OR MIT */
2*437bfbebSnyanmisaka /*
3*437bfbebSnyanmisaka * Copyright (c) 2017 Rockchip Electronics Co., Ltd.
4*437bfbebSnyanmisaka */
5*437bfbebSnyanmisaka
6*437bfbebSnyanmisaka #include <stdio.h>
7*437bfbebSnyanmisaka #include <string.h>
8*437bfbebSnyanmisaka
9*437bfbebSnyanmisaka #include "mpp_parse_cfg.h"
10*437bfbebSnyanmisaka
11*437bfbebSnyanmisaka #include "mpp_log.h"
12*437bfbebSnyanmisaka
13*437bfbebSnyanmisaka #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
14*437bfbebSnyanmisaka
15*437bfbebSnyanmisaka enum CONFIG_TYPE {
16*437bfbebSnyanmisaka CONFIG_TYPE_OPTION,
17*437bfbebSnyanmisaka CONFIG_TYPE_EVENT,
18*437bfbebSnyanmisaka
19*437bfbebSnyanmisaka OPT_TYPE_INDEX_TYPE,
20*437bfbebSnyanmisaka OPT_TYPE_LOOP_NUM,
21*437bfbebSnyanmisaka
22*437bfbebSnyanmisaka IDX_TYPE_FRM_NUM,
23*437bfbebSnyanmisaka IDX_TYPE_MSEC,
24*437bfbebSnyanmisaka };
25*437bfbebSnyanmisaka
26*437bfbebSnyanmisaka struct options_table {
27*437bfbebSnyanmisaka int type;
28*437bfbebSnyanmisaka const char *type_str;
29*437bfbebSnyanmisaka };
30*437bfbebSnyanmisaka
31*437bfbebSnyanmisaka /* table for converting string to type */
32*437bfbebSnyanmisaka static struct options_table op_tbl[] = {
33*437bfbebSnyanmisaka {CONFIG_TYPE_OPTION, "[CONFIG]"},
34*437bfbebSnyanmisaka {CONFIG_TYPE_EVENT, "[EVENT]"},
35*437bfbebSnyanmisaka
36*437bfbebSnyanmisaka {OPT_TYPE_INDEX_TYPE, "index"},
37*437bfbebSnyanmisaka {OPT_TYPE_LOOP_NUM, "loop"},
38*437bfbebSnyanmisaka
39*437bfbebSnyanmisaka {IDX_TYPE_FRM_NUM, "frm"},
40*437bfbebSnyanmisaka {IDX_TYPE_MSEC, "msec"},
41*437bfbebSnyanmisaka };
42*437bfbebSnyanmisaka
43*437bfbebSnyanmisaka struct cfg_file {
44*437bfbebSnyanmisaka FILE *file;
45*437bfbebSnyanmisaka char cache[128];
46*437bfbebSnyanmisaka RK_S32 cache_on;
47*437bfbebSnyanmisaka };
48*437bfbebSnyanmisaka
49*437bfbebSnyanmisaka /* get rid of leading and following space from string */
string_trim(char * string)50*437bfbebSnyanmisaka static char *string_trim(char *string)
51*437bfbebSnyanmisaka {
52*437bfbebSnyanmisaka char *p = string;
53*437bfbebSnyanmisaka long len;
54*437bfbebSnyanmisaka
55*437bfbebSnyanmisaka if (string == NULL)
56*437bfbebSnyanmisaka return NULL;
57*437bfbebSnyanmisaka
58*437bfbebSnyanmisaka while (*p == ' ')
59*437bfbebSnyanmisaka p++;
60*437bfbebSnyanmisaka
61*437bfbebSnyanmisaka len = strlen(p);
62*437bfbebSnyanmisaka
63*437bfbebSnyanmisaka while (p[len - 1] == ' ')
64*437bfbebSnyanmisaka len--;
65*437bfbebSnyanmisaka p[len] = '\0';
66*437bfbebSnyanmisaka
67*437bfbebSnyanmisaka return p;
68*437bfbebSnyanmisaka }
69*437bfbebSnyanmisaka
read_cfg_line(struct cfg_file * cfg)70*437bfbebSnyanmisaka static char *read_cfg_line(struct cfg_file *cfg)
71*437bfbebSnyanmisaka {
72*437bfbebSnyanmisaka int ch;
73*437bfbebSnyanmisaka int i;
74*437bfbebSnyanmisaka
75*437bfbebSnyanmisaka while (!cfg->cache_on) {
76*437bfbebSnyanmisaka i = 0;
77*437bfbebSnyanmisaka
78*437bfbebSnyanmisaka while (1) {
79*437bfbebSnyanmisaka ch = fgetc(cfg->file);
80*437bfbebSnyanmisaka if (i == 0 && ch == EOF)
81*437bfbebSnyanmisaka return NULL;
82*437bfbebSnyanmisaka else if (ch == EOF || feof(cfg->file) || ch == '\n')
83*437bfbebSnyanmisaka break;
84*437bfbebSnyanmisaka
85*437bfbebSnyanmisaka cfg->cache[i++] = ch;
86*437bfbebSnyanmisaka }
87*437bfbebSnyanmisaka cfg->cache[i] = '\0';
88*437bfbebSnyanmisaka
89*437bfbebSnyanmisaka /* a note, ignore and get the next line */
90*437bfbebSnyanmisaka if (cfg->cache[0] != '#')
91*437bfbebSnyanmisaka break;
92*437bfbebSnyanmisaka }
93*437bfbebSnyanmisaka
94*437bfbebSnyanmisaka cfg->cache_on = 1;
95*437bfbebSnyanmisaka return string_trim(cfg->cache);
96*437bfbebSnyanmisaka }
97*437bfbebSnyanmisaka
invalid_cfg_cache(struct cfg_file * cfg)98*437bfbebSnyanmisaka static inline void invalid_cfg_cache(struct cfg_file *cfg)
99*437bfbebSnyanmisaka {
100*437bfbebSnyanmisaka cfg->cache_on = 0;
101*437bfbebSnyanmisaka }
102*437bfbebSnyanmisaka
get_opt_value(char * line)103*437bfbebSnyanmisaka static char *get_opt_value(char *line)
104*437bfbebSnyanmisaka {
105*437bfbebSnyanmisaka size_t i;
106*437bfbebSnyanmisaka
107*437bfbebSnyanmisaka for (i = 0; i < strlen(line); ++i) {
108*437bfbebSnyanmisaka if (line[i] == ':')
109*437bfbebSnyanmisaka return string_trim(&line[i + 1]);
110*437bfbebSnyanmisaka }
111*437bfbebSnyanmisaka
112*437bfbebSnyanmisaka return NULL;
113*437bfbebSnyanmisaka }
114*437bfbebSnyanmisaka
115*437bfbebSnyanmisaka /* convert string to index by look up map table */
lookup_opt_type(char * line)116*437bfbebSnyanmisaka static int lookup_opt_type(char *line)
117*437bfbebSnyanmisaka {
118*437bfbebSnyanmisaka size_t i;
119*437bfbebSnyanmisaka
120*437bfbebSnyanmisaka for (i = 0; i < ARRAY_SIZE(op_tbl); ++i) {
121*437bfbebSnyanmisaka if (!strncmp(op_tbl[i].type_str, line,
122*437bfbebSnyanmisaka strlen(op_tbl[i].type_str))) {
123*437bfbebSnyanmisaka mpp_log("option type %s find\n", op_tbl[i].type_str);
124*437bfbebSnyanmisaka return op_tbl[i].type;
125*437bfbebSnyanmisaka }
126*437bfbebSnyanmisaka }
127*437bfbebSnyanmisaka
128*437bfbebSnyanmisaka return -1;
129*437bfbebSnyanmisaka }
130*437bfbebSnyanmisaka
scan_event_line(struct cfg_file * cfg,struct rc_event * event)131*437bfbebSnyanmisaka static int scan_event_line(struct cfg_file *cfg, struct rc_event *event)
132*437bfbebSnyanmisaka {
133*437bfbebSnyanmisaka char *line = read_cfg_line(cfg);
134*437bfbebSnyanmisaka
135*437bfbebSnyanmisaka if (line != NULL && line[0] != '\n' && line[0] != '[') {
136*437bfbebSnyanmisaka sscanf(line, "%d\t%d\t%f",
137*437bfbebSnyanmisaka &event->idx, &event->bps, &event->fps);
138*437bfbebSnyanmisaka mpp_log("idx: %d, bps %u, fps: %f\n",
139*437bfbebSnyanmisaka event->idx, event->bps, event->fps);
140*437bfbebSnyanmisaka invalid_cfg_cache(cfg);
141*437bfbebSnyanmisaka } else {
142*437bfbebSnyanmisaka return -1;
143*437bfbebSnyanmisaka }
144*437bfbebSnyanmisaka
145*437bfbebSnyanmisaka return 0;
146*437bfbebSnyanmisaka }
147*437bfbebSnyanmisaka
parse_events(struct cfg_file * cfg,struct rc_test_config * ea)148*437bfbebSnyanmisaka static int parse_events(struct cfg_file *cfg, struct rc_test_config *ea)
149*437bfbebSnyanmisaka {
150*437bfbebSnyanmisaka int ret;
151*437bfbebSnyanmisaka int i;
152*437bfbebSnyanmisaka
153*437bfbebSnyanmisaka for (i = 0; i < 128; ++i) {
154*437bfbebSnyanmisaka ret = scan_event_line(cfg, &ea->event[i]);
155*437bfbebSnyanmisaka if (ret < 0) {
156*437bfbebSnyanmisaka ea->event_cnt = i;
157*437bfbebSnyanmisaka break;
158*437bfbebSnyanmisaka }
159*437bfbebSnyanmisaka }
160*437bfbebSnyanmisaka
161*437bfbebSnyanmisaka return 0;
162*437bfbebSnyanmisaka }
163*437bfbebSnyanmisaka
parse_options(struct cfg_file * cfg,struct rc_test_config * ea)164*437bfbebSnyanmisaka static int parse_options(struct cfg_file *cfg, struct rc_test_config *ea)
165*437bfbebSnyanmisaka {
166*437bfbebSnyanmisaka char *opt;
167*437bfbebSnyanmisaka int type;
168*437bfbebSnyanmisaka
169*437bfbebSnyanmisaka while (1) {
170*437bfbebSnyanmisaka opt = read_cfg_line(cfg);
171*437bfbebSnyanmisaka
172*437bfbebSnyanmisaka if (opt && opt[0] != '\n' && opt[0] != '[') {
173*437bfbebSnyanmisaka type = lookup_opt_type(opt);
174*437bfbebSnyanmisaka
175*437bfbebSnyanmisaka switch (type) {
176*437bfbebSnyanmisaka case OPT_TYPE_INDEX_TYPE:
177*437bfbebSnyanmisaka ea->idx_type = lookup_opt_type(get_opt_value(opt));
178*437bfbebSnyanmisaka break;
179*437bfbebSnyanmisaka case OPT_TYPE_LOOP_NUM:
180*437bfbebSnyanmisaka sscanf(get_opt_value(opt), "%d", &ea->loop);
181*437bfbebSnyanmisaka mpp_log("loop num: %d\n", ea->loop);
182*437bfbebSnyanmisaka break;
183*437bfbebSnyanmisaka default:
184*437bfbebSnyanmisaka break;
185*437bfbebSnyanmisaka }
186*437bfbebSnyanmisaka
187*437bfbebSnyanmisaka invalid_cfg_cache(cfg);
188*437bfbebSnyanmisaka } else {
189*437bfbebSnyanmisaka break;
190*437bfbebSnyanmisaka }
191*437bfbebSnyanmisaka }
192*437bfbebSnyanmisaka return 0;
193*437bfbebSnyanmisaka }
194*437bfbebSnyanmisaka
mpp_parse_config(char * cfg_url,struct rc_test_config * ea)195*437bfbebSnyanmisaka int mpp_parse_config(char *cfg_url, struct rc_test_config *ea)
196*437bfbebSnyanmisaka {
197*437bfbebSnyanmisaka struct cfg_file cfg;
198*437bfbebSnyanmisaka
199*437bfbebSnyanmisaka if (cfg_url == NULL || strlen(cfg_url) == 0) {
200*437bfbebSnyanmisaka mpp_err("invalid input config url\n");
201*437bfbebSnyanmisaka return -1;
202*437bfbebSnyanmisaka }
203*437bfbebSnyanmisaka
204*437bfbebSnyanmisaka cfg.file = fopen(cfg_url, "rb");
205*437bfbebSnyanmisaka if (cfg.file == NULL) {
206*437bfbebSnyanmisaka mpp_err("fopen %s failed\n", cfg_url);
207*437bfbebSnyanmisaka return -1;
208*437bfbebSnyanmisaka }
209*437bfbebSnyanmisaka cfg.cache_on = 0;
210*437bfbebSnyanmisaka
211*437bfbebSnyanmisaka while (1) {
212*437bfbebSnyanmisaka char *line = read_cfg_line(&cfg);
213*437bfbebSnyanmisaka
214*437bfbebSnyanmisaka if (!line)
215*437bfbebSnyanmisaka break;
216*437bfbebSnyanmisaka
217*437bfbebSnyanmisaka invalid_cfg_cache(&cfg);
218*437bfbebSnyanmisaka if (line[0] == '[') {
219*437bfbebSnyanmisaka int type = lookup_opt_type(line);
220*437bfbebSnyanmisaka
221*437bfbebSnyanmisaka switch (type) {
222*437bfbebSnyanmisaka case CONFIG_TYPE_EVENT:
223*437bfbebSnyanmisaka parse_events(&cfg, ea);
224*437bfbebSnyanmisaka break;
225*437bfbebSnyanmisaka case CONFIG_TYPE_OPTION:
226*437bfbebSnyanmisaka parse_options(&cfg, ea);
227*437bfbebSnyanmisaka break;
228*437bfbebSnyanmisaka default:
229*437bfbebSnyanmisaka mpp_err("invalid config type find\n");
230*437bfbebSnyanmisaka fclose(cfg.file);
231*437bfbebSnyanmisaka return -1;
232*437bfbebSnyanmisaka }
233*437bfbebSnyanmisaka }
234*437bfbebSnyanmisaka }
235*437bfbebSnyanmisaka
236*437bfbebSnyanmisaka fclose(cfg.file);
237*437bfbebSnyanmisaka
238*437bfbebSnyanmisaka return 0;
239*437bfbebSnyanmisaka }
240*437bfbebSnyanmisaka
241*437bfbebSnyanmisaka #ifdef PARSE_CONFIG_TEST
main(int argc,char ** argv)242*437bfbebSnyanmisaka int main(int argc, char **argv)
243*437bfbebSnyanmisaka {
244*437bfbebSnyanmisaka struct rc_test_config event_array;
245*437bfbebSnyanmisaka
246*437bfbebSnyanmisaka if (argc < 2) {
247*437bfbebSnyanmisaka mpp_err("invalid input argument\n");
248*437bfbebSnyanmisaka return -1;
249*437bfbebSnyanmisaka }
250*437bfbebSnyanmisaka
251*437bfbebSnyanmisaka mpp_parse_config(argv[1], &event_array);
252*437bfbebSnyanmisaka
253*437bfbebSnyanmisaka return 0;
254*437bfbebSnyanmisaka }
255*437bfbebSnyanmisaka #endif
256