OpenCores
URL https://opencores.org/ocsvn/sqmusic/sqmusic/trunk

Subversion Repositories sqmusic

[/] [sqmusic/] [trunk/] [cpp/] [args.h] - Blame information for rev 17

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 16 gryzor
/*
2
  (c) Jose Tejada Gomez, 9th May 2013
3
  You can use this file following the GNU GENERAL PUBLIC LICENSE version 3
4
  Read the details of the license in:
5
  http://www.gnu.org/licenses/gpl.txt
6
 
7
  Send comments to: jose.tejada at ieee.org
8
 
9
*/
10
 
11
#include <string>
12
#include <vector>
13
#include <algorithm>
14
#include <cstdlib>
15
#include <iostream>
16
 
17
typedef std::vector<struct argument_t*> arg_vector_t;
18
 
19
struct argument_t {
20
  std::string short_name, long_name;
21 17 gryzor
  typedef enum { integer, text, flag, real } arg_type;
22 16 gryzor
  arg_type type;
23
  std::string description;
24
  // possible states
25
  int integer_value;
26
  std::string string_value;
27 17 gryzor
  float real_value;
28 16 gryzor
  bool state, req;
29
 
30
  argument_t( arg_vector_t& av, const char* long_name, arg_type type,
31 17 gryzor
    const char* desc="", bool required=false )
32 16 gryzor
    : long_name(long_name), type( type ), description( desc ),
33 17 gryzor
      req(required), state(false), integer_value(0), real_value(0)
34 16 gryzor
  {
35
    if( !this->long_name.empty() ) {
36
      this->short_name = "-" + this->long_name.substr(0,1);
37
      this->long_name = "--" + this->long_name;
38
    }
39
    av.push_back(this);
40
  }
41
  void set() { state=true; }
42
  bool is_set() { return state; }
43
};
44
 
45
class Args {
46
  arg_vector_t& legal_args;
47
  argument_t* def_arg;
48
  std::string program_name;
49
  argument_t help_arg;
50
public:
51
  void throw_error( std::string x ) /*throw const char**/ { throw x.c_str(); }
52
  Args( int argc, char *argv[], arg_vector_t& legal_args ) //throw const char *
53
  : legal_args( legal_args ),
54
    help_arg( legal_args, "help", argument_t::flag, "Display usage information")
55 17 gryzor
  {
56 16 gryzor
    // look for default argument
57
    def_arg=NULL;
58
    for( int j=0; j<legal_args.size(); j++ ) {
59
      if ( legal_args[j]->short_name.empty() && legal_args[j]->long_name.empty() )
60
        if( def_arg==NULL ) def_arg = legal_args[j];
61
        else throw "Cannot set more than one default argument.";
62
    }
63
    if( def_arg && def_arg->type!=argument_t::integer && def_arg->type!=argument_t::text )
64
      throw "Default arguments can only be of type integer or text";
65
 
66
    program_name = argv[0];
67
    for( int k=1; k<argc; k++ ) {
68
      bool matched=false;
69
      for( int j=0; j<legal_args.size(); j++ ) {
70
        argument_t& a = *legal_args[j];
71
        if( a.long_name==argv[k] || a.short_name==argv[k] ) {
72
          if( a.type == argument_t::flag ) { a.set(); matched=true; continue; }
73
          if( a.type == argument_t::text ) {
74
            k++;
75
            if( k>=argc ) throw_error("Expecting input after "+a.long_name+" param");
76
            a.string_value = argv[k];
77
            a.set();
78
            matched=true;
79
            continue;
80
          }
81
          if( a.type == argument_t::integer ) {
82
            k++;
83
            if( k>=argc ) throw_error("Expecting input after "+a.long_name+" param");
84
            a.integer_value = atoi(argv[k]);
85
            a.set();
86
            matched=true;
87
            continue;
88
          }
89 17 gryzor
          if( a.type == argument_t::real ) {
90
            k++;
91
            if( k>=argc ) throw_error("Expecting input after "+a.long_name+" param");
92
            a.real_value = atof(argv[k]);
93
            a.set();
94
            matched=true;
95
            continue;
96
          }
97 16 gryzor
        }
98
      }
99
      if( !matched && def_arg!=NULL )
100
        if( def_arg->state )
101
          throw_error( "Unknown parameter " + std::string(argv[k] ));
102
        else {
103
          if( def_arg->type==argument_t::integer ) def_arg->integer_value=atoi(argv[k]);
104
          if( def_arg->type==argument_t::text ) def_arg->string_value=argv[k];
105
          def_arg->set();
106
        }
107
    }
108
    if( help_arg.is_set() ) return; // do not perform more checks
109
    // check that all required parameters are present
110
    for( int j=0; j<legal_args.size(); j++ ) {
111
      argument_t& a = *legal_args[j];
112
      if( a.req && !a.state ) {
113
        std::string pname;
114
        if( !a.long_name.empty() ) pname=a.long_name;
115
        else if( !a.short_name.empty() ) pname=a.short_name;
116
        throw_error("Parameter "+pname+" is required.");
117
      }
118
    }
119
  }
120 17 gryzor
  bool help_request() { if( help_arg.is_set() ) show_help(); return help_arg.is_set(); }
121 16 gryzor
  std::string brackets( const argument_t& a, std::string s ) {
122
    return a.req ?  "<"+s+">" : "["+s+"]";
123
  }
124
  void show_help() {
125
    std::cout << "Usage: " << program_name << " ";
126
    if( def_arg!=NULL )
127
      std::cout << brackets( *def_arg, def_arg->description.empty() ? "parameter " : def_arg->description);
128
    std::cout << "\n";
129
    for( int j=0; j<legal_args.size(); j++ ) {
130
      argument_t& a = *legal_args[j];
131
      if( a.long_name.empty() && a.long_name.empty() ) continue;
132
      std::cout << "\t";
133
      std::string aux;
134
      if( !a.long_name.empty() ) aux = a.long_name;
135
      if( !a.long_name.empty() && !a.long_name.empty() ) aux += " | ";
136
      if( !a.short_name.empty() ) aux+= a.short_name;
137
      std::cout << brackets( a, aux );
138 17 gryzor
      switch( a.type ) {
139
        case argument_t::integer: std::cout << " followed by integer number. "; break;
140
        case argument_t::real   : std::cout << " followed by real number. "; break;
141
        case argument_t::text   : std::cout << " followed by string. "; break;
142
      }
143 16 gryzor
      if( !a.description.empty() ) std::cout << ":  " << a.description;
144
      std::cout << "\n";
145
    }
146
  }
147
};

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.