xref: /OK3568_Linux_fs/external/mpp/utils/mpp_opt.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /*
2  * Copyright 2020 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 #define MODULE_TAG "mpp_opt"
18 
19 #include "mpp_mem.h"
20 #include "mpp_log.h"
21 #include "mpp_trie.h"
22 #include "mpp_common.h"
23 
24 #include "mpp_opt.h"
25 
26 typedef struct MppOptImpl_t {
27     void        *ctx;
28     MppTrie     trie;
29     RK_S32      node_cnt;
30     RK_S32      info_cnt;
31 } MppOptImpl;
32 
mpp_opt_init(MppOpt * opt)33 MPP_RET mpp_opt_init(MppOpt *opt)
34 {
35     MppOptImpl *impl = mpp_calloc(MppOptImpl, 1);
36 
37     *opt = impl;
38 
39     return (impl) ? MPP_OK : MPP_NOK;
40 }
41 
mpp_opt_deinit(MppOpt opt)42 MPP_RET mpp_opt_deinit(MppOpt opt)
43 {
44     MppOptImpl *impl = (MppOptImpl *)opt;
45 
46     if (NULL == impl)
47         return MPP_NOK;
48 
49     if (impl->trie) {
50         mpp_trie_deinit(impl->trie);
51         impl->trie = NULL;
52     }
53     MPP_FREE(impl);
54 
55     return MPP_OK;
56 }
57 
mpp_opt_setup(MppOpt opt,void * ctx,RK_S32 node_cnt,RK_S32 opt_cnt)58 MPP_RET mpp_opt_setup(MppOpt opt, void *ctx, RK_S32 node_cnt, RK_S32 opt_cnt)
59 {
60     MppOptImpl *impl = (MppOptImpl *)opt;
61 
62     if (NULL == impl)
63         return MPP_NOK;
64 
65     mpp_trie_init(&impl->trie, node_cnt, opt_cnt);
66     if (impl->trie) {
67         impl->ctx = ctx;
68         impl->node_cnt = node_cnt;
69         impl->info_cnt = opt_cnt;
70         return MPP_OK;
71     }
72 
73     mpp_err_f("failed to setup node %d opt %d\n", node_cnt, opt_cnt);
74 
75     return MPP_NOK;
76 }
77 
mpp_opt_add(MppOpt opt,MppOptInfo * info)78 MPP_RET mpp_opt_add(MppOpt opt, MppOptInfo *info)
79 {
80     MppOptImpl *impl = (MppOptImpl *)opt;
81 
82     if (NULL == impl || NULL == impl->trie)
83         return MPP_NOK;
84 
85     if (NULL == info) {
86         RK_S32 node_cnt = mpp_trie_get_node_count(impl->trie);
87         RK_S32 info_cnt = mpp_trie_get_info_count(impl->trie);
88 
89         if (impl->node_cnt != node_cnt || impl->info_cnt != info_cnt)
90             mpp_log("setup:real node %d:%d info %d:%d\n",
91                     impl->node_cnt, node_cnt, impl->info_cnt, info_cnt);
92 
93         return MPP_OK;
94     }
95 
96     return mpp_trie_add_info(impl->trie, &info->name);
97 }
98 
mpp_opt_parse(MppOpt opt,int argc,char ** argv)99 MPP_RET mpp_opt_parse(MppOpt opt, int argc, char **argv)
100 {
101     MppOptImpl *impl = (MppOptImpl *)opt;
102     MPP_RET ret = MPP_NOK;
103     RK_S32 opt_idx = 0;
104 
105     if (NULL == impl || NULL == impl->trie || argc < 2 || NULL == argv)
106         return ret;
107 
108     ret = MPP_OK;
109 
110     while (opt_idx <= argc) {
111         RK_S32 opt_next = opt_idx + 1;
112         char *opts = argv[opt_idx++];
113         char *next = (opt_next >= argc) ? NULL : argv[opt_next];
114 
115         if (NULL == opts)
116             break;
117 
118         if (opts[0] == '-' && opts[1] != '\0') {
119             MppOptInfo *info = NULL;
120             const char **name = mpp_trie_get_info(impl->trie, opts + 1);
121             RK_S32 step = 0;
122 
123             if (NULL == name) {
124                 mpp_err("invalid option %s\n", opts + 1);
125                 continue;
126             }
127 
128             info = container_of(name, MppOptInfo, name);
129             if (info->proc)
130                 step = info->proc(impl->ctx, next);
131 
132             /* option failure or help */
133             if (step < 0) {
134                 ret = step;
135                 break;
136             }
137 
138             opt_idx += step;
139         }
140     }
141 
142     return ret;
143 }
144