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