inih (INI Not Invented Here) adalah pengurai file .INI sederhana yang ditulis dalam C. Kode ini hanya beberapa halaman, dan dirancang agar kecil dan sederhana , sehingga cocok untuk sistem tertanam. Ini juga kurang lebih kompatibel dengan file .INI gaya ConfigParser Python, termasuk sintaks multi-baris gaya RFC 822 dan entri name: value
.
Untuk menggunakannya, cukup berikan ini_parse()
file INI, dan itu akan memanggil panggilan balik untuk setiap pasangan name=value
yang diurai, memberi Anda string untuk bagian, nama, dan nilai. Ini dilakukan dengan cara ini ("gaya SAX") karena ini berfungsi dengan baik pada sistem tertanam dengan memori rendah, tetapi juga karena ini cocok untuk implementasi KISS.
Anda juga dapat memanggil ini_parse_file()
untuk mengurai langsung dari objek FILE*
, ini_parse_string()
untuk mengurai data dari string, atau ini_parse_stream()
untuk mengurai menggunakan fungsi pembaca gaya fgets khusus untuk I/O khusus.
Unduh rilisnya, telusuri sumbernya, atau baca tentang cara menggunakan inih dalam gaya KERING dengan X-Makro.
Anda dapat mengontrol berbagai aspek inih menggunakan definisi praprosesor:
-DINI_ALLOW_MULTILINE=0
.-DINI_ALLOW_BOM=0
.;
karakter. Untuk menonaktifkan, tambahkan -DINI_ALLOW_INLINE_COMMENTS=0
. Anda juga dapat menentukan karakter mana yang memulai komentar sebaris menggunakan INI_INLINE_COMMENT_PREFIXES
.;
dan #
untuk memulai komentar di awal baris. Anda dapat menimpanya dengan mengubah INI_START_COMMENT_PREFIXES
.=
atau :
pada baris) sebagai kesalahan. Untuk mengizinkan nama tanpa nilai, tambahkan -DINI_ALLOW_NO_VALUE=1
, dan inih akan memanggil fungsi pengendali Anda dengan nilai yang disetel ke NULL.-DINI_STOP_ON_FIRST_ERROR=1
.ini_handler
tidak menerima nomor baris sebagai parameter. Jika Anda membutuhkannya, tambahkan -DINI_HANDLER_LINENO=1
.name=value
. Untuk mendeteksi bagian baru (misalnya, file INI memiliki beberapa bagian dengan nama yang sama), tambahkan -DINI_CALL_HANDLER_ON_NEW_SECTION=1
. Fungsi pengendali Anda kemudian akan dipanggil setiap kali bagian baru ditemukan, dengan section
disetel ke nama bagian baru tetapi name
dan value
disetel ke NULL.malloc
, tentukan -DINI_USE_STACK=0
.-DINI_MAX_LINE=1000
. Perhatikan bahwa INI_MAX_LINE
harus lebih 3 dari garis terpanjang (karena r
, n
, dan NUL).INI_INITIAL_ALLOC
menentukan ukuran malloc awal saat menggunakan heap. Standarnya adalah 200 byte.-DINI_USE_STACK=0
), inih mengalokasikan buffer berukuran tetap INI_INITIAL_ALLOC
byte. Untuk memungkinkannya bertambah hingga INI_MAX_LINE
byte, dua kali lipat jika diperlukan, setel -DINI_ALLOW_REALLOC=1
.malloc
, free
, dan realloc
perpustakaan standar digunakan; untuk menggunakan pengalokasi khusus, tentukan -DINI_CUSTOM_ALLOCATOR=1
(dan -DINI_USE_STACK=0
). Anda harus mendefinisikan dan menghubungkan fungsi bernama ini_malloc
, ini_free
, dan (jika INI_ALLOW_REALLOC
disetel) ini_realloc
, yang harus memiliki tanda tangan yang sama dengan fungsi alokasi memori stdlib.h
. #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 ;
}
Jika Anda menyukai C++ dan STL, ada juga kelas INIReader yang mudah digunakan yang menyimpan nilai dalam map
dan memungkinkan Anda Get()
nilai tersebut:
# 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 sederhana ini berfungsi dengan baik, tetapi tidak sepenuhnya lengkap. Saya tidak berencana untuk bekerja lebih banyak pada C++ API saat ini, jadi jika Anda menginginkan lebih banyak kekuatan (misalnya fungsi GetSections()
dan GetFields()
), lihat fork ini:
Beberapa perbedaan antara modul perpustakaan standar inih dan ConfigParser Python:
_wfopen()
untuk membuka file dan kemudian ini_parse_file()
untuk menguraikannya; inih tidak termasuk penanganan wchar_t
atau Unicode. meson.build
tidak diperlukan untuk menggunakan atau mengkompilasi inih, tujuan utamanya adalah untuk distribusi.-Ddefault_library=static
dibuat.-Ddistro_install=false
perpustakaan, header dan file pkg-config tidak akan diinstal.-Dwith_INIReader=false
Anda dapat menonaktifkan pembuatan perpustakaan C++.distro_install
disetel ke true
.inih
dan INIReader
.inih_dep
dan INIReader_dep
. Anda mungkin ingin menyetel default_library=static
dan distro_install=false
untuk subproyek. Bungkus resmi disediakan di WrapDB.version : '<version_as_int>',
setelah tag license
di fungsi project()
dan version : meson.project_version(),
setelah tag soversion
di kedua fungsi library()
. inih
dapat dengan mudah digunakan dalam proyek tipi.build hanya dengan menambahkan entri berikut ke .tipi/deps
Anda (ganti r56
dengan tag versi terbaru):
{
"benhoyt/inih" : { "@" : " r56 " }
}
Jalur penyertaan yang diperlukan dalam proyek Anda adalah:
#include <ini.h>
Anda dapat membangun dan menginstal inih menggunakan manajer ketergantungan vcpkg:
git clone https://github.com/Microsoft/vcpkg.git
cd vcpkg
./bootstrap-vcpkg.sh
./vcpkg integrate install
./vcpkg install inih
Port inih di vcpkg selalu diperbarui oleh anggota tim Microsoft dan kontributor komunitas. Jika versinya sudah kedaluwarsa, silakan buat masalah atau tarik permintaan pada repositori vcpkg.