inih(INI Not Invented Here) 는 C로 작성된 간단한 .INI 파일 파서입니다. 단 두 페이지의 코드이고 작고 단순 하도록 설계되었으므로 임베디드 시스템에 적합합니다. 또한 RFC 822 스타일의 여러 줄 구문 및 name: value
항목을 포함하여 Python의 ConfigParser 스타일의 .INI 파일과 어느 정도 호환됩니다.
이를 사용하려면 ini_parse()
에 INI 파일을 제공하면 구문 분석된 모든 name=value
쌍에 대해 콜백을 호출하여 섹션, 이름 및 값에 대한 문자열을 제공합니다. 이 방식("SAX 스타일")은 메모리가 적은 임베디드 시스템에서도 잘 작동할 뿐만 아니라 KISS 구현에도 적합하기 때문에 수행됩니다.
또한 ini_parse_file()
호출하여 FILE*
객체에서 직접 구문 분석하거나, ini_parse_string()
호출하여 문자열의 데이터를 구문 분석하거나, ini_parse_stream()
호출하여 사용자 정의 I/O에 대한 사용자 정의 fgets 스타일 판독기 함수를 사용하여 구문 분석할 수 있습니다.
릴리스를 다운로드하거나, 소스를 찾아보거나, X-Macros와 함께 DRY 스타일로 inih를 사용하는 방법을 읽어보세요.
전처리기 정의를 사용하여 inih의 다양한 측면을 제어할 수 있습니다.
-DINI_ALLOW_MULTILINE=0
추가하세요.-DINI_ALLOW_BOM=0
추가하세요.;
성격. 비활성화하려면 -DINI_ALLOW_INLINE_COMMENTS=0
추가하세요. INI_INLINE_COMMENT_PREFIXES
사용하여 인라인 주석을 시작하는 문자를 지정할 수도 있습니다.;
그리고 #
줄의 시작 부분에서 주석을 시작합니다. INI_START_COMMENT_PREFIXES
변경하여 이를 무시할 수 있습니다.=
또는 :
없음)을 오류로 처리합니다. 값이 없는 이름을 허용하려면 -DINI_ALLOW_NO_VALUE=1
추가하세요. 그러면 inih는 값이 NULL로 설정된 핸들러 함수를 호출합니다.-DINI_STOP_ON_FIRST_ERROR=1
추가하세요.ini_handler
콜백은 줄 번호를 매개변수로 받지 않습니다. 필요한 경우 -DINI_HANDLER_LINENO=1
추가하세요.name=value
쌍의 핸들러만 호출합니다. 새 섹션을 검색하려면(예: INI 파일에 동일한 이름을 가진 여러 섹션이 있음) -DINI_CALL_HANDLER_ON_NEW_SECTION=1
추가하세요. 그런 다음 새 섹션이 발견될 때마다 핸들러 함수가 호출됩니다. section
새 섹션 이름으로 설정되지만 name
과 value
NULL로 설정됩니다.malloc
사용하여 힙에 할당하려면 -DINI_USE_STACK=0
을 지정하세요.-DINI_MAX_LINE=1000
과 같은 것을 추가하세요. INI_MAX_LINE
은 가장 긴 줄보다 3개 더 커야 합니다( r
, n
및 NUL로 인해).INI_INITIAL_ALLOC
힙을 사용할 때 초기 malloc 크기를 지정합니다. 기본값은 200바이트입니다.-DINI_USE_STACK=0
)을 사용할 때 inih는 INI_INITIAL_ALLOC
바이트의 고정 크기 버퍼를 할당합니다. 필요한 경우 두 배로 늘려 INI_MAX_LINE
바이트까지 늘리려면 -DINI_ALLOW_REALLOC=1
설정하세요.malloc
, free
및 realloc
함수가 사용됩니다. 사용자 지정 할당자를 사용하려면 -DINI_CUSTOM_ALLOCATOR=1
(및 -DINI_USE_STACK=0
)을 지정하세요. stdlib.h
메모리 할당 함수와 동일한 서명을 가져야 하는 ini_malloc
, ini_free
및 ( INI_ALLOW_REALLOC
이 설정된 경우) ini_realloc
함수를 정의하고 연결해야 합니다. #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "../ini.h"
typedef struct
{
int version ;
const char * name ;
const char * email ;
} configuration ;
static int handler ( void * user , const char * section , const char * name ,
const char * value )
{
configuration * pconfig = ( configuration * ) user ;
#define MATCH ( s , n ) strcmp(section, s) == 0 && strcmp(name, n) == 0
if ( MATCH ( "protocol" , "version" )) {
pconfig -> version = atoi ( value );
} else if ( MATCH ( "user" , "name" )) {
pconfig -> name = strdup ( value );
} else if ( MATCH ( "user" , "email" )) {
pconfig -> email = strdup ( value );
} else {
return 0 ; /* unknown section/name, error */
}
return 1 ;
}
int main ( int argc , char * argv [])
{
configuration config ;
if ( ini_parse ( "test.ini" , handler , & config ) < 0 ) {
printf ( "Can't load 'test.ini'n" );
return 1 ;
}
printf ( "Config loaded from 'test.ini': version=%d, name=%s, email=%sn" ,
config . version , config . name , config . email );
return 0 ;
}
C++ 및 STL을 사용하는 경우 map
에 값을 저장하고 해당 값을 Get()
할 수 있는 사용하기 쉬운 INIReader 클래스도 있습니다.
# include < iostream >
# include " INIReader.h "
int main ()
{
INIReader reader ( " ../examples/test.ini " );
if (reader. ParseError () < 0 ) {
std::cout << " Can't load 'test.ini' n " ;
return 1 ;
}
std::cout << " Config loaded from 'test.ini': version= "
<< reader. GetInteger ( " protocol " , " version " , - 1 ) << " , name= "
<< reader. Get ( " user " , " name " , " UNKNOWN " ) << " , email= "
<< reader. Get ( " user " , " email " , " UNKNOWN " ) << " , pi= "
<< reader. GetReal ( " user " , " pi " , - 1 ) << " , active= "
<< reader. GetBoolean ( " user " , " active " , true ) << " n " ;
return 0 ;
}
이 간단한 C++ API는 잘 작동하지만 완전한 기능을 갖춘 것은 아닙니다. 지금은 C++ API에 대해 더 많은 작업을 할 계획이 없으므로 좀 더 강력한 기능(예: GetSections()
및 GetFields()
함수)을 원한다면 다음 포크를 참조하세요.
inih와 Python의 ConfigParser 표준 라이브러리 모듈 간의 몇 가지 차이점은 다음과 같습니다.
_wfopen()
호출하여 파일을 연 다음 ini_parse_file()
호출하여 구문 분석해야 합니다. inih에는 wchar_t
또는 유니코드 처리가 포함되지 않습니다. meson.build
파일이 필요하지 않으며 주요 목적은 배포용입니다.-Ddefault_library=static
정적 라이브러리가 빌드됩니다.-Ddistro_install=false
라이브러리를 사용하면 헤더 및 pkg-config 파일이 설치되지 않습니다.-Dwith_INIReader=false
사용하면 C++ 라이브러리 빌드를 비활성화할 수 있습니다.distro_install
이 true
로 설정된 경우에는 작동하지 않습니다.inih
및 INIReader
입니다.inih_dep
및 INIReader_dep
종속 변수를 사용할 수 있습니다. 하위 프로젝트에 대해 default_library=static
및 distro_install=false
설정할 수 있습니다. 공식 Wrap은 WrapDB에서 제공됩니다.project()
함수에서 license
태그 뒤에 version : '<version_as_int>',
추가하고 두 library()
함수에서 soversion
태그 뒤에 version : meson.project_version(),
추가합니다. inih
.tipi/deps
에 다음 항목을 추가하기만 하면 tipi.build 프로젝트에서 쉽게 사용할 수 있습니다( r56
최신 버전 태그로 교체).
{
"benhoyt/inih" : { "@" : " r56 " }
}
프로젝트에 필요한 포함 경로는 다음과 같습니다.
#include <ini.h>
vcpkg 종속성 관리자를 사용하여 inih를 빌드하고 설치할 수 있습니다.
git clone https://github.com/Microsoft/vcpkg.git
cd vcpkg
./bootstrap-vcpkg.sh
./vcpkg integrate install
./vcpkg install inih
vcpkg의 inih 포트는 Microsoft 팀 구성원과 커뮤니티 기여자가 최신 상태로 유지됩니다. 버전이 오래된 경우 vcpkg 저장소에서 이슈 또는 풀 요청을 생성하세요.