私自身は異なる構成パーサーを使用し、最近のプロジェクトではre2cを使用しました(構成はnginx構成に似ていました)。 Re2cはキャンディと少し共通点があります-これはコード生成です:
構成ファイルや構造をエンコードする必要はありません; Confetty Magicianがすべてを行います。
残念ながら、ドキュメントは一切ありません。そうでなければ、この記事はそうではなかったでしょう。 興味のある方には、...
ソースをインストールする
c github github.com/mailru/confetti基本的な要件は、YACCのインストールです。
サンプルフォルダには使用例があります。 この例を使用して構成を作成するのは直感的です。 全体のポイントは、いくつかのステップの順次実行です。
// 1. example.cfgtmpl:
../confetti -i example.cfgtmpl -n my_product -f my_product.cfg
// 2. h :
../confetti -i example.cfgtmpl -n my_product -h my_product_cfg.h
../confetti -i example.cfgtmpl -n my_product -c my_product_cfg.c
gcc -Wall -g -O0 -Werror -std=gnu99 -I. -c my_product_cfg.c
// 2. :
../confetti -i example.cfgtmpl -H prscfg.h
../confetti -i example.cfgtmpl -p prscfg.c
gcc -Wall -g -O0 -Werror -std=gnu99 -I. -c prscfg.c
// 4.
gcc -Wall -g -O0 -Werror -std=gnu99 -I. -c example.c
gcc -o example example.o my_product_cfg.o prscfg.o
例を検討すると、プロジェクトでの実装方法が明確になります。 以下は、私のプロジェクトの実装手順です。
1.彼のプロジェクトのソースにフォルダーを作成しました
cd config.src
2.実行可能ファイルを書き直した
cp confetty / usr / local / bin
3)makeファイルを修正しました
私のプロジェクトに関連して:
CONFETTI=/usr/local/bin/confetti
NAME=tarantool_proxy
CFG=tarantool_proxy.cfgtmpl
test_OBJS=tarantool_proxy_cfg.o tnt_config.o prscfg.o
all: $(NAME).cfg test
.SUFFIXES: .oc
.co:
$(CC) $(CFLAGS) $(INCLUDE) -c $<
test: $(test_OBJS)
$(CC) -o $@ $(test_OBJS) $(LIB)
tarantool_proxy: $(test_OBJS)
$(CC) -o $@ $(test_OBJS) $(LIB)
$(NAME).cfg: $(CFG)
$(CONFETTI) -i $< -n $(NAME) -f $(NAME).cfg
$(CONFETTI) -i $< -n $(NAME) -h $(NAME)_cfg.h
$(CONFETTI) -i $< -n $(NAME) -c $(NAME)_cfg.c
prscfg.c: $(CFG)
$(CONFETTI) -i $< -p $@
prscfg.h: $(CFG)
$(CONFETTI) -i $< -H $@
prscfg.c: prscfg.h $(NAME)_cfg.h
$(NAME)_cfg.c: prscfg.h $(NAME)_cfg.h
clean:
rm -f $(NAME).cfg $(NAME)_cfg.c $(NAME)_cfg.h
rm -f prscfg.c prscfg.h
rm -f test
rm *.o
install:
cp $(NAME).def.cfg ../cfg/$(NAME).cfg
cp tarantool_proxy_cfg.o ..
cp prscfg.o ..
cp *.h ..
生成されたファイルをプロジェクトのソースにコピーするインストールターゲットを追加したことに注意してください。
3)テンプレート構成ファイルを作成しました
example.cfgtmplから
%{}ブロックで、ファイル名をtarantool_proxy_cfg.hプロジェクトにあるはずの名前に置き換えました。
% {
#include <prscfg.h>
#include <tarantool_proxy_cfg.h>
void out_warning ( ConfettyError r、 char * format、... ) ;
% } :
4.独自の構成を作成しました
そしてそれをチェックしました:
confetti -i tarantool_proxy.cfgtmpl -n tarantool_proxy -f tarantool_proxy.cfg
tarantool_proxy.cfgtmpl構成の欠落部分を追加して、彼に適用します。
pid = "/usr/local/var/tarantool_proxy.pid"
log = "/usr/local/var/log/tarantool_proxy.log"
デーモン= 1
pool_size = 4096
#スレッド数
スレッド= 4
#聞く
host = "localhost"
ポート= 33013
#サーバー接続
サーバー= [
ホスト名= "localhost"
ポート= 33013
名前空間= [
キー= NULL 、必須
]
]
名前空間= [
タイプ= NULL 、必須
]
5.構成ファイルを生成した後
tarantool_proxy.cfgはそれをデフォルトの設定ファイルtarantool_proxy.def.cfgにコピーし、必要なデータ(そのうちのいくつか)を入力しました:
サーバー[ 0 ] 。 ホスト名 = "host2"
サーバー[ 0 ] 。 ポート = 33013
サーバー[ 1 ] 。 ホスト名 = "host1"
サーバー[ 1 ] 。 ポート = 33023
名前空間[ 1 ] 。 タイプ = "str"
名前空間[ 0 ] 。 タイプ = "int"
サーバー[ 0 ] 。 名前空間 [ 0 ] 。 キー = "345"
サーバー[ 0 ] 。 名前空間 [ 1 ] 。 キー = "abc"
サーバー[ 1 ] 。 名前空間 [ 0 ] 。 キー = "xyz"
サーバー[ 1 ] 。 名前空間 [ 1 ] 。 キー = "345"
テンプレートファイルで指定された値がデフォルトで使用されます。
さらに、tarantool_proxy.cfgファイルは常に紙吹雪によって上書きされるため、このファイルを二重として使用しました。
6. example.cに基づいてサンプルファイルテスターを作成しました。
7.すべてがうまくいくまでmakeを行う
それが初めて動作する場合、それは素晴らしいでしょう:)
./test
==========Accepted: 11; Skipped: 0===========
pid => '/usr/local/var/tarantool_proxy.pid'
log => '/usr/local/var/log/tarantool_proxy.log'
daemon => '1'
pool_size => '4096'
threads => '4'
host => 'localhost'
port => '33013'
server[0].hostname => 'localhost'
server[0].port => '33013'
server[0].namespace[0].key => '345'
server[0].namespace[1].key => 'abc'
server[1].hostname => 'tfn24'
server[1].port => '33023'
server[1].namespace[0].key => 'xyz'
server[1].namespace[1].key => '345'
namespace[0].type => 'int'
namespace[1].type => 'str'
==========DIRECT=========
pid=/usr/local/var/tarantool_proxy.pid
daemon=1
keys
==========Destroy=========
:
./test
==========Accepted: 11; Skipped: 0===========
pid => '/usr/local/var/tarantool_proxy.pid'
log => '/usr/local/var/log/tarantool_proxy.log'
daemon => '1'
pool_size => '4096'
threads => '4'
host => 'localhost'
port => '33013'
server[0].hostname => 'localhost'
server[0].port => '33013'
server[0].namespace[0].key => '345'
server[0].namespace[1].key => 'abc'
server[1].hostname => 'tfn24'
server[1].port => '33023'
server[1].namespace[0].key => 'xyz'
server[1].namespace[1].key => '345'
namespace[0].type => 'int'
namespace[1].type => 'str'
==========DIRECT=========
pid=/usr/local/var/tarantool_proxy.pid
daemon=1
keys
==========Destroy=========
./test
==========Accepted: 11; Skipped: 0===========
pid => '/usr/local/var/tarantool_proxy.pid'
log => '/usr/local/var/log/tarantool_proxy.log'
daemon => '1'
pool_size => '4096'
threads => '4'
host => 'localhost'
port => '33013'
server[0].hostname => 'localhost'
server[0].port => '33013'
server[0].namespace[0].key => '345'
server[0].namespace[1].key => 'abc'
server[1].hostname => 'tfn24'
server[1].port => '33023'
server[1].namespace[0].key => 'xyz'
server[1].namespace[1].key => '345'
namespace[0].type => 'int'
namespace[1].type => 'str'
==========DIRECT=========
pid=/usr/local/var/tarantool_proxy.pid
daemon=1
keys
==========Destroy=========
「DIRECT」ブロックに関しては、これは直接アクセスをテストしています:
printf ( "========== DIRECT ========= \ n " ) ;
printf ( "pid =%s \ n " 、 cfg。pid ) ;
printf ( "daemon =%d \ n " 、 cfg。daemon ) ;
または配列要素へのアクセス:
tarantool_proxy_namespace ** it = cfg。 名前空間 ;
while ( * it != NULL ) {
printf ( "namespace type =%s \ n " 、 ( * it ) -> type ) ;
++それ;
}
だから今残っているのは:
- make installを実行します。これにより、必要なすべてのファイルがプロジェクトのディレクトリに書き換えられます。
config.srcディレクトリはテストサイトのままです。
- 自分のプロジェクトに#include {name} _cfg.hを含めます。{name}は、構成ファイルを生成するときに選択した名前です(私のプロジェクトのtarantool_proxyで)
- ソース構成を宣言し、デフォルト値を割り当てます
tarantool_proxy cfg ;
char *キー、 *値。
fill_default_tarantool_proxy ( & cfg ) ;
- 構成ファイルを宣言して読み取ります。
int nAccepted 、 nSkipped ;
FILE * fh = fopen ( filename 、 "r" ) ;
if ( ! fh ) {
fprintf ( stderr 、 "file%sを開けませんでした\ n " 、 argv [ 1 ] ) ;
1を 返し ます。
}
useStdout = 1 ;
parse_cfg_file_tarantool_proxy ( & cfg 、 fh 、 1 、 & nAccepted 、 & nSkipped ) ;
printf ( "========== Accepted:%d; Skipped:%d =========== \ n " 、 nAccepted 、 nSkipped ) ;
fclose ( fh ) ;
配列を使用する場合、反復子を宣言します。
tarantool_proxy_iterator_t * i ;
i = tarantool_proxy_iterator_init ( ) ;
while ( ( key = tarantool_proxy_iterator_next ( i 、 & cfg 、 & value ) ) != NULL ) {
if ( value ) {
printf ( "%s => '%s' \ n " 、 key 、 value ) ;
無料(値) ;
} else {
printf ( "%s =>(null) \ n " 、 key ) ;
}
}
または、前述のように、データ構造への「直接」アクセスを使用します。
以上で、プロジェクトの再構成(構成の構造の変更)にかかる時間は5分以内になりました。
これにより誰かの時間を大幅に節約できることを願っています。
著者のテオドル・シガエフに感謝