[crt]
[reactos.git] / reactos / lib / sdk / crt / string / scanf.h
index 4be9d8d..69ca719 100644 (file)
@@ -26,7 +26,7 @@
 #ifdef WIDE_SCANF
 #define _CHAR_ wchar_t
 #define _EOF_ WEOF
-#define _EOF_RET WEOF
+#define _EOF_RET (short)WEOF
 #define _ISSPACE_(c) iswspace(c)
 #define _ISDIGIT_(c) iswdigit(c)
 #define _WIDE2SUPPORTED_(c) c /* No conversion needed (wide to wide) */
@@ -37,8 +37,8 @@
 #define _CHAR_ char
 #define _EOF_ EOF
 #define _EOF_RET EOF
-#define _ISSPACE_(c) isspace(c)
-#define _ISDIGIT_(c) isdigit(c)
+#define _ISSPACE_(c) isspace((unsigned char)(c))
+#define _ISDIGIT_(c) isdigit((unsigned char)(c))
 #define _WIDE2SUPPORTED_(c) c /* FIXME: convert wide char to char */
 #define _CHAR2SUPPORTED_(c) c /* No conversion needed (char to char) */
 #define _CHAR2DIGIT_(c, base) char2digit((c), (base))
@@ -88,8 +88,11 @@ _FUNCTION_ {
 #endif /* STRING */
 #endif /* CONSOLE */
 #endif /* WIDE_SCANF */
+
     nch = _GETC_(file);
-    if (nch == _EOF_) return _EOF_RET;
+    if (nch == _EOF_) {
+        return _EOF_RET;
+    }
 
     while (*format) {
        /* a whitespace character in the format string causes scanf to read,
@@ -131,8 +134,14 @@ _FUNCTION_ {
            /* read prefix (if any) */
            while (!prefix_finished) {
                switch(*format) {
-               case 'h': h_prefix = 1; break;
-               case 'l': l_prefix = 1; break;
+               case 'h': h_prefix++; break;
+               case 'l':
+                    if(*(format+1) == 'l') {
+                        I64_prefix = 1;
+                        format++;
+                    }
+                    l_prefix = 1;
+                    break;
                case 'w': w_prefix = 1; break;
                case 'L': L_prefix = 1; break;
                case 'I':
@@ -170,7 +179,7 @@ _FUNCTION_ {
                base = 0;
            number: {
                    /* read an integer */
-                   ULONGLONG cur = 0;
+                   __int64 cur = 0;
                    int negative = 0;
                    int seendigit=0;
                     /* skip initial whitespace */
@@ -224,29 +233,30 @@ _FUNCTION_ {
                    if (!seendigit) break; /* not a valid number */
                     st = 1;
                     if (!suppress) {
-#define _SET_NUMBER_(type) *va_arg(ap, type*) = negative ? -cur : cur
+#define _SET_NUMBER_(type) *va_arg(ap, type*) = (type)(negative ? -cur : cur)
                        if (I64_prefix) _SET_NUMBER_(LONGLONG);
                        else if (l_prefix) _SET_NUMBER_(LONG);
-                       else if (h_prefix) _SET_NUMBER_(short int);
+                       else if (h_prefix == 1) _SET_NUMBER_(short int);
                        else _SET_NUMBER_(int);
                    }
                 }
                 break;
-           case 'e':
-           case 'E':
-           case 'f':
-           case 'g':
+            case 'e':
+            case 'E':
+            case 'f':
+            case 'g':
             case 'G': { /* read a float */
                     long double cur = 0;
                    int negative = 0;
                     /* skip initial whitespace */
                     while ((nch!=_EOF_) && _ISSPACE_(nch))
                         nch = _GETC_(file);
-                   /* get sign. */
+
+                    /* get sign. */
                     if (nch == '-' || nch == '+') {
-                       negative = (nch=='-');
-                       if (width>0) width--;
-                       if (width==0) break;
+                        negative = (nch=='-');
+                        if (width>0) width--;
+                        if (width==0) break;
                         nch = _GETC_(file);
                     }
                    /* get first digit. */
@@ -268,48 +278,50 @@ _FUNCTION_ {
                     if (width!=0 && nch == '.') {
                         long double dec = 1;
                         nch = _GETC_(file);
-                       if (width>0) width--;
+                        if (width>0) width--;
                         while (width!=0 && (nch!=_EOF_) && _ISDIGIT_(nch)) {
                             dec /= 10;
                             cur += dec * (nch - '0');
                             nch = _GETC_(file);
-                           if (width>0) width--;
+                            if (width>0) width--;
                         }
                     }
                    /* handle exponent */
                    if (width!=0 && (nch == 'e' || nch == 'E')) {
                        int exponent = 0, negexp = 0;
-                       float expcnt;
+                       double expcnt, shift;
                         nch = _GETC_(file);
-                       if (width>0) width--;
+                        if (width>0) width--;
                        /* possible sign on the exponent */
                        if (width!=0 && (nch=='+' || nch=='-')) {
                            negexp = (nch=='-');
                             nch = _GETC_(file);
-                           if (width>0) width--;
+                            if (width>0) width--;
                        }
                        /* exponent digits */
                        while (width!=0 && (nch!=_EOF_) && _ISDIGIT_(nch)) {
                            exponent *= 10;
                            exponent += (nch - '0');
                             nch = _GETC_(file);
-                           if (width>0) width--;
+                            if (width>0) width--;
                         }
                        /* update 'cur' with this exponent. */
-                       expcnt =  negexp ? .1 : 10;
+                       expcnt = 10;
+                       shift = 1.0;
                        while (exponent!=0) {
                            if (exponent&1)
-                               cur*=expcnt;
+                               shift *= expcnt;
                            exponent/=2;
                            expcnt=expcnt*expcnt;
                        }
+                       cur = (negexp ? cur / shift : cur * shift);
                    }
                     st = 1;
                     if (!suppress) {
                        if (L_prefix) _SET_NUMBER_(long double);
-                       else if (l_prefix) _SET_NUMBER_(double);
-                       else _SET_NUMBER_(float);
-                   }
+                        else if (l_prefix) _SET_NUMBER_(double);
+                        else _SET_NUMBER_(float);
+                    }
                 }
                 break;
                /* According to msdn,
@@ -486,9 +498,9 @@ _FUNCTION_ {
                     /* terminate */
                     if (!suppress) *sptr = 0;
 #ifdef _LIBCNT_
-            RtlFreeHeap(RtlGetProcessHeap(), 0, Mask);
+                    RtlFreeHeap(RtlGetProcessHeap(), 0, Mask);
 #else
-            HeapFree(GetProcessHeap(), 0, Mask);
+                    HeapFree(GetProcessHeap(), 0, Mask);
 #endif
                 }
                 break;
@@ -525,6 +537,7 @@ _FUNCTION_ {
     if (nch!=_EOF_) {
        _UNGETC_(nch, file);
     }
+
     TRACE("returning %d\n", rd);
     return rd;
 }