-
Notifications
You must be signed in to change notification settings - Fork 0
/
oGetopt.php
243 lines (219 loc) · 5.45 KB
/
oGetopt.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
<?php
/**
* Project: oGetopt :: OOPS C library (olibc)의 o_getopt wrapping api<br>
* File: oGetopt.php<br>
* Dependency: {@link ePrint} over 1.0.1
*
* OOPS C library의 o_getopt wrapping Class
* 이 패키지는 getopt function의 대안을 제공한다.
*
* 이 패키지는 {@link ePrint} 1.0.1 이상 버전이 필요하다.
*
* @category Core
* @package oGetopt
* @author JoungKyun.Kim <http://oops.org>
* @copyright (c) 2018, OOPS.org
* @link http://pear.oops.org/package/oGetopt
* @since File available since relase 1.0.0
* @example oGetopt/test.php 샘플 예제 코드
* @filesource
*/
/**
* import ePrint class
* @see ePrint
*/
require_once 'ePrint.php';
if ( ! extension_loaded ('gettext') ) {
function _($s) { return $s; }
}
/**
* Base classes for oops getopt
* @package oGetopt
*/
class oGetopt extends ePrint {
// {{{ properties
/**#@+
* @access public
*/
/**
* 현재 옵션 값
* @var string
*/
static public $optarg;
/**
* 옵션이 아닌 명령행 인자가 할당되는 배열
* @var array
*/
static public $optcmd;
/**
* long 옵션 매핑 테이블
* @var stdClass
*/
static public $longopt;
/**
* 옵션이 아닌 명령행 인자의 수
* @var integer
*/
static public $optcno;
/**#@-*/
/**#@+
* @access private
*/
/**#@+
* @var integer
*/
/**
* Set 1, option command argument parsing is end
*/
static private $optend;
/**
* command argument order
*/
static private $gno;
/**#@-*/
/**#@-*/
// }}}
// {{{ constructor
/**
* @access public
* @return void
*/
function __construct () {
self::init ();
$this->gno = &self::$gno;
$this->optcno = &self::$optcno;
$this->optend = &self::$optend;
$this->optarg = &self::$optarg;
$this->optcmd = &self::$optcmd;
$this->longopt = &self::$longopt;
}
// }}}
// {{{ public function init ()
/**
* 인자의 순서를 초기화
*
* @access public
* @return void
*/
static public function init () {
self::$gno = -1;
self::$optcno = -1;
self::$optend = -1;
self::$optarg = '';
self::$optcmd = array ();
self::$longopt = new stdClass;
}
// }}}
// {{{ public function exec ($argc, $argv, $optstrs)
/**
* getopt 실행
*
* @access public
* @return string short option을 반환.
*
* false를 반환할 경우, getopt 수행이 완료 되었음을 의미.
* 잘못된 옵션이 있을 경우, 에러 메시지 출력 후 null 반환.
*
* @param integer 명령행 인자 수
* @param array 명령행 인자 배열
* @param string 옵션 형식.
* '{@link http://man.kldp.net/wiki/ManPage/getopt.3 man 3 getopt}'
* 참조
*/
static public function exec ($argc, $argv, $optstrs) {
if ( self::$gno < 0 ) self::$gno = 1;
if ( self::$optcno < 0 ) self::$optcno = 0;
if ( ! isset (self::$optcno) || self::$optend < 0 )
self::$optend = 0;
self::$optarg = '';
$errMark = parent::asPrintf ('white', _('ERROR'));
while ( true ) {
if ( self::$gno == $argc )
return false;
// {{{ case by long option
if ( preg_match ('/^--[a-z]/i', $argv[self::$gno] ) && ! self::$optend ) {
$longops = explode ('=', $argv[self::$gno]);
$longname = trim (substr ($longops[0], 2));
self::$optarg = trim ($longops[1]);
$errArg = array ($errMark, $longname);
if ( ! ($opt = self::$longopt->$longname) ) {
parent::ePrintf (_("%s: option --%s don't support"), $errArg);
return null;
}
if ( preg_match ("/{$opt}:/", $optstrs) ) {
self::$optarg = self::$optarg ? self::$optarg : $argv[self::$gno + 1];
if ( ! trim (self::$optarg) ) {
parent::ePrintf (_('%s: option --%s must need values'), $errArg);
return null;
}
if ( ! preg_match ('/=/', $argv[self::$gno]) ) self::$gno++;
}
break;
}
// }}}
// {{{ case by short option
else if ( preg_match ('/^-[a-z]/i', $argv[self::$gno] ) && ! self::$optend ) {
$opt = $argv[self::$gno][1];
$optvalue_c = $argv[self::$gno][2];
$errArg = array ($errMark, $opt);
if ( preg_match ("/{$opt}:/", $optstrs) ) {
if ( $optvalue_c )
self::$optarg = substr ($argv[self::$gno], 2);
else {
$nextArg = $argv[self::$gno + 1];
if ( preg_match ('/^-[a-z-]/i', $nextArg) ) {
parent::ePrintf (_('%s: option -%s must need option value'), $errArg);
return null;
}
self::$optarg = $nextArg;
self::$gno++;
}
if ( ! trim (self::$optarg) ) {
parent::ePrintf (_("%s: option -%s must need option value"), $errArg);
return null;
}
} else {
if ( $optvalue_c ) {
parent::ePrintf (_("%s: option -%s must have not any value"), $errArg);
return null;
}
$buf = preg_replace ('/[a-z]:/i', '', $optstrs);
$blen = strlen ($buf);
$_optok = 0;
for ( $i=0; $i<$blen; $i++ ) {
if ( $buf[$i] == $opt ) {
$_optok++;
break;
}
}
if ( $_optok < 1 ) {
parent::ePrintf (_("%s: option -%s don't support"), $errArg);
return null;
}
}
break;
}
// }}}
// {{{ Case by command arg
else {
/*
* After '--' command argument, next is not options.
* Set self::$optend to 1.
*/
if ( $argv[self::$gno] == '--' ) {
self::$optend = 1;
continue;
}
self::$optcmd[self::$optcno] = $argv[self::$gno];
self::$optcno++;
self::$gno++;
continue;
}
// }}}
}
self::$gno++;
return $opt;
}
// }}}
}
?>