diff --git a/.gitattributes b/.gitattributes index d38f610584384e83a33b0132ecfc06fc328c3ef1..0ee787125c421364f9a8f980c6afa09d0f53b133 100644 --- a/.gitattributes +++ b/.gitattributes @@ -799,7 +799,6 @@ testfont binary /src/test_co.pike foreign_ident /src/time_stuff.h foreign_ident /src/tmodule.c foreign_ident -/src/treeopt.in foreign_ident /src/uncompressor.c foreign_ident /src/version.c foreign_ident /tools/pike.el foreign_ident diff --git a/src/sscanf.c b/src/sscanf.c index 4479aa49fe88867a6d201a384634096e1c8c1d13..4e10ee8f79dcad1e4232d540f2e8d8d187a5931b 100644 --- a/src/sscanf.c +++ b/src/sscanf.c @@ -611,8 +611,8 @@ static INT32 PIKE_CONCAT4(very_low_sscanf_,INPUT_SHIFT,_,MATCH_SHIFT)( \ { \ struct svalue sval; \ INT32 matches, arg; \ - ptrdiff_t cnt, eye, e, field_length = 0; \ - int no_assign = 0, minus_flag = 0, plus_flag = 0; \ + ptrdiff_t cnt, eye, start_eye, e, field_length = 0, truncated = 0; \ + int no_assign = 0, minus_flag = 0, plus_flag = 0, truncate = 0; \ struct sscanf_set set; \ \ \ @@ -658,6 +658,8 @@ static INT32 PIKE_CONCAT4(very_low_sscanf_,INPUT_SHIFT,_,MATCH_SHIFT)( \ field_length=-1; \ minus_flag=0; \ plus_flag=0; \ + truncate=0; \ + start_eye = eye; \ \ cnt++; \ if(cnt>=match_len) \ @@ -694,6 +696,11 @@ static INT32 PIKE_CONCAT4(very_low_sscanf_,INPUT_SHIFT,_,MATCH_SHIFT)( \ cnt++; \ continue; \ \ + case '!': \ + truncate=1; \ + cnt++; \ + continue; \ + \ case '{': \ { \ ONERROR err; \ @@ -1270,7 +1277,7 @@ INPUT_IS_WIDE( \ case 'n': \ sval.type=T_INT; \ sval.subtype=NUMBER_NUMBER; \ - sval.u.integer=TO_INT32(eye); \ + sval.u.integer=TO_INT32(eye - truncated); \ break; \ \ default: \ @@ -1280,6 +1287,9 @@ INPUT_IS_WIDE( \ break; \ } \ matches++; \ + if (truncate) { \ + truncated += eye - start_eye; \ + } \ \ if(no_assign) \ { \ @@ -1456,6 +1466,8 @@ INT32 low_sscanf(struct pike_string *data, struct pike_string *format, INT32 fla *! @expr{-28@}. *! @value "%n" *! Returns the current character offset in @[data]. + *! Note that any characters matching fields scanned with the + *! @expr{"!"@}-modifier are removed from the count (see below). *! @value "%f" *! Reads a float ("0101" makes 101.0). *! @value "%F" @@ -1530,6 +1542,9 @@ INT32 low_sscanf(struct pike_string *data, struct pike_string *format, INT32 fla *! Interpret the data as a signed entity. In other words, *! @expr{"%+1c"@} will read @expr{"\xFF"@} as @expr{-1@} instead *! of @expr{255@}, as @expr{"%1c"@} would have. + *! @value "!" + *! Ignore the matched characters with respect to any following + *! @expr{"%n"@}. *! @endstring *! *! @note @@ -1669,6 +1684,7 @@ static void push_sscanf_argument_types(PCHARP format, ptrdiff_t format_len, case '-': case '+': + case '!': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': cnt++; diff --git a/src/testsuite.in b/src/testsuite.in index a7c955d692f062d75e94cc040cf9dee9afa18f17..286cf916fdd87cd01076f70ac8e9034803ded6b8 100644 --- a/src/testsuite.in +++ b/src/testsuite.in @@ -7704,6 +7704,7 @@ test_equal([[ array_sscanf("\51726\30212\66610\30131", "%*[ \t]%s")[0] ]], test_equal([[ array_sscanf("hej","%s") ]], [[ ({ "hej" }) ]]) test_equal([[ array_sscanf("hej","%s%n") ]], [[ ({ "hej", 3 }) ]]) +test_equal([[ array_sscanf("hejhopp", "%*!3s%s%n") ]], [[ ({ "hopp", 4 }) ]]) test_eval_error([[ function f=array_sscanf; f("hej","%s% ") ]]) test_equal([[ array_sscanf("\x304b\x3066\x3044\x308a\x3087\x3046\x308a", "%[^\x3042\x3044\x3046\x3048\x304a]")[0] ]], diff --git a/src/treeopt.in b/src/treeopt.in index fd2dd946f4ce02e629f384841f7aead1d9a90cdf..f82bc564827148f40f80de5c2c20121182e381cd 100644 --- a/src/treeopt.in +++ b/src/treeopt.in @@ -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: treeopt.in,v 1.101 2010/02/03 20:22:29 grubba Exp $ +// $Id$ // // The tree optimizer // @@ -188,7 +188,7 @@ F_GE(F_APPLY(F_CONSTANT // // => // -// (sscanf(s, "%*" + A + "s" + "xxxx", ...) || 1) - 1 +// (sscanf(s, "%*!" + A + "s" + "xxxx", ...) || 1) - 1 F_SSCANF(':'(4 = +, F_ARG_LIST(F_RANGE(0 = +[ pike_types_le($$->type, string_type_string)], @@ -199,7 +199,7 @@ F_SSCANF(':'(4 = +, { struct pike_string *percent_star_string; struct pike_string *s_string; - MAKE_CONST_STRING(percent_star_string, "%*"); + MAKE_CONST_STRING(percent_star_string, "%*!"); MAKE_CONST_STRING(s_string, "s"); $$ = mkopernode("`-", mknode(F_LOR,