Jack2  1.9.9
JackArgParser.cpp
1 /*
2  Copyright (C) 2006-2008 Grame
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU Lesser General Public License as published by
6  the Free Software Foundation; either version 2.1 of the License, or
7  (at your option) any later version.
8 
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU Lesser General Public License for more details.
13 
14  You should have received a copy of the GNU Lesser General Public License
15  along with this program; if not, write to the Free Software
16  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 
18 */
19 
20 #include "JackDriverLoader.h"
21 #include "JackArgParser.h"
22 #include <stdlib.h>
23 #include <stdio.h>
24 #include <assert.h>
25 
26 using namespace std;
27 
28 namespace Jack {
29 
30  // class JackArgParser ***************************************************
31  JackArgParser::JackArgParser ( const char* arg )
32  {
33  jack_log ( "JackArgParser::JackArgParser, arg_string : '%s'", arg );
34 
35  fArgc = 0;
36  //if empty string
37  if ( strlen(arg) == 0 )
38  return;
39  fArgString = string(arg);
40  //else parse the arg string
41  const size_t arg_len = fArgString.length();
42  unsigned int i = 0;
43  size_t pos = 0;
44  size_t start = 0;
45  size_t copy_start = 0;
46  size_t copy_length = 0;
47  //we need a 'space terminated' string
48  fArgString += " ";
49  //first fill a vector with args
50  do {
51  //find the first non-space character from the actual position
52  start = fArgString.find_first_not_of ( ' ', start );
53  //get the next quote or space position
54  pos = fArgString.find_first_of ( " \"" , start );
55  //no more quotes or spaces, consider the end of the string
56  if ( pos == string::npos )
57  pos = arg_len;
58  //if double quote
59  if ( fArgString[pos] == '\"' ) {
60  //first character : copy the substring
61  if ( pos == start ) {
62  copy_start = start + 1;
63  pos = fArgString.find ( '\"', ++pos );
64  copy_length = pos - copy_start;
65  start = pos + 1;
66  }
67  //else there is someting before the quote, first copy that
68  else {
69  copy_start = start;
70  copy_length = pos - copy_start;
71  start = pos;
72  }
73  }
74  //if space
75  if ( fArgString[pos] == ' ' ) {
76  //short option descriptor
77  if ( ( fArgString[start] == '-' ) && ( fArgString[start + 1] != '-' ) ) {
78  copy_start = start;
79  copy_length = 2;
80  start += copy_length;
81  }
82  //else copy all the space delimitated string
83  else {
84  copy_start = start;
85  copy_length = pos - copy_start;
86  start = pos + 1;
87  }
88  }
89  //then push the substring to the args vector
90  fArgv.push_back ( fArgString.substr ( copy_start, copy_length ) );
91  jack_log ( "JackArgParser::JackArgParser, add : '%s'", (*fArgv.rbegin()).c_str() );
92  } while ( start < arg_len );
93 
94  //finally count the options
95  for ( i = 0; i < fArgv.size(); i++ )
96  if ( fArgv[i].at(0) == '-' )
97  fArgc++;
98  }
99 
100  JackArgParser::~JackArgParser()
101  {}
102 
103  string JackArgParser::GetArgString()
104  {
105  return fArgString;
106  }
107 
108  int JackArgParser::GetNumArgv()
109  {
110  return fArgv.size();
111  }
112 
113  int JackArgParser::GetArgc()
114  {
115  return fArgc;
116  }
117 
118  int JackArgParser::GetArgv ( vector<string>& argv )
119  {
120  argv = fArgv;
121  return 0;
122  }
123 
124  int JackArgParser::GetArgv ( char** argv )
125  {
126  //argv must be NULL
127  if ( argv )
128  return -1;
129  //else allocate and fill it
130  argv = (char**)calloc (fArgv.size(), sizeof(char*));
131  if (argv == NULL)
132  {
133  return -1;
134  }
135  for ( unsigned int i = 0; i < fArgv.size(); i++ )
136  {
137  argv[i] = (char*)calloc(fArgv[i].length(), sizeof(char));
138  fill_n ( argv[i], fArgv[i].length() + 1, 0 );
139  fArgv[i].copy ( argv[i], fArgv[i].length() );
140  }
141  return 0;
142  }
143 
144  void JackArgParser::DeleteArgv ( const char** argv )
145  {
146  unsigned int i;
147  for ( i = 0; i < fArgv.size(); i++ )
148  free((void*)argv[i]);
149  free((void*)argv);
150  }
151 
152  bool JackArgParser::ParseParams ( jack_driver_desc_t* desc, JSList** param_list )
153  {
154  string options_list;
155  unsigned long i = 0;
156  unsigned int param = 0;
157  size_t param_id = 0;
158  JSList* params = NULL;
159  jack_driver_param_t* intclient_param;
160 
161  for ( i = 0; i < desc->nparams; i++ )
162  options_list += desc->params[i].character;
163 
164  for ( param = 0; param < fArgv.size(); param++ )
165  {
166  if ( fArgv[param][0] == '-' )
167  {
168  //valid option
169  if ( ( param_id = options_list.find_first_of ( fArgv[param].at(1) ) ) != string::npos )
170  {
171  intclient_param = static_cast<jack_driver_param_t*> ( calloc ( 1, sizeof ( jack_driver_param_t) ) );
172  intclient_param->character = desc->params[param_id].character;
173 
174  switch ( desc->params[param_id].type )
175  {
176  case JackDriverParamInt:
177  if (param + 1 < fArgv.size()) // something to parse
178  intclient_param->value.i = atoi ( fArgv[param + 1].c_str() );
179  break;
180 
181  case JackDriverParamUInt:
182  if (param + 1 < fArgv.size()) // something to parse
183  intclient_param->value.ui = strtoul ( fArgv[param + 1].c_str(), NULL, 10 );
184  break;
185 
186  case JackDriverParamChar:
187  if (param + 1 < fArgv.size()) // something to parse
188  intclient_param->value.c = fArgv[param + 1][0];
189  break;
190 
191  case JackDriverParamString:
192  if (param + 1 < fArgv.size()) // something to parse
193  fArgv[param + 1].copy ( intclient_param->value.str, min(static_cast<int>(fArgv[param + 1].length()), JACK_DRIVER_PARAM_STRING_MAX) );
194  break;
195 
196  case JackDriverParamBool:
197  intclient_param->value.i = true;
198  break;
199  }
200  //add to the list
201  params = jack_slist_append ( params, intclient_param );
202  }
203  //invalid option
204  else {
205  if (fArgv[param][1] == 'h') {
206  fprintf(stdout, "Internal client parameters:\n");
207  jack_print_driver_options (desc, stdout);
208  return false;
209  } else {
210  jack_error ( "Invalid option '%c'", fArgv[param][1] );
211  }
212  }
213  }
214  }
215 
216  assert(param_list);
217  *param_list = params;
218  return true;
219  }
220 
221  void JackArgParser::FreeParams ( JSList* param_list )
222  {
223  JSList *node_ptr = param_list;
224  JSList *next_node_ptr;
225 
226  while (node_ptr) {
227  next_node_ptr = node_ptr->next;
228  free(node_ptr->data);
229  free(node_ptr);
230  node_ptr = next_node_ptr;
231  }
232  }
233 
234 }
235 
SERVER_EXPORT void jack_error(const char *fmt,...)
Definition: JackError.cpp:91
jack_driver_param_type_t type
SERVER_EXPORT void jack_log(const char *fmt,...)
Definition: JackError.cpp:107
jack_driver_param_desc_t * params