Projektvorstellung: ProgramOptions.hxx



  • Hallo

    Ich möchte meine kleine singe-header Bibliothek ProgramOptions.hxx vorstellen. Sie ist komplett in C++11 geschrieben.

    Mein Ziel war es, einen kleinen aber feinen Programmoptionen-Parser zu schreiben, der sich elegant und modern anfühlt, aber gleichzeitig keinerlei Änderungen am Build-Prozess erfordert. Die Parser-Klasse fühlt sich wie die altbekannte std::map an und die Optionen lassen sich bequem mit verketteten Funktionsaufrufen konfigurieren. Die Defaults sind sinnvoll gewählt und erlauben es, direkt loszulegen. Hinweise zur Benutzung und alles andere Wichtige steht im README auf GitHub. 🙂

    GitHub Repo: https://github.com/Fytch/ProgramOptions.hxx

    Über Anregungen, Rückmeldung, Kritik und Feature Requests, hier oder auf GitHub, würde ich mich sehr freuen.

    LG



  • Sieht hübscher aus als boost::program_options. (EDIT: Also im Ernst, ich schätze Interfaces, die so einfach, simpel, selbsterklärend und ästhetisch sind, dass man gar nichts falsch machen kann. Und zwar fast über alles.)
    Werde ich wohl das nächste Mal verwenden, sobald ich Parameter definiere.

    (EDIT: Und die saubere Readme 👍)



  • Ich finde es befremdlich, wenn man das Rad immer wieder neu erfindet.

    Wäre es nicht besser, sich an der Weiterentwicklung von https://www.gnu.org/software/libc/manual/html_node/Getopt.html zu beteiligen?



  • Find ich Klasse, ganz ohne Boost 👍
    @Andromeda: Getopt ist, so wie ich das sehe, in C geschrieben.



  • Techel schrieb:

    @Andromeda: Getopt ist, so wie ich das sehe, in C geschrieben.

    Kann aber auch in C++ verwendet werden.



  • Sicher, sieht aber mega hässlich aus.



  • Techel schrieb:

    Sicher, sieht aber mega hässlich aus.

    Nein, C ist eine schöne Sprache. Das liegt in ihrer Philosophie begründet:

    Trust the programmer.
        Don’t prevent the programmer from doing what needs to be done.
        Keep the language small and simple.
        Provide only one way to do an operation.
        Make it fast, even if it is not guaranteed to be portable.
    


  • Hallo.

    Danke für die zahlreiche Rückmeldung, freut mich sehr.

    @Andromeda: Danke für den Link, die Bibliothek war mir neu. Ich habe das Beispiel von ihrer Webseite mit meiner Bibliothek nachgebaut:

    #include <ctype.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    
    int
    main (int argc, char **argv)
    {
      int aflag = 0;
      int bflag = 0;
      char *cvalue = NULL;
      int index;
      int c;
    
      opterr = 0;
    
      while ((c = getopt (argc, argv, "abc:")) != -1)
        switch (c)
          {
          case 'a':
            aflag = 1;
            break;
          case 'b':
            bflag = 1;
            break;
          case 'c':
            cvalue = optarg;
            break;
          case '?':
            if (optopt == 'c')
              fprintf (stderr, "Option -%c requires an argument.\n", optopt);
            else if (isprint (optopt))
              fprintf (stderr, "Unknown option `-%c'.\n", optopt);
            else
              fprintf (stderr,
                       "Unknown option character `\\x%x'.\n",
                       optopt);
            return 1;
          default:
            abort ();
          }
    
      printf ("aflag = %d, bflag = %d, cvalue = %s\n",
              aflag, bflag, cvalue);
    
      for (index = optind; index < argc; index++)
        printf ("Non-option argument %s\n", argv[index]);
      return 0;
    }
    

    Wird zu:

    #include <ProgramOptions.hxx>
    #include <iostream>
    
    int main( int argc, char** argv ) {
    	po::parser parser;
    
    	auto&& a = parser[ "a" ];
    	auto&& b = parser[ "b" ];
    	auto&& c = parser[ "c" ]
    		.type( po::string )
    		.fallback( "(null)" );
    	auto&& unnamed = parser[ "" ]
    		.type( po::string )
    		.multi();
    
    	parser( argc, argv );
    
    	std::cout << "aflag = " << a.was_set() << ", ";
    	std::cout << "bflag = " << b.was_set() << ", ";
    	std::cout << "cflag = " << c.get().string << '\n';
    	for( auto&& i : unnamed )
    		std::cout << "Non-option argument " << i.string << '\n';
    }
    

    Was ist nun schöner resp. leserlicher? Ihr entscheidet. 😉

    LG



  • Erstmal finde ich ProgramOptions.hxx gelungener als GNUs Getopt. 👍

    Zweitens würde ich auf Angriffe aus dem C-Lager nicht reagieren. Macht keinen Sinn mit denen zu diskutieren.



  • Ich möchte auch beipflichten, dass deine API sehr schön aussieht und nehme mit Freuden zur Kenntnis, dass du auch Features jüngerer Generation verwendest (siehe rvalue references).

    Den C-Fanboys würde ich nun auch wenig Aufmerksamkeit schenken. Nicht, dass ich was gegen C hätte (im Gegenteil), aber ich hab was gegen blinden Fanatismus.

    Summa summarum: Weiter so, würde deine Implementierung auch gern bei nächster Gelegenheit einsetzen! 🙂


Log in to reply