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