From 247e12ff6b689c4c6bbf3f56fc98b42f33e28867 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Grubbstr=C3=B6m=20=28Grubba=29?= <grubba@grubba.org> Date: Thu, 6 Mar 2003 16:29:56 +0100 Subject: [PATCH] Some minor cleanups of the sscanf() code. Rev: src/opcodes.c:1.142 --- src/opcodes.c | 273 +++++++++++++++++--------------------------------- 1 file changed, 94 insertions(+), 179 deletions(-) diff --git a/src/opcodes.c b/src/opcodes.c index 47c1be0c2d..90c9898049 100644 --- a/src/opcodes.c +++ b/src/opcodes.c @@ -2,7 +2,7 @@ || 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,7 +30,7 @@ #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,6 +1427,28 @@ static inline INT32 TO_INT32(ptrdiff_t x) #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,126 +2094,108 @@ MK_VERY_LOW_SSCANF(2,1) 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,101 +2231,12 @@ void o_sscanf(INT32 args) 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); -- GitLab