From 2a22c4ff0d6129403834e81459fe3826c2e8568b Mon Sep 17 00:00:00 2001 From: Olaf Barthel Date: Fri, 3 Jun 2005 11:12:12 +0000 Subject: [PATCH] - The scanf() family now supports character ranges for the %[ conversion. Note that this is a non-standard feature! git-svn-id: file:///Users/olsen/Code/migration-svn-zu-git/logical-line-staging/clib2/trunk@14970 87f5fb63-7c3d-0410-a384-fd976d0f7a62 --- library/changes | 3 +++ library/stdio_vfscanf.c | 50 +++++++++++++++++++++++++++++++++++------ 2 files changed, 46 insertions(+), 7 deletions(-) diff --git a/library/changes b/library/changes index 51c07f4..83cb5c1 100644 --- a/library/changes +++ b/library/changes @@ -76,6 +76,9 @@ - Ported acosh(), acoshf(), asinh(), asinhf(), lgamma(), lgammaf(), remainder() and remainderf() for C99. +- The scanf() family now supports character ranges for the %[ + conversion. Note that this is a non-standard feature! + c.lib 1.192 (12.5.2005) diff --git a/library/stdio_vfscanf.c b/library/stdio_vfscanf.c index 08470e6..e590736 100644 --- a/library/stdio_vfscanf.c +++ b/library/stdio_vfscanf.c @@ -1,5 +1,5 @@ /* - * $Id: stdio_vfscanf.c,v 1.16 2005-05-29 08:19:36 obarthel Exp $ + * $Id: stdio_vfscanf.c,v 1.17 2005-06-03 11:12:12 obarthel Exp $ * * :ts=4 * @@ -1752,6 +1752,8 @@ vfscanf(FILE *stream, const char *format, va_list arg) { char * s_ptr; char set[256]; + const unsigned char * scanset; + size_t scanset_length,i; int pick; if(NOT assignment_suppressed) @@ -1814,14 +1816,48 @@ vfscanf(FILE *stream, const char *format, va_list arg) format++; } - /* Collect the other characters to form the range. */ - while((c = (*(unsigned char *)format)) != '\0') - { + /* Figure out how many characters are in the scanset. */ + scanset = (const unsigned char *)format; + + for(scanset_length = 0 ; scanset[scanset_length] != '\0' && scanset[scanset_length] != ']' ; scanset_length++) format++; - /* This would end the range. */ - if(c == ']') - break; + /* We already skipped everything but the righ bracket. */ + if((*format) == ']') + format++; + + /* Now have a look at the specification. We support a non-standard + scanf() family feature which permits you to specify ranges of + characters rather than spelling out each character included in + the range. */ + for(i = 0 ; i < scanset_length ; i++) + { + c = scanset[i]; + + /* Could this be a range? It's not a range if it + is the first or the last character in the + specification. */ + if(c == '-' && i != 0 && i != scanset_length - 1) + { + int first,last,j; + + /* Pick the first and the last character in + the range, e.g. for "[A-Z]" the first would + be the 'A' and the 'Z' would be the last. */ + first = scanset[i-1]; + last = scanset[i+1]; + + /* Everything in the scanset now + goes into the set. */ + for(j = first ; j <= last ; j++) + set[j] = pick; + + /* Skip the character which marked the + end of the range and resume scanning. */ + i++; + + continue; + } assert( 0 <= c && c <= 255 );