xref: /rockchip-linux_mpp/utils/mpp_opt.c (revision 437bfbeb9567cca9cd9080e3f6954aa9d6a94f18)
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)58 MPP_RET mpp_opt_setup(MppOpt opt, void *ctx)
59 {
60     MppOptImpl *impl = (MppOptImpl *)opt;
61 
62     if (NULL == impl)
63         return MPP_NOK;
64 
65     mpp_trie_init(&impl->trie, "mpp_opt");
66     if (impl->trie) {
67         impl->ctx = ctx;
68         return MPP_OK;
69     }
70 
71     return MPP_NOK;
72 }
73 
mpp_opt_add(MppOpt opt,MppOptInfo * info)74 MPP_RET mpp_opt_add(MppOpt opt, MppOptInfo *info)
75 {
76     MppOptImpl *impl = (MppOptImpl *)opt;
77 
78     if (NULL == impl || NULL == impl->trie)
79         return MPP_NOK;
80 
81     if (NULL == info)
82         return mpp_trie_add_info(impl->trie, NULL, NULL, 0);
83 
84     return mpp_trie_add_info(impl->trie, info->name, info, sizeof(*info));
85 }
86 
mpp_opt_parse(MppOpt opt,int argc,char ** argv)87 MPP_RET mpp_opt_parse(MppOpt opt, int argc, char **argv)
88 {
89     MppOptImpl *impl = (MppOptImpl *)opt;
90     MPP_RET ret = MPP_NOK;
91     RK_S32 opt_idx = 0;
92 
93     if (NULL == impl || NULL == impl->trie || argc < 2 || NULL == argv)
94         return ret;
95 
96     ret = MPP_OK;
97 
98     while (opt_idx <= argc) {
99         RK_S32 opt_next = opt_idx + 1;
100         char *opts = argv[opt_idx++];
101         char *next = (opt_next >= argc) ? NULL : argv[opt_next];
102 
103         if (NULL == opts)
104             break;
105 
106         if (opts[0] == '-' && opts[1] != '\0') {
107             MppOptInfo *info = NULL;
108             MppTrieInfo *node = mpp_trie_get_info(impl->trie, opts + 1);
109             RK_S32 step = 0;
110 
111             if (NULL == node) {
112                 mpp_err("invalid option %s\n", opts + 1);
113                 continue;
114             }
115 
116             info = mpp_trie_info_ctx(node);
117             if (info->proc)
118                 step = info->proc(impl->ctx, next);
119 
120             /* option failure or help */
121             if (step < 0) {
122                 ret = step;
123                 break;
124             }
125 
126             opt_idx += step;
127         }
128     }
129 
130     return ret;
131 }
132