Confetti - simple and quick configuration of your project
If you write a project a little more than average, then as a rule you are faced with settings and configuration. There are quite a few C / C ++ solutions, I want to tell you about another rather simple and beautiful solution from the Mail @ Ru Company, which I used in my project
. I myself used different config parsers, in recent projects I used re2c (the config was similar to nginx config). In re2c there is even a little bit to do with sweets - is code generation:
no it is not necessary to code configuration files and structures, all of you will do Mage Confetty.
Unfortunately, no documentation whatsoever, otherwise this article would not have been. To those interested, we ask ...
The basic requirement is to install YACC.
The example folder has a usage example. Using the example and building the config is intuitive. The whole point is the sequential implementation of several steps: If you look at an example, it will be clear how to implement it in the project. The following are the implementation steps for my project.
cd config.src
cp confetty / usr / local / bin
in relation to my project: Please note, I added the install target, which copies the generated files to the sources of my project.
from example.cfgtmpl
in the% {} block replaced the file name with the name that should be in the tarantool_proxy_cfg.h project:
and checked it: Added the missing part of the tarantool_proxy.cfgtmpl config as applied to his:
tarantool_proxy.cfg copied it to the default configuration file: tarantool_proxy.def.cfg and filled it with the necessary data (some of them):
The values specified in the template file are used by default.
Further, I used this file as a double, since the tarantool_proxy.cfg file is constantly overwritten by confetti
it will be amazing if it works the first time :)
We get : As for the “DIRECT” block, this is testing direct access:
or access to array elements:
So what now remains:
Or we use “direct” access to data structures, as mentioned above.
That's all, reconfiguring the project (changing the structure of the config) now takes no more than 5 minutes.
I hope that this will save a lot of time for someone.
Thanks to the author Teodor Sigaev
. I myself used different config parsers, in recent projects I used re2c (the config was similar to nginx config). In re2c there is even a little bit to do with sweets - is code generation:
no it is not necessary to code configuration files and structures, all of you will do Mage Confetty.
Unfortunately, no documentation whatsoever, otherwise this article would not have been. To those interested, we ask ...
Install the source
c GitHub github.com/mailru/confettiThe basic requirement is to install YACC.
The example folder has a usage example. Using the example and building the config is intuitive. The whole point is the sequential implementation of several steps: If you look at an example, it will be clear how to implement it in the project. The following are the implementation steps for my project.
// 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. created a folder in the sources of his project
cd config.src
2. rewrote the executable file
cp confetty / usr / local / bin
3) fixed the make file
in relation to my project: Please note, I added the install target, which copies the generated files to the sources of my project.
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: .o.c
.c.o:
$(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) created a template configuration file
from example.cfgtmpl
in the% {} block replaced the file name with the name that should be in the tarantool_proxy_cfg.h project:
% {
#include
#include
void out_warning (ConfettyError r, char * format, ...);
%}:
4. created my own configuration
and checked it: Added the missing part of the tarantool_proxy.cfgtmpl config as applied to his:
confetti -i tarantool_proxy.cfgtmpl -n tarantool_proxy -f tarantool_proxy.cfg
pid = "/usr/local/var/tarantool_proxy.pid"
log = "/usr/local/var/log/tarantool_proxy.log"
daemon = 1
pool_size = 4096
# count of threads
threads = 4
#listen
host = "localhost"
port = 33013
# server connections
server = [
hostname = "localhost"
port = 33013
namespace = [
key = NULL, required
]
]
namespace = [
type = NULL, required
]
5. after generating the configuration file
tarantool_proxy.cfg copied it to the default configuration file: tarantool_proxy.def.cfg and filled it with the necessary data (some of them):
server [0] .hostname = "host2"
server [0] .port = 33013
server [1] .hostname = "host1"
server [1] .port = 33023
namespace [1] .type = "str"
namespace [0] .type = "int"
server [0] .namespace [0] .key = "345"
server [0] .namespace [1] .key = "abc"
server [1] .namespace [0] .key = "xyz "
server [1] .namespace [1] .key =" 345 "
The values specified in the template file are used by default.
Further, I used this file as a double, since the tarantool_proxy.cfg file is constantly overwritten by confetti
6. created an example file tester based on example.c.
7. do make until everything goes well
it will be amazing if it works the first time :)
We get : As for the “DIRECT” block, this is testing direct access:
./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=========
printf ("========== DIRECT ========= \ n");
printf ("pid =% s \ n", cfg.pid);
printf ("daemon =% d \ n", cfg.daemon);
or access to array elements:
tarantool_proxy_namespace ** it = cfg.namespace;
while (* it! = NULL) {
printf ("namespace type =% s \ n", (* it) -> type);
++ it;
}
So what now remains:
- Make make install, which will rewrite all the necessary files into the directory of your project.
The config.src directory remains the test site. - In your own project, include #include {name} _cfg.h where {name} is the name that you selected when generating the config file (in my project tarantool_proxy)
- Declare the source configuration and assign default values
tarantool_proxy cfg;
char * key, * value;
fill_default_tarantool_proxy (& cfg);
- Declare the configuration file and read it:
int nAccepted, nSkipped;
FILE * fh = fopen (filename, "r");
if (! fh) {
fprintf (stderr, "Could not open file% s \ n", argv [1]);
return 1;
}
useStdout = 1;
parse_cfg_file_tarantool_proxy (& cfg, fh, 1, & nAccepted, & nSkipped);
printf ("========== Accepted:% d; Skipped:% d =========== \ n", nAccepted, nSkipped);
fclose (fh);
If we use arrays, then we declare iterators: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);
free (value);
} else {
printf ("% s => (null) \ n", key);
}
}
Or we use “direct” access to data structures, as mentioned above.
That's all, reconfiguring the project (changing the structure of the config) now takes no more than 5 minutes.
I hope that this will save a lot of time for someone.
Thanks to the author Teodor Sigaev