Partage
  • Partager sur Facebook
  • Partager sur Twitter

C++ lire un fichier de config

une lib extensible aux types et containers persos.

    16 novembre 2018 à 15:54:48

    En bref :

    Le projet est disponible ici : https://tentacule.be/fossil/cpp-config/ (il faut accepter le certificat autosigné pour accéder a la page).
    Le code d'exemple est attaché ici, en fin de post.
    Le code est sous GPL3, en C++.

    Le projet est une bibliothèque C++ qui permet de lire un fichier de configuration.
    La bibliothèque est extensible à des types personalisés autour d'une interface template nommée convert
    La bibliothèque est extensible à des containers personalisés autour d'une interface template nommée containers.

    Convert et Container peuveut être utilisés tout seuls dans leur coin (et le sont dans d'autres projets).

    Ls conversions des chaines de caractères vers les nombres nécessitent boost/lexical_cast.hpp. Le reste du code est autonome et portable (c++17).

    Ma vie mon oeuvre (et autres inutilités)

    Par pur soucis de respect du plan afin d'éviter la fermeture de mon post, voici une description tout à fait fantasmée de ma vie et de mon oeuvre. Déjà petit, j'étais né beau gosse avec un clavier d'ordinateur dans les mains, ce qui a du donner un acouchement plus que douloureux. Une fois grand, genre vraiment grand, genre tellement grand que ce n'est plus la taille qui compte, j'ai fait des trucs avec de l'informatique et de la biologie, mais comme nous sommes entre gens civilisés et que la biologie c'est dégoûtant, je ne parlerai que de l'informatique. Donc entre deux licornes, j'ai fait une thèse avec des modèles des migraines, du café et du C++ puis j'ai continuer dans ce domaine, que la vie est bien faite quand on est sur des rails et qu'on ne travaille pas à la SNCF. Dans ce domaine, j'ai parfois à lire des fichiers de configurations, et ma vielle lib qui faisait ça étant un peu daté, en voila une nouvelle version, paillettes, confetties. Sinon BG TBM cherche ... euh non pardon.

    En savoir plus sur le projet

    Genèse

    Au commencement, Dieu créa le fichier de configuration
    Le format était simple et facile : il y avait du texte, des valeurs et des groupe de valeurs, et bien que l'esprit le Dieu puisse le lire, ce n'était pas le cas des programmes.
    Et Dieu dit : que le code soit écrit, Et le code fut écrit.

    Ce projet est le sucesseur de celui là qui fut écrit a une époque ou auto n'existait pas, et où on codait a pied. Il fait pareil, en mieux et avec une interface plus homogène.
    https://tentacule.be/fossil/cpp-BConfig

    Généralités et avancement

    Au début il n'y avait rien, puis ensuite il y eu LE code.

    Objectifs (35mm et autres)

    1) Lire un fichier de configuration (un example en fin de page)

    2) Pouvoir étendre facilement la bibliothèque à des types personnalisés

    3) Pouvoir étendre facilement la bibliothèque à des containers personnalisés

    4) Devenir une licorne, mais pas avant l'invention d'une interface homme machine compatible avec l'utilisation ergonomique de sabots.

    Pourquoi mon projet il est super ?

    1) Ca marche
    2) C'est simple (allez voir l'example a la fin)
    3) C'est gratuit (mais faut respecter la GPL3)
    4) C'est extensible aux types et containers persos
    5) Les mécanismes d'extensions utilisés ici sont génériques, et se marient très bien avec d'autres projets.
    6) Je suis un poney, les poneys c'est sympas.

    Pourquoi mon projet il original

    Pour pas grand chose, c'est simple, ca marche, pas besoin de fantaisie voyons!
    (notez tout le sérieux de cette phrase).

    Public visé :

    Toi, toi et toi, mais pas toi parce que tu développes un logiciel propriétaire et le viol de license c'est mal... Bon chacun ses perversions, mais quand même.

    Où se situe mon projet dans la jungle d'internet

    ici : https://tentacule.be/fossil/cpp-config

    Le code est aussi utilisé dans divers projets de modélisation et de recherche.


    Example

    #--- fichier de configuration ---
    my_house{
      name = pierre's house
      cat  = caterpilar
      cat  = catastrophy
      door_size = 2.1     #meters
    }
    
    tree{}
    tree{}

    //--- code c++ ---
    #include <iostream> //require to use config::Block //conversions are handled trough the default implementation that tries to static_cast from std::strings #include <config/config.hpp> //extend configuration conversion rules, by using boost::lexical_cast for numeric types //NOTE : custom types conversions can be added the same way #include <config/convert_lexical.hpp> //extend configuration container support for loading values into a std::vector //see container folder for a list of supported containers //see container/container.hpp for the full container interface #include <container/vector.hpp> int main(int,char**){ //------------------- //--- load a file --- //------------------- config::Block b; b.load("src/example.txt"); //print the example file as seen after parsing. // #xx are lines numbers from the input file b.save(std::cout); //-------------- //--- blocks --- //-------------- //count blocks; size_t number_all_blocks = b.blocks.size(); size_t number_trees = b.blocks.size("tree"); //get block by index: const config::Block &first_block = b.blocks.at(0); //among all blocks const config::Block &first_tree = b.blocks.at("tree",0); //among blocks named tree //get a unique sub_block const config::Block &my_house = b.blocks.get_unique("my_house"); //iterate trough all blocks for(const config::Block &a_block : b.blocks.crange() ){} //iterate trough blocks named "tree" for(const config::Block &tree : b.blocks.crange("tree") ){} //-------------- //--- values --- //-------------- //--- count values --- size_t number_of_cats = my_house.values.size("cat"); //--- get values by index -- const config::Value &first_value = my_house.values.at(0); //among all values in my_house const config::Value &first_cat = my_house.values.at("cat",0); //among all values named cat in my_house //--- iterate trough values --- for(const config::Value &a_value :my_house.values.crange() ){} //--- convert a value --- const config::Value door_size_v = my_house.values.at("door_size", 0); double door_size_d = door_size_v.to<double>(); //see convert/convert.hpp //--- get values --- //[1] The not template version works on std::string //[2] The template version works on any type supported by convert // here it's double supported by convert_lexical.hpp // //get_unique returns a value //load_unique(write_here,...) write the returned value in write_here std::string house_name; double door_size; //get a unique value, throw if doesn't exists. house_name = my_house.values.get_unique("name");//[1] door_size = my_house.values.get_unique<double>("door_size");//[2] my_house.values.load_unique(house_name, "name"); //[1] my_house.values.load_unique(door_size , "door_size");//[2] //get a unique value, use default if doesn't exists house_name = my_house.values.get_unique("name","Someone house");//[1] door_size = my_house.values.get_unique<double>("door_size",2.0);//[2] my_house.values.load_unique(house_name, "name" , "Someone house");//[1] my_house.values.load_unique(door_size , "door_size", 2.0);//[2] //get multiple values in a container. // - containers are handled trough the container/container.hpp interface // see example-extend-container.hpp for details // - if possible (ex: vector), values are loaded in the same order as the // input file. see container::Add_back_t in container/container.hpp // - if not (ex: set), values are loaded in any order. // see container::Add_anywhere_t in container/container.hpp . // - loaded values are automatically converted to the container value type // (see container::Value_type_t and convert/convert.hpp). // - load_multiple returns the number of loaded values, which is the number // of lines in the current block that has a value for the required name. // If the container does deduplication (ex set) the return of load_multiple // can be higher than the change in container size. // - load_multiple ADD values to the container without cleaning it first. std::vector<std::string> cats_v; my_house.values.load_multiple(cats_v, "cat"); cats_v= my_house.values.get_multiple< std::vector<std::string> >("cats"); std::cout << "\n---\n"<<std::endl; }





    -
    Edité par ledemonboiteux 16 novembre 2018 à 16:08:04

    • Partager sur Facebook
    • Partager sur Twitter

    C++ lire un fichier de config

    × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
    × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
    • Editeur
    • Markdown