Index: branches/libc-0.6/src/emx/ChangeLog.LIBC
===================================================================
--- branches/libc-0.6/src/emx/ChangeLog.LIBC	(revision 2790)
+++ branches/libc-0.6/src/emx/ChangeLog.LIBC	(revision 2792)
@@ -5,4 +5,6 @@
 2006-08-27: knut st. osmundsen <bird-gccos2-spam@anduin.net>
     - libc:
+        o Implemented the new length modifiers for *scanf. Adjusted the length
+          modifier implementation for *printf. Fixes #76.
         o Fixed problems with fork() and module loading/unloading. Fixes #76.
         o Fixed atexit() and on_exit() problem with callbacks in unloaded DLLs. Fixes #103.
Index: branches/libc-0.6/src/emx/src/lib/io/_input.c
===================================================================
--- branches/libc-0.6/src/emx/src/lib/io/_input.c	(revision 2790)
+++ branches/libc-0.6/src/emx/src/lib/io/_input.c	(revision 2792)
@@ -4,4 +4,5 @@
 #include <stdio.h>
 #include <stdlib.h>
+#include <stdint.h>
 #include <stdarg.h>
 #include <string.h>
@@ -16,4 +17,8 @@
 #define TRUE    1
 
+#define SIZE_HH         (('h' << 8) | 'h')
+#define SIZE_LL         (('l' << 8) | 'l')
+
+
 /* This structure holds the local variables of _input() which are
    passed to the functions called by _input(). */
@@ -28,5 +33,5 @@
   int collected;                /* Number of characters collected */
   size_t more_size;             /* Size of the above */
-  char size;                    /* Size (0, 'h', 'l' or 'L') */
+  int size;                     /* Size (0, 'h', SIZE_HH, 'l', SIZE_LL, 'L', 'j', 'z', 'Z', 't' or 'q') */
   char width_given;             /* A field width has been given */
   unsigned char ungetc_count;   /* stream's _ungetc_count prior to get0() */
@@ -192,4 +197,32 @@
 
 
+static void inp_wchar (ilocal *v, wchar_t *dst)
+{
+/** @todo implement sscanf(, "%lc", pwsz). */
+  int c, ok;
+//  mbstate_t mbs;
+
+  if (v->status == END_OF_FILE)
+    {
+      v->status = INPUT_FAILURE;
+      return;
+    }
+  if (!v->width_given)
+    v->width = 1;
+  ok = FALSE;
+//  mbsinit(&mbs);
+  while ((c = get (v)) != EOF)
+    {
+      ok = TRUE;
+      if (dst != NULL)
+        *dst++ = (unsigned char)c;
+    }
+  if (!ok)
+    v->status = INPUT_FAILURE;
+  else if (dst != NULL)
+    ++v->count;
+}
+
+
 static void inp_str (ilocal *v, unsigned char *dst)
 {
@@ -197,5 +230,6 @@
 
   c = skip (v);
-  if (v->status != OK) return;
+  if (v->status != OK)
+    return;
   while (c != EOF && !isspace (c))
     {
@@ -211,4 +245,31 @@
   make_unread (v, c);
 }
+
+
+static void inp_wstr (ilocal *v, wchar_t *dst)
+{
+  int c;
+/** @todo implement sscanf(, "%ls", pwsz). */
+//  mbstate_t mbs;
+
+  c = skip (v);
+  if (v->status != OK)
+    return;
+
+//  mbsinit(&mbs);
+  while (c != EOF && !isspace (c))
+    {
+      if (dst != NULL)
+        *dst++ = (unsigned char)c;
+      c = get (v);
+    }
+  if (dst != NULL)
+    {
+      *dst = 0;
+      ++v->count;
+    }
+  make_unread (v, c);
+}
+
 
 
@@ -372,9 +433,27 @@
       switch (v->size)
         {
-        case 'L':
-          *(long long *)dst = n;
-          break;
         case 'h':
           *(short *)dst = n;
+          break;
+        case SIZE_HH:
+          *(signed char *)dst = n;
+          break;
+        case 'l':
+          *(long *)dst = n;
+          break;
+        case SIZE_LL:
+        case 'L':                       /* GNU */
+        case 'q':                       /* bsd */
+          *(long long *)dst = n;
+          break;
+        case 'j':
+          *(intmax_t *)dst = n;
+          break;
+        case 'z':
+        case 'Z':
+          *(size_t *)dst = n;
+          break;
+        case 't':
+          *(ptrdiff_t *)dst = n;
           break;
         default:
@@ -659,15 +738,21 @@
                 v->width_given = TRUE;
             }
-          if (*format == 'h' || *format == 'l' || *format == 'L')
-            v->size = *format++;
+          if (   *format == 'h' || *format == 'l' || *format == 'L'
+              || *format == 'j' || *format == 'z' || *format == 't'
+              || *format == 'q' || *format == 'Z' )
+            {
+              v->size = *format++;
+              if (v->size == 'l' && *format == 'l')
+                {
+                  v->size = SIZE_LL; ++format;
+                }
+              else if (v->size == 'h' && *format == 'h')
+                {
+                  v->size = SIZE_HH; ++format;
+                }
+            }
           f = *format;
           switch (f)
             {
-            case 'c':
-              if (assign)
-                dst = va_arg (arg_ptr, char *);
-              inp_char (v, dst);
-              break;
-
             case '[':
               if (assign)
@@ -676,9 +761,33 @@
               break;
 
+            case 'c':
+              if (v->size != 'l' && v->size != 'L')
+                {
+                  if (assign)
+                    dst = va_arg (arg_ptr, char *);
+                  inp_char (v, dst);
+                  break;
+                }
+              /* fall thru */
+            case 'C':
+              if (assign)
+                dst = va_arg (arg_ptr, wchar_t *);
+              inp_wchar (v, dst);
+              break;
+
             case 's':
-              if (assign)
-                dst = va_arg (arg_ptr, char *);
-              inp_str (v, dst);
-              break;
+              if (v->size != 'l' && v->size == 'L')
+                {
+                  if (assign)
+                    dst = va_arg (arg_ptr, char *);
+                  inp_str (v, dst);
+                  break;
+                }
+              /* fall thru */
+            case 'S':
+                if (assign)
+                  dst = va_arg (arg_ptr, wchar_t *);
+                inp_wstr (v, dst);
+                break;
 
             case 'f':
@@ -713,9 +822,27 @@
                 switch (v->size)
                   {
-                  case 'L':
-                    dst = va_arg (arg_ptr, long long *);
+                  case SIZE_HH:
+                    dst = va_arg (arg_ptr, char *);
                     break;
                   case 'h':
                     dst = va_arg (arg_ptr, short *);
+                    break;
+                  case 'l':
+                    dst = va_arg (arg_ptr, long *);
+                    break;
+                  case SIZE_LL:
+                  case 'L':
+                  case 'q':
+                    dst = va_arg (arg_ptr, long long *);
+                    break;
+                  case 'j':
+                    dst = va_arg (arg_ptr, uintmax_t *);
+                    break;
+                  case 'z':
+                  case 'Z':
+                    dst = va_arg (arg_ptr, size_t *);
+                    break;
+                  case 't':
+                    dst = va_arg (arg_ptr, ptrdiff_t *);
                     break;
                   default:
@@ -730,9 +857,24 @@
                 switch (v->size)
                   {
-                  case 'L':
-                    *(va_arg (arg_ptr, long long *)) = v->chars;
+                  case SIZE_HH:
+                    *(va_arg (arg_ptr, signed char *)) = v->chars;
                     break;
                   case 'h':
                     *(va_arg (arg_ptr, short *)) = v->chars;
+                    break;
+                  case 'l':
+                    *(va_arg (arg_ptr, long *)) = v->chars;
+                    break;
+                  case SIZE_LL:
+                  case 'L':
+                  case 'q':
+                    *(va_arg (arg_ptr, long long *)) = v->chars;
+                    break;
+                  case 'z':
+                  case 'Z':
+                    *(va_arg (arg_ptr, size_t *)) = v->chars;
+                    break;
+                  case 't':
+                    *(va_arg (arg_ptr, ptrdiff_t *)) = v->chars;
                     break;
                   default:
Index: branches/libc-0.6/src/emx/src/lib/io/_output.c
===================================================================
--- branches/libc-0.6/src/emx/src/lib/io/_output.c	(revision 2790)
+++ branches/libc-0.6/src/emx/src/lib/io/_output.c	(revision 2792)
@@ -5,4 +5,5 @@
 #include <stdlib.h>
 #include <stdarg.h>
+#include <stdint.h>
 #include <string.h>
 #include <math.h>
@@ -21,4 +22,52 @@
 #define SIZE_HH         (('h' << 8) | 'h')
 #define SIZE_LL         (('l' << 8) | 'l')
+
+/* ASSUMES that there are no odd integer sizes (like char being 7 bit or similar weirdnesses). */
+
+#define IS_SIZE_64BIT(size) (   (sizeof(long long) == sizeof(uint64_t) && ((size) == 'L' || (size) == SIZE_LL || (size) == 'q')) \
+                             || (sizeof(size_t)    == sizeof(uint64_t) && ((size) == 'z' || (size) == 'z')) \
+                             || (sizeof(uintmax_t) == sizeof(uint64_t) && (size) == 'j') \
+                             || (sizeof(ptrdiff_t) == sizeof(uint64_t) && (size) == 't') \
+                             || (sizeof(int)       == sizeof(uint64_t) && (size) == 0) \
+                             || (sizeof(short)     == sizeof(uint64_t) && (size) == 'h') \
+                             || (sizeof(char)      == sizeof(uint64_t) && (size) == SIZE_HH) \
+                            )
+
+#define IS_SIZE_32BIT(size) (   (sizeof(long long) == sizeof(uint32_t) && ((size) == 'L' || (size) == SIZE_LL || (size) == 'q')) \
+                             || (sizeof(size_t)    == sizeof(uint32_t) && ((size) == 'z' || (size) == 'z')) \
+                             || (sizeof(uintmax_t) == sizeof(uint32_t) && (size) == 'j') \
+                             || (sizeof(ptrdiff_t) == sizeof(uint32_t) && (size) == 't') \
+                             || (sizeof(int)       == sizeof(uint32_t) && (size) == 0) \
+                             || (sizeof(short)     == sizeof(uint32_t) && (size) == 'h') \
+                             || (sizeof(char)      == sizeof(uint32_t) && (size) == SIZE_HH) \
+                            )
+
+#define IS_SIZE_LE_32BIT(size) (   (sizeof(long long) <= sizeof(uint32_t) && ((size) == 'L' || (size) == SIZE_LL || (size) == 'q')) \
+                                || (sizeof(size_t)    <= sizeof(uint32_t) && ((size) == 'z' || (size) == 'z')) \
+                                || (sizeof(uintmax_t) <= sizeof(uint32_t) && (size) == 'j') \
+                                || (sizeof(ptrdiff_t) <= sizeof(uint32_t) && (size) == 't') \
+                                || (sizeof(int)       <= sizeof(uint32_t) && (size) == 0) \
+                                || (sizeof(short)     <= sizeof(uint32_t) && (size) == 'h') \
+                                || (sizeof(char)      <= sizeof(uint32_t) && (size) == SIZE_HH) \
+                               )
+
+#define IS_SIZE_16BIT(size) (   (sizeof(long long) == sizeof(uint16_t) && ((size) == 'L' || (size) == SIZE_LL || (size) == 'q')) \
+                             || (sizeof(size_t)    == sizeof(uint16_t) && ((size) == 'z' || (size) == 'z')) \
+                             || (sizeof(uintmax_t) == sizeof(uint16_t) && (size) == 'j') \
+                             || (sizeof(ptrdiff_t) == sizeof(uint16_t) && (size) == 't') \
+                             || (sizeof(int)       == sizeof(uint16_t) && (size) == 0) \
+                             || (sizeof(short)     == sizeof(uint16_t) && (size) == 'h') \
+                             || (sizeof(char)      == sizeof(uint16_t) && (size) == SIZE_HH) \
+                            )
+
+#define IS_SIZE_8BIT(size)  (   (sizeof(long long) == sizeof(uint8_t) && ((size) == 'L' || (size) == SIZE_LL || (size) == 'q')) \
+                             || (sizeof(size_t)    == sizeof(uint8_t) && ((size) == 'z' || (size) == 'z')) \
+                             || (sizeof(uintmax_t) == sizeof(uint8_t) && (size) == 'j') \
+                             || (sizeof(ptrdiff_t) == sizeof(uint8_t) && (size) == 't') \
+                             || (sizeof(int)       == sizeof(uint8_t) && (size) == 0) \
+                             || (sizeof(short)     == sizeof(uint8_t) && (size) == 'h') \
+                             || (sizeof(char)      == sizeof(uint8_t) && (size) == SIZE_HH) \
+                            )
+
 
 #define DEFAULT_PREC    6
@@ -369,5 +418,5 @@
 
 
-static int cvt_hex_32 (olocal *v, unsigned n, char x)
+static int cvt_hex_32 (olocal *v, uint32_t n, char x)
 {
   char buf[9];
@@ -378,5 +427,5 @@
 
 
-static int cvt_hex_64 (olocal *v, unsigned long long n, char x)
+static int cvt_hex_64 (olocal *v, uint64_t n, char x)
 {
   char buf[17];
@@ -401,5 +450,5 @@
 
 
-static int cvt_oct_32 (olocal *v, unsigned n)
+static int cvt_oct_32 (olocal *v, uint32_t n)
 {
   char buf[12];
@@ -410,5 +459,5 @@
 
 
-static int cvt_oct_64 (olocal *v, unsigned long long n)
+static int cvt_oct_64 (olocal *v, uint64_t n)
 {
   char buf[23];
@@ -419,5 +468,5 @@
 
 
-static int cvt_dec_32 (olocal *v, unsigned n, int is_signed, int is_neg)
+static int cvt_dec_32 (olocal *v, uint32_t n, int is_signed, int is_neg)
 {
   char buf[11];
@@ -428,6 +477,5 @@
 
 
-static int cvt_dec_64 (olocal *v, unsigned long long n, int is_signed,
-                       int is_neg)
+static int cvt_dec_64 (olocal *v, uint64_t n, int is_signed, int is_neg)
 {
   char buf[21];
@@ -905,8 +953,4 @@
                 size = SIZE_HH; ++format;
               }
-            else if (size == 'q' || size == 'j')
-                size = SIZE_LL;
-            else if (size == 'z' || size == 'Z' || size == 't')
-                size = 'l';
           }
 
@@ -919,22 +963,22 @@
 
           case 'n':
-            if (size == SIZE_LL || size == 'L')
-              {
-                long long *ptr = va_arg (arg_ptr, long long *);
+            if (IS_SIZE_64BIT(size))
+              {
+                int64_t *ptr = va_arg (arg_ptr, int64_t *);
                 *ptr = v.count;
               }
-            else if (size == 'h')
-              {
-                short *ptr = va_arg (arg_ptr, short *);
+            else if (IS_SIZE_16BIT(size))
+              {
+                int16_t *ptr = va_arg (arg_ptr, int16_t *);
                 *ptr = v.count;
               }
-            else if (size == SIZE_HH)
-              {
-                char *ptr = va_arg (arg_ptr, char *);
+            else if (IS_SIZE_8BIT(size))
+              {
+                int8_t *ptr = va_arg (arg_ptr, int8_t *);
                 *ptr = v.count;
               }
-            else
-              {
-                int *ptr = va_arg (arg_ptr, int *);
+            else /* 32-bit */
+              {
+                int32_t *ptr = va_arg (arg_ptr, int32_t *);
                 *ptr = v.count;
               }
@@ -975,7 +1019,7 @@
           case 'd':
           case 'i':
-            if (size == SIZE_LL || size == 'L')
-              {
-                long long n = va_arg (arg_ptr, long long);
+            if (IS_SIZE_64BIT(size))
+              {
+                int64_t n = va_arg (arg_ptr, int64_t);
                 if (n < 0)
                   CHECK (cvt_dec_64 (&v, -n, TRUE, TRUE));
@@ -985,5 +1029,5 @@
             else
               {
-                int n = va_arg (arg_ptr, int);
+                int32_t n = va_arg (arg_ptr, int32_t);
                 if (size == 'h')
                   n = (short)n;
@@ -998,10 +1042,9 @@
 
           case 'u':
-            if (size == SIZE_LL || size == 'L')
-              CHECK (cvt_dec_64 (&v, va_arg (arg_ptr, unsigned long long),
-                                 FALSE, FALSE));
+            if (IS_SIZE_64BIT (size))
+              CHECK (cvt_dec_64 (&v, va_arg (arg_ptr, uint64_t), FALSE, FALSE));
             else
               {
-                unsigned n = va_arg (arg_ptr, unsigned);
+                uint32_t n = va_arg (arg_ptr, uint32_t);
                 if (size == 'h')
                   n = (unsigned short)n;
@@ -1014,15 +1057,18 @@
           case 'p':
             v.hash = TRUE;
-            CHECK (cvt_hex_32 (&v, va_arg (arg_ptr, unsigned), 'x'));
+            if (sizeof(uintptr_t) == sizeof(uint64_t))
+                CHECK (cvt_hex_64 (&v, va_arg (arg_ptr, uintptr_t), 'x'));
+            else
+                CHECK (cvt_hex_32 (&v, va_arg (arg_ptr, uintptr_t), 'x'));
             break;
 
           case 'x':
           case 'X':
-            if (size == SIZE_LL || size == 'L')
-              CHECK (cvt_hex_64 (&v, va_arg (arg_ptr, unsigned long long),
+            if (IS_SIZE_64BIT (size))
+              CHECK (cvt_hex_64 (&v, va_arg (arg_ptr, uint64_t),
                                  *format));
             else
               {
-                unsigned n = va_arg (arg_ptr, unsigned);
+                uint32_t n = va_arg (arg_ptr, uint32_t);
                 if (size == 'h')
                   n = (unsigned short)n;
@@ -1034,9 +1080,9 @@
 
           case 'o':
-            if (size == SIZE_LL || size == 'L')
-              CHECK (cvt_oct_64 (&v, va_arg (arg_ptr, unsigned long long)));
+            if (IS_SIZE_64BIT (size))
+              CHECK (cvt_oct_64 (&v, va_arg (arg_ptr, uint64_t)));
             else
               {
-                unsigned n = va_arg (arg_ptr, unsigned);
+                uint32_t n = va_arg (arg_ptr, uint32_t);
                 if (size == 'h')
                   n = (unsigned short)n;
