Index: trunk/src/emx/ChangeLog.LIBC
===================================================================
--- trunk/src/emx/ChangeLog.LIBC	(revision 2160)
+++ trunk/src/emx/ChangeLog.LIBC	(revision 2161)
@@ -9,4 +9,6 @@
         o Added %m (GLIBC extension) to the printf familiy. %m means
           priting strerror(errno), it takes no arguments.
+        o Fixed serveral bugs in the C/POSIX locale
+        o Implemented the LC_MESSAGES locale.
 
 2005-07-01: knut st. osmundsen <bird-gccos2-spam@anduin.net>
Index: trunk/src/emx/src/lib/locale/locale_lconv.c
===================================================================
--- trunk/src/emx/src/lib/locale/locale_lconv.c	(revision 2160)
+++ trunk/src/emx/src/lib/locale/locale_lconv.c	(revision 2161)
@@ -42,5 +42,5 @@
         "",                             //*mon_grouping;          /** monetary size of grouping */
         "",                             //*positive_sign;         /** non-negative values sign */
-        "-",                            //*negative_sign;         /** negative values sign */
+        "" ,                            //*negative_sign;         /** negative values sign */
         CHAR_MAX,                       //int_frac_digits;        /** number of fractional digits - int currency */
         CHAR_MAX,                       //frac_digits;            /** number of fractional digits - local currency */
@@ -63,2 +63,38 @@
 };
 
+
+/* Locale information structure for the 'C'/'POSIX' locale. */
+const __LIBC_LOCALELCONV       __libc_gLocaleLconvDefault =
+{
+    .s =
+    {
+        ".",                            //*decimal_point;         /** non-monetary decimal point */
+        "",                             //*thousands_sep;         /** non-monetary thousands separator */
+        "",                             //*grouping;              /** non-monetary size of grouping */
+        "",                             //*int_curr_symbol;       /** international currency symbol and separator */
+        "",                             //*currency_symbol;       /** local currency symbol */
+        "",                             //*mon_decimal_point;     /** monetary decimal point */
+        "",                             //*mon_thousands_sep;     /** monetary thousands separator */
+        "",                             //*mon_grouping;          /** monetary size of grouping */
+        "",                             //*positive_sign;         /** non-negative values sign */
+        "" ,                            //*negative_sign;         /** negative values sign */
+        CHAR_MAX,                       //int_frac_digits;        /** number of fractional digits - int currency */
+        CHAR_MAX,                       //frac_digits;            /** number of fractional digits - local currency */
+        CHAR_MAX,                       //p_cs_precedes;          /** (non-neg curr sym) 1-precedes, 0-succeeds */
+        CHAR_MAX,                       //p_sep_by_space;         /** (non-neg curr sym) 1-space, 0-no space */
+        CHAR_MAX,                       //n_cs_precedes;          /** (neg curr sym) 1-precedes, 0-succeeds */
+        CHAR_MAX,                       //n_sep_by_space;         /** (neg curr sym) 1-space, 0-no space */
+        CHAR_MAX,                       //p_sign_posn;            /** positioning of non-negative monetary sign */
+        CHAR_MAX,                       //n_sign_posn;            /** positioning of negative monetary sign */
+        CHAR_MAX,                       //int_p_cs_precedes;
+        CHAR_MAX,                       //int_p_sep_by_space;
+        CHAR_MAX,                       //int_n_cs_precedes;
+        CHAR_MAX,                       //int_n_sep_by_space;
+        CHAR_MAX,                       //int_p_sign_posn;
+        CHAR_MAX                        //int_n_sign_posn;
+    },
+
+    .fNumericConsts = 1,
+    .fMonetaryConsts = 1
+};
+
Index: trunk/src/emx/src/lib/locale/locale_msg.c
===================================================================
--- trunk/src/emx/src/lib/locale/locale_msg.c	(revision 2161)
+++ trunk/src/emx/src/lib/locale/locale_msg.c	(revision 2161)
@@ -0,0 +1,47 @@
+/* $Id$ */
+/** @file
+ *
+ * LIBC Locale - LC_MESSAGE data.
+ *
+ * Copyright (c) 2005 knut st. osmundsen <bird@anduin.net>
+ *
+ *
+ * This file is part of InnoTek LIBC.
+ *
+ * InnoTek LIBC is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * InnoTek LIBC is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with InnoTek LIBC; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#include <InnoTekLIBC/locale.h>
+
+/** Message locale information. */
+__LIBC_LOCALEMSG            __libc_gLocaleMsg =
+{
+    .pszYesExpr = "^[yY]",
+    .pszNoExpr = "^[nN]",
+    .pszYesStr = "",
+    .pszNoStr = "",
+    .fConsts = 1
+};
+
+/** Message locale information for the 'C'/'POSIX' locale. */
+const __LIBC_LOCALEMSG      __libc_gLocaleMsgDefault =
+{
+    .pszYesExpr = "^[yY]",
+    .pszNoExpr = "^[nN]",
+    .pszYesStr = "",
+    .pszNoStr = "",
+    .fConsts = 1
+};
Index: trunk/src/emx/src/lib/locale/locale_time.c
===================================================================
--- trunk/src/emx/src/lib/locale/locale_time.c	(revision 2160)
+++ trunk/src/emx/src/lib/locale/locale_time.c	(revision 2161)
@@ -34,10 +34,44 @@
   .swdays =  { "Sun",   "Mon",   "Tue",    "Wed",      "Thu",     "Fri",   "Sat" },
   .lwdays =  { "Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday" },
-  .date_time_fmt = "%a %b %d %H:%M:%S %Y",
+  .date_time_fmt = "%a %b %e %H:%M:%S %Y",
   .date_fmt = "%m/%d/%y",
   .time_fmt = "%H:%M:%S",
   .am =       "AM",
   .pm =       "PM",
+  .ampm_fmt = "%I:%M:%S %p",
+  .era =      "",
+  .era_date_fmt = "",
+  .era_date_time_fmt = "",
+  .era_time_fmt = "",
+  .alt_digits = "",
+  .datesep =  "/", //?
+  .timesep =  ":", //?
+  .listsep =  "",  //??????
   .fConsts = 1
 };
 
+
+/** Date / time formatting rules for the C/POSIX locale. */
+const __LIBC_LOCALETIME __libc_gLocaleTimeDefault =
+{
+  .smonths = { "Jan",    "Feb",     "Mar",  "Apr",  "May","Jun", "Jul", "Aug",   "Sep",      "Oct",    "Nov",     "Dec"},
+  .lmonths = { "January","February","March","April","May","June","July","August","September","October","November","December" },
+  .swdays =  { "Sun",   "Mon",   "Tue",    "Wed",      "Thu",     "Fri",   "Sat" },
+  .lwdays =  { "Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday" },
+  .date_time_fmt = "%a %b %e %H:%M:%S %Y",
+  .date_fmt = "%m/%d/%y",
+  .time_fmt = "%H:%M:%S",
+  .am =       "AM",
+  .pm =       "PM",
+  .ampm_fmt = "%I:%M:%S %p",
+  .era =      "",
+  .era_date_fmt = "",
+  .era_date_time_fmt = "",
+  .era_time_fmt = "",
+  .alt_digits = "",
+  .datesep =  "/", //?
+  .timesep =  ":", //?
+  .listsep =  "",  //??????
+  .fConsts = 1
+};
+
Index: trunk/src/emx/src/lib/locale/nl_langinfo.c
===================================================================
--- trunk/src/emx/src/lib/locale/nl_langinfo.c	(revision 2160)
+++ trunk/src/emx/src/lib/locale/nl_langinfo.c	(revision 2161)
@@ -101,7 +101,7 @@
 
         case YESSTR:
-            return ""; ///@todo LC_MESSAGE
+            return __libc_gLocaleMsg.pszYesStr;
         case NOSTR:
-            return ""; ///@todo LC_MESSAGE
+            return __libc_gLocaleMsg.pszNoStr;
 
         case CRNCYSTR:
@@ -130,7 +130,7 @@
 
         case YESEXPR:
-            return ""; ///@todo LC_MESSAGE
+            return __libc_gLocaleMsg.pszYesExpr;
         case NOEXPR:
-            return ""; ///@todo LC_MESSAGE
+            return __libc_gLocaleMsg.pszNoExpr;
 
         case DATESEP:
Index: trunk/src/emx/src/lib/locale/setlocale.c
===================================================================
--- trunk/src/emx/src/lib/locale/setlocale.c	(revision 2160)
+++ trunk/src/emx/src/lib/locale/setlocale.c	(revision 2161)
@@ -135,4 +135,6 @@
     /** Numeric and monetary data. */
     __LIBC_LOCALELCONV          Lconv;
+    /** Messages data. */
+    __LIBC_LOCALEMSG            Msg;
 };
 
@@ -228,5 +230,5 @@
 static int query_item(LocaleObject lobj, UconvObject uobj, LocaleItem iItem, char **ppszOut);
 static int query_array(LocaleObject lobj, UconvObject uobj, int cElements, LocaleItem iFirst, char **papszOut);
-static int localeTimeDo(__LIBC_PLOCALETIME pTime, UconvObject uobj, LocaleObject lobj);
+static int localeTimeDo(__LIBC_PLOCALETIME pTime, UconvObject uobj, LocaleObject lobj, const char *pszLocale);
 static void localeTimeFree(__LIBC_PLOCALETIME pTime);
 static void localeNumericFree(__LIBC_PLOCALELCONV pLconv);
@@ -514,5 +516,5 @@
 
     /*
-     * For "C" / "POSIX" we can just use the static default locale.
+     * For "C" / "POSIX" we can simply use the static default locale.
      */
     if (    IS_C_LOCALE(pszLocale)
@@ -766,9 +768,10 @@
  * @returns 0 on success.
  * @returns negated errno on failure.
- * @param   pTime   The time structure to operate on.
- * @param   uobj    The UconvObject to use.
- * @param   lobj    The LocaleObject to use.
- */
-static int localeTimeDo(__LIBC_PLOCALETIME pTime, UconvObject uobj, LocaleObject lobj)
+ * @param   pTime       The time structure to operate on.
+ * @param   uobj        The UconvObject to use.
+ * @param   lobj        The LocaleObject to use.
+ * @param   pszLocale   Pointer to the locale base specifier.
+ */
+static int localeTimeDo(__LIBC_PLOCALETIME pTime, UconvObject uobj, LocaleObject lobj, const char *pszLocale)
 {
     int         rc;
@@ -776,4 +779,14 @@
     /* free old stuff. */
     localeTimeFree(pTime);
+
+    /*
+     * For "C" / "POSIX" we can simply use the static default locale.
+     */
+    if (    IS_C_LOCALE(pszLocale)
+        ||  IS_POSIX_LOCALE(pszLocale))
+    {
+        memcpy(pTime, &__libc_gLocaleTimeDefault, sizeof(*pTime));
+        return 0;
+    }
 
     /* query the items. */
@@ -899,31 +912,33 @@
 {
     int     rc;
+
     /* free any old stuff. */
     localeNumericFree(pLconv);
 
-    if (    !IS_C_LOCALE(pszLocale)
-        &&  !IS_POSIX_LOCALE(pszLocale))
-    {
-        /*
-         * Convert the stuff.
-         */
+    /*
+     * For "C" / "POSIX" we can simply use the static default locale.
+     */
+    if (    IS_C_LOCALE(pszLocale)
+        ||  IS_POSIX_LOCALE(pszLocale))
+    {
+#define COPY(m) do { pLconv->m = __libc_gLocaleLconvDefault.m; } while (0)
+	pLconv->fNumericConsts        = 1;
+        COPY(s.decimal_point);
+        COPY(s.thousands_sep);
+        COPY(s.grouping);
+#undef COPY
+        return 0;
+    }
+
+    /*
+     * Convert the stuff.
+     */
 #define CONVERT_UCS(field) \
     do  { rc = convert_ucs(uobj, pULconv->field, &pLconv->s.field); if (rc) return rc; } while (0)
-        CONVERT_UCS(decimal_point);
-        CONVERT_UCS(thousands_sep);
+    CONVERT_UCS(decimal_point);
+    CONVERT_UCS(thousands_sep);
 #undef CONVERT_UCS
 
-        return localeConvertGrouping(pULconv->grouping, &pLconv->s.grouping);
-    }
-    else
-    {
-	/* the C/POSIX locale */
-        LIBCLOG_MSG2("POSIX '%s'\n", pszLocale);
-	pLconv->fNumericConsts        = 1;
-        pLconv->s.decimal_point       = ".";
-        pLconv->s.thousands_sep       = ",";
-        pLconv->s.grouping            = "";
-	return 0;
-    }
+    return localeConvertGrouping(pULconv->grouping, &pLconv->s.grouping);
 }
 
@@ -943,84 +958,151 @@
 {
     int rc;
+
     /* free any old stuff. */
     localeMonetaryFree(pLconv);
 
-    if (    !IS_C_LOCALE(pszLocale)
-        &&  !IS_POSIX_LOCALE(pszLocale))
-    {
-        /*
-         * Convert the stuff.
-         */
+    /*
+     * For "C" / "POSIX" we can simply use the static default locale.
+     */
+    if (    IS_C_LOCALE(pszLocale)
+        ||  IS_POSIX_LOCALE(pszLocale))
+    {
+#define COPY(m) do { pLconv->m = __libc_gLocaleLconvDefault.m; } while (0)
+        COPY(s.int_curr_symbol);
+        COPY(s.currency_symbol);
+        COPY(s.mon_decimal_point);
+        COPY(s.mon_thousands_sep);
+        COPY(s.positive_sign);
+        COPY(s.negative_sign);
+        COPY(pszCrncyStr);
+        COPY(s.mon_grouping);
+        COPY(s.int_frac_digits);
+        COPY(s.frac_digits);
+        COPY(s.p_cs_precedes);
+        COPY(s.p_sep_by_space);
+        COPY(s.n_cs_precedes);
+        COPY(s.n_sep_by_space);
+        COPY(s.p_sign_posn);
+        COPY(s.n_sign_posn);
+        COPY(s.int_p_cs_precedes);
+        COPY(s.int_n_cs_precedes);
+        COPY(s.int_p_sep_by_space);
+        COPY(s.int_n_sep_by_space);
+        COPY(s.int_p_sign_posn);
+        COPY(s.int_n_sign_posn);
+        pLconv->fMonetaryConsts = 1;
+#undef COPY
+        return 0;
+    }
+    /*
+     * Convert the stuff.
+     */
+#define FIXMAX(val) \
+    ( (val) != 0xff ? (val) : CHAR_MAX ) /* (assumes CHAR_MAX == 0x7f) */
 #define CONVERT_UCS(field) \
     do  { rc = convert_ucs(uobj, pULconv->field, &pLconv->s.field); if (rc) return rc; } while (0)
 
-	if (pszModifier && IS_EURO(pszModifier))
-	{
-            /** @todo check for specs on a standard EURO grouping and stuff. */
-            pLconv->s.currency_symbol = strdup("EUR");
-            pLconv->s.int_curr_symbol = strdup("EUR");
-	}
-	else
-	{
-            CONVERT_UCS(int_curr_symbol);
-            CONVERT_UCS(currency_symbol);
-	}
-        CONVERT_UCS(mon_decimal_point);
-        CONVERT_UCS(mon_thousands_sep);
-        CONVERT_UCS(positive_sign);
-        CONVERT_UCS(negative_sign);
-        pLconv->s.int_frac_digits   = pULconv->int_frac_digits;
-        pLconv->s.frac_digits       = pULconv->frac_digits;
-        pLconv->s.p_cs_precedes     = pULconv->p_cs_precedes;
-        pLconv->s.p_sep_by_space    = pULconv->p_sep_by_space;
-        pLconv->s.n_cs_precedes     = pULconv->n_cs_precedes;
-        pLconv->s.n_sep_by_space    = pULconv->n_sep_by_space;
-        pLconv->s.p_sign_posn       = pULconv->p_sign_posn;
-        pLconv->s.n_sign_posn       = pULconv->n_sign_posn;
-        /* we fake the international variants here. */
-        pLconv->s.int_p_cs_precedes = pULconv->p_cs_precedes;
-        pLconv->s.int_n_cs_precedes = pULconv->n_cs_precedes;
-        pLconv->s.int_p_sep_by_space= pULconv->p_sep_by_space;
-        pLconv->s.int_n_sep_by_space= pULconv->n_sep_by_space;
-        pLconv->s.int_p_sign_posn   = pULconv->p_sign_posn;
-        pLconv->s.int_n_sign_posn   = pULconv->n_sign_posn;
-
+    if (pszModifier && IS_EURO(pszModifier))
+    {
+        /** @todo check for specs on a standard EURO grouping and stuff. */
+        pLconv->s.currency_symbol = strdup("EUR");
+        pLconv->s.int_curr_symbol = strdup("EUR");
+    }
+    else
+    {
+        CONVERT_UCS(int_curr_symbol);
+        CONVERT_UCS(currency_symbol);
+    }
+    CONVERT_UCS(mon_decimal_point);
+    CONVERT_UCS(mon_thousands_sep);
+    CONVERT_UCS(positive_sign);
+    CONVERT_UCS(negative_sign);
+
+    pLconv->s.int_frac_digits   = FIXMAX(pULconv->int_frac_digits);
+    pLconv->s.frac_digits       = FIXMAX(pULconv->frac_digits);
+    pLconv->s.p_cs_precedes     = FIXMAX(pULconv->p_cs_precedes);
+    pLconv->s.p_sep_by_space    = FIXMAX(pULconv->p_sep_by_space);
+    pLconv->s.n_cs_precedes     = FIXMAX(pULconv->n_cs_precedes);
+    pLconv->s.n_sep_by_space    = FIXMAX(pULconv->n_sep_by_space);
+    pLconv->s.p_sign_posn       = FIXMAX(pULconv->p_sign_posn);
+    pLconv->s.n_sign_posn       = FIXMAX(pULconv->n_sign_posn);
+    /* we fake the international variants here. */
+    pLconv->s.int_p_cs_precedes = pLconv->s.p_cs_precedes;
+    pLconv->s.int_n_cs_precedes = pLconv->s.n_cs_precedes;
+    pLconv->s.int_p_sep_by_space= pLconv->s.p_sep_by_space;
+    pLconv->s.int_n_sep_by_space= pLconv->s.n_sep_by_space;
+    pLconv->s.int_p_sign_posn   = pLconv->s.p_sign_posn;
+    pLconv->s.int_n_sign_posn   = pLconv->s.n_sign_posn;
+
+#undef FIXMAX
 #undef CONVERT_UCS
 
-        /*
-         * Extra stuff (which I don't know which member corresponds to).
-         */
-        if ((rc = query_item(lobj, uobj, CRNCYSTR, &pLconv->pszCrncyStr)))
-            return rc;
-
-        return localeConvertGrouping(pULconv->mon_grouping, &pLconv->s.mon_grouping);
-    }
-    else
-    {
-        /*
-         * The C/POSIX locale.
-         */
-        pLconv->fMonetaryConsts = 1;
-        pLconv->s.int_curr_symbol = pLconv->s.currency_symbol = pLconv->s.mon_decimal_point
-            = pLconv->s.mon_thousands_sep = pLconv->s.positive_sign = pLconv->s.negative_sign
-            = pLconv->pszCrncyStr = pLconv->s.mon_grouping = "";
-        pLconv->s.int_frac_digits   = -1;
-        pLconv->s.frac_digits       = -1;
-        pLconv->s.p_cs_precedes     = -1;
-        pLconv->s.p_sep_by_space    = -1;
-        pLconv->s.n_cs_precedes     = -1;
-        pLconv->s.n_sep_by_space    = -1;
-        pLconv->s.p_sign_posn       = -1;
-        pLconv->s.n_sign_posn       = -1;
-        pLconv->s.int_p_cs_precedes = -1;
-        pLconv->s.int_n_cs_precedes = -1;
-        pLconv->s.int_p_sep_by_space= -1;
-        pLconv->s.int_n_sep_by_space= -1;
-        pLconv->s.int_p_sign_posn   = -1;
-        pLconv->s.int_n_sign_posn   = -1;
-
-	return 0;
-    }
-}
+    /*
+     * Extra stuff (which I don't know which member corresponds to).
+     */
+    if ((rc = query_item(lobj, uobj, CRNCYSTR, &pLconv->pszCrncyStr)))
+        return rc;
+
+    return localeConvertGrouping(pULconv->mon_grouping, &pLconv->s.mon_grouping);
+}
+
+/**
+ * Frees all heap strings in the monetary part of the lconv structure.
+ * @param   pLconv  What to work on.
+ */
+static void localeMessagesFree(__LIBC_PLOCALEMSG pMsg)
+{
+    if (!pMsg->fConsts)
+    {
+#define FREE(x) do { if (pMsg->x) free(pMsg->x); pMsg->x = NULL; } while (0)
+        FREE(pszYesExpr);
+        FREE(pszNoExpr);
+        FREE(pszYesStr);
+        FREE(pszNoStr);
+#undef FREE
+    }
+    pMsg->fConsts = 0;
+}
+
+
+/**
+ * Sets the LC_MESSAGES part of the locale.
+ *
+ * @returns 0 on success.
+ * @returns negated errno on failure.
+ * @param   pMsg        The messages locale info structure to operate on.
+ * @param   uobj        The UconvObject to use.
+ * @param   lobj        The LocaleObject to use.
+ * @param   pszLocale   Pointer to the locale base specifier.
+ */
+static int localeMessagesDo(__LIBC_PLOCALEMSG pMsg, UconvObject uobj, LocaleObject lobj, const char *pszLocale)
+{
+    int     rc;
+    /* free any old stuff. */
+    localeMessagesFree(pMsg);
+
+    /*
+     * For "C" / "POSIX" we can simply use the static default locale.
+     */
+    if (    IS_C_LOCALE(pszLocale)
+        ||  IS_POSIX_LOCALE(pszLocale))
+    {
+        memcpy(pMsg, &__libc_gLocaleMsgDefault, sizeof(*pMsg));
+        return 0;
+    }
+
+    /* query the items. */
+    if (    (rc = query_item(lobj, uobj,     YESEXPR,      &pMsg->pszYesExpr))
+        ||  (rc = query_item(lobj, uobj,     NOEXPR,       &pMsg->pszNoExpr))
+        ||  (rc = query_item(lobj, uobj,     YESSTR,       &pMsg->pszYesStr))
+        ||  (rc = query_item(lobj, uobj,     NOSTR,        &pMsg->pszNoStr))
+            )
+    {
+        return rc;
+    }
+
+    return 0;
+}
+
 
 /**
@@ -1037,4 +1119,5 @@
     }
 }
+
 
 /**
@@ -1303,5 +1386,5 @@
 
         case LC_TIME:
-            rc = localeTimeDo(&pTemp->Time, uobj, lobj);
+            rc = localeTimeDo(&pTemp->Time, uobj, lobj, pszLocale);
             break;
 
@@ -1331,5 +1414,7 @@
 
         case LC_MESSAGES:
-            /* Nothing to do for now */
+            rc = localeMessagesDo(&pTemp->Msg, uobj, lobj, pszLocale);
+            break;
+
         default:
             rc = 0;
@@ -1597,4 +1682,6 @@
     if (pTemp->afProcessed[LC_MESSAGES + 1])
     {
+        localeMessagesFree(&__libc_gLocaleMsg);
+        memcpy(&__libc_gLocaleMsg, &pTemp->Msg, sizeof(__libc_gLocaleMsg));
         pTemp->afProcessed[LC_MESSAGES + 1] = 0;
         gLocale.apszNames[LC_MESSAGES + 1] = pTemp->Global.apszNames[LC_MESSAGES + 1];
@@ -1672,4 +1759,6 @@
     if (pTemp->afProcessed[LC_MONETARY + 1])
         localeMonetaryFree(&pTemp->Lconv);
+    if (pTemp->afProcessed[LC_MESSAGES + 1])
+        localeMessagesFree(&pTemp->Msg);
     for (iCat = 0; iCat < _LC_LAST; iCat++)
         if (pTemp->afProcessed[iCat + 1])
