Jack2 1.9.12

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
jack_error
SERVER_EXPORT void jack_error(const char *fmt,...)
Definition: JackError.cpp:92
jack_driver_desc_t::nparams
uint32_t nparams
Definition: driver_interface.h:137
jack_driver_param_desc_t::type
jack_driver_param_type_t type
Definition: driver_interface.h:116
jack_driver_param_t
Definition: driver_interface.h:125
_JSList
Definition: linux/alsa/jslist.h:35
jack_log
SERVER_EXPORT void jack_log(const char *fmt,...)
Definition: JackError.cpp:108
jack_driver_desc_t
Definition: driver_interface.h:132
jack_driver_desc_t::params
jack_driver_param_desc_t * params
Definition: driver_interface.h:138
jack_driver_param_desc_t::character
char character
Definition: driver_interface.h:115