PageRenderTime 27ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 0ms

/unit-test/testlib/bpm-getopt.php

http://buddypress-media.googlecode.com/
PHP | 374 lines | 238 code | 15 blank | 121 comment | 70 complexity | b40960703f93c7e3d502b2a551fef453 MD5 | raw file
Possible License(s): AGPL-1.0, Apache-2.0, GPL-2.0, LGPL-2.1
  1. <?php
  2. /**
  3. * getopt relacement / extenstion
  4. *
  5. * prior to PHP 5.3 getopt is not supported on the windows plattform
  6. * and it does not support long options on other plattforms as well.
  7. *
  8. * this file offers a _getopt() function as a replacement. via the
  9. * php.net manual page for getop().
  10. *
  11. * original author is ???? / uberlinuxguy at tulg dot org
  12. *
  13. * the function has been taken from that website, and refactored
  14. * into a helper class to increase the protability
  15. *
  16. * @version 1.0 hakre-1
  17. *
  18. * CHANGELOG:
  19. *
  20. * - refactored the functions into a class (better portability)
  21. * - reformatted the code (copy & paste issues)
  22. * - removed eval calls (commented)
  23. * - smarter quoting
  24. * - indentation on tab and cleanup of whitespaces
  25. * - deprecated string access ({}) fixed with [].
  26. *
  27. * TODO:
  28. * (empty)
  29. *
  30. *
  31. * @link http://www.ntu.beautifulworldco.com/weblog/?p=526
  32. * @link http://www.php.net/getopt
  33. */
  34. /**
  35. * getoptParser
  36. *
  37. * getopt() compatible argv parsing.
  38. *
  39. * @see getoptParser::getopt()
  40. * @see getoptParser::split_para()
  41. */
  42. class getoptParser {
  43. /**
  44. * getopt()
  45. *
  46. * Usage: _getopt ( [$flag,] $short_option [, $long_option] );
  47. *
  48. * Note that another function split_para() is required, which can be
  49. * found in the same page.
  50. *
  51. * _getopt() fully simulates getopt() which is described at
  52. * (@see http://us.php.net/manual/en/function.getopt.php} , including long
  53. * options for PHP version under 5.3.0. (Prior to 5.3.0, long options was
  54. * only available on few systems)
  55. *
  56. * Besides legacy usage of getopt(), I also added a new option to manipulate
  57. * your own argument lists instead of those from command lines. This new
  58. * option can be a string or an array such as
  59. *
  60. * $flag = "-f value_f -ab --required 9 --optional=PK --option -v test -k";
  61. *
  62. * or
  63. *
  64. * $flag = array ( "-f", "value_f", "-ab", "--required", "9", "--optional=PK", "--option" );
  65. *
  66. * So there are four ways to work with _getopt(),
  67. *
  68. * 1. _getopt ( $short_option );
  69. * it's a legacy usage, same as getopt ( $short_option ).
  70. *
  71. * 2. _getopt ( $short_option, $long_option );
  72. * it's a legacy usage, same as getopt ( $short_option, $long_option ).
  73. *
  74. * 3. _getopt ( $flag, $short_option );
  75. * use your own argument lists instead of command line arguments.
  76. *
  77. * 4. _getopt ( $flag, $short_option, $long_option );
  78. * use your own argument lists instead of command line arguments.
  79. *
  80. * @version 1.3
  81. * @date 2009/05/30 (taken from the website 2010-01-11)
  82. * @author ???? / uberlinuxguy at tulg dot org
  83. * @see http://www.ntu.beautifulworldco.com/weblog/?p=526
  84. *
  85. * @params mixed
  86. * @return array
  87. */
  88. static function getopt() {
  89. if ( func_num_args() == 1 ) {
  90. $flag = $flag_array = $GLOBALS['argv'];
  91. $short_option = func_get_arg ( 0 );
  92. $long_option = array ();
  93. } elseif ( func_num_args() == 2 ) {
  94. if ( is_array ( func_get_arg ( 1 ) ) ) {
  95. $flag = $GLOBALS['argv'];
  96. $short_option = func_get_arg ( 0 );
  97. $long_option = func_get_arg ( 1 );
  98. } else {
  99. $flag = func_get_arg ( 0 );
  100. $short_option = func_get_arg ( 1 );
  101. $long_option = array ();
  102. }
  103. } elseif ( func_num_args() == 3 ) {
  104. $flag = func_get_arg ( 0 );
  105. $short_option = func_get_arg ( 1 );
  106. $long_option = func_get_arg ( 2 );
  107. } else {
  108. exit ( "wrong options\n" );
  109. }
  110. $short_option = trim($short_option);
  111. $short_no_value = array();
  112. $short_required_value = array();
  113. $short_optional_value = array();
  114. $long_no_value = array();
  115. $long_required_value = array();
  116. $long_optional_value = array();
  117. $options = array();
  118. for ( $i = 0; $i < strlen ( $short_option ); ) {
  119. if ( $short_option[$i] != ':' ) {
  120. if ( $i == strlen ( $short_option ) - 1 ) {
  121. $short_no_value[] = $short_option[$i];
  122. break;
  123. } elseif ( $short_option[$i+1] != ':' ) {
  124. $short_no_value[] = $short_option[$i];
  125. $i++;
  126. continue;
  127. } elseif ( $short_option[$i+1] == ':' && $short_option[$i+2] != ':' ) {
  128. $short_required_value[] = $short_option[$i];
  129. $i += 2;
  130. continue;
  131. } elseif ( $short_option[$i+1] == ':' && $short_option[$i+2] == ':' ) {
  132. $short_optional_value[] = $short_option[$i];
  133. $i += 3;
  134. continue;
  135. }
  136. } else {
  137. continue;
  138. }
  139. }
  140. foreach ( $long_option as $a ) {
  141. if ( substr( $a, -2 ) == '::' ) {
  142. $long_optional_value[] = substr($a, 0, -2);
  143. } elseif ( substr($a, -1) == ':' ) {
  144. $long_required_value[] = substr($a, 0, -1);
  145. } else {
  146. $long_no_value[] = $a;
  147. }
  148. }
  149. if ( is_array ( $flag ) ) {
  150. $flag_array = $flag;
  151. } else {
  152. $flag = "- $flag";
  153. $flag_array = self::_split_para($flag);
  154. }
  155. for ( $i = 0; $i < count($flag_array); ) {
  156. if ( !$flag_array[$i] || ( '-' == $flag_array[$i] ) ) {
  157. $i++;
  158. continue;
  159. } elseif ( '-' != $flag_array[$i][0] ) {
  160. $i++;
  161. continue;
  162. }
  163. if ( substr($flag_array[$i], 0, 2) == '--' ) {
  164. if (strpos($flag_array[$i], '=') != false) {
  165. list($key, $value) = explode('=', substr($flag_array[$i], 2), 2);
  166. if ( in_array($key, $long_required_value ) || in_array($key, $long_optional_value ) )
  167. $options[$key][] = $value;
  168. $i++;
  169. continue;
  170. } elseif (strpos($flag_array[$i], '=') == false) {
  171. $key = substr($flag_array[$i], 2);
  172. if ( in_array(substr( $flag_array[$i], 2 ), $long_required_value ) ) {
  173. $options[$key][] = $flag_array[$i+1];
  174. $i++;
  175. } elseif ( in_array(substr( $flag_array[$i], 2 ), $long_optional_value ) ) {
  176. if ( $flag_array[$i+1] != '' && $flag_array[$i+1][0] != '-' ) {
  177. $options[$key][] = $flag_array[$i+1];
  178. $i++;
  179. } else {
  180. $options[$key][] = FALSE;
  181. }
  182. } elseif ( in_array(substr( $flag_array[$i], 2 ), $long_no_value ) ) {
  183. $options[$key][] = FALSE;
  184. }
  185. $i++;
  186. continue;
  187. }
  188. } elseif ( $flag_array[$i][0] == '-' && $flag_array[$i][1] != '-' ) {
  189. for ( $j=1; $j < strlen($flag_array[$i]); $j++ ) {
  190. if ( in_array($flag_array[$i][$j], $short_required_value ) || in_array($flag_array[$i][$j], $short_optional_value )) {
  191. if ( $j == strlen($flag_array[$i]) - 1 ) {
  192. if ( in_array($flag_array[$i][$j], $short_required_value ) ) {
  193. if (isset($flag_array[$i+1]))
  194. $options[$flag_array[$i][$j]][] = $flag_array[$i+1];
  195. $i++;
  196. } elseif ( in_array($flag_array[$i][$j], $short_optional_value ) && $flag_array[$i+1] != '' && $flag_array[$i+1][0] != '-' ) {
  197. $options[$flag_array[$i][$j]][] = $flag_array[$i+1];
  198. $i++;
  199. } else {
  200. $options[$flag_array[$i][$j]][] = FALSE;
  201. }
  202. } else {
  203. $options[$flag_array[$i][$j]][] = substr ( $flag_array[$i], $j + 1 );
  204. }
  205. $plus_i = 0;
  206. $i++;
  207. break;
  208. } elseif ( in_array($flag_array[$i][$j], $short_no_value ) ) {
  209. $options[$flag_array[$i][$j]][] = FALSE;
  210. $plus_i = 1;
  211. continue;
  212. } else {
  213. $plus_i = 1;
  214. break;
  215. }
  216. }
  217. $i += $plus_i;
  218. continue;
  219. } // if
  220. $i++;
  221. } // for
  222. // reduce options array depth if possible
  223. foreach ( $options as $key => $value ) {
  224. if ( count($value) == 1 )
  225. $options[$key] = $value[0];
  226. }
  227. return $options;
  228. }
  229. /**
  230. * split parameters
  231. *
  232. * static helper function
  233. *
  234. * @version 1.0
  235. * @date 2008/08/19
  236. * @see http://www.ntu.beautifulworldco.com/weblog/?p=526
  237. *
  238. * This function is to parse parameters and split them into smaller pieces.
  239. * preg_split() does similar thing but in our function, besides "space", we
  240. * also take the three symbols " (double quote), '(single quote),
  241. * and \ (backslash) into consideration because things in a pair of " or '
  242. * should be grouped together.
  243. *
  244. * As an example, this parameter list
  245. *
  246. * -f "test 2" -ab --required "t\"est 1" --optional="te'st 3" --option -v 'test 4'
  247. *
  248. * will be splited into
  249. *
  250. * -f; test 2; -ab; --required; t"est 1; --optional=te'st 3; --option; -v; test 4
  251. *
  252. * see the code below:
  253. *
  254. * <code>
  255. * $pattern = "-f \"test 2\" -ab --required \"t\\\"est 1\" --optional=\"te'st 3\" --option -v 'test 4'";
  256. * $result = getoptParser::split_para($pattern);
  257. * echo "ORIGINAL PATTERN: $pattern\n\n";
  258. * var_dump($result);
  259. * </code>
  260. *
  261. * @param string $pattern
  262. * @return array
  263. */
  264. public static function split_para($pattern) {
  265. $begin = 0;
  266. $backslash = 0;
  267. $quote = '';
  268. $quote_mark = array();
  269. $result = array();
  270. $pattern = trim($pattern);
  271. $cand1 = '';
  272. for ( $end = 0; $end < strlen($pattern); ) {
  273. if ( !in_array($pattern[$end], array(' ', '"', "'", "\\")) ) {
  274. $backslash = 0;
  275. $end++;
  276. continue;
  277. }
  278. if ( $pattern[$end] == "\\" ) {
  279. $backslash++;
  280. $end++;
  281. continue;
  282. } elseif ( $pattern[$end] == '"' ) {
  283. if ( $backslash % 2 == 1 || $quote == "'" ) {
  284. $backslash = 0;
  285. $end++;
  286. continue;
  287. }
  288. if ( $quote == '' ) {
  289. $quote_mark[] = $end - $begin;
  290. $quote = '"';
  291. } elseif ( $quote == '"' ) {
  292. $quote_mark[] = $end - $begin;
  293. $quote = '';
  294. }
  295. $backslash = 0;
  296. $end++;
  297. continue;
  298. } elseif ( $pattern[$end] == "'" ) {
  299. if ( $backslash % 2 == 1 || $quote == '"' ) {
  300. $backslash = 0;
  301. $end++;
  302. continue;
  303. }
  304. if ( $quote == '' ) {
  305. $quote_mark[] = $end - $begin;
  306. $quote = "'";
  307. } elseif ( $quote == "'" ) {
  308. $quote_mark[] = $end - $begin;
  309. $quote = '';
  310. }
  311. $backslash = 0;
  312. $end++;
  313. continue;
  314. } elseif ( $pattern[$end] == ' ' ) {
  315. if ( $quote != '' ) {
  316. $backslash = 0;
  317. $end++;
  318. continue;
  319. } else {
  320. $backslash = 0;
  321. $cand = substr($pattern, $begin, $end-$begin);
  322. for ( $j = 0; $j < strlen($cand); $j++ ) {
  323. if ( in_array($j, $quote_mark) )
  324. continue;
  325. $cand1 .= $cand[$j];
  326. }
  327. if ( $cand1 ) {
  328. // commented and replaced:
  329. // eval( "\$cand1 = \"$cand1\";" );
  330. $result[] = (string) $cand1;
  331. }
  332. $quote_mark = array();
  333. $cand1 = '';
  334. $begin =++$end;
  335. continue;
  336. }
  337. }
  338. }
  339. $cand = substr($pattern, $begin, $end-$begin);
  340. for ( $j = 0; $j < strlen($cand); $j++ ) {
  341. if ( in_array($j, $quote_mark ) )
  342. continue;
  343. $cand1 .= $cand[$j];
  344. }
  345. // commented and replaced:
  346. // eval( "\$cand1 = \"$cand1\";" );
  347. $cand1 = (string) $cand1;
  348. if ( $cand1 )
  349. $result[] = $cand1;
  350. return $result;
  351. }
  352. }
  353. ?>