1*437bfbebSnyanmisaka /*
2*437bfbebSnyanmisaka * Copyright 2020 Rockchip Electronics Co. LTD
3*437bfbebSnyanmisaka *
4*437bfbebSnyanmisaka * Licensed under the Apache License, Version 2.0 (the "License");
5*437bfbebSnyanmisaka * you may not use this file except in compliance with the License.
6*437bfbebSnyanmisaka * You may obtain a copy of the License at
7*437bfbebSnyanmisaka *
8*437bfbebSnyanmisaka * http://www.apache.org/licenses/LICENSE-2.0
9*437bfbebSnyanmisaka *
10*437bfbebSnyanmisaka * Unless required by applicable law or agreed to in writing, software
11*437bfbebSnyanmisaka * distributed under the License is distributed on an "AS IS" BASIS,
12*437bfbebSnyanmisaka * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*437bfbebSnyanmisaka * See the License for the specific language governing permissions and
14*437bfbebSnyanmisaka * limitations under the License.
15*437bfbebSnyanmisaka */
16*437bfbebSnyanmisaka
17*437bfbebSnyanmisaka #define MODULE_TAG "mpp_opt"
18*437bfbebSnyanmisaka
19*437bfbebSnyanmisaka #include "mpp_mem.h"
20*437bfbebSnyanmisaka #include "mpp_log.h"
21*437bfbebSnyanmisaka #include "mpp_trie.h"
22*437bfbebSnyanmisaka #include "mpp_common.h"
23*437bfbebSnyanmisaka
24*437bfbebSnyanmisaka #include "mpp_opt.h"
25*437bfbebSnyanmisaka
26*437bfbebSnyanmisaka typedef struct MppOptImpl_t {
27*437bfbebSnyanmisaka void *ctx;
28*437bfbebSnyanmisaka MppTrie trie;
29*437bfbebSnyanmisaka RK_S32 node_cnt;
30*437bfbebSnyanmisaka RK_S32 info_cnt;
31*437bfbebSnyanmisaka } MppOptImpl;
32*437bfbebSnyanmisaka
mpp_opt_init(MppOpt * opt)33*437bfbebSnyanmisaka MPP_RET mpp_opt_init(MppOpt *opt)
34*437bfbebSnyanmisaka {
35*437bfbebSnyanmisaka MppOptImpl *impl = mpp_calloc(MppOptImpl, 1);
36*437bfbebSnyanmisaka
37*437bfbebSnyanmisaka *opt = impl;
38*437bfbebSnyanmisaka
39*437bfbebSnyanmisaka return (impl) ? MPP_OK : MPP_NOK;
40*437bfbebSnyanmisaka }
41*437bfbebSnyanmisaka
mpp_opt_deinit(MppOpt opt)42*437bfbebSnyanmisaka MPP_RET mpp_opt_deinit(MppOpt opt)
43*437bfbebSnyanmisaka {
44*437bfbebSnyanmisaka MppOptImpl *impl = (MppOptImpl *)opt;
45*437bfbebSnyanmisaka
46*437bfbebSnyanmisaka if (NULL == impl)
47*437bfbebSnyanmisaka return MPP_NOK;
48*437bfbebSnyanmisaka
49*437bfbebSnyanmisaka if (impl->trie) {
50*437bfbebSnyanmisaka mpp_trie_deinit(impl->trie);
51*437bfbebSnyanmisaka impl->trie = NULL;
52*437bfbebSnyanmisaka }
53*437bfbebSnyanmisaka MPP_FREE(impl);
54*437bfbebSnyanmisaka
55*437bfbebSnyanmisaka return MPP_OK;
56*437bfbebSnyanmisaka }
57*437bfbebSnyanmisaka
mpp_opt_setup(MppOpt opt,void * ctx)58*437bfbebSnyanmisaka MPP_RET mpp_opt_setup(MppOpt opt, void *ctx)
59*437bfbebSnyanmisaka {
60*437bfbebSnyanmisaka MppOptImpl *impl = (MppOptImpl *)opt;
61*437bfbebSnyanmisaka
62*437bfbebSnyanmisaka if (NULL == impl)
63*437bfbebSnyanmisaka return MPP_NOK;
64*437bfbebSnyanmisaka
65*437bfbebSnyanmisaka mpp_trie_init(&impl->trie, "mpp_opt");
66*437bfbebSnyanmisaka if (impl->trie) {
67*437bfbebSnyanmisaka impl->ctx = ctx;
68*437bfbebSnyanmisaka return MPP_OK;
69*437bfbebSnyanmisaka }
70*437bfbebSnyanmisaka
71*437bfbebSnyanmisaka return MPP_NOK;
72*437bfbebSnyanmisaka }
73*437bfbebSnyanmisaka
mpp_opt_add(MppOpt opt,MppOptInfo * info)74*437bfbebSnyanmisaka MPP_RET mpp_opt_add(MppOpt opt, MppOptInfo *info)
75*437bfbebSnyanmisaka {
76*437bfbebSnyanmisaka MppOptImpl *impl = (MppOptImpl *)opt;
77*437bfbebSnyanmisaka
78*437bfbebSnyanmisaka if (NULL == impl || NULL == impl->trie)
79*437bfbebSnyanmisaka return MPP_NOK;
80*437bfbebSnyanmisaka
81*437bfbebSnyanmisaka if (NULL == info)
82*437bfbebSnyanmisaka return mpp_trie_add_info(impl->trie, NULL, NULL, 0);
83*437bfbebSnyanmisaka
84*437bfbebSnyanmisaka return mpp_trie_add_info(impl->trie, info->name, info, sizeof(*info));
85*437bfbebSnyanmisaka }
86*437bfbebSnyanmisaka
mpp_opt_parse(MppOpt opt,int argc,char ** argv)87*437bfbebSnyanmisaka MPP_RET mpp_opt_parse(MppOpt opt, int argc, char **argv)
88*437bfbebSnyanmisaka {
89*437bfbebSnyanmisaka MppOptImpl *impl = (MppOptImpl *)opt;
90*437bfbebSnyanmisaka MPP_RET ret = MPP_NOK;
91*437bfbebSnyanmisaka RK_S32 opt_idx = 0;
92*437bfbebSnyanmisaka
93*437bfbebSnyanmisaka if (NULL == impl || NULL == impl->trie || argc < 2 || NULL == argv)
94*437bfbebSnyanmisaka return ret;
95*437bfbebSnyanmisaka
96*437bfbebSnyanmisaka ret = MPP_OK;
97*437bfbebSnyanmisaka
98*437bfbebSnyanmisaka while (opt_idx <= argc) {
99*437bfbebSnyanmisaka RK_S32 opt_next = opt_idx + 1;
100*437bfbebSnyanmisaka char *opts = argv[opt_idx++];
101*437bfbebSnyanmisaka char *next = (opt_next >= argc) ? NULL : argv[opt_next];
102*437bfbebSnyanmisaka
103*437bfbebSnyanmisaka if (NULL == opts)
104*437bfbebSnyanmisaka break;
105*437bfbebSnyanmisaka
106*437bfbebSnyanmisaka if (opts[0] == '-' && opts[1] != '\0') {
107*437bfbebSnyanmisaka MppOptInfo *info = NULL;
108*437bfbebSnyanmisaka MppTrieInfo *node = mpp_trie_get_info(impl->trie, opts + 1);
109*437bfbebSnyanmisaka RK_S32 step = 0;
110*437bfbebSnyanmisaka
111*437bfbebSnyanmisaka if (NULL == node) {
112*437bfbebSnyanmisaka mpp_err("invalid option %s\n", opts + 1);
113*437bfbebSnyanmisaka continue;
114*437bfbebSnyanmisaka }
115*437bfbebSnyanmisaka
116*437bfbebSnyanmisaka info = mpp_trie_info_ctx(node);
117*437bfbebSnyanmisaka if (info->proc)
118*437bfbebSnyanmisaka step = info->proc(impl->ctx, next);
119*437bfbebSnyanmisaka
120*437bfbebSnyanmisaka /* option failure or help */
121*437bfbebSnyanmisaka if (step < 0) {
122*437bfbebSnyanmisaka ret = step;
123*437bfbebSnyanmisaka break;
124*437bfbebSnyanmisaka }
125*437bfbebSnyanmisaka
126*437bfbebSnyanmisaka opt_idx += step;
127*437bfbebSnyanmisaka }
128*437bfbebSnyanmisaka }
129*437bfbebSnyanmisaka
130*437bfbebSnyanmisaka return ret;
131*437bfbebSnyanmisaka }
132