~ubuntu-branches/ubuntu/maverick/aspectc++/maverick

« back to all changes in this revision

Viewing changes to Puma/src/common/OptsParser.cc

  • Committer: Bazaar Package Importer
  • Author(s): Reinhard Tartler
  • Date: 2008-04-10 17:40:52 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20080410174052-xdnsm7oi8hauyyf1
Tags: 1.0pre4~svn.20080409+dfsg-3
Fix another missing include, this time in Ag++/StdSystem.cc

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
#include "Puma/ParserKey.h"
21
21
#include <string>
22
22
//#include <iostream>
 
23
#include <string.h>
23
24
using namespace std;
24
25
 
25
26
namespace Puma {
26
27
 
27
28
 
28
 
OptsParser::OptsParser (int argc, char **argv, const Option *opts) : m_opts (opts) {
29
 
  for (int idx = 1; idx < argc; idx++) {
30
 
    m_argv.push_back (argv[idx]);
31
 
  }
32
 
  m_curarg = m_tonext = m_number = 0;
33
 
}
34
 
 
35
 
 
36
 
OptsParser::OptsParser (const string &line, const Option *opts) : m_opts (opts) {
37
 
  tokenize (line, m_argv, " \t\n\r");
38
 
  m_curarg = m_tonext = m_number = 0;
39
 
}
40
 
 
41
 
 
42
 
int OptsParser::getOption () {
43
 
  m_number = FINISH;
44
 
 
45
 
  m_curarg += m_tonext;
46
 
  if (m_curarg < m_argv.size ()) {
47
 
    m_tonext=1;
48
 
    m_opt = m_arg = "";
49
 
    const string &arg (m_argv[m_curarg]);
50
 
    if (ParserKey::isLongKey (arg) && arg.length () > ParserKey::getLongKeyLength ()) {
51
 
      m_number = getLongOption (arg);
52
 
    } else if (ParserKey::isKey (arg) && arg.length () > 1) {
53
 
      m_number = getShortOption (arg);
54
 
    } else {
55
 
//cout << "no option: " << arg << endl;
56
 
      m_arg = strip (arg);
57
 
      m_number = NOOPTION;
58
 
    }
59
 
  }
60
 
 
61
 
  return m_number;
62
 
}
63
 
 
64
 
 
65
 
int OptsParser::getLongOption (const string &arg) {
66
 
  int res = UNKNOWN;
67
 
  const Option *opts = m_opts;
68
 
  unsigned int keyLen = ParserKey::getLongKeyLength ();
69
 
 
70
 
  // search for long option name in arg 
71
 
  while (opts->number != 0) {
72
 
    if (opts->name != NULL) {
73
 
      if ((opts->args != AT_NONE) || 
74
 
          ((arg.length () - keyLen) == strlen (opts->name))) {
75
 
        if (arg.find (opts->name) == keyLen)
76
 
          break;
77
 
      }
78
 
    }
79
 
    opts++;
80
 
  }
81
 
  
82
 
  // if we found an option go on with processing
83
 
  if (opts->number) {
84
 
    res = opts->number;
85
 
 
86
 
    // option possibly has arguments
87
 
    if (opts->args != AT_NONE) {
88
 
      if (processOption (arg, (unsigned int)strlen (opts->name) + 
89
 
                         ParserKey::getLongKeyLength (),opts->args) == false)
90
 
        res = NOARG;
91
 
    } else 
92
 
      m_opt = arg.substr (0, strlen (opts->name) + ParserKey::getLongKeyLength ());
93
 
//cout << "found long option: " << arg << " with argument " << getArgument () << endl;
94
 
  } else {
95
 
//cout << "unknown long option: " << arg << endl;
96
 
    m_arg = arg;
97
 
  }
98
 
 
99
 
  return res;
100
 
}
101
 
 
102
 
 
103
 
int OptsParser::getShortOption (const string &arg) {
104
 
  int res = UNKNOWN;
105
 
  const Option *opts = m_opts;
106
 
 
107
 
  // search for short option
108
 
  while (opts->number != 0 && opts->key != arg[1]) {
109
 
    opts++;
110
 
  }
111
 
  
112
 
  // ok we found a short option that fits
113
 
  if (opts->number) {
114
 
    res = opts->number;
115
 
    
116
 
    if (processOption (arg, 2,opts->args) == false){
117
 
        res = NOARG;
118
 
    }
119
 
    
120
 
//cout << "found short option: " << arg << " with argument " << getArgument () << endl;
121
 
    
122
 
  } else {
123
 
//cout << "unknown short option: " << arg << endl;
124
 
    m_arg = arg;
125
 
  }
126
 
        
127
 
  return res;
128
 
}
129
 
 
130
 
// process option and option argument.
131
 
// there can AT_NONE, a AT_MANDATORY or an AT_OPTIONAL option argument. 
132
 
bool OptsParser::processOption (const string &arg, unsigned int len,ArgType argtype) {
133
 
  
134
 
  // set current option
135
 
  m_opt = arg.substr (0, len);
136
 
  
137
 
  // if there should be no argument provided don't process it
138
 
  if (argtype == AT_NONE){
139
 
          return true;
140
 
  }        
141
 
  
142
 
  // if there are characters behind the end of the option name, 
143
 
  // treat them as option argument
144
 
  if (arg.length () > len) {
145
 
          m_arg = strip (arg.substr (len, arg.length () - len));
146
 
  } 
147
 
 
148
 
  // if ARGV contains at least one more element
149
 
  // check if it is an option argument
150
 
  else if (m_curarg + 1 < m_argv.size () ) {
151
 
 
152
 
          // if the next element of ARGV is NOT an other option treat it as option argument 
153
 
          // otherwise m_arg will continue containing an empty string
154
 
          const string &next_argv(m_argv[m_curarg + 1]);
155
 
          if (! ( (ParserKey::isLongKey(next_argv) && next_argv.length() > ParserKey::getLongKeyLength()) ||   
156
 
                          (ParserKey::isKey(next_argv)     && next_argv.length() > ParserKey::getKeyLength())))
157
 
          {
158
 
                  m_arg = strip(next_argv);
159
 
                  ++m_tonext;
160
 
          }
161
 
 
162
 
  }
163
 
 
164
 
  // return false if there should be an argument
165
 
  if( m_arg.empty() && argtype == AT_MANDATORY){
166
 
        return false;   
167
 
  }
168
 
 
169
 
  return true;
170
 
}
171
 
 
172
 
 
173
 
bool OptsParser::revokeArgument () {
174
 
  bool ret=false;
175
 
  if (m_tonext > 1){
176
 
         --m_tonext;
177
 
         ret=true;
178
 
  }
179
 
  return ret;
180
 
}
181
 
 
182
 
int OptsParser::getCurrentArgNum () const {
183
 
  return m_curarg + 1;
184
 
}
185
 
 
186
 
int OptsParser::getNextArgNum () const {
187
 
  return m_curarg + m_tonext + 1 ;
188
 
}
189
 
 
190
 
 
191
 
int OptsParser::getResult () const {
192
 
  return m_number;
193
 
}
194
 
 
195
 
 
196
 
const string &OptsParser::getArgument () const {
197
 
  return m_arg;
198
 
}
199
 
 
200
 
 
201
 
const string &OptsParser::getOptionName () const {
202
 
  return m_opt;
203
 
}
204
 
 
 
29
   OptsParser::OptsParser(int argc, char **argv, const Option *opts) : m_opts(opts)
 
30
   {
 
31
      for (int idx = 0; idx < argc; idx++) 
 
32
      {
 
33
         m_argv.push_back (argv[idx]);
 
34
      }
 
35
      m_curarg =1;
 
36
      m_tonext = 0; 
 
37
      m_number = 0;
 
38
   }
 
39
 
 
40
 
 
41
   OptsParser::OptsParser(const string &line, const Option *opts) : m_opts(opts)
 
42
   {
 
43
      tokenize (line, m_argv, " \t\n\r");
 
44
      m_curarg = m_tonext = m_number = 0;
 
45
   }
 
46
 
 
47
   int OptsParser::getOption ()
 
48
   {
 
49
      
 
50
      m_number = FINISH;
 
51
      m_curarg += m_tonext;
 
52
      
 
53
      if (m_curarg < m_argv.size())
 
54
      {
 
55
         bool isLong = false;
 
56
         const string &arg (m_argv[m_curarg]);
 
57
         const Option* curOpt;
 
58
         
 
59
         m_tonext=1;
 
60
         m_opt = m_arg = "";
 
61
         
 
62
         
 
63
         if (  ParserKey::isLongKey(arg) && 
 
64
               ( arg.length() > ParserKey::getLongKeyLength() )
 
65
            )
 
66
         {
 
67
            isLong = true;
 
68
         }
 
69
         else if (  ( ParserKey::isKey(arg)) &&
 
70
                  ( arg.length() > ParserKey::getKeyLength() )
 
71
               )
 
72
         {
 
73
            isLong = false;
 
74
         }
 
75
         else
 
76
         {
 
77
            m_number=NOOPTION;
 
78
            m_arg=arg;
 
79
         }
 
80
         
 
81
         if (m_number != NOOPTION)
 
82
         {
 
83
            // search options in argument string
 
84
            curOpt=findOption(arg,isLong);
 
85
 
 
86
            // if we found an option go on with processing
 
87
            if((curOpt != NULL) && (curOpt->number != 0))
 
88
            {
 
89
 
 
90
               if (processOption(arg, curOpt, isLong) == false)
 
91
               {
 
92
                  m_number = NOARG;
 
93
               }
 
94
               else
 
95
               {
 
96
                  m_number = curOpt->number;
 
97
               }
 
98
            }
 
99
            else
 
100
            {
 
101
               //cout << "no option: " << arg << endl;
 
102
               m_arg = strip (arg);
 
103
               m_number = UNKNOWN;
 
104
            }
 
105
         }
 
106
      }
 
107
      return m_number;
 
108
   }
 
109
 
 
110
   int OptsParser::getRawOption ()
 
111
   {
 
112
      m_number = FINISH;
 
113
 
 
114
      m_curarg += m_tonext;
 
115
      if (m_curarg < m_argv.size ())
 
116
      {
 
117
         m_tonext=1;
 
118
         m_opt = m_arg = "";
 
119
         m_arg = strip (m_argv[m_curarg]);
 
120
         m_number = NOOPTION;
 
121
      }
 
122
      return m_number;
 
123
   }
 
124
 
 
125
 
 
126
   const Puma::OptsParser::Option* OptsParser::findOption(const string &arg, bool isLong)
 
127
   {
 
128
      unsigned int keyLen;
 
129
      string curName;
 
130
      const Option *curOpt = m_opts;
 
131
      const Option *selOpt = NULL;
 
132
      unsigned int selOptLength=0;
 
133
 
 
134
      // search for long option name in arg     
 
135
      while (curOpt->number != 0)
 
136
      {
 
137
         
 
138
         if((isLong == true) && (curOpt->longName != NULL))
 
139
         {
 
140
            keyLen = ParserKey::getLongKeyLength();
 
141
            curName=curOpt->longName;
 
142
         }
 
143
         else if(curOpt->shortName != NULL)
 
144
         {
 
145
            keyLen = ParserKey::getKeyLength();
 
146
            curName=curOpt->shortName;
 
147
         }
 
148
         else
 
149
         {
 
150
            curName="";
 
151
            keyLen = 0;
 
152
         }
 
153
 
 
154
         /* Select option if:
 
155
          *    - name is not null AND
 
156
          *    - selected option is either null OR shorter than
 
157
          *      the currently analyzed option  AND
 
158
          *    - the current option receives a parameter OR is exactly as long 
 
159
          *      as passed argument AND
 
160
          *    - the string passed as argument starts at the position after 
 
161
          *      the option key
 
162
          */
 
163
         if (
 
164
               ( ! curName.empty() ) && 
 
165
               ((selOpt == NULL) || (selOptLength <= curName.length()) ) &&
 
166
               ( (curOpt->argType != AT_NONE) || ((arg.length() - keyLen) == curName.length()) ) &&
 
167
               ( arg.find(curName) == keyLen )
 
168
            )
 
169
         {
 
170
            selOpt = curOpt;
 
171
            selOptLength = curName.length();
 
172
         }
 
173
         curOpt++;
 
174
      }
 
175
      return selOpt;
 
176
   }
 
177
 
 
178
   // process option and option argument.
 
179
   // there can AT_NONE, a AT_MANDATORY or an AT_OPTIONAL option argument. 
 
180
   bool OptsParser::processOption (const string &arg, const Option* curOpt,bool isLong)
 
181
   {
 
182
      unsigned int len;
 
183
 
 
184
      if(isLong == true)
 
185
      {
 
186
         len = (ParserKey::getLongKeyLength() + strlen(curOpt->longName));
 
187
      }
 
188
      else
 
189
      {
 
190
         len = (ParserKey::getKeyLength() + strlen(curOpt->shortName));
 
191
      }
 
192
      
 
193
      // set current option
 
194
      m_opt = arg.substr (0, len);
 
195
      
 
196
      // if there should be no argument provided do not proceed
 
197
      if (curOpt->argType == AT_NONE)
 
198
      {
 
199
         return true;
 
200
      }    
 
201
 
 
202
      // if there are characters behind the end of the option name, 
 
203
      // treat them as option parameter
 
204
      if (arg.length() > len)
 
205
      {
 
206
         m_arg = strip(arg.substr(len, arg.length() - len));
 
207
      } 
 
208
 
 
209
      // if ARGV contains at least one more element
 
210
      // check if it is an option argument
 
211
      else if ((m_curarg + 1) < m_argv.size() )
 
212
      {
 
213
 
 
214
         // if the next element of ARGV is NOT an other option treat it as option argument 
 
215
         // otherwise m_arg will continue containing an empty string
 
216
         const string &next_argv(m_argv[m_curarg + 1]);
 
217
         if (! ( (ParserKey::isLongKey(next_argv) && next_argv.length() > ParserKey::getLongKeyLength()) ||   
 
218
                  (ParserKey::isKey(next_argv)     && next_argv.length() > ParserKey::getKeyLength())))
 
219
         {
 
220
            m_arg = strip(next_argv);
 
221
            ++m_tonext;
 
222
         }
 
223
      }
 
224
 
 
225
      // return false if there should be an argument
 
226
      if( m_arg.empty() && curOpt->argType == AT_MANDATORY)
 
227
      {
 
228
         return false;  
 
229
      }
 
230
 
 
231
      return true;
 
232
   }
 
233
 
 
234
 
 
235
   int OptsParser::getResult () const
 
236
   {
 
237
      return m_number;
 
238
   }
 
239
 
 
240
 
 
241
   const string &OptsParser::getArgument () const {
 
242
      return m_arg;
 
243
   }
 
244
 
 
245
 
 
246
   const string &OptsParser::getOptionName () const {
 
247
      return m_opt;
 
248
   }
 
249
   
 
250
   int OptsParser::getCurrentArgNum () const {
 
251
     return m_curarg;
 
252
   }
 
253
   
 
254
   int OptsParser::getNextArgNum () const {
 
255
     return m_curarg + m_tonext;
 
256
   }
205
257
 
206
258
} // namespace Puma