License Public Domain
Lines 82
Keywords
Boost (2) Boost::Spirit (1)
Permissions
Owner: Stou S.
Viewable by Everyone
Editable by All Siafoo Users
Hide
Bored? Check out the Recent Activity on Siafoo 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.