pike.git/
src/
opcodes.c
Branch:
Tag:
Non-build tags
All tags
No tags
2003-03-06
2003-03-06 15:29:56 by Henrik Grubbström (Grubba) <grubba@grubba.org>
247e12ff6b689c4c6bbf3f56fc98b42f33e28867 (
274
lines) (+
95
/-
179
)
[
Show
|
Annotate
]
Branch:
7.9
Some minor cleanups of the sscanf() code.
Rev: src/opcodes.c:1.142
2:
|| This file is part of Pike. For copyright information see COPYRIGHT. || Pike is distributed under GPL, LGPL and MPL. See the file COPYING || for more information.
-
|| $Id: opcodes.c,v 1.
141
2003/
02
/
19
01
:
59
:
39
marcus
Exp $
+
|| $Id: opcodes.c,v 1.
142
2003/
03
/
06
15
:
29
:
56
grubba
Exp $
*/ #include "global.h"
30:
#define sp Pike_sp
-
RCSID("$Id: opcodes.c,v 1.
141
2003/
02
/
19
01
:
59
:
39
marcus
Exp $");
+
RCSID("$Id: opcodes.c,v 1.
142
2003/
03
/
06
15
:
29
:
56
grubba
Exp $");
void index_no_free(struct svalue *to,struct svalue *what,struct svalue *ind) {
1427:
#define TO_INT32(x) ((INT32)(x)) #endif /* __ECL */
+
/* INT32 very_low_sscanf_{0,1,2}_{0,1,2}(p_wchar *input, ptrdiff_t input_len,
+
* p_wchar *match, ptrdiff_t match_len,
+
* ptrdiff_t *chars_matched,
+
* int *success)
+
*
+
* Perform the actual parsing.
+
*
+
* Arguments:
+
* input, input_len Input data to parse.
+
* match, match_len Format string.
+
* chars_matched Gets set to the number of characters
+
* in the input that were advanced.
+
* success Gets set to 1 on success.
+
*
+
* Returns:
+
* Returns the number of %-directives that were successfully matched.
+
* Pushes non-ignored matches on the Pike stack in the order they
+
* were matched.
+
*
+
* FIXME: chars_matched and success are only used internally, and
+
* should probably be gotten rid of.
+
*/
#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, \
2072:
MK_VERY_LOW_SSCANF(1,2) MK_VERY_LOW_SSCANF(2,2)
-
/*
!
@decl
int
sscanf(string
data
,
string format
,
mixed
.
..
lvalues)
-
*
!
-
*!
The purpose of
sscanf
is to match one string against a format string and
-
*! place the matching results into a list of variables. The list of @[lvalues]
-
*! are destructively modified
(
which
is only possible because sscanf really is
-
*! an opcode, rather than a
pike
function) with the values extracted from the
-
*
! @[
data
]
according
to the @[format] specification. Only the variables up to
-
*! the last matching directive of the format
string
are touched.
-
*
!
-
*! Refer to the @[chapter::sscanf] chapter for the complete list of directives
-
*! sscanf understands.
-
*!
-
*! @returns
-
*! The number of directives matched in the
format
string. Note that a string
-
*! directive (%s or %[]
)
always counts as a match, even when matching the
-
*! empty string.
-
*! @seealso
-
*! @[array_sscanf()], @[chapter::sscanf]
-
*/
-
void o_sscanf(INT32 args)
+
/*
Simplified
interface
to very_low_
sscanf
_{0
,
1
,
2}_{0,1,2}()
. *
/
+
static
INT32
low_
sscanf
(struct
pike_
string *
data
,
struct
pike
_
string *format)
{
-
INT32 i=0;
-
int x;
+
ptrdiff_t matched_chars;
-
struct
svalue *save_sp=sp
;
-
-
if(sp[-args].type
!= T_STRING)
-
SIMPLE_BAD_ARG_ERROR("sscanf", 1, "string")
;
-
-
if(sp[1-args].type != T_STRING)
-
SIMPLE_BAD_ARG_ERROR("sscanf", 2, "string");
-
-
switch(
sp[
-
args].u.string-
>size_shift*3 +
sp[1
-
args].u.string-
>size_shift) {
+
int
x
;
+
INT32
i
;
+
switch(
data
->size_shift*3 +
format
->size_shift) {
/* input_shift : match_shift */ case 0: /* 0 : 0 */
-
i=very_low_sscanf_0_0(STR0(
sp[-args].u.string
),
-
sp[
-
args].u.string-
>len,
-
STR0(
sp[1-args].u.string
),
-
sp[1
-
args].u.string-
>len,
-
&matched_chars,
-
&x);
+
i
=
very_low_sscanf_0_0(STR0(
data
),
data
->len,
+
STR0(
format
),
format
->len,
+
&matched_chars, &x);
break; case 1: /* 0 : 1 */
-
i=very_low_sscanf_0_1(STR0(
sp[-args].u.string
),
-
sp[
-
args].u.string-
>len,
-
STR1(
sp[1-args].u.string
),
-
sp[1
-
args].u.string-
>len,
-
&matched_chars,
-
&x);
+
i
=
very_low_sscanf_0_1(STR0(
data
),
data
->len,
+
STR1(
format
),
format
->len,
+
&matched_chars, &x);
break; case 2: /* 0 : 2 */
-
i=very_low_sscanf_0_2(STR0(
sp[-args].u.string
),
-
sp[
-
args].u.string-
>len,
-
STR2(
sp[1-args].u.string
),
-
sp[1
-
args].u.string-
>len,
-
&matched_chars,
-
&x);
+
i
=
very_low_sscanf_0_2(STR0(
data
),
data
->len,
+
STR2(
format
),
format
->len,
+
&matched_chars, &x);
break; case 3: /* 1 : 0 */
-
i=very_low_sscanf_1_0(STR1(
sp[-args].u.string
),
-
sp[
-
args].u.string-
>len,
-
STR0(
sp[1-args].u.string
),
-
sp[1
-
args].u.string-
>len,
-
&matched_chars,
-
&x);
+
i
=
very_low_sscanf_1_0(STR1(
data
),
data
->len,
+
STR0(
format
),
format
->len,
+
&matched_chars, &x);
break; case 4: /* 1 : 1 */
-
i=very_low_sscanf_1_1(STR1(
sp[-args].u.string
),
-
sp[
-
args].u.string-
>len,
-
STR1(
sp[1-args].u.string
),
-
sp[1
-
args].u.string-
>len,
-
&matched_chars,
-
&x);
+
i
=
very_low_sscanf_1_1(STR1(
data
),
data
->len,
+
STR1(
format
),
format
->len,
+
&matched_chars, &x);
break; case 5: /* 1 : 2 */
-
i=very_low_sscanf_1_2(STR1(
sp[-args].u.string
),
-
sp[
-
args].u.string-
>len,
-
STR2(
sp[1-args].u.string
),
-
sp[1
-
args].u.string-
>len,
-
&matched_chars,
-
&x);
+
i
=
very_low_sscanf_1_2(STR1(
data
),
data
->len,
+
STR2(
format
),
format
->len,
+
&matched_chars, &x);
break; case 6: /* 2 : 0 */
-
i=very_low_sscanf_2_0(STR2(
sp[-args].u.string
),
-
sp[
-
args].u.string-
>len,
-
STR0(
sp[1-args].u.string
),
-
sp[1
-
args].u.string-
>len,
-
&matched_chars,
-
&x);
+
i
=
very_low_sscanf_2_0(STR2(
data
),
data
->len,
+
STR0(
format
),
format
->len,
+
&matched_chars, &x);
break; case 7: /* 2 : 1 */
-
i=very_low_sscanf_2_1(STR2(
sp[-args].u.string
),
-
sp[
-
args].u.string-
>len,
-
STR1(
sp[1-args].u.string
),
-
sp[1
-
args].u.string-
>len,
-
&matched_chars,
-
&x);
+
i
=
very_low_sscanf_2_1(STR2(
data
),
data
->len,
+
STR1(
format
),
format
->len,
+
&matched_chars, &x);
break; case 8: /* 2 : 2 */
-
i=very_low_sscanf_2_2(STR2(
sp[-args].u.string
),
-
sp[
-
args].u.string-
>len,
-
STR2(
sp[1-args].u.string
),
-
sp[1
-
args].u.string-
>len,
-
&matched_chars,
-
&x);
+
i
=
very_low_sscanf_2_2(STR2(
data
),
data
->len,
+
STR2(
format
),
format
->len,
+
&matched_chars, &x);
break; default:
-
Pike_
error
("Unsupported shift-combination to sscanf(): %d:%d\n",
-
sp[
-
args].u.string-
>size_shift,
sp[1
-
args].u.string-
>size_shift);
+
Pike_
fatal
("Unsupported shift-combination to
low_
sscanf(): %d:%d\n",
+
data
->size_shift,
format
->size_shift);
break; }
-
+
return i;
+
}
-
+
/*! @decl int sscanf(string data, string format, mixed ... lvalues)
+
*!
+
*! The purpose of sscanf is to match one string against a format string and
+
*! place the matching results into a list of variables. The list of @[lvalues]
+
*! are destructively modified (which is only possible because sscanf really is
+
*! an opcode, rather than a pike function) with the values extracted from the
+
*! @[data] according to the @[format] specification. Only the variables up to
+
*! the last matching directive of the format string are touched.
+
*!
+
*! Refer to the @[chapter::sscanf] chapter for the complete list of directives
+
*! sscanf understands.
+
*!
+
*! @returns
+
*! The number of directives matched in the format string. Note that a string
+
*! directive (%s or %[]) always counts as a match, even when matching the
+
*! empty string.
+
*! @seealso
+
*! @[array_sscanf()], @[chapter::sscanf]
+
*/
+
void o_sscanf(INT32 args)
+
{
+
INT32 i=0;
+
int x;
+
struct svalue *save_sp=sp;
+
+
if(sp[-args].type != T_STRING)
+
SIMPLE_BAD_ARG_ERROR("sscanf", 1, "string");
+
+
if(sp[1-args].type != T_STRING)
+
SIMPLE_BAD_ARG_ERROR("sscanf", 2, "string");
+
+
i = low_sscanf(sp[-args].u.string, sp[1-args].u.string);
+
if(sp-save_sp > args/2-1) Pike_error("Too few arguments for sscanf format.\n");
2227:
PMOD_EXPORT void f_sscanf(INT32 args) { INT32 i;
-
int x;
-
ptrdiff_t matched_chars;
+
struct svalue *save_sp=sp; struct array *a; check_all_args("array_sscanf",args,BIT_STRING, BIT_STRING,0);
-
switch(sp[-args].u.string->size_shift*3 + sp[1-args].u.string->size_shift) {
-
/* input_shift : match_shift */
-
case 0:
-
/* 0 : 0 */
-
i
=very_low_sscanf_0_0(STR0(sp[-args].u.string),
-
sp[-args].u.string->len,
-
STR0(sp[1-args].u.string),
-
sp[1-args].u.string->len,
-
&matched_chars,
-
&x);
-
break;
-
case 1:
-
/* 0 : 1 */
-
i
=
very_low_sscanf_0_1(STR0(sp[-args].u.string),
-
sp[-args].u.string->len,
-
STR1(sp[1-args].u.string),
-
sp[1-args].u.string->len,
-
&matched_chars,
-
&x);
-
break;
-
case 2:
-
/* 0 : 2 */
-
i=very_
low_sscanf
_0_2
(
STR0(
sp[-args].u.string
)
,
-
sp[
-args].u.string->len,
-
STR2(sp[
1-args].u.string)
,
-
sp[1-args].u.string->len,
-
&matched_chars,
-
&x)
;
-
break;
-
case 3:
-
/* 1 : 0 */
-
i=very_low_sscanf_1_0(STR1(sp[-args].u.string),
-
sp[-args].u.string->len,
-
STR0(sp[1-args].u.string),
-
sp[1-args].u.string->len,
-
&matched_chars,
-
&x);
-
break;
-
case 4:
-
/* 1 : 1 */
-
i=very_low_sscanf_1_1(STR1(sp[-args].u.string),
-
sp[-args].u.string->len,
-
STR1(sp[1-args].u.string),
-
sp[1-args].u.string->len,
-
&matched_chars,
-
&x);
-
break;
-
case 5:
-
/* 1 : 2 */
-
i=very_low_sscanf_1_2(STR1(sp[-args].u.string),
-
sp[-args].u.string->len,
-
STR2(sp[1-args].u.string),
-
sp[1-args].u.string->len,
-
&matched_chars,
-
&x);
-
break;
-
case 6:
-
/* 2 : 0 */
-
i=very_low_sscanf_2_0(STR2(sp[-args].u.string),
-
sp[-args].u.string->len,
-
STR0(sp[1-args].u.string),
-
sp[1-args].u.string->len,
-
&matched_chars,
-
&x);
-
break;
-
case 7:
-
/* 2 : 1 */
-
i=very_low_sscanf_2_1(STR2(sp[-args].u.string),
-
sp[-args].u.string->len,
-
STR1(sp[1-args].u.string),
-
sp[1-args].u.string->len,
-
&matched_chars,
-
&x);
-
break;
-
case 8:
-
/* 2 : 2 */
-
i=very_low_sscanf_2_2(STR2(sp[-args].u.string),
-
sp[-args].u.string->len,
-
STR2(sp[1-args].u.string),
-
sp[1-args].u.string->len,
-
&matched_chars,
-
&x);
-
break;
-
default:
-
Pike_error("Unsupported shift-combination to sscanf(): %d:%d\n",
-
sp[-args].u.string->size_shift, sp[1-args].u.string->size_shift);
-
break;
-
}
+
i = low_sscanf(sp[-args].u.string, sp[1-args].u.string);
a = aggregate_array(DO_NOT_WARN(sp - save_sp)); pop_n_elems(args);