]> pd.if.org Git - pdclib.old/blobdiff - functions/_PDCLIB/scan.c
Some fixes to string scanning. First half of scanset scanning.
[pdclib.old] / functions / _PDCLIB / scan.c
index 0d46f9ecfd53efe0f8a13fdd901487f482198c55..63afff235e25281778b4bdc584ca42b1e8952596 100644 (file)
@@ -87,6 +87,14 @@ static void UNGET( int c, struct _PDCLIB_status_t * status )
 }
 
 
+/* Helper function to check if a character is part of a given scanset */
+static bool NOT_IN_SCANSET( const char * start_scanlist, const char * end_scanlist, bool negate_scanlist, int rc )
+{
+    // SOLAR
+    return true;
+}
+
+
 const char * _PDCLIB_scan( const char * spec, struct _PDCLIB_status_t * status )
 {
     /* generic input character */
@@ -264,20 +272,23 @@ const char * _PDCLIB_scan( const char * spec, struct _PDCLIB_status_t * status )
             {
                 if ( isspace( rc ) )
                 {
+                    UNGET( rc, status );
                     if ( value_parsed )
                     {
                         /* matching sequence terminated by whitespace */
                         *c = '\0';
-                        return spec;
+                        ++status->n;
+                        return ++spec;
                     }
                     else
                     {
-                        /* leading whitespace not counted against width */
-                        --(status->this);
+                        /* matching error */
+                        return NULL;
                     }
                 }
                 else
                 {
+                    /* match */
                     value_parsed = true;
                     *(c++) = rc;
                 }
@@ -299,6 +310,48 @@ const char * _PDCLIB_scan( const char * spec, struct _PDCLIB_status_t * status )
                 return NULL;
             }
         }
+        case '[':
+        {
+            const char * endspec = spec;
+            bool negative_scanlist = false;
+            if ( *(++endspec) == '^' )
+            {
+                negative_scanlist = true;
+                ++endspec;
+            }
+            spec = endspec;
+            do
+            {
+                // TODO: This can run beyond a malformed format string
+                ++endspec;
+            } while ( *endspec != ']' );
+            // read according to scanlist, equiv. to %s above
+            char * c = va_arg( status->arg, char * );
+            while ( ( status->this < status->width ) && 
+                    ( ( rc = GET( status ) ) != EOF ) )
+            {
+                if ( NOT_IN_SCANSET( spec, endspec, negative_scanlist, rc ) )
+                {
+                    break;
+                }
+                value_parsed = true;
+                *(c++) = rc;
+            }
+            if ( value_parsed )
+            {
+                *c = '\0';
+                ++status->n;
+                return ++endspec;
+            }
+            else
+            {
+                if ( status->n == 0 )
+                {
+                    status->n = -1;
+                }
+                return NULL;
+            }
+        }
         case 'p':
             status->base = 16;
             status->flags |= E_unsigned;
@@ -318,8 +371,6 @@ const char * _PDCLIB_scan( const char * spec, struct _PDCLIB_status_t * status )
     {
         /* integer conversion */
         uintmax_t value = 0;         /* absolute value read */
-        uintmax_t limit;             /* max. value allowed */
-        uintmax_t threshold;         /* overflow threshold */
         bool prefix_parsed = false;
         int sign = 0;
         while ( ( status->this < status->width ) &&
@@ -356,53 +407,6 @@ const char * _PDCLIB_scan( const char * spec, struct _PDCLIB_status_t * status )
                         UNGET( rc, status );
                         break;
                 }
-                switch ( status->flags & ( E_char | E_short | E_long | E_llong | E_intmax | E_size | E_ptrdiff | E_unsigned ) )
-                {
-                    case E_char:
-                        limit = ( sign == 1 ) ? CHAR_MAX : ( CHAR_MIN * sign );
-                        break;
-                    case E_char | E_unsigned:
-                        limit = UCHAR_MAX;
-                        break;
-                    case E_short:
-                        limit = ( sign == 1 ) ? SHRT_MAX : ( SHRT_MIN * sign );
-                        break;
-                    case E_short | E_unsigned:
-                        limit = USHRT_MAX;
-                        break;
-                    case E_long:
-                        limit = ( sign == 1 ) ? LONG_MAX : ( LONG_MIN * sign );
-                        break;
-                    case E_long | E_unsigned:
-                        limit = ULONG_MAX;
-                        break;
-                    case E_llong:
-                        limit = ( sign == 1 ) ? LLONG_MAX : ( LLONG_MIN * sign );
-                        break;
-                    case E_llong | E_unsigned:
-                        limit = ULLONG_MAX;
-                        break;
-                    case E_intmax:
-                        limit = ( sign == 1 ) ? INTMAX_MAX : ( INTMAX_MIN * sign );
-                        break;
-                    case E_intmax | E_unsigned:
-                        limit = UINTMAX_MAX;
-                        break;
-                    case E_size:
-                    case E_size | E_unsigned:
-                        limit = SIZE_MAX;
-                        break;
-                    case E_ptrdiff:
-                    case E_ptrdiff | E_unsigned:
-                        limit = ( sign == 1 ) ? PTRDIFF_MAX : ( PTRDIFF_MIN * sign );
-                        break;
-                    case E_unsigned:
-                        limit = UINT_MAX;
-                        break;
-                    default:
-                        limit = ( sign == 1 ) ? INT_MAX : ( INT_MIN * sign );
-                        break;
-                }
             }
             else if ( ! prefix_parsed )
             {
@@ -468,20 +472,9 @@ const char * _PDCLIB_scan( const char * spec, struct _PDCLIB_status_t * status )
                     UNGET( rc, status );
                     break;
                 }
-                // SOLAR
-                // if ( ( ( limit - ( digitptr - _PDCLIB_digits ) ) / status->base ) >= value )
-                //if ( ( ( limit / status->base ) >= value ) && ( ( limit - ( digitptr - _PDCLIB_digits ) ) >= ( value * status->base ) ) )
-                {
-                    /* no overflow */
-                    value *= status->base;
-                    value += digitptr - _PDCLIB_digits;
-                    value_parsed = true;
-                }
-                //else
-                //{
-                //    value = limit;
-                //    threshold = 0;
-                //}
+                value *= status->base;
+                value += digitptr - _PDCLIB_digits;
+                value_parsed = true;
             }
         }
         /* width or input exhausted, or non-matching character */