pike.git/
src/
opcodes.c
Branch:
Tag:
Non-build tags
All tags
No tags
1999-11-04
1999-11-04 20:04:07 by Fredrik Hübinette (Hubbe) <hubbe@hubbe.net>
e7a172fb9b0617aebf774e2f4761cf91515205a7 (
1230
lines) (+
677
/-
553
)
[
Show
|
Annotate
]
Branch:
7.9
fixed sscanf sets for wide strings
Rev: src/opcodes.c:1.64
Rev: src/testsuite.in:1.222
25:
#include "security.h" #include "bignum.h"
-
RCSID("$Id: opcodes.c,v 1.
63
1999/
10
/
31
22
:
53
:
38
grubba
Exp $");
+
RCSID("$Id: opcodes.c,v 1.
64
1999/
11
/
04
20
:
04
:
05
hubbe
Exp $");
void index_no_free(struct svalue *to,struct svalue *what,struct svalue *ind) {
623:
%% */
-
static
int read
_set
(unsigned char *match,int cnt,char *set,int match_len)
+
+
struct
sscanf
_set
{
-
int
init
;
-
int
last=0
;
-
int
e
;
+
int
neg
;
+
char
c[256]
;
+
struct
array *a
;
+
};
-
if(cnt>=match_len)
-
error
(
"Error
in
sscanf
format
string.\n");
+
/*
FIXME:
+
* This implementation will break in certain cases, especially cases
+
*
like
this
[\1000-\1002\1001]
(
ie,
there
is
a
single character which
+
* is also a part of a range
+
* /Hubbe
+
*/
-
if(match[cnt]=='^')
-
{
-
for(e=0;e<256;e++) set[e]=1;
-
init=0;
-
cnt++;
-
if(cnt>=match_len)
-
error("Error in sscanf format string.\n");
-
}else{
-
for(e=0;e<256;e++) set[e]=0;
-
init=1;
-
}
-
if(match[cnt]==']' || match[cnt]=='-')
-
{
-
set[last=match[cnt]]=init;
-
cnt++;
-
if(cnt>=match_len)
-
error("Error in sscanf format string.\n");
-
}
+
-
for(;match[cnt]!=']';cnt++)
-
{
-
if(match[cnt]=='-')
-
{
-
cnt++;
-
if(cnt>=match_len)
-
error("Error in sscanf format string.\n");
-
if(match[cnt]==']')
-
{
-
set['-']=
init
;
-
break;
+
#define
MKREADSET(SIZE)
\
+
static int PIKE_CONCAT(read_set,SIZE) ( \
+
PIKE_CONCAT(p_wchar,SIZE) *match, \
+
int cnt, \
+
struct sscanf_set *set, \
+
int match_len) \
+
{ \
+
unsigned long e,last=0; \
+
CHAROPT( int set_size=0; ) \
+
\
+
if(cnt>=match_len) \
+
error("Error in sscanf format string.\n"); \
+
\
+
MEMSET(set->c, 0, sizeof(set->c)); \
+
set->a=0; \
+
\
+
if(match[cnt]=='^') \
+
{ \
+
set->neg=1; \
+
cnt++; \
+
if(cnt>=match_len) \
+
error("Error in sscanf format string.\n"); \
+
}else{ \
+
set->neg=0; \
+
} \
+
\
+
if(match[cnt]==']' || match[cnt]=='-') \
+
{ \
+
set->c[last=match[cnt]]=1; \
+
cnt++; \
+
if(cnt>=match_len) \
+
error("Error in sscanf format string.\n"); \
+
} \
+
\
+
for(;match[cnt]!=']';cnt++)
\
+
{
\
+
if(match[cnt]=='-')
\
+
{
\
+
cnt++;
\
+
if(cnt>=match_len)
\
+
error("Error in sscanf format string.\n");
\
+
\
+
if(match[cnt]==']')
\
+
{
\
+
set
->c
['-']=
1
;
\
+
break;
\
+
} \
+
\
+
if(last >= match[cnt]) \
+
error("Error in sscanf format string.\n"); \
+
\
+
CHAROPT( \
+
if(last < sizeof(set->c)) \
+
{ \
+
if(match[cnt] < sizeof(set->c)) \
+
{ \
+
) \
+
for(e=last;e<match[cnt];e++) set->c[e]=1; \
+
CHAROPT( \
+
}else{ \
+
for(e=last;e<sizeof(set->c);e++) set->c[e]=1; \
+
\
+
check_stack(2); \
+
push_int(256); \
+
push_int(match[cnt]); \
+
set_size++; \
+
} \
+
} \
+
else \
+
{ \
+
sp[-1].u.integer=match[cnt]; \
+
} \
+
) \
+
continue; \
+
} \
+
last=match[cnt]; \
+
if(last < sizeof(set->c)) \
+
set->c[last]=1; \
+
CHAROPT( \
+
else{ \
+
if(set_size && sp[-1].u.integer == last-1) \
+
{ \
+
sp[-1].u.integer++; \
+
}else{ \
+
check_stack(2); \
+
push_int(last); \
+
push_int(last); \
+
set_size++; \
+
} \
+
} \
+
) \
+
} \
+
\
+
CHAROPT( \
+
if(set_size) \
+
{ \
+
INT32 *order; \
+
set->a=aggregate_array(set_size*2); \
+
order=get_switch_order(set->a); \
+
for(e=0;e<set->a->size;e+=2) \
+
{ \
+
if(order[e]+1 != order[e+1]) \
+
{ \
+
free_array(set->a); \
+
set->a=0; \
+
free((char *)order); \
+
error("Overlapping ranges in sscanf not supported.\n"); \
+
} \
+
} \
+
\
+
order_array(set->a,order); \
+
free((char *)order); \
+
} \
+
) \
+
return cnt; \
}
-
for(e=last;e<(int) EXTRACT_UCHAR(match+cnt);e++) set[e]=init;
-
}
-
set[last=EXTRACT_UCHAR(match+cnt)]=init;
-
}
-
return cnt;
-
}
+
860:
#endif #endif
-
#define MK_VERY_LOW_SSCANF(INPUT_SHIFT, MATCH_SHIFT) \
-
static INT32 PIKE_CONCAT4(very_low_sscanf_,INPUT_SHIFT,_,MATCH_SHIFT)( \
-
PIKE_CONCAT(p_wchar, INPUT_SHIFT) *input, \
-
long input_len, \
-
PIKE_CONCAT(p_wchar, MATCH_SHIFT) *match, \
-
long match_len, \
-
long *chars_matched, \
-
int *success) \
-
{ \
-
struct svalue sval; \
-
int e,cnt,matches,eye,arg; \
-
int no_assign = 0, field_length = 0, minus_flag = 0; \
-
char
set
[256]
;
\
-
struct svalue *argp; \
+
#define MK_VERY_LOW_SSCANF(INPUT_SHIFT, MATCH_SHIFT)
\
+
static INT32 PIKE_CONCAT4(very_low_sscanf_,INPUT_SHIFT,_,MATCH_SHIFT)(
\
+
PIKE_CONCAT(p_wchar, INPUT_SHIFT) *input,
\
+
long input_len,
\
+
PIKE_CONCAT(p_wchar, MATCH_SHIFT) *match,
\
+
long match_len,
\
+
long *chars_matched,
\
+
int *success)
\
+
{
\
+
struct svalue sval;
\
+
int e,cnt,matches,eye,arg;
\
+
int no_assign = 0, field_length = 0, minus_flag = 0;
\
+
struct
sscanf_
set
set
; \
+
struct svalue *argp;
\
\
-
success[0]=0; \
+
\
-
arg
=
eye
=
matches=
0; \
+
set.a
=
0; \
+
success[0]
=0;
\
\
-
for(cnt
=
0; cnt < match_len; cnt++) \
-
{ \
-
for(;cnt<match_len;cnt++) \
-
{ \
-
if(match[cnt]=='%') \
-
{ \
-
if(match[cnt+1]=='%') \
-
{ \
-
cnt++; \
-
}else{ \
-
break; \
-
} \
-
} \
-
if(
eye
>
=
input_len || input[eye]!=match[cnt]) \
-
{ \
-
chars_matched[0]=eye; \
-
return
matches
; \
-
} \
-
eye++; \
-
} \
-
if(cnt>
=
match_len) \
-
{ \
-
chars_matched[
0
]=eye
;
\
-
return
matches;
\
-
} \
+
arg
=eye=matches=0; \
\
-
DO
_
IF_DEBUG
( \
-
if(match[cnt]
!
='%'
||
match[cnt+1]=='%') \
-
{ \
-
fatal
(
"Error
in
sscanf.\n"
); \
-
} \
-
); \
+
for(cnt
=
0; cnt < match
_
len; cnt++) \
+
{ \
+
for(;cnt<match
_
len;cnt++)
\
+
{
\
+
if(match[cnt]=
=
'%'
)
\
+
{ \
+
if(
match[cnt+1]=='%')
\
+
{
\
+
cnt++;
\
+
}else{ \
+
break; \
+
} \
+
} \
+
if
(
eye>=input_len
||
input[eye]!=match[cnt]
)
\
+
{ \
+
chars_matched[0]=eye
;
\
+
return matches; \
+
}
\
+
eye++;
\
+
} \
+
if(cnt>=match_len
)
\
+
{ \
+
chars_matched[0]=eye
;
\
+
return
matches;
\
+
} \
\
-
no
_
assign=0;
\
-
field_length
=
-1
; \
-
minus_flag=0
; \
+
DO
_
IF_DEBUG( \
+
if(match[cnt]!
=
'%'
||
match[cnt+1]=='%')
\
+
{
\
+
fatal("Error in sscanf.\n")
;
\
+
}
\
+
)
;
\
\
-
cnt++
;
\
-
if(cnt>=match
_
len)
\
-
error("Error
in
sscanf
format
string.\n");
\
+
no_assign=0
;
\
+
field_length=-1;
\
+
minus_flag=0;
\
\
-
while(1) \
-
{ \
-
switch(match[cnt]) \
-
{ \
-
case '*': \
-
no_assign=1
;
\
-
cnt++;
\
-
if(cnt>=match_len)
\
-
error("Error in sscanf format string.\n");
\
-
continue;
\
+
cnt++
; \
+
if(cnt>=match_len)
\
+
error("Error in sscanf format string.\n"); \
\
-
case
'0':
case
'1':
case
'2':
case
'3':
case
'4':
\
-
case
'5':
case
'6':
case
'7':
case
'8':
case
'9':
\
-
{ \
-
PCHARP
t;
\
-
field
_
length
=
STRTOL_PCHARP(MKPCHARP(match+cnt,
MATCH_SHIFT),
\
-
&t,10);
\
-
cnt
=
SUBTRACT_PCHARP(t, MKPCHARP(
match
, MATCH
_
SHIFT
)
);
\
-
continue;
\
-
}
\
+
while(1)
\
+
{
\
+
switch(match[cnt])
\
+
{
\
+
case
'*':
\
+
no
_
assign
=
1;
\
+
cnt++;
\
+
if(
cnt
>
=match_
len
)
\
+
error("Error
in
sscanf
format
string.\n");
\
+
continue;
\
\
-
case '
-
': \
-
minus_flag=1;
\
-
cnt++
; \
-
continue; \
+
case '
0
':
case
'1':
case
'2':
case
'3':
case
'4':
\
+
case
'5':
case
'6':
case
'7':
case
'8':
case
'9':
\
+
{
\
+
PCHARP t
;
\
+
field_length = STRTOL_PCHARP(MKPCHARP(match+cnt, MATCH_SHIFT),
\
+
&t,10); \
+
cnt = SUBTRACT_PCHARP(t, MKPCHARP(match, MATCH_SHIFT)); \
+
continue;
\
+
} \
\
-
case '
{
':
\
-
{
\
-
ONERROR err; \
-
long tmp; \
-
for(e
=
cnt+1,tmp=
1;
tmp;e++)
\
-
{
\
-
if(!match[e]) \
-
{ \
-
error("Missing %%} in format string.\n")
;
\
-
break;
/*
UNREACHED
*/
\
-
} \
-
if(match[e]=='%') \
-
{ \
-
switch(match[e+1]) \
-
{ \
-
case '%': e++
;
break;
\
-
case
'}':
tmp--; break;
\
-
case '{': tmp++; break; \
-
} \
-
} \
-
} \
-
sval.type=T_ARRAY; \
-
sval.u.array=allocate_array(0); \
-
SET_ONERROR(err, do_free_array, sval.u.array); \
+
case '
-
': \
+
minus_flag
=1; \
+
cnt++
; \
+
continue
; \
\
-
while(input_len-eye)
\
-
{
\
-
int
yes;
\
-
struct
svalue
*save_sp=sp;
\
-
PIKE_CONCAT4(very_low_sscanf_,
INPUT_SHIFT,
_,
MATCH_SHIFT)(\
-
input+eye
, \
-
input_len-eye,
\
-
match+cnt+1,
\
-
e-cnt-2,
\
-
&tmp,
\
-
&yes)
;
\
-
if(yes
&&
tmp)
\
-
{
\
-
f_aggregate(sp-save_sp);
\
-
sval.u.array=append_array(sval.u.array,sp-1);
\
-
pop_stack
()
;
\
-
eye+=tmp;
\
-
}else{
\
-
pop_n_elems(sp-save_sp);
\
-
break;
\
-
}
\
-
}
\
-
cnt=e;
\
-
UNSET_ONERROR(err);
\
-
break
;
\
-
}
\
+
case
'{':
\
+
{
\
+
ONERROR
err;
\
+
long
tmp;
\
+
for(e=cnt+1
,
tmp=1;tmp;e++)
\
+
{
\
+
if(!match[e])
\
+
{
\
+
error("Missing
%%}
in
format
string.\n");
\
+
break
;
/*
UNREACHED
*/
\
+
}
\
+
if(match[e]=='%')
\
+
{
\
+
switch
(
match[e+1]
) \
+
{
\
+
case
'%':
e++;
break;
\
+
case
'}':
tmp--;
break;
\
+
case
'{':
tmp++;
break;
\
+
} \
+
} \
+
}
\
+
sval.type=T_ARRAY
; \
+
sval.u.array=allocate_array(0);
\
+
SET_ONERROR(err,
do_free_array,
sval.u.array);
\
\
-
case
'c':
\
-
if(field_length
==
-1)
field_length
=
1
; \
-
if
(
eye+field
_
length
>
input_len
)
\
-
{
\
-
chars_matched[0]=eye;
\
-
return
matches
; \
-
}
\
-
sval.
type
=
T
_
INT
; \
-
sval.subtype
=
NUMBER_NUMBER
; \
-
sval.u.integer=0;
\
-
if
(
minus
_
flag
) \
-
{
\
-
int
x,
pos
=
0
; \
+
while(input_len-eye)
\
+
{
\
+
int
yes; \
+
struct svalue *save
_
sp
=
sp
;
\
+
PIKE_CONCAT4
(
very
_
low_sscanf_,
INPUT_SHIFT,
_, MATCH_SHIFT)( \
+
input+eye, \
+
input_len
-eye,
\
+
match+cnt+1,
\
+
e-cnt-2,
\
+
&tmp,
\
+
&yes)
;
\
+
if(yes && tmp)
\
+
{
\
+
f_aggregate(sp-save_sp); \
+
sval.
u.array
=
append
_
array(sval.u.array,sp-1)
;
\
+
pop_stack();
\
+
eye+
=
tmp
;
\
+
}else{
\
+
pop_n_elems
(
sp-save
_
sp
)
;
\
+
break;
\
+
}
\
+
}
\
+
cnt
=
e
;
\
+
UNSET_ONERROR(err); \
+
break; \
+
} \
\
-
while
(-
-
field_length
>
=
0
) \
-
{
\
-
int
lshfun,
orfun
; \
-
x
=
input[eye]
; \
+
case
'c':
\
+
if
(
field_length ==
-
1)
field_length =
1; \
+
if(eye+field_length > input_len
)
\
+
{
\
+
chars_matched[0]=eye;
\
+
return
matches;
\
+
}
\
+
sval.type=T_INT
;
\
+
sval.subtype=NUMBER_NUMBER;
\
+
sval.u.integer=0; \
+
if (minus_flag) \
+
{ \
+
int
x
,
pos
=
0
;
\
\
-
DO_IF_BIGNUM
(
\
-
if(INT_TYPE_LSH_OVERFLOW(x,
pos))
\
-
{
\
-
push_int(sval.u.integer);
\
-
convert_stack_top_to_bignum()
;
\
-
lshfun=FIND_LFUN(sp[-1].u.object->prog,
LFUN_LSH);
\
-
orfun=FIND_LFUN(sp[-1].u.object->prog, LFUN_OR); \
+
while(--field
_
length
>=
0)
\
+
{
\
+
int
lshfun,
orfun;
\
+
x
=
input[eye]
; \
\
-
while(field
_
length--
>=
0)
\
-
{
\
-
push
_
int
(
input[eye]
)
;
\
-
convert_stack_top_to_bignum();
\
-
push_int(pos);
\
-
apply
_
low
(
sp[-2]
.u.
object, lshfun, 1
);
\
-
stack_swap();
\
-
pop
_stack();
\
-
apply
_
low
(sp[-
2
].u.object,
orfun, 1); \
-
stack
_
swap(
);
\
-
pop
_
stack
(
); \
-
pos+=8; \
-
eye++; \
-
} \
-
sval=*
--
sp;
\
-
break; \
-
} \
-
);
\
-
sval.u.integer|=x<<pos; \
+
DO_IF_BIGNUM
( \
+
if(INT
_
TYPE_LSH_OVERFLOW
(
x, pos
)
)
\
+
{
\
+
push
_
int
(
sval
.u.
integer
); \
+
convert
_stack
_top_to_bignum
(); \
+
lshfun=FIND
_
LFUN
(sp[-
1
].u.object
->prog
,
LFUN
_
LSH
); \
+
orfun=FIND
_
LFUN
(
sp[
-
1].u.object
-
>prog,
LFUN_OR
); \
\
-
pos+
=
8;
\
-
eye++;
\
-
}
\
-
}
\
-
else
\
-
while(--field_length
>=
0
) \
-
{
\
-
int
lshfun,
orfun
; \
-
DO_IF_BIGNUM(
\
-
if(INT_TYPE_LSH_OVERFLOW(sval.u.integer,
8))
\
-
{
\
-
push_int(
sval
.u.integer)
; \
-
convert_stack_top_to_bignum()
; \
-
lshfun=FIND_LFUN(sp[-1].u.object->prog,
LFUN_LSH);
\
-
orfun=FIND_LFUN(sp[-1]
.u.
object->prog, LFUN_OR)
; \
+
while(field_length-- >
=
0)
\
+
{
\
+
push_int(input[eye]);
\
+
convert_stack_top_to_bignum();
\
+
push_int(pos);
\
+
apply_low(sp[-2].u.object,
lshfun,
1);
\
+
stack_swap();
\
+
pop_stack(
)
;
\
+
apply_low(sp[-2].u.object,
orfun,
1);
\
+
stack_swap();
\
+
pop_stack()
;
\
+
pos+=8;
\
+
eye++;
\
+
}
\
+
sval
=*--sp
;
\
+
break
;
\
+
}
\
+
);
\
+
sval
.u.
integer|=x<<pos
;
\
\
-
while(field_length-- >
=
0)
\
-
{
\
-
push_int(8)
;
\
-
apply_low(sp[-2].u.object, lshfun, 1);
\
-
stack_swap();
\
-
pop_stack();
\
-
push_int(input[eye]);
\
-
apply_low(sp[-2].u.object,
orfun,
1);
\
-
stack_swap();
\
-
pop_stack();
\
-
eye++;
\
-
}
\
-
sval=*--sp
;
\
-
break;
\
-
}
\
-
);
\
-
sval.u.integer
<<=8
;
\
-
sval.u.integer
|=
input[eye]
;
\
-
eye++;
\
-
}
\
-
break
;
\
+
pos+
=
8;
\
+
eye++;
\
+
}
\
+
}
\
+
else
\
+
while
(-
-field_length
>=
0
)
\
+
{
\
+
int
lshfun,
orfun
; \
+
DO_IF_BIGNUM(
\
+
if(INT_TYPE_LSH_OVERFLOW(
sval
.u.integer,
8))
\
+
{
\
+
push_int(
sval.u.integer
)
; \
+
convert_stack_top_to_bignum()
; \
+
lshfun=FIND_LFUN(sp[-1].u.object->prog,
LFUN_LSH);
\
+
orfun=FIND_LFUN(sp[-1].u.object->prog,
LFUN_OR)
; \
\
-
case
'b':
\
-
case
'o':
\
-
case
'd':
\
-
case
'x':
\
-
case
'D':
\
-
case
'i':
\
-
{
\
-
int
base
=
0
; \
-
PIKE_CONCAT(p_wchar,
INPUT_SHIFT
)
*t
; \
+
while(field_length--
>=
0)
\
+
{
\
+
push_int(8);
\
+
apply_low(sp[-2].u.object, lshfun, 1);
\
+
stack_swap();
\
+
pop_stack();
\
+
push_int(input[eye]);
\
+
apply_low(sp[-2].u.object, orfun, 1);
\
+
stack_swap();
\
+
pop_stack();
\
+
eye++;
\
+
}
\
+
sval
=
*--sp;
\
+
break
;
\
+
} \
+
)
;
\
+
sval.u.integer<<=8
;
\
+
sval.u.integer |= input[eye]; \
+
eye++; \
+
} \
+
break; \
\
-
if(eye>=input_len)
\
-
{
\
-
chars_matched[0]=eye;
\
-
return
matches;
\
-
}
\
+
case
'b':
\
+
case
'o':
\
+
case 'd':
\
+
case
'x':
\
+
case
'D':
\
+
case
'i':
\
+
{
\
+
int base = 0; \
+
PIKE_CONCAT(p_wchar, INPUT_SHIFT) *t; \
\
-
switch
(
match[cnt]
) \
-
{ \
-
case
'b':
base
=
2
;
break;
\
-
case 'o': base = 8; break;
\
-
case
'd':
base
= 10
;
break;
\
-
case 'x': base = 16; break;
\
-
} \
+
if
(
eye>=input_len
)
\
+
{
\
+
chars_matched[0]
=
eye
; \
+
return
matches
; \
+
}
\
\
-
wide_string_to_svalue_inumber
(
&sval,
input+eye,
(void
**)&t,
\
-
base
,
field_length,
\
-
INPUT_SHIFT)
; \
+
switch
(
match[cnt])
\
+
{
\
+
case 'b':
base
=
2;
break;
\
+
case
'o':
base
=
8;
break;
\
+
case 'd': base = 10
;
break;
\
+
case 'x': base = 16; break; \
+
} \
\
-
if
(
input
+
eye
== t
)
\
-
{
\
-
chars
_
matched[0]=eye;
\
-
return
matches;
\
-
} \
-
eye=t-input
;
\
-
break; \
-
} \
+
wide_string_to_svalue_inumber
(
&sval,
input+eye,
(void
**)&
t
,
\
+
base,
field
_
length,
\
+
INPUT_SHIFT)
; \
\
-
case
'f':
\
-
{
\
-
PIKE_CONCAT(p_wchar,
INPUT_SHIFT)
*
t; \
-
PCHARP t2
; \
+
if(input
+
eye
==
t)
\
+
{
\
+
chars_matched[0]=eye;
\
+
return
matches;
\
+
}
\
+
eye=
t
-input
;
\
+
break
;
\
+
} \
\
-
if(eye>=input_len)
\
-
{
\
-
chars_matched[0]=eye;
\
-
return
matches;
\
-
} \
-
sval.u.float_number=STRTOD_PCHARP(MKPCHARP(input+eye, \
-
INPUT_SHIFT),&t2); \
-
t = (
PIKE_CONCAT(p_wchar, INPUT_SHIFT) *
)(t2.ptr); \
-
if(input + eye ==
t
) \
-
{ \
-
chars_matched[0]=eye
;
\
-
return matches
;
\
-
}
\
-
eye=t-input; \
-
sval.type=T_FLOAT; \
-
DO_IF_CHECKER(sval.subtype=0); \
-
break; \
-
} \
+
case
'f':
\
+
{
\
+
PIKE_CONCAT(p_wchar, INPUT_SHIFT) *t; \
+
PCHARP
t2
; \
\
-
case
'F':
\
-
if(
field_length
=
= -1) field
_
length = 4; \
-
if(field_length != 4 && field_length != 8
)
\
-
error("Invalid
IEEE
width
%d
in
sscanf
format
string.\n",
\
-
field_length);
\
-
if(eye+field_length > input_len) \
-
{ \
-
chars_matched[0]=eye; \
-
return matches; \
-
} \
-
sval.
type
=
T
_
FLOAT;
\
-
DO_IF_CHECKER(sval.subtype=0);
\
-
switch(field_length)
{
\
-
case
4:
\
-
EXTRACT_FLOAT(sval,
input+eye,
INPUT_SHIFT);
\
-
eye +
=
4
;
\
-
break
;
\
-
case
8:
\
-
EXTRACT_DOUBLE(sval,
input+eye,
INPUT_SHIFT);
\
-
eye
+=
8;
\
-
break;
\
-
}
\
-
break;
\
+
if(
eye>
=
input
_
len
) \
+
{
\
+
chars_matched[0]=eye;
\
+
return matches;
\
+
}
\
+
sval.
u.float_number
=
STRTOD
_
PCHARP(MKPCHARP(input+eye,
\
+
INPUT_SHIFT),&t2);
\
+
t
=
(PIKE_CONCAT(p_wchar,
INPUT_SHIFT)
*)(t2.ptr);
\
+
if(input
+
eye
==
t)
\
+
{
\
+
chars_matched[0]=
eye; \
+
return
matches
;
\
+
}
\
+
eye=t-input;
\
+
sval.type=T_FLOAT;
\
+
DO_IF_CHECKER(sval.subtype=0);
\
+
break;
\
+
}
\
\
-
case '
s
': \
-
if(field_length
!
= -1) \
-
{
\
-
if(input_len
-
eye
<
field_length)
\
-
{
\
-
chars_matched[0]=eye;
\
-
return matches; \
-
} \
+
case '
F
':
\
+
if(field_length =
=
-1)
field_length
=
4;
\
+
if(field_length
!=
4
&&
field_length != 8)
\
+
error("Invalid
IEEE
width
%d
in
sscanf
format
string.\n",
\
+
field_length);
\
+
if(eye+field_length
>
input_len
)
\
+
{
\
+
chars_matched[0]=eye;
\
+
return matches;
\
+
}
\
+
sval.type=T_FLOAT; \
+
DO_IF_CHECKER(sval.subtype=0); \
+
switch(field_length) { \
+
case 4: \
+
EXTRACT_FLOAT(sval, input+eye, INPUT_SHIFT); \
+
eye += 4; \
+
break; \
+
case 8: \
+
EXTRACT_DOUBLE(sval, input+eye, INPUT_SHIFT); \
+
eye += 8; \
+
break; \
+
}
\
+
break; \
\
-
sval.type=T_STRING;
\
-
DO_IF_CHECKER
(
sval.subtype
=
0
)
;
\
-
sval.u.string=PIKE_CONCAT(make_shared_binary_string,
\
-
INPUT_SHIFT)(input+eye,
\
-
field_length);
\
-
eye+=field_length;
\
-
break
; \
-
}
\
+
case
's':
\
+
if(field_length
!=
-1
)
\
+
{
\
+
if(input_len
-
eye
<
field_length)
\
+
{
\
+
chars_matched[0]=eye
;
\
+
return
matches;
\
+
} \
\
-
if(cnt+1>=match_len)
\
-
{ \
-
sval.type=T_STRING; \
-
DO_IF_CHECKER(sval.subtype=0); \
-
sval.u.string=PIKE_CONCAT(make_shared_binary_string, \
-
INPUT_SHIFT)(input+eye, \
-
input
_
len-eye
); \
-
eye
=
input
_
len
;
\
-
break;
\
-
}else{
\
-
PIKE_CONCAT(p_wchar,
MATCH_SHIFT)
*end_str_start;
\
-
PIKE_CONCAT(p_wchar,
MATCH_SHIFT)
*end_str_end;
\
-
PIKE_CONCAT(p_wchar,
MATCH_SHIFT)
*s=0;
\
-
PIKE_CONCAT(p_wchar, MATCH_SHIFT) *p=0; \
-
int start,contains_percent_percent, new_eye; \
+
sval.type=T_STRING;
\
+
DO_IF_CHECKER(sval.subtype=0);
\
+
sval.u.string=PIKE_CONCAT(make_shared_binary_string,
\
+
INPUT_SHIFT)(input+eye,
\
+
field
_
length
);
\
+
eye+
=
field
_
length
; \
+
break; \
+
}
\
\
-
start
=eye; \
-
end_str_start=
match+cnt+1
; \
+
if(cnt+1>=match_len)
\
+
{ \
+
sval.type
=
T_STRING; \
+
DO_IF_CHECKER(sval.subtype=0); \
+
sval.u.string=PIKE_CONCAT(make_shared_binary_string, \
+
INPUT_SHIFT)(input+eye, \
+
input_len-
eye
)
;
\
+
eye=input_len;
\
+
break; \
+
}else{ \
+
PIKE_CONCAT(p_wchar, MATCH_SHIFT) *
end_str_start
; \
+
PIKE_CONCAT(p_wchar, MATCH_SHIFT) *end_str_end; \
+
PIKE_CONCAT(p_wchar, MATCH_SHIFT) *s
=
0
;
\
+
PIKE_CONCAT(p_wchar, MATCH_SHIFT) *p=0;
\
+
int start,contains_percent_percent, new_eye; \
\
-
s
=
match+cnt+1
;
\
-
test_again:
\
-
if(*s
=
='%') \
-
{ \
-
s++
;
\
-
if(*s=='*') s++; \
-
switch(*s) \
-
{ \
-
case 'n': \
-
s++; \
-
goto test_again; \
+
start
=
eye
; \
+
end_str_start
=
match+cnt+1
; \
\
-
case
'
s'
:
\
-
error("Illegal
to
have
two
adjecent
%%
s.
\n"
); \
-
return
0
;
/*
make
gcc
happy
*/
\
+
s=match+cnt+1;
\
+
test_again: \
+
if(*
s
==
'
%')
\
+
{
\
+
s++; \
+
if
(
*s=='*')
s++;
\
+
set.neg=0; \
+
switch(*
s)
\
+
{ \
+
case 'n': \
+
s++
;
\
+
goto
test_again
;
\
\
-
/*
sscanf("foo-bar","%s%d",a,b)
might
not
work
as
expected */ \
-
case '
d
': \
-
for
(
e=0;e<256;e++)
set[e]=1;
\
-
for(e='0';e<='9';e++
)
set[e]=0
;
\
-
set['-']=
0;
\
-
goto match_set; \
+
case '
s
':
\
+
error
(
"Illegal
to
have
two
adjecent
%%s.\n"
); \
+
return
0;
/*
make
gcc
happy
*/
\
\
-
case '
o
': \
-
for
(
e=0;e<256;e++)
set
[e]=
1;
\
-
for(e='0';e<='
7
';e++) set[e]=0; \
-
goto match_set; \
+
/*
sscanf("foo-bar","%s%d",a,b)
might
not
work
as
expected */ \
+
case '
d
':
\
+
MEMSET
(
set.c,
1, sizeof(
set
.c))
; \
+
for(e='0';e<='
9
';e++) set
.c
[e]=0;
\
+
set.c['-']=0;
\
+
goto match_set;
\
\
-
case '
x
': \
-
for
(
e=0;e<256;e++)
set
[e]=
1
;
\
-
for
(
e='0';e<='9';e++)
set
[e]=0
; \
-
for(e='
a
';e<='
f
';e++) set[e]=0;
\
-
goto match_set; \
+
case '
o
':
\
+
MEMSET
(
set.c,
1
,
sizeof
(
set.c
)
)
; \
+
for(e='
0
';e<='
7
';e++) set
.c
[e]=0; \
+
goto match_set;
\
\
-
case '
D
': \
-
for
(
e=0;e<256;e++)
set
[e]=
1;
\
-
for(e='0';e<='9';e++) set[e]=0;
\
-
set[
'
-
'
]
=
0
;
\
-
set[
'x'
]=0;
\
-
goto match_set; \
+
case '
x
':
\
+
MEMSET
(
set.c,
1, sizeof(
set
.c))
; \
+
for(e='0';e<='9';e++) set
.c
[e]=0; \
+
for(e=
'
a
'
;e<
=
'f'
;
e++)
set
.c
[
e
]=0; \
+
goto match_set;
\
\
-
case '
f
': \
-
for
(
e=0;e<256;e++)
set
[e]=
1;
\
-
for(e='0';e<='9';e++) set[e]=0;
\
-
set['
.
']=set['
-
']=0; \
-
goto match_set; \
+
case '
D
':
\
+
MEMSET
(
set.c,
1, sizeof(
set
.c))
; \
+
for(e='0';e<='9';e++) set
.c
[e]=0; \
+
set
.c
['
-
']=
0; \
+
set
.c
['
x
']=0;
\
+
goto match_set;
\
\
-
case '
[
':
/*
oh
dear
*/
\
-
/*
FIXME!
*/
\
-
read_set(match,s-match+1,set,match_len); \
-
for(e=0;e<
256
;e++) set[e]=
!set[e]
; \
-
goto match_
set;
\
-
}
\
-
} \
+
case '
f
':
\
+
MEMSET(set.c,
1,
sizeof(set.c));
\
+
for(e=
'
0
'
;e<
='9'
;e++) set
.c
[e]=
0
;
\
+
set
.c['.']=set.c['-']=0
; \
+
goto
match_set;
\
\
-
contains
_
percent
_
percent
=
0
; \
+
case '[': /* oh dear */ \
+
PIKE
_
CONCAT(read
_
set,MATCH_SHIFT)(match, \
+
s-match+1, \
+
&set, \
+
match_len); \
+
set.neg
=
!set.neg
;
\
+
goto match_set; \
+
} \
+
} \
\
-
for(e=cnt;e<match_len;e++) \
-
{ \
-
if(match[e]=='%') \
-
{ \
-
if(match[e+1]=='%') \
-
{ \
-
contains_percent_percent=
1
;
\
-
e++;
\
-
}else{ \
-
break; \
-
} \
-
} \
-
} \
+
contains_percent_percent=
0
; \
\
-
end
_
str
_
end
=
match+e
; \
+
for(e=cnt;e<match
_
len;e++) \
+
{ \
+
if(match[e]=='%') \
+
{ \
+
if(match[e+1]=='%') \
+
{ \
+
contains
_
percent_percent
=
1
;
\
+
e++;
\
+
}else{ \
+
break; \
+
} \
+
} \
+
} \
\
-
if(!contains_percent_percent) \
-
{ \
-
struct generic_mem_searcher searcher; \
-
PIKE_CONCAT(p_wchar, INPUT_SHIFT) *s2; \
-
init_generic_memsearcher(&searcher,
end_str_
start, \
-
end
_str_end - end_str_start, \
-
MATCH_SHIFT, input_len - eye, \
-
INPUT_SHIFT); \
-
s2
=
generic_memory_search(&searcher, input+eye, \
-
input_len - eye, INPUT_SHIFT)
;
\
-
if(!s2)
\
-
{ \
-
chars_matched[0]=eye; \
-
return matches; \
-
} \
-
eye=s2-input; \
-
new_eye=eye+end_str_end-end_str_start; \
-
}else{ \
-
PIKE_CONCAT(p_wchar, INPUT_SHIFT) *p2 = NULL; \
-
for(;eye<input_len;eye++) \
-
{ \
-
p2=input+eye; \
-
for(s=end_str_start;s<end_str_end;s++,p2++) \
-
{ \
-
if(*s!=*p2) break; \
-
if(*s=='%') s++; \
-
} \
-
if(s==end_str_end) \
-
break; \
-
} \
-
if(eye==input_len) \
-
{ \
-
chars_matched[0]=eye; \
-
return matches; \
-
} \
-
new_eye=p2-input; \
-
} \
+
end_str_end=
match+e
; \
\
-
sval.type=T
_
STRING
; \
-
DO
_
IF
_
CHECKER
(
sval.subtype
=
0
); \
-
sval.u.string
=PIKE_CONCAT(
make
_
shared
_
binary
_
string
, \
-
INPUT
_
SHIFT
)(
input+start,
\
-
eye-
start)
; \
+
if(!contains
_
percent_percent) \
+
{ \
+
struct generic_mem_searcher searcher
;
\
+
PIKE_CONCAT(p_wchar,
INPUT_SHIFT)
*s2;
\
+
init
_
generic
_
memsearcher
(
&searcher, end_str_start, \
+
end_str_end - end_str_start, \
+
MATCH_SHIFT, input_len - eye, \
+
INPUT_SHIFT); \
+
s2
=
generic_memory_search(&searcher, input+eye, \
+
input_len - eye, INPUT_SHIFT
);
\
+
if(!s2)
\
+
{ \
+
chars_matched[0]
=
eye; \
+
return matches; \
+
} \
+
eye=s2-input; \
+
new_eye=eye+end_str_end-end_str_start; \
+
}else{ \
+
PIKE_CONCAT(
p
_
wchar, INPUT
_
SHIFT) *p2 = NULL; \
+
for(;eye<input
_
len;eye++) \
+
{ \
+
p2=input+eye; \
+
for(s=end_str_start;s<end_str_end;s++
,
p2++)
\
+
{
\
+
if(*s!=*p2) break; \
+
if(*s=='%') s++; \
+
} \
+
if(s==end
_
str_end
)
\
+
break; \
+
} \
+
if
(
eye==input_len)
\
+
{
\
+
chars_matched[0]=
eye
; \
+
return matches; \
+
} \
+
new_eye=p2
-
input
;
\
+
} \
\
-
cnt
=
end
_
str_end-match-1
;
\
-
eye=new_eye;
\
-
break;
\
-
}
\
+
sval.type
=
T
_
STRING
;
\
+
DO_IF_CHECKER(sval.subtype=0);
\
+
sval.u.string=PIKE_CONCAT(make_shared_binary_string,
\
+
INPUT_SHIFT)(input+start,
\
+
eye-start);
\
\
-
case
'[':
\
-
/*
FIXME!
*/
\
-
cnt=read_set(match,cnt+1,set,match_len);
\
+
cnt=end_str_end-match-1;
\
+
eye=new_eye;
\
+
break;
\
+
}
\
\
-
match_set:
\
-
/* FIXME! */ \
-
for(e=eye;eye<input_len && !(input
[
eye]&~0xff)
&&
\
-
set[input[eye]];eye++);
\
-
sval.type
=
T_STRING; \
-
DO_IF_CHECKER(sval.subtype=0); \
-
sval.u.string=
PIKE_CONCAT(
make
_
shared_binary_string
,
\
-
INPUT
_SHIFT)(
input+e
,
eye-e);
\
-
break;
\
+
case
'
[
':
\
+
cnt
=PIKE_CONCAT(
read
_
set
,
MATCH
_SHIFT)(
match
,
cnt+1,
\
+
&set,match_len);
\
\
-
case
'n':
\
-
sval
.type=T_INT; \
-
sval.
subtype
=
NUMBER
_
NUMBER
; \
-
sval.u.
integer
=
eye;
\
-
break; \
+
match_set:
\
+
for(e=eye;eye<input_len;eye++)
\
+
{ \
+
CHAROPT( \
+
if(input[eye]<sizeof(set
.
c)) \
+
{ \
+
) \
+
if(set.c[input[eye]] == set.neg) \
+
break; \
+
CHAROPT( \
+
}else{ \
+
if(set.a) \
+
{ \
+
INT32 x; \
+
struct svalue tmp; \
+
tmp.
type=T_INT;
\
+
tmp.u.integer=input[eye];
\
+
x=switch_lookup(set.a, &tmp); \
+
if( set.neg != (x<0 && (x&1)) ) break; \
+
}else{ \
+
break; \
+
} \
+
} \
+
) \
+
} \
+
if(set.a) { free_array(set.a); set.a=0; } \
+
sval.
type
=
T
_
STRING
;
\
+
DO_IF_CHECKER(
sval.
subtype=0); \
+
sval.
u.
string
=
PIKE_CONCAT(make_shared_binary_string,
\
+
INPUT_SHIFT)(input+e,eye-e);
\
+
break;
\
\
-
default
: \
-
error("Unknown
sscanf
token
%%%c(0x%02x)\n",
\
-
match[cnt],
match[cnt]);
\
-
}
\
-
break;
\
-
}
\
-
matches++
;
\
+
case 'n'
: \
+
sval.type=T_INT;
\
+
sval.subtype=NUMBER_NUMBER;
\
+
sval.u.integer=eye;
\
+
break
; \
\
-
if(no_assign) \
-
{ \
-
free_svalue(&sval); \
-
}else{ \
-
check_stack(1); \
-
*sp++=sval; \
-
DO_IF_DEBUG(sval.type=99); \
-
} \
-
} \
-
chars_matched[0]=eye; \
-
success[0]=1; \
-
return matches; \
+
default: \
+
error("Unknown sscanf token %%%c(0x%02x)\n", \
+
match[cnt], match[cnt]); \
+
} \
+
break; \
+
} \
+
matches++; \
+
\
+
if(no_assign)
\
+
{
\
+
free_svalue(&sval);
\
+
}else{
\
+
check_stack(1);
\
+
*sp++=sval;
\
+
DO_IF_DEBUG(sval.type=99);
\
+
}
\
+
}
\
+
chars_matched[0]=eye;
\
+
success[0]=1;
\
+
return matches;
\
}
-
+
#define CHAROPT(X)
+
+
MKREADSET(0)
MK_VERY_LOW_SSCANF(0,0)
-
MK_VERY_LOW_SSCANF(0,1)
-
MK_VERY_LOW_SSCANF(0,2)
+
MK_VERY_LOW_SSCANF(1,0)
-
MK_VERY_LOW_SSCANF(1,1)
-
MK_VERY_LOW_SSCANF(1,2)
+
MK_VERY_LOW_SSCANF(2,0)
-
+
+
#undef CHAROPT
+
#define CHAROPT(X) X
+
MKREADSET(1)
+
MKREADSET(2)
+
+
+
MK_VERY_LOW_SSCANF(0,1)
+
MK_VERY_LOW_SSCANF(1,1)
MK_VERY_LOW_SSCANF(2,1)
-
+
MK_VERY_LOW_SSCANF(0,2)
+
MK_VERY_LOW_SSCANF(1,2)
MK_VERY_LOW_SSCANF(2,2) void o_sscanf(INT32 args)