License Public Domain
Lines 82
Keywords
Boost (2) Boost::Spirit (1)
Permissions
Owner: Stou S.
Viewable by Everyone
Editable by All Siafoo Users
Hide
Know what you're getting – Unlike many sites, all our code is clearly licensed. Join Siafoo Now or Learn More

Parsing command line arguments using Boost::Spirit Atom Feed 0

In Brief If you happen to be using Boost::Spirit for your parsing needs than you can save some time by having it also parse your application's command line arguments for you.... more
# 's
 1/**
2 * Created on May 19, 2009
3 *
4 * @author Stou Sandalski
5 *
6 * This code is released in the public domain.
7 *
8 * You can find the latest version on siafoo (http://www.siafoo.net/snippet/298)
9 *
10 */
11
12#include <iostream>
13#include <map>
14#include <string>
15#include <vector>
16
17#include <boost/spirit.hpp>
18#include <boost/spirit/actor/insert_at_actor.hpp>
19
20using namespace std;
21using namespace boost::spirit;
22
23int main(int argc, char* argv[]){
24
25 if(argc <= 1){
26 cout<<"Enter some arguments"<<endl;
27 return 0;
28 }
29
30 // Hardcoded arguments/flags
31 bool argDebug = false;
32 string argFileName;
33 float argFudgeFactor = 0.0f;
34 int argMagic = 0;
35
36 // Arbitrary arguments
37 // Temp stuff for
38 string tmpName;
39 string tmpValue;
40
41 vector<string> flags; // eg. --debug --quiet -z -k
42 map<string, string> options; // for things like --file=something
43
44 // Syntax rules
45 rule<phrase_scanner_t> args;
46
47 // The fun part
48 args // If -d is present set argDebug=true
49 = str_p("-d")[assign_a(argDebug, true)]
50 // get the --file (--file="/dev/zero")
51 | str_p("--file=")>>(+(alnum_p|chset_p("\\/.~%")))[assign_a(argFileName)]
52 // get a double (--fudge=3.14)
53 | str_p("--fudge=")>>real_p[assign_a(argFudgeFactor)]
54 // get an int (--magic=42)
55 | str_p("--magic=")>>int_p[assign_a(argMagic)]
56 // -m42
57 | str_p("-m")>>int_p[assign_a(argMagic)]
58 // Pick up any extra config parameters like --foo=bar
59 | (str_p("--")>>(+alnum_p)[assign_a(tmpName)]>>'='>>(+anychar_p)[assign_a(tmpValue)]>>!(space_p))[insert_at_a(options, tmpName, tmpValue)]
60 // Extra options like --foo --bar
61 | str_p("--")>>(+alnum_p)[push_back_a(flags)]
62 // Extra single character options -f -b
63 | str_p("-")>>(+alnum_p)[push_back_a(flags)]
64 ;
65
66 cout<<"Arguments: "<<endl;
67 for(int i = 1; i < argc; ++i){
68 cout<<"\t"<<i<<"\t"<<argv[i]<<endl;
69
70 // Yes this loop is kind of lazy/innefficient... I'll fix it later.
71 parse(argv[i],
72 (
73 *args
74 ),
75 space_p
76 ).full;
77 }
78
79 cout<<"Configuration: "<<endl
80 <<"\tDebug: "<<std::boolalpha<<argDebug<<endl
81 <<"\tFile: "<<argFileName<<endl
82 <<"\tFudge Factor: "<<argFudgeFactor<<endl
83 <<"\tMagic: "<<argMagic<<endl
84 // <<"\tBounds: "<<bounds.size()<<endl
85 ;
86
87 cout<<"Flags: "<<flags.size()<<endl;
88 for(vector<string>::iterator i = flags.begin(); i != flags.end(); ++i) {
89 cout<<"\t"<<(*i)<<endl;
90 }
91
92 cout<<"Parameters: "<<options.size()<<endl;
93 for(map<string, string>::iterator i = options.begin(); i != options.end(); ++i) {
94 cout<<"\t"<<i->first<<" : "<<i->second<<endl;
95 }
96
97 return 0;
98}

If you happen to be using Boost::Spirit for your parsing needs than you can save some time by having it also parse your application's command line arguments for you.

Talk about overkill. Anyway...

Compile and run:

$ g++ -Wall spiritargs.cpp -o spiritargs

$ ./spiritargs --testing=123! -d -m 34 -a -b -c -gef --file="/etc/X11/xorg.conf"

Warning

There's at least 150 ways to parse command line arguments more efficiently. There's also at least 17 better ways to implement the above parser.

Before you start flaming me... I use Boost::Spirit to parse some configuration data, being lazy I wanted the minimum amount of code that will setup the program configuration from the command line.