--- old/usr/src/test/libc-tests/tests/newlocale/newlocale_test.c	Mon Jul 14 17:48:01 2014
+++ new/usr/src/test/libc-tests/tests/newlocale/newlocale_test.c	Mon Jul 14 17:48:01 2014
@@ -29,9 +29,9 @@
 #include <err.h>
 #include <unistd.h>
 #include <pthread.h>
+#include <note.h>
+#include "test_common.h"
 
-int debug = 0;
-
 /*
  * Note that on some platforms, different symbols are used.  For example,
  * MacOS Mavericks uses "Eu" for Euro symbol, instead of €.  If the locale
@@ -53,47 +53,15 @@
 #define	NUMTHR	20
 #define	NUMITR	200
 
-static void
-test_start(const char *testName, const char *format, ...)
-{
-	va_list args;
+int extra_debug = 0;
 
-	(void) printf("TEST STARTING %s: ", testName);
-
-	va_start(args, format);
-	(void) vprintf(format, args);
-	va_end(args);
-	(void) fflush(stdout);
-}
-
-static void
-test_failed(const char *testName, const char *format, ...)
+void
+testlocale_thr_one(test_t t, void *arg)
 {
-	va_list args;
-
-	(void) printf("TEST FAILED %s: ", testName);
-
-	va_start(args, format);
-	(void) vprintf(format, args);
-	va_end(args);
-
-	(void) exit(-1);
-}
-
-static void
-test_passed(const char *testName)
-{
-	(void) printf("TEST PASS: %s\n", testName);
-	(void) fflush(stdout);
-}
-
-void *
-testlocale_thr(void *ptr)
-{
+	_NOTE(ARGUNUSED(arg));
 	locale_t	cloc, loc;
 	struct lconv	*lc;
 	char		*day;
-	char		*tname = ptr;
 
 	for (int i = 0; i < NUMITR; i++) {
 		struct ldata *l = &ldata[i % NUM_LDATA];
@@ -101,24 +69,24 @@
 
 		loc = newlocale(LC_ALL_MASK, l->locale, NULL);
 		if (loc == NULL) {
-			test_failed("newlocale %s failed", l->locale);
+			test_failed(t, "newlocale %s failed", l->locale);
 		}
 		day = nl_langinfo_l(DAY_1, loc);
 		if (strcmp(day, l->day1) != 0) {
-			test_failed(tname, "newlocale data mismatch (%s != %s)",
+			test_failed(t, "newlocale data mismatch (%s != %s)",
 			    day, l->day1);
 		}
-		if (debug)
-			(void) printf("DAY1: %s\n", day);
+		if (extra_debug)
+			test_debugf(t, "DAY1: %s", day);
 
 		day = nl_langinfo(DAY_1);
 		if (strcmp(day, "Sunday") != 0) {
-			test_failed(tname, "C locale day wrong %s != Sunday",
+			test_failed(t, "C locale day wrong %s != Sunday",
 			    day);
 		}
 		lc = localeconv();
 		if (strcmp(lc->currency_symbol, "") != 0) {
-			test_failed(tname, "C cursym mismatch (%s != %s)",
+			test_failed(t, "C cursym mismatch (%s != %s)",
 			    lc->currency_symbol, "");
 		}
 
@@ -128,68 +96,164 @@
 		(void) uselocale(loc);
 		day = nl_langinfo(DAY_1);
 		if (strcmp(day, l->day1) != 0) {
-			test_failed(tname, "uselocale data mismatch (%s != %s)",
+			test_failed(t, "uselocale data mismatch (%s != %s)",
 			    day, l->day1);
 		}
 
 		lc = localeconv();
 		if (strcmp(lc->currency_symbol, l->cursym) != 0) {
-			test_failed(tname, "uselocal cursym %s != %s",
+			test_failed(t, "uselocal cursym %s != %s",
 			    lc->currency_symbol, l->cursym);
 		}
-		if (debug)
-			(void) printf("CSYM: %s\n", lc->currency_symbol);
+		if (extra_debug)
+			test_debugf(t, "CSYM: %s", lc->currency_symbol);
 
 		/* we sleep a random bit to mix it up */
 		(void) usleep(rand() % 10);
 
 		if (uselocale(cloc) != loc) {
-			test_failed(tname, "revert old locale mismatch");
+			test_failed(t, "revert old locale mismatch");
 		}
 		freelocale(loc);
 		if (uselocale(LC_GLOBAL_LOCALE) != cloc) {
-			test_failed(tname, "revert GLOBAL_LOCALE mismatch");
+			test_failed(t, "revert GLOBAL_LOCALE mismatch");
 		}
 	}
-	return (NULL);
+	test_passed(t);
 }
 
 
 void
-testlocale(void)
+test_newlocale_threaded(void)
 {
-	char		*tname = "newlocale/uselocale";
-	pthread_t	tid[NUMTHR];
+	test_run(NUMTHR, testlocale_thr_one, NULL, "newlocale_threaded");
+}
 
-	test_start(tname, "running %d threads %d iterations\n", NUMTHR, NUMITR);
+void
+test_newlocale_negative(void)
+{
+	locale_t loc, bad;
+	char *day;
+	char *tname = "newlocale_negative";
+	test_t t;
 
-	for (int i = 0; i < NUMTHR; i++) {
-		(void) pthread_create(&tid[i], NULL, testlocale_thr, tname);
+	t = test_start(tname);
+	loc = newlocale(LC_ALL_MASK, "de_DE.UTF-8", NULL);
+	if (loc == NULL) {
+		test_failed(t, "cannot set de_DE.UTF-8");
 	}
+	day = nl_langinfo_l(DAY_1, loc);
+	if (strcmp(day, "Sonntag") != 0) {
+		test_failed(t, "incorrect Sonntag != %s", day);
+	}
 
-	for (int i = 0; i < NUMTHR; i++) {
-		(void) pthread_join(tid[i], NULL);
+	bad = newlocale(LC_ALL_MASK, "cn_US.BIZRRE", loc);
+	if (bad != NULL) {
+		test_failed(t, "passed setting bogus locale");
 	}
-	test_passed(tname);
+	day = nl_langinfo_l(DAY_1, loc);
+	if (strcmp(day, "Sonntag") != 0) {
+		test_failed(t, "incorrect Sonntag != %s", day);
+	}
+	test_passed(t);
 }
 
+void
+test_newlocale_categories(void)
+{
+	locale_t loc;
+	char *day, *cur, *yes;
+	char *tname = "newlocale_categories";
+	test_t t;
+
+	t = test_start(tname);
+
+	loc = NULL;
+	loc = newlocale(LC_TIME_MASK, "de_DE.UTF-8", loc);
+	loc = newlocale(LC_MESSAGES_MASK, "ru_RU.UTF-8", loc);
+	loc = newlocale(LC_MONETARY_MASK, "en_US.UTF-8", loc);
+
+	if (loc == NULL) {
+		test_failed(t, "failed to set locale");
+	}
+
+	day = nl_langinfo_l(DAY_1, loc);
+	if ((day == NULL) || (strcmp(day, "Sonntag") != 0)) {
+		test_failed(t, "day1 mismatch %s != %s", day, "Sonntag");
+	}
+	yes = nl_langinfo_l(YESSTR, loc);
+	if ((yes == NULL) || (strcmp(yes, "да") != 0)) {
+		test_failed(t, "currency mismatch");
+	}
+	cur = nl_langinfo_l(CRNCYSTR, loc);
+	if ((cur == NULL) || (strcmp(cur, "-$") != 0)) {
+		test_failed(t, "currency mismatch [%s] != [%s]", cur, "-$");
+	}
+
+	test_passed(t);
+}
+
+void
+test_newlocale_composite(void)
+{
+	locale_t loc;
+	char *day, *cur, *yes;
+	char *tname = "newlocale_composite";
+	test_t t;
+
+	t = test_start(tname);
+
+	/* order: CTYPE/NUMERIC/TIME/COLLATE/MONETARY/MESSAGES */
+	loc = newlocale(LC_ALL_MASK,
+	    "C/C/de_DE.UTF-8/C/en_US.UTF-8/ru_RU.UTF-8", NULL);
+
+	if (loc == NULL) {
+		test_failed(t, "failed to set composite locale");
+	}
+
+	day = nl_langinfo_l(DAY_1, loc);
+	if ((day == NULL) || (strcmp(day, "Sonntag") != 0)) {
+		test_failed(t, "day1 mismatch %s != %s", day, "Sonntag");
+	}
+	yes = nl_langinfo_l(YESSTR, loc);
+	if ((yes == NULL) || (strcmp(yes, "да") != 0)) {
+		test_failed(t, "currency mismatch");
+	}
+	cur = nl_langinfo_l(CRNCYSTR, loc);
+	if ((cur == NULL) || (strcmp(cur, "-$") != 0)) {
+		test_failed(t, "currency mismatch [%s] != [%s]", cur, "-$");
+	}
+
+	test_passed(t);
+}
+
 int
 main(int argc, char **argv)
 {
 	int optc;
 
-	while ((optc = getopt(argc, argv, "d")) != EOF) {
+	while ((optc = getopt(argc, argv, "Ddf")) != EOF) {
 		switch (optc) {
 		case 'd':
-			debug++;
+			test_set_debug();
 			break;
+		case 'f':
+			test_set_force();
+			break;
+		case 'D':
+			test_set_debug();
+			extra_debug++;
+			break;
 		default:
-			(void) fprintf(stderr, "Usage: %s [-d]\n", argv[0]);
+			(void) fprintf(stderr, "Usage: %s [-df]\n", argv[0]);
 			exit(1);
 		}
 	}
 
-	testlocale();
+	test_newlocale_threaded();
+	test_newlocale_negative();
+	test_newlocale_categories();
+	test_newlocale_composite();
 
 	exit(0);
 }
