Jack2 1.9.6
|
00001 /* 00002 Copyright (C) 2006-2008 Grame 00003 00004 This program is free software; you can redistribute it and/or modify 00005 it under the terms of the GNU Lesser General Public License as published by 00006 the Free Software Foundation; either version 2.1 of the License, or 00007 (at your option) any later version. 00008 00009 This program is distributed in the hope that it will be useful, 00010 but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 GNU Lesser General Public License for more details. 00013 00014 You should have received a copy of the GNU Lesser General Public License 00015 along with this program; if not, write to the Free Software 00016 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00017 00018 */ 00019 00020 #include "JackDriverLoader.h" 00021 #include "JackArgParser.h" 00022 #include <stdlib.h> 00023 #include <stdio.h> 00024 #include <assert.h> 00025 00026 using namespace std; 00027 00028 namespace Jack { 00029 00030 // class JackArgParser *************************************************** 00031 JackArgParser::JackArgParser ( const char* arg ) 00032 { 00033 jack_log ( "JackArgParser::JackArgParser, arg_string : '%s'", arg ); 00034 00035 fArgc = 0; 00036 //if empty string 00037 if ( strlen(arg) == 0 ) 00038 return; 00039 fArgString = string(arg); 00040 //else parse the arg string 00041 const size_t arg_len = fArgString.length(); 00042 unsigned int i = 0; 00043 size_t pos = 0; 00044 size_t start = 0; 00045 size_t copy_start = 0; 00046 size_t copy_length = 0; 00047 //we need a 'space terminated' string 00048 fArgString += " "; 00049 //first fill a vector with args 00050 do { 00051 //find the first non-space character from the actual position 00052 start = fArgString.find_first_not_of ( ' ', start ); 00053 //get the next quote or space position 00054 pos = fArgString.find_first_of ( " \"" , start ); 00055 //no more quotes or spaces, consider the end of the string 00056 if ( pos == string::npos ) 00057 pos = arg_len; 00058 //if double quote 00059 if ( fArgString[pos] == '\"' ) { 00060 //first character : copy the substring 00061 if ( pos == start ) { 00062 copy_start = start + 1; 00063 pos = fArgString.find ( '\"', ++pos ); 00064 copy_length = pos - copy_start; 00065 start = pos + 1; 00066 } 00067 //else there is someting before the quote, first copy that 00068 else { 00069 copy_start = start; 00070 copy_length = pos - copy_start; 00071 start = pos; 00072 } 00073 } 00074 //if space 00075 if ( fArgString[pos] == ' ' ) { 00076 //short option descriptor 00077 if ( ( fArgString[start] == '-' ) && ( fArgString[start + 1] != '-' ) ) { 00078 copy_start = start; 00079 copy_length = 2; 00080 start += copy_length; 00081 } 00082 //else copy all the space delimitated string 00083 else { 00084 copy_start = start; 00085 copy_length = pos - copy_start; 00086 start = pos + 1; 00087 } 00088 } 00089 //then push the substring to the args vector 00090 fArgv.push_back ( fArgString.substr ( copy_start, copy_length ) ); 00091 jack_log ( "JackArgParser::JackArgParser, add : '%s'", (*fArgv.rbegin()).c_str() ); 00092 } while ( start < arg_len ); 00093 00094 //finally count the options 00095 for ( i = 0; i < fArgv.size(); i++ ) 00096 if ( fArgv[i].at(0) == '-' ) 00097 fArgc++; 00098 } 00099 00100 JackArgParser::~JackArgParser() 00101 {} 00102 00103 string JackArgParser::GetArgString() 00104 { 00105 return fArgString; 00106 } 00107 00108 int JackArgParser::GetNumArgv() 00109 { 00110 return fArgv.size(); 00111 } 00112 00113 int JackArgParser::GetArgc() 00114 { 00115 return fArgc; 00116 } 00117 00118 int JackArgParser::GetArgv ( vector<string>& argv ) 00119 { 00120 argv = fArgv; 00121 return 0; 00122 } 00123 00124 int JackArgParser::GetArgv ( char** argv ) 00125 { 00126 //argv must be NULL 00127 if ( argv ) 00128 return -1; 00129 //else allocate and fill it 00130 argv = (char**)calloc (fArgv.size(), sizeof(char*)); 00131 if (argv == NULL) 00132 { 00133 return -1; 00134 } 00135 for ( unsigned int i = 0; i < fArgv.size(); i++ ) 00136 { 00137 argv[i] = (char*)calloc(fArgv[i].length(), sizeof(char)); 00138 fill_n ( argv[i], fArgv[i].length() + 1, 0 ); 00139 fArgv[i].copy ( argv[i], fArgv[i].length() ); 00140 } 00141 return 0; 00142 } 00143 00144 void JackArgParser::DeleteArgv ( const char** argv ) 00145 { 00146 unsigned int i; 00147 for ( i = 0; i < fArgv.size(); i++ ) 00148 free((void*)argv[i]); 00149 free((void*)argv); 00150 } 00151 00152 bool JackArgParser::ParseParams ( jack_driver_desc_t* desc, JSList** param_list ) 00153 { 00154 string options_list; 00155 unsigned long i = 0; 00156 unsigned int param = 0; 00157 size_t param_id = 0; 00158 JSList* params = NULL; 00159 jack_driver_param_t* intclient_param; 00160 00161 for ( i = 0; i < desc->nparams; i++ ) 00162 options_list += desc->params[i].character; 00163 00164 for ( param = 0; param < fArgv.size(); param++ ) 00165 { 00166 if ( fArgv[param][0] == '-' ) 00167 { 00168 //valid option 00169 if ( ( param_id = options_list.find_first_of ( fArgv[param].at(1) ) ) != string::npos ) 00170 { 00171 intclient_param = static_cast<jack_driver_param_t*> ( calloc ( 1, sizeof ( jack_driver_param_t) ) ); 00172 intclient_param->character = desc->params[param_id].character; 00173 00174 switch ( desc->params[param_id].type ) 00175 { 00176 case JackDriverParamInt: 00177 if (param + 1 < fArgv.size()) // something to parse 00178 intclient_param->value.i = atoi ( fArgv[param + 1].c_str() ); 00179 break; 00180 00181 case JackDriverParamUInt: 00182 if (param + 1 < fArgv.size()) // something to parse 00183 intclient_param->value.ui = strtoul ( fArgv[param + 1].c_str(), NULL, 10 ); 00184 break; 00185 00186 case JackDriverParamChar: 00187 if (param + 1 < fArgv.size()) // something to parse 00188 intclient_param->value.c = fArgv[param + 1][0]; 00189 break; 00190 00191 case JackDriverParamString: 00192 if (param + 1 < fArgv.size()) // something to parse 00193 fArgv[param + 1].copy ( intclient_param->value.str, min(static_cast<int>(fArgv[param + 1].length()), JACK_DRIVER_PARAM_STRING_MAX) ); 00194 break; 00195 00196 case JackDriverParamBool: 00197 intclient_param->value.i = true; 00198 break; 00199 } 00200 //add to the list 00201 params = jack_slist_append ( params, intclient_param ); 00202 } 00203 //invalid option 00204 else { 00205 if (fArgv[param][1] == 'h') { 00206 fprintf(stdout, "Internal client parameters:\n"); 00207 jack_print_driver_options (desc, stdout); 00208 return false; 00209 } else { 00210 jack_error ( "Invalid option '%c'", fArgv[param][1] ); 00211 } 00212 } 00213 } 00214 } 00215 00216 assert(param_list); 00217 *param_list = params; 00218 return true; 00219 } 00220 00221 void JackArgParser::FreeParams ( JSList* param_list ) 00222 { 00223 JSList *node_ptr = param_list; 00224 JSList *next_node_ptr; 00225 00226 while (node_ptr) { 00227 next_node_ptr = node_ptr->next; 00228 free(node_ptr->data); 00229 free(node_ptr); 00230 node_ptr = next_node_ptr; 00231 } 00232 } 00233 00234 } 00235