Stun Server  Compliant with the latest RFCs including 5389, 5769, and 5780
discover the local host's own external IP address
cmdlineparser.cpp
Go to the documentation of this file.
1 /*
2  Copyright 2011 John Selbie
3 
4  Licensed under the Apache License, Version 2.0 (the "License");
5  you may not use this file except in compliance with the License.
6  You may obtain a copy of the License at
7 
8  http://www.apache.org/licenses/LICENSE-2.0
9 
10  Unless required by applicable law or agreed to in writing, software
11  distributed under the License is distributed on an "AS IS" BASIS,
12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  See the License for the specific language governing permissions and
14  limitations under the License.
15 */
16 
17 
18 #include "commonincludes.hpp"
19 #include <getopt.h>
20 
21 #include "cmdlineparser.h"
22 
23 
25 {
26  _options.clear();
27 
28  size_t len = _listOptionDetails.size();
29  for (size_t index = 0; index < len; index++)
30  {
31  option opt = {};
32  opt.has_arg = _listOptionDetails[index].has_arg;
33 
34  // Solaris 11 (released in 2011), only sees fit to include header files from 2004 where "option::name" is just a char* and not const char*
35  opt.name = (char*)(_listOptionDetails[index].strName.c_str());
36 
37 
38  _options.push_back(opt);
39  }
40 
41  option zero = {0,0,0,0};
42  _options.push_back(zero);
43 
44 
45  return &_options.front();
46 }
47 
48 
49 
50 HRESULT CCmdLineParser::AddOption(const char* pszName, int has_arg, std::string* pStrResult)
51 {
52  HRESULT hr = S_OK;
53  OptionDetail od;
54 
55  ChkIfA(pszName==NULL, E_INVALIDARG);
56  ChkIfA(has_arg < 0, E_INVALIDARG);
57  ChkIfA(has_arg > 2, E_INVALIDARG);
58  ChkIfA(pStrResult==NULL, E_INVALIDARG);
59 
60  od.has_arg = has_arg;
61  od.pStrResult = pStrResult;
62  od.strName = pszName;
63 
64  _listOptionDetails.push_back(od);
65 
66 Cleanup:
67  return hr;
68 
69 }
70 
71 HRESULT CCmdLineParser::AddNonOption(std::string* pStrResult)
72 {
73  _namelessArgs.push_back(pStrResult);
74  return S_OK;
75 }
76 
77 
78 HRESULT CCmdLineParser::ParseCommandLine(int argc, char** argv, int startindex, bool* pErrorFlag)
79 {
80 
81  int oldopterr = ::opterr;
82  size_t offset = 0;
83 
84 
85  ::opterr = 0;
86  ::optind = startindex;
87 
88 
89 
90  const option* longopts = GenerateOptions();
91 
92  if (pErrorFlag)
93  {
94  *pErrorFlag = false;
95  }
96 
97  while (true)
98  {
99  int index = 0;
100  int ret;
101 
102  ret = ::getopt_long_only(argc, argv, "", longopts, &index);
103 
104  if (ret < 0)
105  {
106  break;
107  }
108 
109  if ((ret == '?') || (ret == ':'))
110  {
111  if (pErrorFlag)
112  {
113  *pErrorFlag = true;
114  }
115  continue;
116  }
117 
118  if ((longopts[index].has_arg != 0) && (optarg != NULL))
119  {
120  _listOptionDetails[index].pStrResult->assign(optarg);
121  }
122  else
123  {
124  _listOptionDetails[index].pStrResult->assign("1");
125  }
126  }
127 
128  offset = 0;
129  for (int j = ::optind; j < argc; j++)
130  {
131  if (strcmp("--", argv[j]) == 0)
132  {
133  continue;
134  }
135 
136  if (_namelessArgs.size() <= offset)
137  {
138  // should we set the error flag if we don't have a binding for this arg?
139  break;
140  }
141 
142  _namelessArgs[offset]->assign(argv[j]);
143  offset++;
144  }
145 
146 
147  ::opterr = oldopterr;
148  return S_OK;
149 }
150 
#define S_OK
Definition: hresult.h:46
std::vector< option > _options
Definition: cmdlineparser.h:27
const option * GenerateOptions()
int32_t HRESULT
Definition: hresult.h:22
HRESULT ParseCommandLine(int argc, char **argv, int startindex, bool *fParseError)
#define E_INVALIDARG
Definition: hresult.h:51
HRESULT AddNonOption(std::string *pStrResult)
std::vector< OptionDetail > _listOptionDetails
Definition: cmdlineparser.h:39
HRESULT AddOption(const char *pszName, int has_arg, std::string *pStrResult)
#define ChkIfA(expr, hrerror)
Definition: chkmacros.h:84
std::vector< std::string * > _namelessArgs
Definition: cmdlineparser.h:29