MFH: Implemented "jump label" operator (limited "goto")

[DOC]
This commit is contained in:
Felipe Pena 2008-03-28 14:35:01 +00:00
parent 9d9468e9f4
commit f66f55edc5
26 changed files with 3076 additions and 2641 deletions

14
Zend/tests/jump01.phpt Executable file
View File

@ -0,0 +1,14 @@
--TEST--
jump 01: goto backward
--FILE--
<?php
$n = 1;
L1:
echo "$n: ok\n";
$n++;
if ($n <= 3) goto L1;
?>
--EXPECT--
1: ok
2: ok
3: ok

16
Zend/tests/jump02.phpt Executable file
View File

@ -0,0 +1,16 @@
--TEST--
jump 02: goto forward
--FILE--
<?php
$n = 1;
L1:
if ($n > 3) goto L2;
echo "$n: ok\n";
$n++;
goto L1;
L2:
?>
--EXPECT--
1: ok
2: ok
3: ok

18
Zend/tests/jump03.phpt Executable file
View File

@ -0,0 +1,18 @@
--TEST--
jump 03: goto inside control structures
--FILE--
<?php
do {
if (1) {
echo "1: ok\n";
goto L1;
} else {
echo "bug\n";
L1:
echo "2: ok\n";
}
} while (0);
?>
--EXPECT--
1: ok
2: ok

24
Zend/tests/jump04.phpt Executable file
View File

@ -0,0 +1,24 @@
--TEST--
jump 04: goto from loop (backward)
--FILE--
<?php
$s = "X";
echo "1: ok\n";
L1: if ($s != "X") {
echo "4: ok\n";
} else {
echo "2: ok\n";
while ($s != "XXX") {
echo "3: ok\n";
$s .= "X";
goto L1;
echo "bug\n";
}
echo "bug\n";
}
?>
--EXPECT--
1: ok
2: ok
3: ok
4: ok

26
Zend/tests/jump05.phpt Executable file
View File

@ -0,0 +1,26 @@
--TEST--
jump 05: goto from loop (forward)
--FILE--
<?php
$ar = array("1","2","3");
foreach ($ar as $val) {
switch ($val) {
case "1":
echo "1: ok\n";
break;
case "2":
echo "2: ok\n";
goto L1;
case "3":
echo "bug\n";
break;
}
}
echo "bug\n";
L1:
echo "3: ok\n";
?>
--EXPECT--
1: ok
2: ok
3: ok

8
Zend/tests/jump06.phpt Executable file
View File

@ -0,0 +1,8 @@
--TEST--
jump 06: goto to undefined label
--FILE--
<?php
goto L1;
?>
--EXPECTF--
Fatal error: 'goto' to undefined label 'L1' in %sjump06.php on line 2

11
Zend/tests/jump07.phpt Executable file
View File

@ -0,0 +1,11 @@
--TEST--
jump 07: goto into loop (backward)
--FILE--
<?php
while (0) {
L1: echo "bug\n";
}
goto L1;
?>
--EXPECTF--
Fatal error: 'goto' into loop or switch statement is disallowed in %sjump07.php on line 5

11
Zend/tests/jump08.phpt Executable file
View File

@ -0,0 +1,11 @@
--TEST--
jump 08: goto into loop (forward)
--FILE--
<?php
goto L1;
while (0) {
L1: echo "bug\n";
}
?>
--EXPECTF--
Fatal error: 'goto' into loop or switch statement is disallowed in %sjump08.php on line 2

13
Zend/tests/jump09.phpt Executable file
View File

@ -0,0 +1,13 @@
--TEST--
jump 09: goto into switch (backward)
--FILE--
<?php
switch (0) {
case 1:
L1: echo "bug\n";
break;
}
goto L1;
?>
--EXPECTF--
Fatal error: 'goto' into loop or switch statement is disallowed in %sjump09.php on line 7

13
Zend/tests/jump10.phpt Executable file
View File

@ -0,0 +1,13 @@
--TEST--
jump 10: goto into switch (forward)
--FILE--
<?php
goto L1;
switch (0) {
case 1:
L1: echo "bug\n";
break;
}
?>
--EXPECTF--
Fatal error: 'goto' into loop or switch statement is disallowed in %sjump10.php on line 2

26
Zend/tests/jump11.phpt Normal file
View File

@ -0,0 +1,26 @@
--TEST--
jump 08: goto inside switch in constructor
--FILE--
<?php
class foobar {
public function __construct() {
switch (1) {
default:
goto b;
a:
print "ok!\n";
break;
b:
print "ok!\n";
goto a;
}
print "ok!\n";
}
}
new foobar;
?>
--EXPECT--
ok!
ok!
ok!

19
Zend/tests/jump12.phpt Normal file
View File

@ -0,0 +1,19 @@
--TEST--
jump 09: goto in declare statement
--FILE--
<?php
a: print "ok!\n";
goto c;
declare (ticks=1) {
b:
print "ok!\n";
exit;
}
c:
print "ok!\n";
goto b;
?>
--EXPECT--
ok!
ok!
ok!

25
Zend/tests/jump13.phpt Normal file
View File

@ -0,0 +1,25 @@
--TEST--
jump 10: goto with try blocks
--FILE--
<?php
goto a;
e: return;
try {
a: print 1;
goto b;
try {
b: print 2;
goto c;
}
catch(Exception $e) {
c: print 3;
goto d;
}
}
catch(Exception $e) {
d: print 4;
goto e;
}
?>
--EXPECT--
1234

View File

@ -130,6 +130,8 @@ void zend_init_compiler_data_structures(TSRMLS_D)
CG(current_import) = NULL;
init_compiler_declarables(TSRMLS_C);
zend_hash_apply(CG(auto_globals), (apply_func_t) zend_auto_global_arm TSRMLS_CC);
zend_stack_init(&CG(labels_stack));
CG(labels) = NULL;
}
@ -163,6 +165,7 @@ void shutdown_compiler(TSRMLS_D)
zend_stack_destroy(&CG(list_stack));
zend_hash_destroy(&CG(filenames_table));
zend_llist_destroy(&CG(open_files));
zend_stack_destroy(&CG(labels_stack));
}
@ -1274,6 +1277,9 @@ void zend_do_begin_function_declaration(znode *function_token, znode *function_n
CG(doc_comment) = NULL;
CG(doc_comment_len) = 0;
}
zend_stack_push(&CG(labels_stack), (void *) &CG(labels), sizeof(HashTable*));
CG(labels) = NULL;
}
void zend_do_handle_exception(TSRMLS_D)
@ -1295,6 +1301,7 @@ void zend_do_end_function_declaration(znode *function_token TSRMLS_DC)
zend_do_return(NULL, 0 TSRMLS_CC);
pass_two(CG(active_op_array) TSRMLS_CC);
zend_release_labels(TSRMLS_C);
if (CG(active_class_entry)) {
zend_check_magic_method_implementation(CG(active_class_entry), (zend_function*)CG(active_op_array), E_COMPILE_ERROR TSRMLS_CC);
@ -1668,6 +1675,110 @@ void zend_do_fetch_class(znode *result, znode *class_name TSRMLS_DC)
*result = opline->result;
}
void zend_do_label(znode *label TSRMLS_DC) /* {{{ */
{
zend_op_array *oparray = CG(active_op_array);
zend_label dest;
if (!CG(labels)) {
ALLOC_HASHTABLE(CG(labels));
zend_hash_init(CG(labels), 4, NULL, NULL, 0);
}
dest.brk_cont = oparray->current_brk_cont;
dest.opline_num = get_next_op_number(oparray);
if (zend_hash_add(CG(labels), Z_STRVAL(label->u.constant), Z_STRLEN(label->u.constant) + 1, (void**)&dest, sizeof(zend_label), NULL) == FAILURE) {
zend_error(E_COMPILE_ERROR, "Label '%s' already defined", Z_STRVAL(label->u.constant));
}
/* Done with label now */
zval_dtor(&label->u.constant);
}
/* }}} */
void zend_resolve_goto_label(zend_op_array *op_array, zend_op *opline, int pass2 TSRMLS_DC) /* {{{ */
{
zend_label *dest;
long current, distance;
if (CG(labels) == NULL ||
zend_hash_find(CG(labels), Z_STRVAL(opline->op2.u.constant), Z_STRLEN(opline->op2.u.constant)+1, (void**)&dest) == FAILURE) {
if (pass2) {
CG(in_compilation) = 1;
CG(active_op_array) = op_array;
CG(zend_lineno) = opline->lineno;
zend_error(E_COMPILE_ERROR, "'goto' to undefined label '%s'", Z_STRVAL(opline->op2.u.constant));
} else {
/* Label is not defined. Delay to pass 2. */
INC_BPC(op_array);
return;
}
}
opline->op1.u.opline_num = dest->opline_num;
zval_dtor(&opline->op2.u.constant);
/* Check that we are not moving into loop or switch */
current = opline->extended_value;
for (distance = 0; current != dest->brk_cont; distance++) {
if (current == -1) {
if (pass2) {
CG(in_compilation) = 1;
CG(active_op_array) = op_array;
CG(zend_lineno) = opline->lineno;
}
zend_error(E_COMPILE_ERROR, "'goto' into loop or switch statement is disallowed");
}
current = op_array->brk_cont_array[current].parent;
}
if (distance == 0) {
/* Nothing to break out of, optimize to ZEND_JMP */
opline->opcode = ZEND_JMP;
opline->extended_value = 0;
SET_UNUSED(opline->op2);
} else {
/* Set real break distance */
ZVAL_LONG(&opline->op2.u.constant, distance);
}
if (pass2) {
DEC_BPC(op_array);
}
}
/* }}} */
void zend_do_goto(znode *label TSRMLS_DC) /* {{{ */
{
zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
opline->opcode = ZEND_GOTO;
opline->extended_value = CG(active_op_array)->current_brk_cont;
SET_UNUSED(opline->op1);
opline->op2 = *label;
zend_resolve_goto_label(CG(active_op_array), opline, 0 TSRMLS_CC);
}
/* }}} */
void zend_release_labels(TSRMLS_D) /* {{{ */
{
if (CG(labels)) {
zend_hash_destroy(CG(labels));
FREE_HASHTABLE(CG(labels));
}
if (!zend_stack_is_empty(&CG(labels_stack))) {
HashTable **pht;
zend_stack_top(&CG(labels_stack), (void**)&pht);
CG(labels) = *pht;
zend_stack_del_top(&CG(labels_stack));
} else {
CG(labels) = NULL;
}
}
/* }}} */
void zend_do_build_full_name(znode *result, znode *prefix, znode *name TSRMLS_DC)
{

View File

@ -95,6 +95,10 @@ typedef struct _zend_brk_cont_element {
int parent;
} zend_brk_cont_element;
typedef struct _zend_label {
int brk_cont;
zend_uint opline_num;
} zend_label;
typedef struct _zend_try_catch_element {
zend_uint try_op;
@ -520,6 +524,11 @@ void zend_do_namespace(znode *name TSRMLS_DC);
void zend_do_use(znode *name, znode *new_name, int is_global TSRMLS_DC);
void zend_do_end_compilation(TSRMLS_D);
void zend_do_label(znode *label TSRMLS_DC);
void zend_do_goto(znode *label TSRMLS_DC);
void zend_resolve_goto_label(zend_op_array *op_array, zend_op *opline, int pass2 TSRMLS_DC);
void zend_release_labels(TSRMLS_D);
ZEND_API void function_add_ref(zend_function *function);
#define INITIAL_OP_ARRAY_SIZE 64

View File

@ -1371,6 +1371,11 @@ void execute_new_code(TSRMLS_D) /* {{{ */
Z_SET_REFCOUNT(opline->op2.u.constant, 2);
}
switch (opline->opcode) {
case ZEND_GOTO:
if (Z_TYPE(opline->op2.u.constant) != IS_LONG) {
zend_resolve_goto_label(CG(active_op_array), opline, 1 TSRMLS_CC);
}
/* break omitted intentionally */
case ZEND_JMP:
opline->op1.u.jmp_addr = &CG(active_op_array)->opcodes[opline->op1.u.opline_num];
break;
@ -1385,7 +1390,9 @@ void execute_new_code(TSRMLS_D) /* {{{ */
ZEND_VM_SET_OPCODE_HANDLER(opline);
opline++;
}
zend_release_labels(TSRMLS_C);
EG(return_value_ptr_ptr) = &local_retval;
EG(active_op_array) = CG(active_op_array);
zend_execute(CG(active_op_array) TSRMLS_CC);

View File

@ -131,6 +131,9 @@ struct _zend_compiler_globals {
zval *current_namespace;
HashTable *current_import;
HashTable *labels;
zend_stack labels_stack;
#ifdef ZTS
HashTable **static_members;
int last_static_member;

View File

@ -105,6 +105,7 @@
%token T_DEFAULT
%token T_BREAK
%token T_CONTINUE
%token T_GOTO
%token T_FUNCTION
%token T_CONST
%token T_RETURN
@ -199,6 +200,7 @@ inner_statement:
statement:
unticked_statement { zend_do_ticks(TSRMLS_C); }
| T_STRING ':' { zend_do_label(&$1 TSRMLS_CC); }
;
unticked_statement:
@ -247,6 +249,7 @@ unticked_statement:
'{' inner_statement_list '}' { zend_do_end_catch(&$1 TSRMLS_CC); }
additional_catches { zend_do_mark_last_catch(&$7, &$18 TSRMLS_CC); }
| T_THROW expr ';' { zend_do_throw(&$2 TSRMLS_CC); }
| T_GOTO T_STRING ';' { zend_do_goto(&$2 TSRMLS_CC); }
;

File diff suppressed because it is too large Load Diff

View File

@ -299,6 +299,7 @@ ZEND_API zend_op_array *compile_file(zend_file_handle *file_handle, int type TSR
CG(active_op_array) = original_active_op_array;
if (compilation_successful) {
pass_two(op_array TSRMLS_CC);
zend_release_labels(TSRMLS_C);
} else {
efree(op_array);
retval = NULL;
@ -421,6 +422,7 @@ zend_op_array *compile_string(zval *source_string, char *filename TSRMLS_DC)
zend_do_return(NULL, 0 TSRMLS_CC);
CG(active_op_array) = original_active_op_array;
pass_two(op_array TSRMLS_CC);
zend_release_labels(TSRMLS_C);
retval = op_array;
}
zend_restore_lexical_state(&original_lex_state TSRMLS_CC);
@ -782,6 +784,10 @@ NOWDOC_CHARS ({NEWLINE}*(([^a-zA-Z_\x7f-\xff\n\r][^\n\r]*)|({LABEL}[^a-zA-Z0-9_
return T_CONTINUE;
}
<ST_IN_SCRIPTING>"goto" {
return T_GOTO;
}
<ST_IN_SCRIPTING>"echo" {
return T_ECHO;
}

View File

@ -1,4 +1,4 @@
/* Generated by re2c 0.13.4.dev on Sat Mar 22 18:34:15 2008 */
/* Generated by re2c 0.13.4.dev on Wed Mar 26 23:08:45 2008 */
#line 3 "Zend/zend_language_scanner_defs.h"
enum YYCONDTYPE {

View File

@ -390,6 +390,11 @@ int pass_two(zend_op_array *op_array TSRMLS_DC)
Z_SET_REFCOUNT(opline->op2.u.constant, 2);
}
switch (opline->opcode) {
case ZEND_GOTO:
if (Z_TYPE(opline->op2.u.constant) != IS_LONG) {
zend_resolve_goto_label(op_array, opline, 1 TSRMLS_CC);
}
/* break omitted intentionally */
case ZEND_JMP:
opline->op1.u.jmp_addr = &op_array->opcodes[opline->op1.u.opline_num];
break;

View File

@ -2645,6 +2645,28 @@ ZEND_VM_HANDLER(51, ZEND_CONT, ANY, CONST|TMP|VAR|CV)
ZEND_VM_JMP(EX(op_array)->opcodes + el->cont);
}
ZEND_VM_HANDLER(100, ZEND_GOTO, ANY, CONST)
{
zend_op *brk_opline;
zend_op *opline = EX(opline);
zend_brk_cont_element *el;
el = zend_brk_cont(&opline->op2.u.constant, opline->extended_value,
EX(op_array), EX(Ts) TSRMLS_CC);
brk_opline = EX(op_array)->opcodes + el->brk;
switch (brk_opline->opcode) {
case ZEND_SWITCH_FREE:
zend_switch_free(&EX_T(brk_opline->op1.u.var), brk_opline->op1.op_type, brk_opline->extended_value TSRMLS_CC);
break;
case ZEND_FREE:
zendi_zval_dtor(EX_T(brk_opline->op1.u.var).tmp_var);
break;
}
ZEND_VM_JMP(opline->op1.u.jmp_addr);
}
ZEND_VM_HANDLER(48, ZEND_CASE, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
{
zend_op *opline = EX(opline);

View File

@ -773,6 +773,28 @@ static int ZEND_CONT_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
ZEND_VM_JMP(EX(op_array)->opcodes + el->cont);
}
static int ZEND_GOTO_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
zend_op *brk_opline;
zend_op *opline = EX(opline);
zend_brk_cont_element *el;
el = zend_brk_cont(&opline->op2.u.constant, opline->extended_value,
EX(op_array), EX(Ts) TSRMLS_CC);
brk_opline = EX(op_array)->opcodes + el->brk;
switch (brk_opline->opcode) {
case ZEND_SWITCH_FREE:
zend_switch_free(&EX_T(brk_opline->op1.u.var), brk_opline->op1.op_type, brk_opline->extended_value TSRMLS_CC);
break;
case ZEND_FREE:
zendi_zval_dtor(EX_T(brk_opline->op1.u.var).tmp_var);
break;
}
ZEND_VM_JMP(opline->op1.u.jmp_addr);
}
static int ZEND_ADD_INTERFACE_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
zend_op *opline = EX(opline);
@ -31806,27 +31828,27 @@ void zend_init_opcodes_handlers(void)
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_GOTO_SPEC_CONST_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_GOTO_SPEC_CONST_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_GOTO_SPEC_CONST_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_GOTO_SPEC_CONST_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_GOTO_SPEC_CONST_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,

View File

@ -118,6 +118,7 @@
#define ZEND_FETCH_OBJ_UNSET 97
#define ZEND_FETCH_DIM_TMP_VAR 98
#define ZEND_FETCH_CONSTANT 99
#define ZEND_GOTO 100
#define ZEND_EXT_STMT 101
#define ZEND_EXT_FCALL_BEGIN 102
#define ZEND_EXT_FCALL_END 103

View File

@ -1,4 +1,4 @@
/* Generated by re2c 0.12.1 on Wed Oct 10 12:26:17 2007 */
/* Generated by re2c 0.13.4.dev on Wed Mar 26 23:08:34 2008 */
#line 1 "ext/standard/url_scanner_ex.re"
/*
+----------------------------------------------------------------------+
@ -109,7 +109,10 @@ static inline void append_modified_url(smart_str *url, smart_str *dest, smart_st
q = (p = url->c) + url->len;
scan:
#line 114 "ext/standard/url_scanner_ex.c"
{
YYCTYPE yych;
static const unsigned char yybm[] = {
128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128,
@ -145,42 +148,37 @@ scan:
128, 128, 128, 128, 128, 128, 128, 128,
};
#line 149 "ext/standard/url_scanner_ex.c"
{
YYCTYPE yych;
if(YYLIMIT == YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
if(yybm[0+yych] & 128) {
goto yy8;
}
if(yych <= '9') goto yy6;
if(yych >= ';') goto yy4;
++YYCURSOR;
#line 116 "ext/standard/url_scanner_ex.re"
{ smart_str_append(dest, url); return; }
#line 163 "ext/standard/url_scanner_ex.c"
yy4:
++YYCURSOR;
#line 117 "ext/standard/url_scanner_ex.re"
{ sep = separator; goto scan; }
#line 168 "ext/standard/url_scanner_ex.c"
yy6:
++YYCURSOR;
#line 118 "ext/standard/url_scanner_ex.re"
{ bash = p - 1; goto done; }
#line 173 "ext/standard/url_scanner_ex.c"
yy8:
++YYCURSOR;
if(YYLIMIT == YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
if(yybm[0+yych] & 128) {
goto yy8;
}
#line 119 "ext/standard/url_scanner_ex.re"
{ goto scan; }
#line 183 "ext/standard/url_scanner_ex.c"
if (YYLIMIT <= YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
if (yybm[0+yych] & 128) {
goto yy8;
}
if (yych <= '9') goto yy6;
if (yych >= ';') goto yy4;
++YYCURSOR;
#line 116 "ext/standard/url_scanner_ex.re"
{ smart_str_append(dest, url); return; }
#line 162 "ext/standard/url_scanner_ex.c"
yy4:
++YYCURSOR;
#line 117 "ext/standard/url_scanner_ex.re"
{ sep = separator; goto scan; }
#line 167 "ext/standard/url_scanner_ex.c"
yy6:
++YYCURSOR;
#line 118 "ext/standard/url_scanner_ex.re"
{ bash = p - 1; goto done; }
#line 172 "ext/standard/url_scanner_ex.c"
yy8:
++YYCURSOR;
if (YYLIMIT <= YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
if (yybm[0+yych] & 128) {
goto yy8;
}
#line 119 "ext/standard/url_scanner_ex.re"
{ goto scan; }
#line 182 "ext/standard/url_scanner_ex.c"
}
#line 120 "ext/standard/url_scanner_ex.re"
@ -361,7 +359,10 @@ state_plain_begin:
state_plain:
start = YYCURSOR;
#line 364 "ext/standard/url_scanner_ex.c"
{
YYCTYPE yych;
static const unsigned char yybm[] = {
128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128,
@ -396,37 +397,35 @@ state_plain:
128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128,
};
#line 401 "ext/standard/url_scanner_ex.c"
{
YYCTYPE yych;
if(YYLIMIT == YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
if(yybm[0+yych] & 128) {
goto yy15;
}
++YYCURSOR;
#line 299 "ext/standard/url_scanner_ex.re"
{ passthru(STD_ARGS); STATE = STATE_TAG; goto state_tag; }
#line 412 "ext/standard/url_scanner_ex.c"
yy15:
++YYCURSOR;
if(YYLIMIT == YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
if(yybm[0+yych] & 128) {
goto yy15;
}
#line 300 "ext/standard/url_scanner_ex.re"
{ passthru(STD_ARGS); goto state_plain; }
#line 422 "ext/standard/url_scanner_ex.c"
if (YYLIMIT <= YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
if (yybm[0+yych] & 128) {
goto yy15;
}
++YYCURSOR;
#line 299 "ext/standard/url_scanner_ex.re"
{ passthru(STD_ARGS); STATE = STATE_TAG; goto state_tag; }
#line 409 "ext/standard/url_scanner_ex.c"
yy15:
++YYCURSOR;
if (YYLIMIT <= YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
if (yybm[0+yych] & 128) {
goto yy15;
}
#line 300 "ext/standard/url_scanner_ex.re"
{ passthru(STD_ARGS); goto state_plain; }
#line 419 "ext/standard/url_scanner_ex.c"
}
#line 301 "ext/standard/url_scanner_ex.re"
state_tag:
start = YYCURSOR;
#line 427 "ext/standard/url_scanner_ex.c"
{
YYCTYPE yych;
static const unsigned char yybm[] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
@ -461,42 +460,37 @@ state_tag:
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
};
#line 466 "ext/standard/url_scanner_ex.c"
{
YYCTYPE yych;
if((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
yych = *YYCURSOR;
if(yych <= '@') {
if(yych != ':') goto yy22;
} else {
if(yych <= 'Z') goto yy20;
if(yych <= '`') goto yy22;
if(yych >= '{') goto yy22;
}
if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
yych = *YYCURSOR;
if (yych <= '@') {
if (yych != ':') goto yy22;
} else {
if (yych <= 'Z') goto yy20;
if (yych <= '`') goto yy22;
if (yych >= '{') goto yy22;
}
yy20:
++YYCURSOR;
yych = *YYCURSOR;
goto yy25;
++YYCURSOR;
yych = *YYCURSOR;
goto yy25;
yy21:
#line 306 "ext/standard/url_scanner_ex.re"
{ handle_tag(STD_ARGS); /* Sets STATE */; passthru(STD_ARGS); if (STATE == STATE_PLAIN) goto state_plain; else goto state_next_arg; }
#line 485 "ext/standard/url_scanner_ex.c"
{ handle_tag(STD_ARGS); /* Sets STATE */; passthru(STD_ARGS); if (STATE == STATE_PLAIN) goto state_plain; else goto state_next_arg; }
#line 480 "ext/standard/url_scanner_ex.c"
yy22:
++YYCURSOR;
++YYCURSOR;
#line 307 "ext/standard/url_scanner_ex.re"
{ passthru(STD_ARGS); goto state_plain_begin; }
#line 490 "ext/standard/url_scanner_ex.c"
{ passthru(STD_ARGS); goto state_plain_begin; }
#line 485 "ext/standard/url_scanner_ex.c"
yy24:
++YYCURSOR;
if(YYLIMIT == YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
++YYCURSOR;
if (YYLIMIT <= YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
yy25:
if(yybm[0+yych] & 128) {
goto yy24;
}
goto yy21;
if (yybm[0+yych] & 128) {
goto yy24;
}
goto yy21;
}
#line 308 "ext/standard/url_scanner_ex.re"
@ -506,7 +500,10 @@ state_next_arg_begin:
state_next_arg:
start = YYCURSOR;
#line 505 "ext/standard/url_scanner_ex.c"
{
YYCTYPE yych;
static const unsigned char yybm[] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 128, 128, 128, 0, 128, 0, 0,
@ -541,71 +538,69 @@ state_next_arg:
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
};
#line 546 "ext/standard/url_scanner_ex.c"
{
YYCTYPE yych;
if((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
yych = *YYCURSOR;
if(yych <= ' ') {
if(yych <= 0x0C) {
if(yych <= 0x08) goto yy34;
if(yych <= 0x0B) goto yy30;
goto yy34;
} else {
if(yych <= 0x0D) goto yy30;
if(yych <= 0x1F) goto yy34;
goto yy30;
}
if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
yych = *YYCURSOR;
if (yych <= ' ') {
if (yych <= '\f') {
if (yych <= 0x08) goto yy34;
if (yych <= '\v') goto yy30;
goto yy34;
} else {
if(yych <= '@') {
if(yych != '>') goto yy34;
} else {
if(yych <= 'Z') goto yy32;
if(yych <= '`') goto yy34;
if(yych <= 'z') goto yy32;
goto yy34;
}
if (yych <= '\r') goto yy30;
if (yych <= 0x1F) goto yy34;
goto yy30;
}
++YYCURSOR;
} else {
if (yych <= '@') {
if (yych != '>') goto yy34;
} else {
if (yych <= 'Z') goto yy32;
if (yych <= '`') goto yy34;
if (yych <= 'z') goto yy32;
goto yy34;
}
}
++YYCURSOR;
#line 316 "ext/standard/url_scanner_ex.re"
{ passthru(STD_ARGS); handle_form(STD_ARGS); goto state_plain_begin; }
#line 574 "ext/standard/url_scanner_ex.c"
{ passthru(STD_ARGS); handle_form(STD_ARGS); goto state_plain_begin; }
#line 567 "ext/standard/url_scanner_ex.c"
yy30:
++YYCURSOR;
yych = *YYCURSOR;
goto yy37;
++YYCURSOR;
yych = *YYCURSOR;
goto yy37;
yy31:
#line 317 "ext/standard/url_scanner_ex.re"
{ passthru(STD_ARGS); goto state_next_arg; }
#line 582 "ext/standard/url_scanner_ex.c"
{ passthru(STD_ARGS); goto state_next_arg; }
#line 575 "ext/standard/url_scanner_ex.c"
yy32:
++YYCURSOR;
++YYCURSOR;
#line 318 "ext/standard/url_scanner_ex.re"
{ --YYCURSOR; STATE = STATE_ARG; goto state_arg; }
#line 587 "ext/standard/url_scanner_ex.c"
{ --YYCURSOR; STATE = STATE_ARG; goto state_arg; }
#line 580 "ext/standard/url_scanner_ex.c"
yy34:
++YYCURSOR;
++YYCURSOR;
#line 319 "ext/standard/url_scanner_ex.re"
{ passthru(STD_ARGS); goto state_plain_begin; }
#line 592 "ext/standard/url_scanner_ex.c"
{ passthru(STD_ARGS); goto state_plain_begin; }
#line 585 "ext/standard/url_scanner_ex.c"
yy36:
++YYCURSOR;
if(YYLIMIT == YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
++YYCURSOR;
if (YYLIMIT <= YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
yy37:
if(yybm[0+yych] & 128) {
goto yy36;
}
goto yy31;
if (yybm[0+yych] & 128) {
goto yy36;
}
goto yy31;
}
#line 320 "ext/standard/url_scanner_ex.re"
state_arg:
start = YYCURSOR;
#line 602 "ext/standard/url_scanner_ex.c"
{
YYCTYPE yych;
static const unsigned char yybm[] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
@ -640,46 +635,44 @@ state_arg:
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
};
#line 645 "ext/standard/url_scanner_ex.c"
{
YYCTYPE yych;
if((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
yych = *YYCURSOR;
if(yych <= '@') goto yy42;
if(yych <= 'Z') goto yy40;
if(yych <= '`') goto yy42;
if(yych >= '{') goto yy42;
if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
yych = *YYCURSOR;
if (yych <= '@') goto yy42;
if (yych <= 'Z') goto yy40;
if (yych <= '`') goto yy42;
if (yych >= '{') goto yy42;
yy40:
++YYCURSOR;
yych = *YYCURSOR;
goto yy45;
++YYCURSOR;
yych = *YYCURSOR;
goto yy45;
yy41:
#line 325 "ext/standard/url_scanner_ex.re"
{ passthru(STD_ARGS); handle_arg(STD_ARGS); STATE = STATE_BEFORE_VAL; goto state_before_val; }
#line 661 "ext/standard/url_scanner_ex.c"
{ passthru(STD_ARGS); handle_arg(STD_ARGS); STATE = STATE_BEFORE_VAL; goto state_before_val; }
#line 652 "ext/standard/url_scanner_ex.c"
yy42:
++YYCURSOR;
++YYCURSOR;
#line 326 "ext/standard/url_scanner_ex.re"
{ passthru(STD_ARGS); STATE = STATE_NEXT_ARG; goto state_next_arg; }
#line 666 "ext/standard/url_scanner_ex.c"
{ passthru(STD_ARGS); STATE = STATE_NEXT_ARG; goto state_next_arg; }
#line 657 "ext/standard/url_scanner_ex.c"
yy44:
++YYCURSOR;
if(YYLIMIT == YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
++YYCURSOR;
if (YYLIMIT <= YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
yy45:
if(yybm[0+yych] & 128) {
goto yy44;
}
goto yy41;
if (yybm[0+yych] & 128) {
goto yy44;
}
goto yy41;
}
#line 327 "ext/standard/url_scanner_ex.re"
state_before_val:
start = YYCURSOR;
#line 674 "ext/standard/url_scanner_ex.c"
{
YYCTYPE yych;
static const unsigned char yybm[] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
@ -714,52 +707,47 @@ state_before_val:
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
};
#line 719 "ext/standard/url_scanner_ex.c"
{
YYCTYPE yych;
if((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
yych = *YYCURSOR;
if(yych == ' ') goto yy48;
if(yych == '=') goto yy50;
goto yy52;
if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
yych = *YYCURSOR;
if (yych == ' ') goto yy48;
if (yych == '=') goto yy50;
goto yy52;
yy48:
yych = *(YYMARKER = ++YYCURSOR);
if(yych == ' ') goto yy55;
if(yych == '=') goto yy53;
yych = *(YYMARKER = ++YYCURSOR);
if (yych == ' ') goto yy55;
if (yych == '=') goto yy53;
yy49:
#line 333 "ext/standard/url_scanner_ex.re"
{ --YYCURSOR; goto state_next_arg_begin; }
#line 734 "ext/standard/url_scanner_ex.c"
{ --YYCURSOR; goto state_next_arg_begin; }
#line 723 "ext/standard/url_scanner_ex.c"
yy50:
++YYCURSOR;
yych = *YYCURSOR;
goto yy54;
++YYCURSOR;
yych = *YYCURSOR;
goto yy54;
yy51:
#line 332 "ext/standard/url_scanner_ex.re"
{ passthru(STD_ARGS); STATE = STATE_VAL; goto state_val; }
#line 742 "ext/standard/url_scanner_ex.c"
{ passthru(STD_ARGS); STATE = STATE_VAL; goto state_val; }
#line 731 "ext/standard/url_scanner_ex.c"
yy52:
yych = *++YYCURSOR;
goto yy49;
yych = *++YYCURSOR;
goto yy49;
yy53:
++YYCURSOR;
if(YYLIMIT == YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
++YYCURSOR;
if (YYLIMIT <= YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
yy54:
if(yybm[0+yych] & 128) {
goto yy53;
}
goto yy51;
yy55:
++YYCURSOR;
if(YYLIMIT == YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
if(yych == ' ') goto yy55;
if(yych == '=') goto yy53;
YYCURSOR = YYMARKER;
goto yy49;
if (yybm[0+yych] & 128) {
goto yy53;
}
goto yy51;
yy55:
++YYCURSOR;
if (YYLIMIT <= YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
if (yych == ' ') goto yy55;
if (yych == '=') goto yy53;
YYCURSOR = YYMARKER;
goto yy49;
}
#line 334 "ext/standard/url_scanner_ex.re"
@ -767,7 +755,10 @@ yy55:
state_val:
start = YYCURSOR;
#line 760 "ext/standard/url_scanner_ex.c"
{
YYCTYPE yych;
static const unsigned char yybm[] = {
248, 248, 248, 248, 248, 248, 248, 248,
248, 160, 160, 248, 248, 160, 248, 248,
@ -802,119 +793,114 @@ state_val:
248, 248, 248, 248, 248, 248, 248, 248,
248, 248, 248, 248, 248, 248, 248, 248,
};
#line 807 "ext/standard/url_scanner_ex.c"
{
YYCTYPE yych;
if((YYLIMIT - YYCURSOR) < 3) YYFILL(3);
yych = *YYCURSOR;
if(yych <= ' ') {
if(yych <= 0x0C) {
if(yych <= 0x08) goto yy63;
if(yych <= 0x0A) goto yy64;
goto yy63;
} else {
if(yych <= 0x0D) goto yy64;
if(yych <= 0x1F) goto yy63;
goto yy64;
}
if ((YYLIMIT - YYCURSOR) < 3) YYFILL(3);
yych = *YYCURSOR;
if (yych <= ' ') {
if (yych <= '\f') {
if (yych <= 0x08) goto yy63;
if (yych <= '\n') goto yy64;
goto yy63;
} else {
if(yych <= '&') {
if(yych != '"') goto yy63;
} else {
if(yych <= '\'') goto yy62;
if(yych == '>') goto yy64;
goto yy63;
}
if (yych <= '\r') goto yy64;
if (yych <= 0x1F) goto yy63;
goto yy64;
}
yych = *(YYMARKER = ++YYCURSOR);
goto yy77;
} else {
if (yych <= '&') {
if (yych != '"') goto yy63;
} else {
if (yych <= '\'') goto yy62;
if (yych == '>') goto yy64;
goto yy63;
}
}
yych = *(YYMARKER = ++YYCURSOR);
goto yy77;
yy61:
#line 342 "ext/standard/url_scanner_ex.re"
{ handle_val(STD_ARGS, 0, ' '); goto state_next_arg_begin; }
#line 836 "ext/standard/url_scanner_ex.c"
{ handle_val(STD_ARGS, 0, ' '); goto state_next_arg_begin; }
#line 823 "ext/standard/url_scanner_ex.c"
yy62:
yych = *(YYMARKER = ++YYCURSOR);
goto yy69;
yych = *(YYMARKER = ++YYCURSOR);
goto yy69;
yy63:
yych = *++YYCURSOR;
goto yy67;
yych = *++YYCURSOR;
goto yy67;
yy64:
++YYCURSOR;
++YYCURSOR;
#line 343 "ext/standard/url_scanner_ex.re"
{ passthru(STD_ARGS); goto state_next_arg_begin; }
#line 847 "ext/standard/url_scanner_ex.c"
{ passthru(STD_ARGS); goto state_next_arg_begin; }
#line 834 "ext/standard/url_scanner_ex.c"
yy66:
++YYCURSOR;
if(YYLIMIT == YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
++YYCURSOR;
if (YYLIMIT <= YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
yy67:
if(yybm[0+yych] & 8) {
goto yy66;
}
goto yy61;
if (yybm[0+yych] & 8) {
goto yy66;
}
goto yy61;
yy68:
YYMARKER = ++YYCURSOR;
if((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
yych = *YYCURSOR;
YYMARKER = ++YYCURSOR;
if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
yych = *YYCURSOR;
yy69:
if(yybm[0+yych] & 16) {
goto yy68;
}
if(yych <= '&') goto yy72;
if(yych >= '(') goto yy61;
++YYCURSOR;
if(yybm[0+(yych = *YYCURSOR)] & 8) {
goto yy66;
}
if (yybm[0+yych] & 16) {
goto yy68;
}
if (yych <= '&') goto yy72;
if (yych >= '(') goto yy61;
++YYCURSOR;
if (yybm[0+(yych = *YYCURSOR)] & 8) {
goto yy66;
}
yy71:
#line 341 "ext/standard/url_scanner_ex.re"
{ handle_val(STD_ARGS, 1, '\''); goto state_next_arg_begin; }
#line 874 "ext/standard/url_scanner_ex.c"
{ handle_val(STD_ARGS, 1, '\''); goto state_next_arg_begin; }
#line 861 "ext/standard/url_scanner_ex.c"
yy72:
++YYCURSOR;
if(YYLIMIT == YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
if(yybm[0+yych] & 32) {
goto yy72;
}
if(yych <= '=') goto yy75;
++YYCURSOR;
if (YYLIMIT <= YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
if (yybm[0+yych] & 32) {
goto yy72;
}
if (yych <= '=') goto yy75;
yy74:
YYCURSOR = YYMARKER;
goto yy61;
YYCURSOR = YYMARKER;
goto yy61;
yy75:
yych = *++YYCURSOR;
goto yy71;
yych = *++YYCURSOR;
goto yy71;
yy76:
YYMARKER = ++YYCURSOR;
if((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
yych = *YYCURSOR;
YYMARKER = ++YYCURSOR;
if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
yych = *YYCURSOR;
yy77:
if(yybm[0+yych] & 64) {
goto yy76;
}
if(yych <= '!') goto yy80;
if(yych >= '#') goto yy61;
++YYCURSOR;
if(yybm[0+(yych = *YYCURSOR)] & 8) {
goto yy66;
}
if (yybm[0+yych] & 64) {
goto yy76;
}
if (yych <= '!') goto yy80;
if (yych >= '#') goto yy61;
++YYCURSOR;
if (yybm[0+(yych = *YYCURSOR)] & 8) {
goto yy66;
}
yy79:
#line 340 "ext/standard/url_scanner_ex.re"
{ handle_val(STD_ARGS, 1, '"'); goto state_next_arg_begin; }
#line 906 "ext/standard/url_scanner_ex.c"
{ handle_val(STD_ARGS, 1, '"'); goto state_next_arg_begin; }
#line 893 "ext/standard/url_scanner_ex.c"
yy80:
++YYCURSOR;
if(YYLIMIT == YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
if(yybm[0+yych] & 128) {
goto yy80;
}
if(yych >= '>') goto yy74;
++YYCURSOR;
yych = *YYCURSOR;
goto yy79;
++YYCURSOR;
if (YYLIMIT <= YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
if (yybm[0+yych] & 128) {
goto yy80;
}
if (yych >= '>') goto yy74;
++YYCURSOR;
yych = *YYCURSOR;
goto yy79;
}
#line 344 "ext/standard/url_scanner_ex.re"