mirror of
				https://github.com/nyanmisaka/mpp.git
				synced 2025-10-31 12:36:44 +08:00 
			
		
		
		
	 94ab4c1e5f
			
		
	
	94ab4c1e5f
	
	
	
		
			
			Change-Id: I9c4836d35366ff8ab2f16ac9c474b65471862bd2 Signed-off-by: Herman Chen <herman.chen@rock-chips.com>
		
			
				
	
	
		
			144 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			144 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  * Copyright 2020 Rockchip Electronics Co. LTD
 | |
|  *
 | |
|  * Licensed under the Apache License, Version 2.0 (the "License");
 | |
|  * you may not use this file except in compliance with the License.
 | |
|  * You may obtain a copy of the License at
 | |
|  *
 | |
|  *      http://www.apache.org/licenses/LICENSE-2.0
 | |
|  *
 | |
|  * Unless required by applicable law or agreed to in writing, software
 | |
|  * distributed under the License is distributed on an "AS IS" BASIS,
 | |
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | |
|  * See the License for the specific language governing permissions and
 | |
|  * limitations under the License.
 | |
|  */
 | |
| 
 | |
| #define MODULE_TAG "mpp_opt"
 | |
| 
 | |
| #include "mpp_mem.h"
 | |
| #include "mpp_log.h"
 | |
| #include "mpp_trie.h"
 | |
| #include "mpp_common.h"
 | |
| 
 | |
| #include "mpp_opt.h"
 | |
| 
 | |
| typedef struct MppOptImpl_t {
 | |
|     void        *ctx;
 | |
|     MppTrie     trie;
 | |
|     RK_S32      node_cnt;
 | |
|     RK_S32      info_cnt;
 | |
| } MppOptImpl;
 | |
| 
 | |
| MPP_RET mpp_opt_init(MppOpt *opt)
 | |
| {
 | |
|     MppOptImpl *impl = mpp_calloc(MppOptImpl, 1);
 | |
| 
 | |
|     *opt = impl;
 | |
| 
 | |
|     return (impl) ? MPP_OK : MPP_NOK;
 | |
| }
 | |
| 
 | |
| MPP_RET mpp_opt_deinit(MppOpt opt)
 | |
| {
 | |
|     MppOptImpl *impl = (MppOptImpl *)opt;
 | |
| 
 | |
|     if (NULL == impl)
 | |
|         return MPP_NOK;
 | |
| 
 | |
|     if (impl->trie) {
 | |
|         mpp_trie_deinit(impl->trie);
 | |
|         impl->trie = NULL;
 | |
|     }
 | |
|     MPP_FREE(impl);
 | |
| 
 | |
|     return MPP_OK;
 | |
| }
 | |
| 
 | |
| MPP_RET mpp_opt_setup(MppOpt opt, void *ctx, RK_S32 node_cnt, RK_S32 opt_cnt)
 | |
| {
 | |
|     MppOptImpl *impl = (MppOptImpl *)opt;
 | |
| 
 | |
|     if (NULL == impl)
 | |
|         return MPP_NOK;
 | |
| 
 | |
|     mpp_trie_init(&impl->trie, node_cnt, opt_cnt);
 | |
|     if (impl->trie) {
 | |
|         impl->ctx = ctx;
 | |
|         impl->node_cnt = node_cnt;
 | |
|         impl->info_cnt = opt_cnt;
 | |
|         return MPP_OK;
 | |
|     }
 | |
| 
 | |
|     mpp_err_f("failed to setup node %d opt %d\n", node_cnt, opt_cnt);
 | |
| 
 | |
|     return MPP_NOK;
 | |
| }
 | |
| 
 | |
| MPP_RET mpp_opt_add(MppOpt opt, MppOptInfo *info)
 | |
| {
 | |
|     MppOptImpl *impl = (MppOptImpl *)opt;
 | |
| 
 | |
|     if (NULL == impl || NULL == impl->trie)
 | |
|         return MPP_NOK;
 | |
| 
 | |
|     if (NULL == info) {
 | |
|         RK_S32 node_cnt = mpp_trie_get_node_count(impl->trie);
 | |
|         RK_S32 info_cnt = mpp_trie_get_info_count(impl->trie);
 | |
| 
 | |
|         if (impl->node_cnt != node_cnt || impl->info_cnt != info_cnt)
 | |
|             mpp_log("setup:real node %d:%d info %d:%d\n",
 | |
|                     impl->node_cnt, node_cnt, impl->info_cnt, info_cnt);
 | |
| 
 | |
|         return MPP_OK;
 | |
|     }
 | |
| 
 | |
|     return mpp_trie_add_info(impl->trie, &info->name);
 | |
| }
 | |
| 
 | |
| MPP_RET mpp_opt_parse(MppOpt opt, int argc, char **argv)
 | |
| {
 | |
|     MppOptImpl *impl = (MppOptImpl *)opt;
 | |
|     MPP_RET ret = MPP_NOK;
 | |
|     RK_S32 opt_idx = 0;
 | |
| 
 | |
|     if (NULL == impl || NULL == impl->trie || argc < 2 || NULL == argv)
 | |
|         return ret;
 | |
| 
 | |
|     ret = MPP_OK;
 | |
| 
 | |
|     while (opt_idx <= argc) {
 | |
|         RK_S32 opt_next = opt_idx + 1;
 | |
|         char *opts = argv[opt_idx++];
 | |
|         char *next = (opt_next >= argc) ? NULL : argv[opt_next];
 | |
| 
 | |
|         if (NULL == opts)
 | |
|             break;
 | |
| 
 | |
|         if (opts[0] == '-' && opts[1] != '\0') {
 | |
|             MppOptInfo *info = NULL;
 | |
|             const char **name = mpp_trie_get_info(impl->trie, opts + 1);
 | |
|             RK_S32 step = 0;
 | |
| 
 | |
|             if (NULL == name) {
 | |
|                 mpp_err("invalid option %s\n", opts + 1);
 | |
|                 continue;
 | |
|             }
 | |
| 
 | |
|             info = container_of(name, MppOptInfo, name);
 | |
|             if (info->proc)
 | |
|                 step = info->proc(impl->ctx, next);
 | |
| 
 | |
|             /* option failure or help */
 | |
|             if (step < 0) {
 | |
|                 ret = step;
 | |
|                 break;
 | |
|             }
 | |
| 
 | |
|             opt_idx += step;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     return ret;
 | |
| }
 |