Merge pull request #350 from Yangyuanxin/master
add ini Parse & ini Parse demo
This commit is contained in:
44
board/Linux_Posix/ini_demo/CMakeLists.txt
Executable file
44
board/Linux_Posix/ini_demo/CMakeLists.txt
Executable file
@@ -0,0 +1,44 @@
|
||||
cmake_minimum_required(VERSION 3.8)
|
||||
|
||||
project(ini_test)
|
||||
|
||||
set(CMAKE_BUILD_TYPE "Debug")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g2 -ggdb")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall")
|
||||
|
||||
set(TINY_ROOT ../../../)
|
||||
|
||||
include_directories(${TINY_ROOT}/osal/cmsis_os)
|
||||
include_directories(${TINY_ROOT}/kernel/core/include)
|
||||
include_directories(${TINY_ROOT}/kernel/evtdrv/include)
|
||||
include_directories(${TINY_ROOT}/kernel/hal/include)
|
||||
include_directories(${TINY_ROOT}/kernel/pm/include)
|
||||
|
||||
set(CMSIS_SRCS ${TINY_ROOT}/osal/cmsis_os/cmsis_os.c)
|
||||
aux_source_directory(${TINY_ROOT}/kernel/core CORE_SRCS)
|
||||
aux_source_directory(${TINY_ROOT}/kernel/evtdrv EVTDRV_SRCS)
|
||||
aux_source_directory(${TINY_ROOT}/kernel/pm PM_SRCS)
|
||||
|
||||
set(ARCH_ROOT ${TINY_ROOT}/arch/linux)
|
||||
|
||||
include_directories(${ARCH_ROOT}/common/include)
|
||||
include_directories(${ARCH_ROOT}/posix/gcc)
|
||||
include_directories(${TINY_ROOT}/components/utils/INI/include)
|
||||
|
||||
aux_source_directory(${ARCH_ROOT}/common ARCH_COMMON_SRCS)
|
||||
aux_source_directory(${ARCH_ROOT}/posix/gcc ARCH_POSIX_SRCS)
|
||||
|
||||
aux_source_directory(${TINY_ROOT}/components/utils/INI/src INI_SRCS)
|
||||
|
||||
set(ARCH_SRCS ${ARCH_COMMON_SRCS} ${ARCH_POSIX_SRCS})
|
||||
|
||||
set(TINY_SRCS ${ARCH_SRCS} ${CMSIS_SRCS} ${EVTDRV_SRCS} ${PM_SRCS} ${CORE_SRCS} ${INI_SRCS} )
|
||||
|
||||
include_directories(./)
|
||||
include_directories(./inc)
|
||||
|
||||
set(APP_SRCS src/main.c)
|
||||
|
||||
add_executable(inidemo ${APP_SRCS} ${TINY_SRCS})
|
||||
|
||||
target_link_libraries(inidemo pthread)
|
50
board/Linux_Posix/ini_demo/Makefile
Executable file
50
board/Linux_Posix/ini_demo/Makefile
Executable file
@@ -0,0 +1,50 @@
|
||||
###################################################################
|
||||
#automatic detection QTOP and LOCALDIR
|
||||
CUR_DIR := $(patsubst %/,%,$(dir $(realpath $(firstword $(MAKEFILE_LIST)))))
|
||||
TRYQTOP := $(shell if [ -n "$$QTOP" ] ; then\
|
||||
echo $$QTOP;\
|
||||
else\
|
||||
cd $(CUR_DIR); while /usr/bin/test ! -e qmk ; do \
|
||||
dir=`cd ../;pwd`; \
|
||||
if [ "$$dir" = "/" ] ; then \
|
||||
echo Cannot find QTOP in $(firstword $(MAKEFILE_LIST)) 1>&2; \
|
||||
exit 1; \
|
||||
fi ; \
|
||||
cd $$dir; \
|
||||
done ; \
|
||||
pwd; \
|
||||
fi)
|
||||
QTOP ?= $(realpath ${TRYQTOP})
|
||||
|
||||
ifeq ($(QTOP),)
|
||||
$(error Please run this in a tree)
|
||||
endif
|
||||
LOCALDIR = $(patsubst %/,%,$(subst $(realpath $(QTOP))/,,$(CUR_DIR)))
|
||||
export QTOP
|
||||
|
||||
####################################################################
|
||||
|
||||
|
||||
export BP=Linux_Posix
|
||||
|
||||
TREE_LIB_ENABLE=1
|
||||
lib=
|
||||
subdirs =
|
||||
|
||||
|
||||
all::
|
||||
make -C ${QTOP}/arch BP=${BP}
|
||||
make -C ${QTOP}/kernel BP=${BP}
|
||||
make -C ${QTOP}/osal BP=${BP}
|
||||
make -C ${QTOP}/net BP=${BP}
|
||||
make -C ${QTOP}/devices BP=${BP}
|
||||
exec =
|
||||
LD_A_FILES += $(LIBDIR)/libarch.a
|
||||
LD_A_FILES += $(LIBDIR)/libkernel.a
|
||||
LD_A_FILES += $(LIBDIR)/libini_demo.a
|
||||
LD_A_FILES += $(LIBDIR)/libcmsis_os.a
|
||||
LDFLAGS += -lpthread
|
||||
|
||||
include ${QTOP}/qmk/generic/Make.exec
|
||||
|
||||
|
236
board/Linux_Posix/ini_demo/inc/lwipopts.h
Executable file
236
board/Linux_Posix/ini_demo/inc/lwipopts.h
Executable file
@@ -0,0 +1,236 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file lwipopts.h
|
||||
* @author MCD Application Team
|
||||
* @version V1.1.0
|
||||
* @date 31-July-2013
|
||||
* @brief lwIP Options Configuration.
|
||||
* This file is based on Utilities\lwip_v1.4.1\src\include\lwip\opt.h
|
||||
* and contains the lwIP configuration for the STM32F4x7 demonstration.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef __LWIPOPTS_H__
|
||||
#define __LWIPOPTS_H__
|
||||
|
||||
/**
|
||||
* SYS_LIGHTWEIGHT_PROT==1: if you want inter-task protection for certain
|
||||
* critical regions during buffer allocation, deallocation and memory
|
||||
* allocation and deallocation.
|
||||
*/
|
||||
#define SYS_LIGHTWEIGHT_PROT 1
|
||||
|
||||
/**
|
||||
* NO_SYS==1: Provides VERY minimal functionality. Otherwise,
|
||||
* use lwIP facilities.
|
||||
*/
|
||||
#define NO_SYS 0
|
||||
|
||||
/**
|
||||
* NO_SYS_NO_TIMERS==1: Drop support for sys_timeout when NO_SYS==1
|
||||
* Mainly for compatibility to old versions.
|
||||
*/
|
||||
#define NO_SYS_NO_TIMERS 0
|
||||
|
||||
/* ---------- Memory options ---------- */
|
||||
/* MEM_ALIGNMENT: should be set to the alignment of the CPU for which
|
||||
lwIP is compiled. 4 byte alignment -> define MEM_ALIGNMENT to 4, 2
|
||||
byte alignment -> define MEM_ALIGNMENT to 2. */
|
||||
#define MEM_ALIGNMENT 4
|
||||
|
||||
/* MEM_SIZE: the size of the heap memory. If the application will send
|
||||
a lot of data that needs to be copied, this should be set high. */
|
||||
#define MEM_SIZE (5 * 1024)
|
||||
|
||||
/* MEMP_NUM_PBUF: the number of memp struct pbufs. If the application
|
||||
sends a lot of data out of ROM (or other static memory), this
|
||||
should be set high. */
|
||||
#define MEMP_NUM_PBUF 25
|
||||
/* MEMP_NUM_UDP_PCB: the number of UDP protocol control blocks. One
|
||||
per active UDP "connection". */
|
||||
#define MEMP_NUM_UDP_PCB 4
|
||||
/* MEMP_NUM_TCP_PCB: the number of simulatenously active TCP
|
||||
connections. */
|
||||
#define MEMP_NUM_TCP_PCB 6
|
||||
/* MEMP_NUM_TCP_PCB_LISTEN: the number of listening TCP
|
||||
connections. */
|
||||
#define MEMP_NUM_TCP_PCB_LISTEN 6
|
||||
/* MEMP_NUM_TCP_SEG: the number of simultaneously queued TCP
|
||||
segments. */
|
||||
#define MEMP_NUM_TCP_SEG 150
|
||||
/* MEMP_NUM_SYS_TIMEOUT: the number of simulateously active
|
||||
timeouts. */
|
||||
#define MEMP_NUM_SYS_TIMEOUT 6
|
||||
|
||||
/* ---------- Pbuf options ---------- */
|
||||
/* PBUF_POOL_SIZE: the number of buffers in the pbuf pool. */
|
||||
#define PBUF_POOL_SIZE 25
|
||||
/* PBUF_POOL_BUFSIZE: the size of each pbuf in the pbuf pool. */
|
||||
#define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(TCP_MSS + 40 + PBUF_LINK_ENCAPSULATION_HLEN + PBUF_LINK_HLEN)
|
||||
|
||||
/* ---------- TCP options ---------- */
|
||||
#define LWIP_TCP 1
|
||||
#define TCP_TTL 255
|
||||
|
||||
/* Controls if TCP should queue segments that arrive out of
|
||||
order. Define to 0 if your device is low on memory. */
|
||||
#define TCP_QUEUE_OOSEQ 0
|
||||
|
||||
/* TCP Maximum segment size. */
|
||||
#define TCP_MSS (1500 - 40) /* TCP_MSS = (Ethernet MTU - IP header size - TCP header size) */
|
||||
|
||||
/* TCP sender buffer space (bytes). */
|
||||
#define TCP_SND_BUF (7 * TCP_MSS)
|
||||
|
||||
/* TCP_SND_QUEUELEN: TCP sender buffer space (pbufs). This must be at least
|
||||
as much as (2 * TCP_SND_BUF/TCP_MSS) for things to work. */
|
||||
|
||||
#define TCP_SND_QUEUELEN (8 * TCP_SND_BUF / TCP_MSS)
|
||||
|
||||
/* TCP receive window. */
|
||||
#define TCP_WND (9 * TCP_MSS)
|
||||
|
||||
/* ---------- ICMP options ---------- */
|
||||
#define LWIP_ICMP 1
|
||||
|
||||
/* ---------- DHCP options ---------- */
|
||||
/* Define LWIP_DHCP to 1 if you want DHCP configuration of
|
||||
interfaces. DHCP is not implemented in lwIP 0.5.1, however, so
|
||||
turning this on does currently not work. */
|
||||
#define LWIP_DHCP 1
|
||||
|
||||
/* ---------- UDP options ---------- */
|
||||
#define LWIP_UDP 1
|
||||
#define UDP_TTL 255
|
||||
|
||||
/* ---------- Statistics options ---------- */
|
||||
#define LWIP_STATS 0
|
||||
#define LWIP_PROVIDE_ERRNO 1
|
||||
|
||||
/* ---------- link callback options ---------- */
|
||||
/* LWIP_NETIF_LINK_CALLBACK==1: Support a callback function from an interface
|
||||
* whenever the link changes (i.e., link down)
|
||||
*/
|
||||
#define LWIP_NETIF_LINK_CALLBACK 0
|
||||
/*
|
||||
--------------------------------------
|
||||
---------- Checksum options ----------
|
||||
--------------------------------------
|
||||
*/
|
||||
|
||||
/*
|
||||
The STM32F4x7 allows computing and verifying the IP, UDP, TCP and ICMP checksums by hardware:
|
||||
- To use this feature let the following define uncommented.
|
||||
- To disable it and process by CPU comment the the checksum.
|
||||
*/
|
||||
#define CHECKSUM_BY_HARDWARE
|
||||
//#undef CHECKSUM_BY_HARDWARE
|
||||
|
||||
#ifdef CHECKSUM_BY_HARDWARE
|
||||
/* CHECKSUM_GEN_IP==0: Generate checksums by hardware for outgoing IP packets.*/
|
||||
#define CHECKSUM_GEN_IP 0
|
||||
/* CHECKSUM_GEN_UDP==0: Generate checksums by hardware for outgoing UDP packets.*/
|
||||
#define CHECKSUM_GEN_UDP 0
|
||||
/* CHECKSUM_GEN_TCP==0: Generate checksums by hardware for outgoing TCP packets.*/
|
||||
#define CHECKSUM_GEN_TCP 0
|
||||
/* CHECKSUM_CHECK_IP==0: Check checksums by hardware for incoming IP packets.*/
|
||||
#define CHECKSUM_CHECK_IP 0
|
||||
/* CHECKSUM_CHECK_UDP==0: Check checksums by hardware for incoming UDP packets.*/
|
||||
#define CHECKSUM_CHECK_UDP 0
|
||||
/* CHECKSUM_CHECK_TCP==0: Check checksums by hardware for incoming TCP packets.*/
|
||||
#define CHECKSUM_CHECK_TCP 0
|
||||
/* CHECKSUM_CHECK_ICMP==0: Check checksums by hardware for incoming ICMP packets.*/
|
||||
#define CHECKSUM_GEN_ICMP 0
|
||||
#else
|
||||
/* CHECKSUM_GEN_IP==1: Generate checksums in software for outgoing IP packets.*/
|
||||
#define CHECKSUM_GEN_IP 1
|
||||
/* CHECKSUM_GEN_UDP==1: Generate checksums in software for outgoing UDP packets.*/
|
||||
#define CHECKSUM_GEN_UDP 1
|
||||
/* CHECKSUM_GEN_TCP==1: Generate checksums in software for outgoing TCP packets.*/
|
||||
#define CHECKSUM_GEN_TCP 1
|
||||
/* CHECKSUM_CHECK_IP==1: Check checksums in software for incoming IP packets.*/
|
||||
#define CHECKSUM_CHECK_IP 1
|
||||
/* CHECKSUM_CHECK_UDP==1: Check checksums in software for incoming UDP packets.*/
|
||||
#define CHECKSUM_CHECK_UDP 1
|
||||
/* CHECKSUM_CHECK_TCP==1: Check checksums in software for incoming TCP packets.*/
|
||||
#define CHECKSUM_CHECK_TCP 1
|
||||
/* CHECKSUM_CHECK_ICMP==1: Check checksums by hardware for incoming ICMP packets.*/
|
||||
#define CHECKSUM_GEN_ICMP 1
|
||||
#endif
|
||||
|
||||
#define LWIP_TCPIP_CORE_LOCKING 1
|
||||
|
||||
/*
|
||||
----------------------------------------------
|
||||
---------- Sequential layer options ----------
|
||||
----------------------------------------------
|
||||
*/
|
||||
/**
|
||||
* LWIP_NETCONN==1: Enable Netconn API (require to use api_lib.c)
|
||||
*/
|
||||
#define LWIP_NETCONN 1
|
||||
|
||||
/*
|
||||
------------------------------------
|
||||
---------- Socket options ----------
|
||||
------------------------------------
|
||||
*/
|
||||
/**
|
||||
* LWIP_SOCKET==1: Enable Socket API (require to use sockets.c)
|
||||
*/
|
||||
#define LWIP_SOCKET 1
|
||||
|
||||
/*
|
||||
---------------------------------
|
||||
---------- OS options ----------
|
||||
---------------------------------
|
||||
*/
|
||||
|
||||
#define DEFAULT_UDP_RECVMBOX_SIZE 10
|
||||
#define DEFAULT_TCP_RECVMBOX_SIZE 10
|
||||
#define DEFAULT_ACCEPTMBOX_SIZE 10
|
||||
#define DEFAULT_THREAD_STACKSIZE 1024 * 2
|
||||
|
||||
#define TCPIP_THREAD_NAME "lwip"
|
||||
#define TCPIP_THREAD_STACKSIZE 1024
|
||||
#define TCPIP_MBOX_SIZE 10
|
||||
#define TCPIP_THREAD_PRIO 1
|
||||
|
||||
#define LWIP_DNS_API_DECLARE_STRUCTS 1
|
||||
#define LWIP_DNS 1
|
||||
|
||||
/** DNS server IP address */
|
||||
#ifndef DNS_SERVER_ADDRESS
|
||||
#define DNS_SERVER_ADDRESS(ipaddr) (ip4_addr_set_u32(ipaddr, ipaddr_addr("208.67.222.222"))) /* resolver1.opendns.com */
|
||||
#endif
|
||||
|
||||
/*
|
||||
----------------------------------------
|
||||
---------- Lwip Debug options ----------
|
||||
----------------------------------------
|
||||
*/
|
||||
#define LWIP_DEBUG 0
|
||||
|
||||
#define ethernet_with_mac 1
|
||||
|
||||
#endif /* __LWIPOPTS_H__ */
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
51
board/Linux_Posix/ini_demo/inc/tos_config.h
Executable file
51
board/Linux_Posix/ini_demo/inc/tos_config.h
Executable file
@@ -0,0 +1,51 @@
|
||||
#ifndef _TOS_CONFIG_H_
|
||||
#define _TOS_CONFIG_H_
|
||||
|
||||
#include "stddef.h"
|
||||
#include "stdint.h"
|
||||
|
||||
#define TOS_CFG_TASK_PRIO_MAX 10u // 配置TencentOS tiny默认支持的最大优先级数量
|
||||
|
||||
#define TOS_CFG_ROUND_ROBIN_EN 1u // 配置TencentOS tiny的内核是否开启时间片轮转
|
||||
|
||||
#define TOS_CFG_OBJECT_VERIFY_EN 1u // 配置TencentOS tiny是否校验指针合法
|
||||
|
||||
#define TOS_CFG_EVENT_EN 1u // TencentOS tiny 事件模块功能宏
|
||||
|
||||
#define TOS_CFG_MMHEAP_EN 1u // 配置TencentOS tiny是否开启动态内存模块
|
||||
|
||||
#define TOS_CFG_MMHEAP_POOL_SIZE 0x100 // 配置TencentOS tiny动态内存池大小
|
||||
|
||||
#define TOS_CFG_MMHEAP_DEFAULT_POOL_SIZE 0x100 // 配置TencentOS tiny动态内存池大小
|
||||
|
||||
#define TOS_CFG_MUTEX_EN 1u // 配置TencentOS tiny是否开启互斥锁模块
|
||||
|
||||
#define TOS_CFG_MESSAGE_QUEUE_EN 1u
|
||||
#define TOS_CFG_MAIL_QUEUE_EN 1u
|
||||
|
||||
#define TOS_CFG_PRIORITY_MESSAGE_QUEUE_EN 1u
|
||||
|
||||
#define TOS_CFG_PRIORITY_MAIL_QUEUE_EN 1u
|
||||
#define TOS_CFG_TIMER_EN 1u // 配置TencentOS tiny是否开启软件定时器模块
|
||||
|
||||
#define TOS_CFG_SEM_EN 1u // 配置TencentOS tiny是否开启信号量模块
|
||||
|
||||
#define TOS_CFG_MMBLK_EN 1u
|
||||
|
||||
#if (TOS_CFG_QUEUE_EN > 0u)
|
||||
#define TOS_CFG_MSG_EN 1u
|
||||
#else
|
||||
#define TOS_CFG_MSG_EN 0u
|
||||
#endif
|
||||
|
||||
#define TOS_CFG_MSG_POOL_SIZE 10u // 配置TencentOS tiny消息队列大小
|
||||
|
||||
#define TOS_CFG_IDLE_TASK_STK_SIZE 256u // 配置TencentOS tiny空闲任务栈大小
|
||||
|
||||
#define TOS_CFG_CPU_TICK_PER_SECOND 1000u // 配置TencentOS tiny的tick频率
|
||||
|
||||
#define TOS_CFG_CPU_CLOCK 1000000u // 配置TencentOS tiny CPU频率
|
||||
|
||||
#define TOS_CFG_TIMER_AS_PROC 1u // 配置是否将TIMER配置成函数模式
|
||||
|
||||
#endif
|
36
board/Linux_Posix/ini_demo/readme.md
Executable file
36
board/Linux_Posix/ini_demo/readme.md
Executable file
@@ -0,0 +1,36 @@
|
||||
# How to run the demo in linux
|
||||
|
||||
## step1
|
||||
make sure your develop environment.
|
||||
+ `cmake` and version greater than 3.8.2
|
||||
+ `gcc` `gdb` `make` is installed
|
||||
|
||||
## step2
|
||||
make `build` directory and compile in `build`
|
||||
|
||||
```bash
|
||||
mkdir build && cd build
|
||||
cmake ..
|
||||
make
|
||||
```
|
||||
|
||||
## step3
|
||||
run program !!
|
||||
|
||||
```bash
|
||||
# in build directory
|
||||
./hello_world
|
||||
```
|
||||
|
||||
## other
|
||||
you can copy this demo to other path, but if you want do it,
|
||||
you need modify `CMakeLists.txt`. find line
|
||||
|
||||
```cmake
|
||||
set(TINY_ROOT ../../../)
|
||||
```
|
||||
|
||||
and modify `path-to-tinyos`
|
||||
```cmake
|
||||
set(TINY_ROOT path-to-tinyos)
|
||||
```
|
170
board/Linux_Posix/ini_demo/src/main.c
Executable file
170
board/Linux_Posix/ini_demo/src/main.c
Executable file
@@ -0,0 +1,170 @@
|
||||
#include "cmsis_os.h"
|
||||
#include "iniparser.h"
|
||||
#define CONFIG_NAME "Config.ini"
|
||||
|
||||
struct DataInfo_t
|
||||
{
|
||||
int InitData;
|
||||
int VolumeData;
|
||||
int LanguageVersion;
|
||||
};
|
||||
|
||||
#define TASK1_STK_SIZE 512
|
||||
void task1(void *arg);
|
||||
osThreadDef(task1, osPriorityNormal, 1, TASK1_STK_SIZE);
|
||||
|
||||
void task1(void *arg)
|
||||
{
|
||||
int Len = -1;
|
||||
int Ret = -1;
|
||||
char Buf[128];
|
||||
char *DataPtr = NULL;
|
||||
struct DataInfo_t Data;
|
||||
FILE *IniTest = NULL ;
|
||||
FILE *DefaultIni = NULL;
|
||||
dictionary *ConfigIni = NULL;
|
||||
|
||||
/*1. Create ini config file*/
|
||||
IniTest = fopen(CONFIG_NAME, "w");
|
||||
if(NULL == IniTest)
|
||||
{
|
||||
printf("IniTest is Null!\n");
|
||||
return ;
|
||||
}
|
||||
|
||||
fprintf(IniTest,
|
||||
"[Setting]\n"
|
||||
"init_data=0;\n"
|
||||
"volume_data=1;\n"
|
||||
"language_version=1;\n"
|
||||
);
|
||||
|
||||
Ret = fclose(IniTest);
|
||||
if(Ret != 0)
|
||||
{
|
||||
printf("close IniTest fail!\n");
|
||||
return ;
|
||||
}
|
||||
|
||||
IniTest = NULL;
|
||||
|
||||
IniTest = fopen(CONFIG_NAME, "r");
|
||||
if(NULL == IniTest)
|
||||
{
|
||||
printf("IniTest is Null!\n");
|
||||
return ;
|
||||
}
|
||||
|
||||
memset(Buf, 0, sizeof(Buf));
|
||||
while(fgets(Buf, sizeof(Buf), IniTest))
|
||||
{
|
||||
printf("Buf: %s", Buf);
|
||||
}
|
||||
|
||||
fclose(IniTest);
|
||||
IniTest = NULL;
|
||||
|
||||
putchar('\n');
|
||||
|
||||
/*2. Test read ini config file data*/
|
||||
ConfigIni = iniparser_load(CONFIG_NAME);
|
||||
if(NULL == ConfigIni)
|
||||
{
|
||||
printf("ConfigIni is NULL!\n");
|
||||
return ;
|
||||
}
|
||||
|
||||
//iniparser_dump(ConfigIni, stderr);
|
||||
Data.InitData = iniparser_getint(ConfigIni,"Setting:init_data",-1);
|
||||
if(-1 == Data.InitData)
|
||||
{
|
||||
printf("iniparser_getint fail!\n");
|
||||
return ;
|
||||
}
|
||||
Data.VolumeData = iniparser_getint(ConfigIni,"Setting:volume_data",-1);
|
||||
if(-1 == Data.VolumeData)
|
||||
{
|
||||
printf("iniparser_getint fail!\n");
|
||||
return ;
|
||||
}
|
||||
Data.LanguageVersion = iniparser_getint(ConfigIni,"Setting:language_version",-1);
|
||||
if(-1 == Data.LanguageVersion)
|
||||
{
|
||||
printf("iniparser_getint fail!\n");
|
||||
return ;
|
||||
}
|
||||
|
||||
printf("Data.InitData:%d\n", Data.InitData);
|
||||
printf("Data.VolumeData:%d\n", Data.VolumeData);
|
||||
printf("Data.LanguageVersion:%d\n", Data.LanguageVersion);
|
||||
|
||||
/* 3. Set modify one of the parameters*/
|
||||
iniparser_set(ConfigIni,"Setting:init_data", "111");
|
||||
iniparser_set(ConfigIni,"Setting:volume_data", "222");
|
||||
iniparser_set(ConfigIni,"Setting:language_version", "333");
|
||||
|
||||
putchar('\n');
|
||||
|
||||
/*4. Write data to int config file*/
|
||||
DefaultIni = fopen(CONFIG_NAME, "w");
|
||||
if(NULL == DefaultIni)
|
||||
{
|
||||
printf("DefaultIni is NULL!\n");
|
||||
return ;
|
||||
}
|
||||
iniparser_dump_ini(ConfigIni, DefaultIni);
|
||||
Ret = fclose(DefaultIni);
|
||||
if(Ret != 0)
|
||||
{
|
||||
printf("close DefaultIni fail!\n");
|
||||
return ;
|
||||
}
|
||||
|
||||
/*5.Read the modified Config ini file data*/
|
||||
Data.InitData = iniparser_getint(ConfigIni, "Setting:init_data", -1);
|
||||
if(-1 == Data.InitData)
|
||||
{
|
||||
printf("iniparser_getint fail!\n");
|
||||
return ;
|
||||
}
|
||||
Data.VolumeData = iniparser_getint(ConfigIni, "Setting:volume_data", -1);
|
||||
if(-1 == Data.VolumeData)
|
||||
{
|
||||
printf("iniparser_getint fail!\n");
|
||||
return ;
|
||||
}
|
||||
Data.LanguageVersion = iniparser_getint(ConfigIni, "Setting:language_version", -1);
|
||||
if(-1 == Data.LanguageVersion)
|
||||
{
|
||||
printf("iniparser_getint fail!\n");
|
||||
return ;
|
||||
}
|
||||
|
||||
printf("Data.InitData:%d\n", Data.InitData);
|
||||
printf("Data.VolumeData:%d\n", Data.VolumeData);
|
||||
printf("Data.LanguageVersion:%d\n", Data.LanguageVersion);
|
||||
|
||||
iniparser_freedict(ConfigIni);
|
||||
|
||||
while(1)
|
||||
{
|
||||
printf("Ini test success!\n");
|
||||
osDelay(1000);
|
||||
}
|
||||
}
|
||||
|
||||
void application_entry(void *arg)
|
||||
{
|
||||
osThreadCreate(osThread(task1), NULL); // Create task1
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
osKernelInitialize(); //TOS Tiny kernel initialize
|
||||
application_entry(NULL);
|
||||
osKernelStart(); //Start TOS Tiny
|
||||
|
||||
while (1)
|
||||
{
|
||||
}
|
||||
}
|
35
components/utils/INI/Makefile
Executable file
35
components/utils/INI/Makefile
Executable file
@@ -0,0 +1,35 @@
|
||||
###################################################################
|
||||
#automatic detection QTOP and LOCALDIR
|
||||
CUR_DIR := $(patsubst %/,%,$(dir $(realpath $(firstword $(MAKEFILE_LIST)))))
|
||||
TRYQTOP := $(shell if [ -n "$$QTOP" ] ; then\
|
||||
echo $$QTOP;\
|
||||
else\
|
||||
cd $(CUR_DIR); while /usr/bin/test ! -d qmk ; do \
|
||||
dir=`cd ../;pwd`; \
|
||||
if [ "$$dir" = "/" ] ; then \
|
||||
echo Cannot find QTOP in $(firstword $(MAKEFILE_LIST)) 1>&2; \
|
||||
exit 1; \
|
||||
fi ; \
|
||||
cd $$dir; \
|
||||
done ; \
|
||||
pwd; \
|
||||
fi)
|
||||
QTOP ?= $(realpath ${TRYQTOP})
|
||||
|
||||
ifeq ($(QTOP),)
|
||||
$(error Please run this in a tree)
|
||||
endif
|
||||
LOCALDIR = $(patsubst %/,%,$(subst $(realpath $(QTOP))/,,$(CUR_DIR)))
|
||||
|
||||
####################################################################
|
||||
|
||||
|
||||
TREE_LIB_ENABLE=y
|
||||
lib=
|
||||
subdirs=
|
||||
|
||||
CFGFLAGS += -I$(CUR_DIR)/include
|
||||
|
||||
include ${QTOP}/qmk/generic/Make.tpl
|
||||
|
||||
|
207
components/utils/INI/include/dictionary.h
Executable file
207
components/utils/INI/include/dictionary.h
Executable file
@@ -0,0 +1,207 @@
|
||||
/*
|
||||
Copyright (c) 2000-2011 by Nicolas Devillard.
|
||||
MIT License
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@file dictionary.h
|
||||
@author N. Devillard
|
||||
@brief Implements a dictionary for string variables.
|
||||
|
||||
This module implements a simple dictionary object, i.e. a list
|
||||
of string/string associations. This object is useful to store e.g.
|
||||
informations retrieved from a configuration file (ini files).
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef DICTIONARY_H
|
||||
#define DICTIONARY_H
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Includes
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
//#include <unistd.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
New types
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Dictionary object
|
||||
|
||||
This object contains a list of string/string associations. Each
|
||||
association is identified by a unique string key. Looking up values
|
||||
in the dictionary is speeded up by the use of a (hopefully collision-free)
|
||||
hash function.
|
||||
*/
|
||||
/*-------------------------------------------------------------------------*/
|
||||
typedef struct _dictionary_
|
||||
{
|
||||
int n ; /** Number of entries in dictionary */
|
||||
int size ; /** Storage size */
|
||||
char ** val ; /** List of string values */
|
||||
char ** key ; /** List of string keys */
|
||||
unsigned * hash ; /** List of hash values for keys */
|
||||
} dictionary ;
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Function prototypes
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Compute the hash key for a string.
|
||||
@param key Character string to use for key.
|
||||
@return 1 unsigned int on at least 32 bits.
|
||||
|
||||
This hash function has been taken from an Article in Dr Dobbs Journal.
|
||||
This is normally a collision-free function, distributing keys evenly.
|
||||
The key is stored anyway in the struct so that collision can be avoided
|
||||
by comparing the key itself in last resort.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
unsigned dictionary_hash(const char * key);
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Create a new dictionary object.
|
||||
@param size Optional initial size of the dictionary.
|
||||
@return 1 newly allocated dictionary objet.
|
||||
|
||||
This function allocates a new dictionary object of given size and returns
|
||||
it. If you do not know in advance (roughly) the number of entries in the
|
||||
dictionary, give size=0.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
dictionary * dictionary_new(size_t size);
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Delete a dictionary object
|
||||
@param d dictionary object to deallocate.
|
||||
@return void
|
||||
|
||||
Deallocate a dictionary object and all memory associated to it.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
void dictionary_del(dictionary * vd);
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Get a value from a dictionary.
|
||||
@param d dictionary object to search.
|
||||
@param key Key to look for in the dictionary.
|
||||
@param def Default value to return if key not found.
|
||||
@return 1 pointer to internally allocated character string.
|
||||
|
||||
This function locates a key in a dictionary and returns a pointer to its
|
||||
value, or the passed 'def' pointer if no such key can be found in
|
||||
dictionary. The returned character pointer points to data internal to the
|
||||
dictionary object, you should not try to free it or modify it.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
char * dictionary_get(dictionary * d, const char * key, char * def);
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Set a value in a dictionary.
|
||||
@param d dictionary object to modify.
|
||||
@param key Key to modify or add.
|
||||
@param val Value to add.
|
||||
@return int 0 if Ok, anything else otherwise
|
||||
|
||||
If the given key is found in the dictionary, the associated value is
|
||||
replaced by the provided one. If the key cannot be found in the
|
||||
dictionary, it is added to it.
|
||||
|
||||
It is Ok to provide a NULL value for val, but NULL values for the dictionary
|
||||
or the key are considered as errors: the function will return immediately
|
||||
in such a case.
|
||||
|
||||
Notice that if you dictionary_set a variable to NULL, a call to
|
||||
dictionary_get will return a NULL value: the variable will be found, and
|
||||
its value (NULL) is returned. In other words, setting the variable
|
||||
content to NULL is equivalent to deleting the variable from the
|
||||
dictionary. It is not possible (in this implementation) to have a key in
|
||||
the dictionary without value.
|
||||
|
||||
This function returns non-zero in case of failure.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int dictionary_set(dictionary * vd, const char * key, const char * val);
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Delete a key in a dictionary
|
||||
@param d dictionary object to modify.
|
||||
@param key Key to remove.
|
||||
@return void
|
||||
|
||||
This function deletes a key in a dictionary. Nothing is done if the
|
||||
key cannot be found.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
void dictionary_unset(dictionary * d, const char * key);
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Dump a dictionary to an opened file pointer.
|
||||
@param d Dictionary to dump
|
||||
@param f Opened file pointer.
|
||||
@return void
|
||||
|
||||
Dumps a dictionary onto an opened file pointer. Key pairs are printed out
|
||||
as @c [Key]=[Value], one per line. It is Ok to provide stdout or stderr as
|
||||
output file pointers.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
void dictionary_dump(dictionary * d, FILE * out);
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Duplicate a string
|
||||
@param s String to duplicate
|
||||
@return Pointer to a newly allocated string, to be freed with free()
|
||||
|
||||
This is a replacement for strdup(). This implementation is provided
|
||||
for systems that do not have it.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
char * xstrdup(const char * s);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
348
components/utils/INI/include/iniparser.h
Executable file
348
components/utils/INI/include/iniparser.h
Executable file
@@ -0,0 +1,348 @@
|
||||
/*
|
||||
Copyright (c) 2000-2011 by Nicolas Devillard.
|
||||
MIT License
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@file iniparser.h
|
||||
@author N. Devillard
|
||||
@brief Parser for ini files.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef INIPARSER_H
|
||||
#define INIPARSER_H
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Includes
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef SUPPORT_FATFS
|
||||
#include "fatfs.h"
|
||||
#endif
|
||||
/*
|
||||
* The following #include is necessary on many Unixes but not Linux.
|
||||
* It is not needed for Windows platforms.
|
||||
* Uncomment it if needed.
|
||||
*/
|
||||
/* #include <unistd.h> */
|
||||
|
||||
#include "dictionary.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Get number of sections in a dictionary
|
||||
@param d Dictionary to examine
|
||||
@return int Number of sections found in dictionary
|
||||
|
||||
This function returns the number of sections found in a dictionary.
|
||||
The test to recognize sections is done on the string stored in the
|
||||
dictionary: a section name is given as "section" whereas a key is
|
||||
stored as "section:key", thus the test looks for entries that do not
|
||||
contain a colon.
|
||||
|
||||
This clearly fails in the case a section name contains a colon, but
|
||||
this should simply be avoided.
|
||||
|
||||
This function returns -1 in case of error.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
int iniparser_getnsec(dictionary * d);
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Get name for section n in a dictionary.
|
||||
@param d Dictionary to examine
|
||||
@param n Section number (from 0 to nsec-1).
|
||||
@return Pointer to char string
|
||||
|
||||
This function locates the n-th section in a dictionary and returns
|
||||
its name as a pointer to a string statically allocated inside the
|
||||
dictionary. Do not free or modify the returned string!
|
||||
|
||||
This function returns NULL in case of error.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
char * iniparser_getsecname(dictionary * d, int n);
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Save a dictionary to a loadable ini file
|
||||
@param d Dictionary to dump
|
||||
@param f Opened file pointer to dump to
|
||||
@return void
|
||||
|
||||
This function dumps a given dictionary into a loadable ini file.
|
||||
It is Ok to specify @c stderr or @c stdout as output files.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#ifdef SUPPORT_FATFS
|
||||
void iniparser_dump_ini(dictionary * d, FIL * f);
|
||||
#else
|
||||
void iniparser_dump_ini(dictionary * d, FILE * f);
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Save a dictionary section to a loadable ini file
|
||||
@param d Dictionary to dump
|
||||
@param s Section name of dictionary to dump
|
||||
@param f Opened file pointer to dump to
|
||||
@return void
|
||||
|
||||
This function dumps a given section of a given dictionary into a loadable ini
|
||||
file. It is Ok to specify @c stderr or @c stdout as output files.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#ifdef SUPPORT_FATFS
|
||||
void iniparser_dumpsection_ini(dictionary * d, char * s, FIL *f);
|
||||
#else
|
||||
void iniparser_dumpsection_ini(dictionary * d, char * s, FILE * f);
|
||||
#endif
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Dump a dictionary to an opened file pointer.
|
||||
@param d Dictionary to dump.
|
||||
@param f Opened file pointer to dump to.
|
||||
@return void
|
||||
|
||||
This function prints out the contents of a dictionary, one element by
|
||||
line, onto the provided file pointer. It is OK to specify @c stderr
|
||||
or @c stdout as output files. This function is meant for debugging
|
||||
purposes mostly.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#ifdef SUPPORT_FATFS
|
||||
void iniparser_dump(dictionary * d, FIL *f);
|
||||
#else
|
||||
void iniparser_dump(dictionary * d, FILE * f);
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Get the number of keys in a section of a dictionary.
|
||||
@param d Dictionary to examine
|
||||
@param s Section name of dictionary to examine
|
||||
@return Number of keys in section
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int iniparser_getsecnkeys(dictionary * d, char * s);
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Get the number of keys in a section of a dictionary.
|
||||
@param d Dictionary to examine
|
||||
@param s Section name of dictionary to examine
|
||||
@return pointer to statically allocated character strings
|
||||
|
||||
This function queries a dictionary and finds all keys in a given section.
|
||||
Each pointer in the returned char pointer-to-pointer is pointing to
|
||||
a string allocated in the dictionary; do not free or modify them.
|
||||
|
||||
This function returns NULL in case of error.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
char ** iniparser_getseckeys(dictionary * d, char * s);
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Get the string associated to a key
|
||||
@param d Dictionary to search
|
||||
@param key Key string to look for
|
||||
@param def Default value to return if key not found.
|
||||
@return pointer to statically allocated character string
|
||||
|
||||
This function queries a dictionary for a key. A key as read from an
|
||||
ini file is given as "section:key". If the key cannot be found,
|
||||
the pointer passed as 'def' is returned.
|
||||
The returned char pointer is pointing to a string allocated in
|
||||
the dictionary, do not free or modify it.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
char * iniparser_getstring(dictionary * d, const char * key, char * def);
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Get the string associated to a key, convert to an int
|
||||
@param d Dictionary to search
|
||||
@param key Key string to look for
|
||||
@param notfound Value to return in case of error
|
||||
@return integer
|
||||
|
||||
This function queries a dictionary for a key. A key as read from an
|
||||
ini file is given as "section:key". If the key cannot be found,
|
||||
the notfound value is returned.
|
||||
|
||||
Supported values for integers include the usual C notation
|
||||
so decimal, octal (starting with 0) and hexadecimal (starting with 0x)
|
||||
are supported. Examples:
|
||||
|
||||
- "42" -> 42
|
||||
- "042" -> 34 (octal -> decimal)
|
||||
- "0x42" -> 66 (hexa -> decimal)
|
||||
|
||||
Warning: the conversion may overflow in various ways. Conversion is
|
||||
totally outsourced to strtol(), see the associated man page for overflow
|
||||
handling.
|
||||
|
||||
Credits: Thanks to A. Becker for suggesting strtol()
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int iniparser_getint(dictionary * d, const char * key, int notfound);
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Get the string associated to a key, convert to a double
|
||||
@param d Dictionary to search
|
||||
@param key Key string to look for
|
||||
@param notfound Value to return in case of error
|
||||
@return double
|
||||
|
||||
This function queries a dictionary for a key. A key as read from an
|
||||
ini file is given as "section:key". If the key cannot be found,
|
||||
the notfound value is returned.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
double iniparser_getdouble(dictionary * d, const char * key, double notfound);
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Get the string associated to a key, convert to a boolean
|
||||
@param d Dictionary to search
|
||||
@param key Key string to look for
|
||||
@param notfound Value to return in case of error
|
||||
@return integer
|
||||
|
||||
This function queries a dictionary for a key. A key as read from an
|
||||
ini file is given as "section:key". If the key cannot be found,
|
||||
the notfound value is returned.
|
||||
|
||||
A true boolean is found if one of the following is matched:
|
||||
|
||||
- A string starting with 'y'
|
||||
- A string starting with 'Y'
|
||||
- A string starting with 't'
|
||||
- A string starting with 'T'
|
||||
- A string starting with '1'
|
||||
|
||||
A false boolean is found if one of the following is matched:
|
||||
|
||||
- A string starting with 'n'
|
||||
- A string starting with 'N'
|
||||
- A string starting with 'f'
|
||||
- A string starting with 'F'
|
||||
- A string starting with '0'
|
||||
|
||||
The notfound value returned if no boolean is identified, does not
|
||||
necessarily have to be 0 or 1.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int iniparser_getboolean(dictionary * d, const char * key, int notfound);
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Set an entry in a dictionary.
|
||||
@param ini Dictionary to modify.
|
||||
@param entry Entry to modify (entry name)
|
||||
@param val New value to associate to the entry.
|
||||
@return int 0 if Ok, -1 otherwise.
|
||||
|
||||
If the given entry can be found in the dictionary, it is modified to
|
||||
contain the provided value. If it cannot be found, -1 is returned.
|
||||
It is Ok to set val to NULL.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int iniparser_set(dictionary * ini, const char * entry, const char * val);
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Delete an entry in a dictionary
|
||||
@param ini Dictionary to modify
|
||||
@param entry Entry to delete (entry name)
|
||||
@return void
|
||||
|
||||
If the given entry can be found, it is deleted from the dictionary.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
void iniparser_unset(dictionary * ini, const char * entry);
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Finds out if a given entry exists in a dictionary
|
||||
@param ini Dictionary to search
|
||||
@param entry Name of the entry to look for
|
||||
@return integer 1 if entry exists, 0 otherwise
|
||||
|
||||
Finds out if a given entry exists in the dictionary. Since sections
|
||||
are stored as keys with NULL associated values, this is the only way
|
||||
of querying for the presence of sections in a dictionary.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int iniparser_find_entry(dictionary * ini, const char * entry) ;
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Parse an ini file and return an allocated dictionary object
|
||||
@param ininame Name of the ini file to read.
|
||||
@return Pointer to newly allocated dictionary
|
||||
|
||||
This is the parser for ini files. This function is called, providing
|
||||
the name of the file to be read. It returns a dictionary object that
|
||||
should not be accessed directly, but through accessor functions
|
||||
instead.
|
||||
|
||||
The returned dictionary must be freed using iniparser_freedict().
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
dictionary * iniparser_load(const char * ininame);
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Free all memory associated to an ini dictionary
|
||||
@param d Dictionary to free
|
||||
@return void
|
||||
|
||||
Free all memory associated to an ini dictionary.
|
||||
It is mandatory to call this function before the dictionary object
|
||||
gets out of the current context.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
void iniparser_freedict(dictionary * d);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
489
components/utils/INI/src/dictionary.c
Executable file
489
components/utils/INI/src/dictionary.c
Executable file
@@ -0,0 +1,489 @@
|
||||
/*
|
||||
Copyright (c) 2000-2011 by Nicolas Devillard.
|
||||
MIT License
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@file dictionary.c
|
||||
@author N. Devillard
|
||||
@brief Implements a dictionary for string variables.
|
||||
|
||||
This module implements a simple dictionary object, i.e. a list
|
||||
of string/string associations. This object is useful to store e.g.
|
||||
informations retrieved from a configuration file (ini files).
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Includes
|
||||
---------------------------------------------------------------------------*/
|
||||
#include "dictionary.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
//#include <unistd.h>
|
||||
|
||||
/** Maximum value size for integers and doubles. */
|
||||
#define MAXVALSZ 1024
|
||||
|
||||
/** Minimal allocated number of entries in a dictionary */
|
||||
#define DICTMINSZ 128
|
||||
|
||||
/** Invalid key token */
|
||||
#define DICT_INVALID_KEY ((char*)-1)
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Private functions
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
/* Doubles the allocated size associated to a pointer */
|
||||
/* 'size' is the current allocated size. */
|
||||
static void * mem_double(void * ptr, size_t size)
|
||||
{
|
||||
void * newptr ;
|
||||
|
||||
newptr = calloc(2 * size, 1);
|
||||
|
||||
if (newptr == NULL)
|
||||
{
|
||||
return NULL ;
|
||||
}
|
||||
|
||||
memcpy(newptr, ptr, size);
|
||||
free(ptr);
|
||||
return newptr ;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Duplicate a string
|
||||
@param s String to duplicate
|
||||
@return Pointer to a newly allocated string, to be freed with free()
|
||||
|
||||
This is a replacement for strdup(). This implementation is provided
|
||||
for systems that do not have it.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
char * xstrdup(const char * s)
|
||||
{
|
||||
char * t ;
|
||||
size_t len ;
|
||||
|
||||
if (!s)
|
||||
return NULL ;
|
||||
|
||||
len = strlen(s) + 1 ;
|
||||
t = (char *)malloc(len) ;
|
||||
|
||||
if (t)
|
||||
{
|
||||
memcpy(t, s, len) ;
|
||||
}
|
||||
|
||||
return t ;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Function codes
|
||||
---------------------------------------------------------------------------*/
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Compute the hash key for a string.
|
||||
@param key Character string to use for key.
|
||||
@return 1 unsigned int on at least 32 bits.
|
||||
|
||||
This hash function has been taken from an Article in Dr Dobbs Journal.
|
||||
This is normally a collision-free function, distributing keys evenly.
|
||||
The key is stored anyway in the struct so that collision can be avoided
|
||||
by comparing the key itself in last resort.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
unsigned dictionary_hash(const char * key)
|
||||
{
|
||||
size_t len ;
|
||||
unsigned hash ;
|
||||
size_t i ;
|
||||
|
||||
len = strlen(key);
|
||||
|
||||
for (hash = 0, i = 0 ; i < len ; i++)
|
||||
{
|
||||
hash += (unsigned)key[i] ;
|
||||
hash += (hash << 10);
|
||||
hash ^= (hash >> 6) ;
|
||||
}
|
||||
|
||||
hash += (hash << 3);
|
||||
hash ^= (hash >> 11);
|
||||
hash += (hash << 15);
|
||||
return hash ;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Create a new dictionary object.
|
||||
@param size Optional initial size of the dictionary.
|
||||
@return 1 newly allocated dictionary objet.
|
||||
|
||||
This function allocates a new dictionary object of given size and returns
|
||||
it. If you do not know in advance (roughly) the number of entries in the
|
||||
dictionary, give size=0.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
dictionary * dictionary_new(size_t size)
|
||||
{
|
||||
dictionary * d ;
|
||||
|
||||
/* If no size was specified, allocate space for DICTMINSZ */
|
||||
if (size < DICTMINSZ) size = DICTMINSZ ;
|
||||
|
||||
d = (dictionary *)calloc(1, sizeof * d) ;
|
||||
|
||||
if (d)
|
||||
{
|
||||
d->size = size ;
|
||||
d->val = (char **)calloc(size, sizeof * d->val);
|
||||
d->key = (char **)calloc(size, sizeof * d->key);
|
||||
d->hash = (unsigned int *)calloc(size, sizeof * d->hash);
|
||||
}
|
||||
|
||||
return d ;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Delete a dictionary object
|
||||
@param d dictionary object to deallocate.
|
||||
@return void
|
||||
|
||||
Deallocate a dictionary object and all memory associated to it.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
void dictionary_del(dictionary * d)
|
||||
{
|
||||
int i ;
|
||||
|
||||
if (d == NULL) return ;
|
||||
|
||||
for (i = 0 ; i < d->size ; i++)
|
||||
{
|
||||
if (d->key[i] != NULL)
|
||||
free(d->key[i]);
|
||||
|
||||
if (d->val[i] != NULL)
|
||||
free(d->val[i]);
|
||||
}
|
||||
|
||||
free(d->val);
|
||||
free(d->key);
|
||||
free(d->hash);
|
||||
free(d);
|
||||
return ;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Get a value from a dictionary.
|
||||
@param d dictionary object to search.
|
||||
@param key Key to look for in the dictionary.
|
||||
@param def Default value to return if key not found.
|
||||
@return 1 pointer to internally allocated character string.
|
||||
|
||||
This function locates a key in a dictionary and returns a pointer to its
|
||||
value, or the passed 'def' pointer if no such key can be found in
|
||||
dictionary. The returned character pointer points to data internal to the
|
||||
dictionary object, you should not try to free it or modify it.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
char * dictionary_get(dictionary * d, const char * key, char * def)
|
||||
{
|
||||
unsigned hash ;
|
||||
int i ;
|
||||
|
||||
hash = dictionary_hash(key);
|
||||
|
||||
for (i = 0 ; i < d->size ; i++)
|
||||
{
|
||||
if (d->key[i] == NULL)
|
||||
continue ;
|
||||
|
||||
/* Compare hash */
|
||||
if (hash == d->hash[i])
|
||||
{
|
||||
/* Compare string, to avoid hash collisions */
|
||||
if (!strcmp(key, d->key[i]))
|
||||
{
|
||||
return d->val[i] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return def ;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Set a value in a dictionary.
|
||||
@param d dictionary object to modify.
|
||||
@param key Key to modify or add.
|
||||
@param val Value to add.
|
||||
@return int 0 if Ok, anything else otherwise
|
||||
|
||||
If the given key is found in the dictionary, the associated value is
|
||||
replaced by the provided one. If the key cannot be found in the
|
||||
dictionary, it is added to it.
|
||||
|
||||
It is Ok to provide a NULL value for val, but NULL values for the dictionary
|
||||
or the key are considered as errors: the function will return immediately
|
||||
in such a case.
|
||||
|
||||
Notice that if you dictionary_set a variable to NULL, a call to
|
||||
dictionary_get will return a NULL value: the variable will be found, and
|
||||
its value (NULL) is returned. In other words, setting the variable
|
||||
content to NULL is equivalent to deleting the variable from the
|
||||
dictionary. It is not possible (in this implementation) to have a key in
|
||||
the dictionary without value.
|
||||
|
||||
This function returns non-zero in case of failure.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int dictionary_set(dictionary * d, const char * key, const char * val)
|
||||
{
|
||||
int i ;
|
||||
unsigned hash ;
|
||||
|
||||
if (d == NULL || key == NULL) return -1 ;
|
||||
|
||||
/* Compute hash for this key */
|
||||
hash = dictionary_hash(key) ;
|
||||
|
||||
/* Find if value is already in dictionary */
|
||||
if (d->n > 0)
|
||||
{
|
||||
for (i = 0 ; i < d->size ; i++)
|
||||
{
|
||||
if (d->key[i] == NULL)
|
||||
continue ;
|
||||
|
||||
if (hash == d->hash[i]) /* Same hash value */
|
||||
{
|
||||
if (!strcmp(key, d->key[i])) /* Same key */
|
||||
{
|
||||
/* Found a value: modify and return */
|
||||
if (d->val[i] != NULL)
|
||||
free(d->val[i]);
|
||||
|
||||
d->val[i] = val ? xstrdup(val) : NULL ;
|
||||
/* Value has been modified: return */
|
||||
return 0 ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Add a new value */
|
||||
/* See if dictionary needs to grow */
|
||||
if (d->n == d->size)
|
||||
{
|
||||
|
||||
/* Reached maximum size: reallocate dictionary */
|
||||
d->val = (char **)mem_double(d->val, d->size * sizeof * d->val) ;
|
||||
d->key = (char **)mem_double(d->key, d->size * sizeof * d->key) ;
|
||||
d->hash = (unsigned int *)mem_double(d->hash, d->size * sizeof * d->hash) ;
|
||||
|
||||
if ((d->val == NULL) || (d->key == NULL) || (d->hash == NULL))
|
||||
{
|
||||
/* Cannot grow dictionary */
|
||||
return -1 ;
|
||||
}
|
||||
|
||||
/* Double size */
|
||||
d->size *= 2 ;
|
||||
}
|
||||
|
||||
/* Insert key in the first empty slot. Start at d->n and wrap at
|
||||
d->size. Because d->n < d->size this will necessarily
|
||||
terminate. */
|
||||
for (i = d->n ; d->key[i] ; )
|
||||
{
|
||||
if(++i == d->size) i = 0;
|
||||
}
|
||||
|
||||
/* Copy key */
|
||||
d->key[i] = xstrdup(key);
|
||||
d->val[i] = val ? xstrdup(val) : NULL ;
|
||||
d->hash[i] = hash;
|
||||
d->n ++ ;
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Delete a key in a dictionary
|
||||
@param d dictionary object to modify.
|
||||
@param key Key to remove.
|
||||
@return void
|
||||
|
||||
This function deletes a key in a dictionary. Nothing is done if the
|
||||
key cannot be found.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
void dictionary_unset(dictionary * d, const char * key)
|
||||
{
|
||||
unsigned hash ;
|
||||
int i ;
|
||||
|
||||
if (key == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
hash = dictionary_hash(key);
|
||||
|
||||
for (i = 0 ; i < d->size ; i++)
|
||||
{
|
||||
if (d->key[i] == NULL)
|
||||
continue ;
|
||||
|
||||
/* Compare hash */
|
||||
if (hash == d->hash[i])
|
||||
{
|
||||
/* Compare string, to avoid hash collisions */
|
||||
if (!strcmp(key, d->key[i]))
|
||||
{
|
||||
/* Found key */
|
||||
break ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (i >= d->size)
|
||||
/* Key not found */
|
||||
return ;
|
||||
|
||||
free(d->key[i]);
|
||||
d->key[i] = NULL ;
|
||||
|
||||
if (d->val[i] != NULL)
|
||||
{
|
||||
free(d->val[i]);
|
||||
d->val[i] = NULL ;
|
||||
}
|
||||
|
||||
d->hash[i] = 0 ;
|
||||
d->n -- ;
|
||||
return ;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Dump a dictionary to an opened file pointer.
|
||||
@param d Dictionary to dump
|
||||
@param f Opened file pointer.
|
||||
@return void
|
||||
|
||||
Dumps a dictionary onto an opened file pointer. Key pairs are printed out
|
||||
as @c [Key]=[Value], one per line. It is Ok to provide stdout or stderr as
|
||||
output file pointers.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
void dictionary_dump(dictionary * d, FILE * out)
|
||||
{
|
||||
int i ;
|
||||
|
||||
if (d == NULL || out == NULL) return ;
|
||||
|
||||
if (d->n < 1)
|
||||
{
|
||||
fprintf(out, "empty dictionary\n");
|
||||
return ;
|
||||
}
|
||||
|
||||
for (i = 0 ; i < d->size ; i++)
|
||||
{
|
||||
if (d->key[i])
|
||||
{
|
||||
fprintf(out, "%20s\t[%s]\n",
|
||||
d->key[i],
|
||||
d->val[i] ? d->val[i] : "UNDEF");
|
||||
}
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/* Test code */
|
||||
#ifdef TESTDIC
|
||||
#define NVALS 20000
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
dictionary * d ;
|
||||
char * val ;
|
||||
int i ;
|
||||
char cval[90] ;
|
||||
|
||||
/* Allocate dictionary */
|
||||
printf("allocating...\n");
|
||||
d = dictionary_new(0);
|
||||
|
||||
/* Set values in dictionary */
|
||||
printf("setting %d values...\n", NVALS);
|
||||
|
||||
for (i = 0 ; i < NVALS ; i++)
|
||||
{
|
||||
sprintf(cval, "%04d", i);
|
||||
dictionary_set(d, cval, "salut");
|
||||
}
|
||||
|
||||
printf("getting %d values...\n", NVALS);
|
||||
|
||||
for (i = 0 ; i < NVALS ; i++)
|
||||
{
|
||||
sprintf(cval, "%04d", i);
|
||||
val = dictionary_get(d, cval, DICT_INVALID_KEY);
|
||||
|
||||
if (val == DICT_INVALID_KEY)
|
||||
{
|
||||
printf("cannot get value for key [%s]\n", cval);
|
||||
}
|
||||
}
|
||||
|
||||
printf("unsetting %d values...\n", NVALS);
|
||||
|
||||
for (i = 0 ; i < NVALS ; i++)
|
||||
{
|
||||
sprintf(cval, "%04d", i);
|
||||
dictionary_unset(d, cval);
|
||||
}
|
||||
|
||||
if (d->n != 0)
|
||||
{
|
||||
printf("error deleting values\n");
|
||||
}
|
||||
|
||||
printf("deallocating...\n");
|
||||
dictionary_del(d);
|
||||
return 0 ;
|
||||
}
|
||||
#endif
|
||||
/* vim: set ts=4 et sw=4 tw=75 */
|
1141
components/utils/INI/src/iniparser.c
Executable file
1141
components/utils/INI/src/iniparser.c
Executable file
File diff suppressed because it is too large
Load Diff
5
components/utils/Makefile
Normal file → Executable file
5
components/utils/Makefile
Normal file → Executable file
@@ -24,10 +24,13 @@ LOCALDIR = $(patsubst %/,%,$(subst $(realpath $(QTOP))/,,$(CUR_DIR)))
|
||||
####################################################################
|
||||
|
||||
|
||||
TREE_LIB_ENABLE=0
|
||||
TREE_LIB_ENABLE=y
|
||||
lib=
|
||||
subdirs=
|
||||
|
||||
CFGFLAGS += -I$(QTOP)/components/utils/JSON/include
|
||||
CFGFLAGS += -I$(QTOP)/components/utils/INI/include
|
||||
|
||||
include ${QTOP}/qmk/generic/Make.tpl
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user