jack2 codebase
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

236 lines
8.0KB

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