diff options
author | Garrett D'Amore <garrett@damore.org> | 2014-07-06 12:52:24 -0700 |
---|---|---|
committer | Garrett D'Amore <garrett@damore.org> | 2014-07-15 14:05:46 -0700 |
commit | 538aa54d819fa7751ca82bcc30d4ed8c57ec2ef2 (patch) | |
tree | 53b18be80f1470a87571c45a8a90cc4597d071bb /usr/src/test | |
parent | e42d205944d245bf5d1c4fc45261cbe09e28a7b9 (diff) | |
download | illumos-joyent-538aa54d819fa7751ca82bcc30d4ed8c57ec2ef2.tar.gz |
4964 nl_langinfo(CRNCYSTR) returns wrong alignment character
4999 libc test suite enhancements
4939 desire wcsnrtombs() function
Reviewed by: Jason King <jason.brian.king@gmail.com>
Reviewed by: Dan McDonald <danmcd@omniti.com>
Reviewed by: Igor Kozhukhov <ikozhukhov@gmail.com>
Approved by: Robert Mustacchi <rm@joyent.com>
Diffstat (limited to 'usr/src/test')
-rw-r--r-- | usr/src/test/libc-tests/doc/README | 12 | ||||
-rw-r--r-- | usr/src/test/libc-tests/runfiles/default.run | 4 | ||||
-rw-r--r-- | usr/src/test/libc-tests/tests/Makefile | 3 | ||||
-rw-r--r-- | usr/src/test/libc-tests/tests/Makefile.com | 89 | ||||
-rw-r--r-- | usr/src/test/libc-tests/tests/common/run_arch_tests.ksh | 65 | ||||
-rw-r--r-- | usr/src/test/libc-tests/tests/common/test_common.c | 206 | ||||
-rw-r--r-- | usr/src/test/libc-tests/tests/common/test_common.h | 41 | ||||
-rw-r--r-- | usr/src/test/libc-tests/tests/newlocale/Makefile | 42 | ||||
-rw-r--r-- | usr/src/test/libc-tests/tests/newlocale/newlocale_test.c | 192 | ||||
-rw-r--r-- | usr/src/test/libc-tests/tests/nl_langinfo/Makefile | 21 | ||||
-rw-r--r-- | usr/src/test/libc-tests/tests/nl_langinfo/nl_langinfo_test.c | 278 | ||||
-rw-r--r-- | usr/src/test/libc-tests/tests/wcsrtombs/Makefile | 21 | ||||
-rw-r--r-- | usr/src/test/libc-tests/tests/wcsrtombs/wcsrtombs_test.c | 388 |
13 files changed, 1253 insertions, 109 deletions
diff --git a/usr/src/test/libc-tests/doc/README b/usr/src/test/libc-tests/doc/README index 60fc3b969a..f5640c58dd 100644 --- a/usr/src/test/libc-tests/doc/README +++ b/usr/src/test/libc-tests/doc/README @@ -25,7 +25,9 @@ libc Unit Test Suite README 1. What this Unit Test Suite tests -This Unit Test Suite is for testing various libc interfaces. +This Unit Test Suite is for testing various libc interfaces. The suite +will test both 32 and 64 bit versions, provided that your kernel supports +both. 2. Building and installing this Unit Test Suite @@ -55,12 +57,12 @@ dependencies and will be automatically installed. The pre-requisites for running the this Unit Test Suite are: - Any user may perform these tests. - - The en_US.UTF-8, ja_JP.UTF-8, de_DE.UTF-8, and ru_RU.UTF-8 locales - must be installed. + - The en_US.UTF-8, en_GB.ISO8859-15, ja_JP.UTF-8, de_DE.UTF-8, and + ru_RU.UTF-8 locales must be installed. -Once the pre-requisites are satisfied, simply run the ostest script: +Once the pre-requisites are satisfied, simply run the libctest script: - test_machine$ /opt/util-tests/bin/libctest + test_machine$ /opt/libc-tests/bin/libctest 4. Test results diff --git a/usr/src/test/libc-tests/runfiles/default.run b/usr/src/test/libc-tests/runfiles/default.run index 18f1475199..ae204ecccd 100644 --- a/usr/src/test/libc-tests/runfiles/default.run +++ b/usr/src/test/libc-tests/runfiles/default.run @@ -23,3 +23,7 @@ post = outputdir = /var/tmp/test_results [/opt/libc-tests/tests/newlocale_test] + +[/opt/libc-tests/tests/nl_langinfo_test] + +[/opt/libc-tests/tests/wcsrtombs_test] diff --git a/usr/src/test/libc-tests/tests/Makefile b/usr/src/test/libc-tests/tests/Makefile index 310dcf06a7..01207bd6d1 100644 --- a/usr/src/test/libc-tests/tests/Makefile +++ b/usr/src/test/libc-tests/tests/Makefile @@ -14,6 +14,7 @@ # Copyright 2014 Garrett D'Amore <garrett@damore.org> # -SUBDIRS = newlocale +SUBDIRS = newlocale nl_langinfo wcsrtombs +include $(SRC)/Makefile.master include $(SRC)/test/Makefile.com diff --git a/usr/src/test/libc-tests/tests/Makefile.com b/usr/src/test/libc-tests/tests/Makefile.com new file mode 100644 index 0000000000..78f357257a --- /dev/null +++ b/usr/src/test/libc-tests/tests/Makefile.com @@ -0,0 +1,89 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright (c) 2012 by Delphix. All rights reserved. +# Copyright 2014 Garrett D'Amore <garrett@damore.org> +# + +include $(SRC)/Makefile.master +include $(SRC)/cmd/Makefile.cmd +include $(SRC)/test/Makefile.com + +$(OBJS_OVERRIDE)OBJS = $(PROG).o test_common.o +OBJS32 = $(OBJS:%.o=%.$(MACH).o) +PROG32 = $(PROG).$(MACH) + +$(BUILD64) OBJS64 = $(OBJS:%.o=%.$(MACH64).o) +$(BUILD64) PROG64= $(PROG).$(MACH64) + +$(OBJS_OVERRIDE)SRCS = $(PROG).c ../common/test_common.c + +C99MODE = -xc99=%all +LINTFLAGS += -I../common -DARCH=\"ARCH\" -DLINT +CPPFLAGS += -I../common + +ROOTOPTPKG = $(ROOT)/opt/libc-tests +TESTDIR = $(ROOTOPTPKG)/tests + +CMDS = $(PROG32:%=$(TESTDIR)/%) $(PROG64:%=$(TESTDIR)/%) \ + $(KSHPROG:%=$(TESTDIR)/%) $(ARCHPROG:%=$(TESTDIR)/%) +$(CMDS) := FILEMODE = 0555 + +all: $(PROG32) $(PROG64) $(KSHPROG) $(ARCHPROG) $(SUBDIRS) + +$(PROG32): $(OBJS32) + $(LINK.c) $(OBJS32) -o $@ $(LDLIBS) + $(POST_PROCESS) + +$(PROG64): $(OBJS64) + $(LINK64.c) $(OBJS64) -o $@ $(LDLIBS64) + $(POST_PROCESS) + +$(KSHPROG): $(KSHPROG).ksh + $(RM) $@ + $(CP) $(KSHPROG).ksh $(@) + $(CHMOD) +x $@ + +$(ARCHPROG): ../common/run_arch_tests.ksh + $(RM) $@ + $(CP) ../common/run_arch_tests.ksh $(@) + $(CHMOD) +x $@ + +%.$(MACH).o: %.c + $(COMPILE.c) -o $@ $(CFLAGS_$(MACH)) -DARCH=\"$(MACH)\" $< + +%.$(MACH).o: ../common/%.c + $(COMPILE.c) -o $@ $(CFLAGS_$(MACH)) -DARCH=\"$(MACH)\" $< + +%.$(MACH64).o: %.c + $(COMPILE64.c) -o $@ $(CFLAGS_$(MACH64)) -DARCH=\"$(MACH64)\" $< + +%.$(MACH64).o: ../common/%.c + $(COMPILE64.c) -o $@ $(CFLAGS_$(MACH64)) -DARCH=\"$(MACH64)\" $< + +install: $(SUBDIRS) $(CMDS) + +lint: lint_SRCS + +clobber: clean + -$(RM) $(PROG32) $(PROG64) $(KSHPROG) $(ARCHPROG) + +clean: + -$(RM) $(OBJS32) $(OBJS64) + +$(CMDS): $(TESTDIR) $(PROG32) $(PROG64) $(KSHPROG) $(ARCHPROG) + +$(TESTDIR): + $(INS.dir) + +$(TESTDIR)/%: % + $(INS.file) diff --git a/usr/src/test/libc-tests/tests/common/run_arch_tests.ksh b/usr/src/test/libc-tests/tests/common/run_arch_tests.ksh new file mode 100644 index 0000000000..2598fc9d5b --- /dev/null +++ b/usr/src/test/libc-tests/tests/common/run_arch_tests.ksh @@ -0,0 +1,65 @@ +#!/usr/bin/ksh +# +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright 2014 Garrett D'Amore <garrett@damore.org> +# + +# First we set $dir to dirname $0, and $prog to basename $0 .ksh, +# using efficient ksh builtins. +case $0 in +*/*) + dir=${0%/*} + prog=${0##*/} + ;; +*) + dir=. + prog=${0} + ;; +esac +prog=${prog%.ksh} + +for a in $* +do + if [[ $a == "-d" ]] + then + debug=yes + fi +done + +# We look for architecture specific versions of the program, +# searching in several candidate directories. We run each one as +# we find it. +for f in $(/usr/bin/isainfo) +do + found= + [[ -n $debug ]] && print "Checking for arch $f:" + for p in \ + ${dir}/${prog}.${f} \ + ${dir}/${f}/${prog}.${f} \ + ${dir}/${f}/${prog} + do + [[ -n $found ]] && continue + [[ -n $debug ]] && print -n " $p" + if [[ -f $p ]]; then + [[ -n $debug ]] && print " FOUND" + [[ -n $debug ]] && print "Executing $p $*" + found=yes + $p $* || exit 1 + else + [[ -n $debug ]] && print + fi + done + [[ -z $found ]] && [[ -n $debug ]] && print "NOT PRESENT" +done +exit 0 diff --git a/usr/src/test/libc-tests/tests/common/test_common.c b/usr/src/test/libc-tests/tests/common/test_common.c new file mode 100644 index 0000000000..21ecc018b9 --- /dev/null +++ b/usr/src/test/libc-tests/tests/common/test_common.c @@ -0,0 +1,206 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2014 Garrett D'Amore <garrett@damore.org> + */ + +/* + * Common handling for test programs. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <stdarg.h> +#include <pthread.h> +#include "test_common.h" + +static int debug = 0; +static int force = 0; +static pthread_mutex_t lk; + +struct test { + char *name; + int ntids; + pthread_t *tids; + int fails; + void *arg; + void (*func)(test_t t, void *); +}; + +void +test_set_debug(void) +{ + debug++; +} + +void +test_set_force(void) +{ + force++; +} + +test_t +test_start(const char *format, ...) +{ + va_list args; + test_t t; + char *s; + + t = calloc(1, sizeof (*t)); + va_start(args, format); + (void) vasprintf(&s, format, args); + va_end(args); + + (void) asprintf(&t->name, "%s (%s)", s, ARCH); + free(s); + + (void) pthread_mutex_lock(&lk); + (void) printf("TEST STARTING %s:\n", t->name); + (void) fflush(stdout); + (void) pthread_mutex_unlock(&lk); + +#ifdef LINT + /* We inject references to make avoid name unused warnings */ + test_run(0, NULL, NULL, NULL); + test_debugf(t, NULL); + test_failed(t, NULL); + test_passed(t); + test_set_debug(); + test_set_force(); +#endif + + return (t); + +} + +void +test_failed(test_t t, const char *format, ...) +{ + va_list args; + + (void) pthread_mutex_lock(&lk); + if (force || (t->ntids > 0)) { + (void) printf("TEST FAILING %s: ", t->name); + } else { + (void) printf("TEST FAILED %s: ", t->name); + } + + va_start(args, format); + (void) vprintf(format, args); + va_end(args); + (void) printf("\n"); + (void) fflush(stdout); + (void) pthread_mutex_unlock(&lk); + + t->fails++; + if (!force) { + if (t->ntids > 0) { + pthread_exit(NULL); + } else { + (void) exit(EXIT_FAILURE); + } + } +} + +void +test_passed(test_t t) +{ + if (t->ntids > 0) { + if (debug) { + (void) pthread_mutex_lock(&lk); + (void) printf("TEST PASSING: %s\n", t->name); + (void) pthread_mutex_unlock(&lk); + } + return; + } + (void) pthread_mutex_lock(&lk); + if (t->fails == 0) { + (void) printf("TEST PASS: %s\n", t->name); + } else { + (void) printf("TEST FAILED: %d failures\n", t->fails); + } + (void) fflush(stdout); + (void) pthread_mutex_unlock(&lk); + free(t->name); + if (t->tids) { + free(t->tids); + } + free(t); +} + +void +test_debugf(test_t t, const char *format, ...) +{ + va_list args; + + if (!debug) + return; + + (void) pthread_mutex_lock(&lk); + (void) printf("TEST DEBUG %s: ", t->name); + + va_start(args, format); + (void) vprintf(format, args); + va_end(args); + (void) printf("\n"); + (void) fflush(stdout); + (void) pthread_mutex_unlock(&lk); +} + +static void * +test_thr_one(void *arg) +{ + test_t t = arg; + t->func(t, t->arg); + return (NULL); +} + +void +test_run(int nthr, void (*func)(test_t, void *), void *arg, + const char *tname, ...) +{ + test_t t; + char *s; + va_list args; + + t = calloc(1, sizeof (*t)); + t->ntids = nthr; + t->tids = calloc(nthr, sizeof (pthread_t)); + t->func = func; + t->arg = arg; + + va_start(args, tname); + (void) vasprintf(&s, tname, args); + va_end(args); + + (void) asprintf(&t->name, "%s (%s)", s, ARCH); + free(s); + + (void) pthread_mutex_lock(&lk); + (void) printf("TEST STARTING %s:\n", t->name); + (void) fflush(stdout); + (void) pthread_mutex_unlock(&lk); + + test_debugf(t, "running %d threads", nthr); + + for (int i = 0; i < nthr; i++) { + test_debugf(t, "started thread %d", i); + (void) pthread_create(&t->tids[i], NULL, test_thr_one, t); + } + + for (int i = 0; i < nthr; i++) { + (void) pthread_join(t->tids[i], NULL); + test_debugf(t, "thread %d joined", i); + t->ntids--; + } + test_passed(t); +} diff --git a/usr/src/test/libc-tests/tests/common/test_common.h b/usr/src/test/libc-tests/tests/common/test_common.h new file mode 100644 index 0000000000..9234bfac19 --- /dev/null +++ b/usr/src/test/libc-tests/tests/common/test_common.h @@ -0,0 +1,41 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2014 Garrett D'Amore <garrett@damore.org> + */ + +/* + * Common handling for test programs. + */ + +#ifndef _TEST_COMMON_H +#define _TEST_COMMON_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct test *test_t; +typedef void (*test_func_t)(test_t, void *); + +extern void test_set_debug(void); +extern void test_set_force(void); +extern test_t test_start(const char *name, ...); +extern void test_failed(test_t, const char *format, ...); +extern void test_passed(test_t); +extern void test_debugf(test_t, const char *format, ...); +extern void test_run(int nthr, test_func_t, void *arg, const char *, ...); + +#ifdef __cplusplus +} +#endif +#endif /* _TEST_COMMON_H */ diff --git a/usr/src/test/libc-tests/tests/newlocale/Makefile b/usr/src/test/libc-tests/tests/newlocale/Makefile index 4f761595ca..480f7066d7 100644 --- a/usr/src/test/libc-tests/tests/newlocale/Makefile +++ b/usr/src/test/libc-tests/tests/newlocale/Makefile @@ -10,48 +10,12 @@ # # -# Copyright (c) 2012 by Delphix. All rights reserved. # Copyright 2014 Garrett D'Amore <garrett@damore.org> # -include $(SRC)/cmd/Makefile.cmd -include $(SRC)/test/Makefile.com +include $(SRC)/Makefile.master PROG = newlocale_test -OBJS = $(PROG:%=%.o) -SRCS = $(OBJS:%.o=%.c) +ARCHPROG = newlocale_test -C99MODE = -xc99=%all - -ROOTOPTPKG = $(ROOT)/opt/libc-tests -TESTDIR = $(ROOTOPTPKG)/tests - -CMDS = $(PROG:%=$(TESTDIR)/%) -$(CMDS) := FILEMODE = 0555 - -all: $(PROG) - -$(PROG): $(OBJS) - $(LINK.c) $(OBJS) -o $@ $(LDLIBS) - $(POST_PROCESS) - -%.o: ../%.c - $(COMPILE.c) $< - -install: all $(CMDS) - -lint: lint_SRCS - -clobber: clean - -$(RM) $(PROG) - -clean: - -$(RM) $(OBJS) - -$(CMDS): $(TESTDIR) $(PROG) - -$(TESTDIR): - $(INS.dir) - -$(TESTDIR)/%: % - $(INS.file) +include ../Makefile.com diff --git a/usr/src/test/libc-tests/tests/newlocale/newlocale_test.c b/usr/src/test/libc-tests/tests/newlocale/newlocale_test.c index 214fa9fb19..22a23c5587 100644 --- a/usr/src/test/libc-tests/tests/newlocale/newlocale_test.c +++ b/usr/src/test/libc-tests/tests/newlocale/newlocale_test.c @@ -29,8 +29,8 @@ #include <err.h> #include <unistd.h> #include <pthread.h> - -int debug = 0; +#include <note.h> +#include "test_common.h" /* * Note that on some platforms, different symbols are used. For example, @@ -53,47 +53,15 @@ struct ldata { #define NUMTHR 20 #define NUMITR 200 -static void -test_start(const char *testName, const char *format, ...) -{ - va_list args; - - (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, ...) -{ - 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); -} +int extra_debug = 0; -void * -testlocale_thr(void *ptr) +void +testlocale_thr_one(test_t t, void *arg) { + _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 @@ testlocale_thr(void *ptr) 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,49 +96,135 @@ testlocale_thr(void *ptr) (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; + + 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_create(&tid[i], NULL, testlocale_thr, tname); + bad = newlocale(LC_ALL_MASK, "cn_US.BIZRRE", loc); + if (bad != NULL) { + test_failed(t, "passed setting bogus locale"); + } + day = nl_langinfo_l(DAY_1, loc); + if (strcmp(day, "Sonntag") != 0) { + test_failed(t, "incorrect Sonntag != %s", day); } + test_passed(t); +} - for (int i = 0; i < NUMTHR; i++) { - (void) pthread_join(tid[i], NULL); +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"); } - test_passed(tname); + 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 @@ -178,18 +232,28 @@ 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); } diff --git a/usr/src/test/libc-tests/tests/nl_langinfo/Makefile b/usr/src/test/libc-tests/tests/nl_langinfo/Makefile new file mode 100644 index 0000000000..f58927159e --- /dev/null +++ b/usr/src/test/libc-tests/tests/nl_langinfo/Makefile @@ -0,0 +1,21 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright 2014 Garrett D'Amore <garrett@damore.org> +# + +include $(SRC)/Makefile.master + +PROG = nl_langinfo_test +ARCHPROG = nl_langinfo_test + +include ../Makefile.com diff --git a/usr/src/test/libc-tests/tests/nl_langinfo/nl_langinfo_test.c b/usr/src/test/libc-tests/tests/nl_langinfo/nl_langinfo_test.c new file mode 100644 index 0000000000..4488e18d41 --- /dev/null +++ b/usr/src/test/libc-tests/tests/nl_langinfo/nl_langinfo_test.c @@ -0,0 +1,278 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2014 Garrett D'Amore <garrett@damore.org> + */ + +/* + * This program tests that newlocale and uselocale work properly in + * multi-threaded programs. In order for it to work, it requires that + * some additional locales be installed. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <locale.h> +#include <libintl.h> +#include <langinfo.h> +#include <nl_types.h> +#include <err.h> +#include <errno.h> +#include <unistd.h> +#include "test_common.h" + +/* + * Note that on some platforms, different symbols are used. For example, + * MacOS Mavericks uses "Eu" for Euro symbol, instead of €. If the locale + * data changes, then this program will need to update to reflect that. + * + * Note also that this file is easiest edited with a UTF-8 capable editor, + * as there are embedded UTF-8 symbols in some of the strings. + */ +struct langinfo_test { + nl_item param; + const char *value; +}; + +struct langinfo_test C_data[] = { + { CODESET, "646" }, + { D_T_FMT, "%a %b %e %H:%M:%S %Y" }, + { D_FMT, "%m/%d/%y" }, + { T_FMT, "%H:%M:%S" }, + { T_FMT_AMPM, "%I:%M:%S %p" }, + { AM_STR, "AM" }, + { PM_STR, "PM" }, + { ERA, "" }, + { ERA_D_FMT, "" }, + { ERA_D_T_FMT, "" }, + { ERA_T_FMT, "" }, + { DAY_1, "Sunday" }, + { DAY_7, "Saturday" }, + { ABDAY_1, "Sun" }, + { ABDAY_7, "Sat" }, + { MON_1, "January" }, + { MON_12, "December" }, + { ABMON_1, "Jan" }, + { ABMON_12, "Dec" }, + { RADIXCHAR, "." }, + { THOUSEP, "" }, + { YESSTR, "yes" }, + { NOSTR, "no" }, + { YESEXPR, "^[yY]" }, + { NOEXPR, "^[nN]" }, + { CRNCYSTR, "" }, + { -1, NULL } +}; + +struct langinfo_test en_us_utf8_data[] = { + { CODESET, "UTF-8" }, + { D_T_FMT, "%B %e, %Y %I:%M:%S %p %Z" }, + { D_FMT, "%m/%e/%y" }, + { T_FMT, "%I:%M:%S %p" }, + { T_FMT_AMPM, "%I:%M:%S %p" }, + { AM_STR, "AM" }, + { PM_STR, "PM" }, + { ERA, "" }, + { ERA_D_FMT, "" }, + { ERA_D_T_FMT, "" }, + { ERA_T_FMT, "" }, + { DAY_1, "Sunday" }, + { DAY_7, "Saturday" }, + { ABDAY_1, "Sun" }, + { ABDAY_7, "Sat" }, + { MON_1, "January" }, + { MON_12, "December" }, + { ABMON_1, "Jan" }, + { ABMON_12, "Dec" }, + { RADIXCHAR, "." }, + { THOUSEP, "," }, + { YESSTR, "yes" }, + { NOSTR, "no" }, + { YESEXPR, "^(([yY]([eE][sS])?))" }, + { NOEXPR, "^(([nN]([oO])?))" }, + { CRNCYSTR, "-$" }, + { -1, NULL } +}; + +struct langinfo_test en_gb_latin15_data[] = { + { CODESET, "ISO8859-15" }, + { D_T_FMT, "%e %B %Y %H:%M:%S %Z" }, + { D_FMT, "%d/%m/%Y" }, + { T_FMT, "%H:%M:%S" }, + { T_FMT_AMPM, "%I:%M:%S %p" }, + { AM_STR, "AM" }, + { PM_STR, "PM" }, + { ERA, "" }, + { ERA_D_FMT, "" }, + { ERA_D_T_FMT, "" }, + { ERA_T_FMT, "" }, + { DAY_1, "Sunday" }, + { DAY_7, "Saturday" }, + { ABDAY_1, "Sun" }, + { ABDAY_7, "Sat" }, + { MON_1, "January" }, + { MON_12, "December" }, + { ABMON_1, "Jan" }, + { ABMON_12, "Dec" }, + { RADIXCHAR, "." }, + { THOUSEP, "," }, + { YESSTR, "yes" }, + { NOSTR, "no" }, + { YESEXPR, "^(([yY]([eE][sS])?))" }, + { NOEXPR, "^(([nN]([oO])?))" }, + { CRNCYSTR, "-\243" }, + { -1, NULL } +}; + +struct langinfo_test ru_ru_utf8_data[] = { + { CODESET, "UTF-8" }, + { D_T_FMT, "%e %B %Y г. %H:%M:%S %Z"}, + { D_FMT, "%d.%m.%y" }, + { T_FMT, "%H:%M:%S" }, + { T_FMT_AMPM, "%I:%M:%S %p" }, + { AM_STR, "до полудня" }, + { PM_STR, "после полудня" }, + { ERA, "" }, + { ERA_D_FMT, "" }, + { ERA_D_T_FMT, "" }, + { ERA_T_FMT, "" }, + { DAY_1, "воскресенье" }, + { DAY_7, "суббота" }, + { ABDAY_1, "вс" }, + { ABDAY_7, "сб" }, + { MON_1, "января" }, + { MON_12, "декабря" }, + { ABMON_1, "янв" }, + { ABMON_12, "дек" }, + { RADIXCHAR, "," }, + { THOUSEP, " " }, + { YESSTR, "да" }, + { NOSTR, "нет" }, + { YESEXPR, "^(([дД]([аА])?)|([yY]([eE][sS])?))" }, + { NOEXPR, "^(([нН]([еЕ][тТ])?)|([nN]([oO])?))" }, + { CRNCYSTR, "+руб." }, + { -1, NULL } +}; + +struct { + const char *locale; + struct langinfo_test *loctest; +} locales[] = { + { "C", C_data }, + { "en_US.UTF-8", en_us_utf8_data }, + { "en_GB.ISO8859-15", en_gb_latin15_data }, + { "ru_RU.UTF-8", ru_ru_utf8_data }, + { NULL, NULL } +}; + +void +test_nl_langinfo_1(const char *locale, struct langinfo_test *test) +{ + char tname[128]; + char *v; + test_t t; + + (void) snprintf(tname, sizeof (tname), "nl_langinfo (locale %s)", + locale); + t = test_start(tname); + + v = setlocale(LC_ALL, locale); + if (v == NULL) { + test_failed(t, "setlocale failed: %s", strerror(errno)); + } + if (strcmp(v, locale) != 0) { + test_failed(t, "setlocale got %s instead of %s", v, locale); + } + + for (int i = 0; test[i].value != NULL; i++) { + v = nl_langinfo(test[i].param); + test_debugf(t, "%d: expect [%s], got [%s]", + test[i].param, test[i].value, v); + if (strcmp(v, test[i].value) != 0) { + test_failed(t, + "param %d wrong, expected [%s], got [%s]", + test[i].param, test[i].value, v); + } + } + test_passed(t); +} + +void +test_nl_langinfo_l(const char *locale, struct langinfo_test *test) +{ + char tname[128]; + char *v; + test_t t; + locale_t loc; + + (void) snprintf(tname, sizeof (tname), "nl_langinfo_l (locale %s)", + locale); + t = test_start(tname); + + v = setlocale(LC_ALL, "C"); + if (v == NULL) { + test_failed(t, "setlocale failed: %s", strerror(errno)); + } + if (strcmp(v, "C") != 0) { + test_failed(t, "setlocale got %s instead of %s", v, "C"); + } + + loc = newlocale(LC_ALL_MASK, locale, NULL); + if (loc == NULL) { + test_failed(t, "newlocale failed: %s", strerror(errno)); + } + + for (int i = 0; test[i].value != NULL; i++) { + v = nl_langinfo_l(test[i].param, loc); + test_debugf(t, "%d: expect [%s], got [%s]", + test[i].param, test[i].value, v); + if (strcmp(v, test[i].value) != 0) { + test_failed(t, + "param %d wrong, expected [%s], got [%s]", + test[i].param, test[i].value, v); + } + } + test_passed(t); +} +void +test_nl_langinfo(void) +{ + for (int i = 0; locales[i].locale != NULL; i++) { + test_nl_langinfo_1(locales[i].locale, locales[i].loctest); + test_nl_langinfo_l(locales[i].locale, locales[i].loctest); + } +} + +int +main(int argc, char **argv) +{ + int optc; + + while ((optc = getopt(argc, argv, "df")) != EOF) { + switch (optc) { + case 'd': + test_set_debug(); + break; + case 'f': + test_set_force(); + break; + default: + (void) fprintf(stderr, "Usage: %s [-df]\n", argv[0]); + exit(1); + } + } + + test_nl_langinfo(); + + exit(0); +} diff --git a/usr/src/test/libc-tests/tests/wcsrtombs/Makefile b/usr/src/test/libc-tests/tests/wcsrtombs/Makefile new file mode 100644 index 0000000000..657bb91696 --- /dev/null +++ b/usr/src/test/libc-tests/tests/wcsrtombs/Makefile @@ -0,0 +1,21 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright 2014 Garrett D'Amore <garrett@damore.org> +# + +include $(SRC)/Makefile.master + +PROG = wcsrtombs_test +ARCHPROG = wcsrtombs_test + +include ../Makefile.com diff --git a/usr/src/test/libc-tests/tests/wcsrtombs/wcsrtombs_test.c b/usr/src/test/libc-tests/tests/wcsrtombs/wcsrtombs_test.c new file mode 100644 index 0000000000..f083254952 --- /dev/null +++ b/usr/src/test/libc-tests/tests/wcsrtombs/wcsrtombs_test.c @@ -0,0 +1,388 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2014 Garrett D'Amore <garrett@damore.org> + */ + +/* + * This program tests that wcsrtombs and friends work properly. + * In order for it to work, it requires that some additional locales + * be installed. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <locale.h> +#include <wchar.h> +#include <err.h> +#include <errno.h> +#include <unistd.h> +#include <xlocale.h> +#include <note.h> +#include "test_common.h" + +int extra_debug = 0; + +#define NUMTHR 300 +#define NUMITR 300 + +/* + * Note that this file is easiest edited with a UTF-8 capable editor, + * as there are embedded UTF-8 symbols in some of the strings. + */ +struct wcsrtombs_test { + char mbs[32]; + wchar_t wcs[32]; +}; + +#define TESTING_MBS "TESTING" +#define TESTING_WCS { 'T', 'E', 'S', 'T', 'I', 'N', 'G', 0 } +#define HELLO_RU_MBS "ПРИВЕТ" +#define HELLO_RU_WCS { 1055, 1056, 1048, 1042, 1045, 1058, 0 } +#define HELLO_EN_MBS "HELLO" +#define HELLO_EN_WCS { 'H', 'E', 'L', 'L', 'O', 0 } + +/* Unicode values never have the high order bit set */ +#define BAD_WCS { 'B', 'A', 'D', (wchar_t)0xf000f000, 'W', 'C', 'S' } + +struct wcsrtombs_test C_data[] = { + { TESTING_MBS, TESTING_WCS }, + { HELLO_EN_MBS, HELLO_EN_WCS }, + { 0, 0 }, +}; + +struct wcsrtombs_test utf8_data[] = { + { TESTING_MBS, TESTING_WCS }, + { HELLO_EN_MBS, HELLO_EN_WCS }, + { HELLO_RU_MBS, HELLO_RU_WCS }, + { 0, 0 }, +}; + +struct { + const char *locale; + struct wcsrtombs_test *test; +} locales[] = { + { "C", C_data }, + { "en_US.UTF-8", utf8_data }, + { NULL, NULL } +}; + +void +test_wcsrtombs_1(const char *locale, struct wcsrtombs_test *test) +{ + test_t t; + char *v; + mbstate_t ms; + + t = test_start("wcsrtombs (locale %s)", locale); + + v = setlocale(LC_ALL, locale); + if (v == NULL) { + test_failed(t, "setlocale failed: %s", strerror(errno)); + } + if (strcmp(v, locale) != 0) { + test_failed(t, "setlocale got %s instead of %s", v, locale); + } + + for (int i = 0; test[i].mbs[0] != 0; i++) { + char mbs[32]; + const wchar_t *wcs = test[i].wcs; + size_t cnt; + + (void) memset(&ms, 0, sizeof (ms)); + (void) memset(mbs, 0, sizeof (mbs)); + cnt = wcsrtombs(mbs, &wcs, sizeof (mbs), &ms); + if (cnt != strlen(test[i].mbs)) { + test_failed(t, "incorrect return value: %d != %d", + cnt, strlen(test[i].mbs)); + } + if (strcmp(mbs, test[i].mbs) != 0) { + test_failed(t, "wrong result: %s != %s", + mbs, test[i].mbs); + } + if (extra_debug) { + test_debugf(t, "mbs is %s", mbs); + } + } + test_passed(t); +} + +void +test_wcsrtombs_l(const char *locale, struct wcsrtombs_test *test) +{ + test_t t; + locale_t loc; + char *v; + mbstate_t ms; + + t = test_start("wcsrtombs_l (locale %s)", locale); + + v = setlocale(LC_ALL, "C"); + if (v == NULL) { + test_failed(t, "setlocale failed: %s", strerror(errno)); + } + if (strcmp(v, "C") != 0) { + test_failed(t, "setlocale got %s instead of %s", v, "C"); + } + + loc = newlocale(LC_ALL_MASK, locale, NULL); + if (loc == NULL) { + test_failed(t, "newlocale failed: %s", strerror(errno)); + } + + for (int i = 0; test[i].mbs[0] != 0; i++) { + char mbs[32]; + const wchar_t *wcs = test[i].wcs; + size_t cnt; + + (void) memset(&ms, 0, sizeof (ms)); + (void) memset(mbs, 0, sizeof (mbs)); + cnt = wcsrtombs_l(mbs, &wcs, sizeof (mbs), &ms, loc); + if (cnt != strlen(test[i].mbs)) { + test_failed(t, "incorrect return value: %d != %d", + cnt, strlen(test[i].mbs)); + } + if (strcmp(mbs, test[i].mbs) != 0) { + test_failed(t, "wrong result: %s != %s", mbs, + test[i].mbs); + } + if (extra_debug) { + test_debugf(t, "mbs is %s", mbs); + } + } + test_passed(t); +} + +void +test_wcsrtombs_thr_iter(test_t t, const char *locale, + struct wcsrtombs_test *test) +{ + locale_t loc; + mbstate_t ms; + + loc = newlocale(LC_ALL_MASK, locale, NULL); + if (loc == NULL) { + test_failed(t, "newlocale failed: %s", strerror(errno)); + } + + for (int i = 0; test[i].mbs[0] != 0; i++) { + char mbs[32]; + const wchar_t *wcs = test[i].wcs; + size_t cnt; + + (void) memset(&ms, 0, sizeof (ms)); + (void) memset(mbs, 0, sizeof (mbs)); + cnt = wcsrtombs_l(mbs, &wcs, sizeof (mbs), &ms, loc); + if (cnt != strlen(test[i].mbs)) { + test_failed(t, "incorrect return value: %d != %d", + cnt, strlen(test[i].mbs)); + } + if (strcmp(mbs, test[i].mbs) != 0) { + test_failed(t, "wrong result: %s != %s", mbs, + test[i].mbs); + } + if (extra_debug) { + test_debugf(t, "mbs is %s", mbs); + } + } + + freelocale(loc); +} + +void +test_wcsrtombs_thr_work(test_t t, void *arg) +{ + _NOTE(ARGUNUSED(arg)); + for (int j = 0; j < NUMITR; j++) { + test_debugf(t, "iteration %d", j); + for (int i = 0; locales[i].locale != NULL; i++) { + test_wcsrtombs_thr_iter(t, locales[i].locale, + locales[i].test); + } + } + test_passed(t); +} + +void +test_wcsrtombs_threaded(void) +{ + (void) setlocale(LC_ALL, "C"); + test_run(NUMTHR, test_wcsrtombs_thr_work, NULL, "wcsrtombs_threaded"); +} + +void +test_wcsrtombs_partial(void) +{ + test_t t; + mbstate_t ms; + wchar_t src[32] = HELLO_RU_WCS; + char mbs[32]; + char *dst; + const wchar_t *wcs; + size_t cnt; + + + (void) memset(&ms, 0, sizeof (ms)); + t = test_start("wcsrtombs_partial"); + + if (setlocale(LC_ALL, "ru_RU.UTF-8") == NULL) { + test_failed(t, "setlocale failed: %s", strerror(errno)); + } + + wcs = src; + dst = mbs; + cnt = wcsrtombs(dst, &wcs, 1, &ms); + if (cnt != 0) { + test_failed(t, "gave back a conversion cnt %d != 0", cnt); + } + if (wcs != src) { + test_failed(t, "incorrectly advanced wcs"); + } + + cnt = wcsrtombs(dst, &wcs, 2, &ms); + if (cnt != 2) { + test_failed(t, "gave back a conversion cnt %d != 2", cnt); + } + dst += cnt; + + cnt = wcsrtombs(dst, &wcs, 4, &ms); + dst += cnt; + + cnt = wcsrtombs(dst, &wcs, sizeof (mbs) - strlen(mbs), &ms); + if (extra_debug) { + test_debugf(t, "mbs is %s", mbs); + } + if (strcmp(mbs, HELLO_RU_MBS) != 0) { + test_failed(t, "wrong result: %s != %s", mbs, HELLO_RU_MBS); + } + test_passed(t); +} + +void +test_wcsrtombs_negative(void) +{ + mbstate_t ms; + const wchar_t *wcs; + char mbs[32]; + char *dst; + int e; + wchar_t src[32] = BAD_WCS; + test_t t; + int cnt; + + t = test_start("wcsrtombs_negative"); + + (void) memset(&ms, 0, sizeof (ms)); + if (setlocale(LC_ALL, "ru_RU.UTF-8") == NULL) { + test_failed(t, "setlocale failed: %s", strerror(errno)); + } + + wcs = src; + dst = mbs; + cnt = wcsrtombs(dst, &wcs, sizeof (mbs), &ms); + if (cnt != -1) { + test_failed(t, "bogus success (%d)", cnt); + } + if ((e = errno) != EILSEQ) { + test_failed(t, "wrong errno, wanted %d (EILSEQ), got %d: %s", + EILSEQ, e, strerror(e)); + } + test_passed(t); +} + +void +test_wcsnrtombs_partial(void) +{ + test_t t; + mbstate_t ms; + wchar_t src[32] = HELLO_RU_WCS; + char mbs[32]; + char *dst; + const wchar_t *wcs; + size_t cnt; + + + (void) memset(&ms, 0, sizeof (ms)); + t = test_start("wcsrntombs_partial"); + + if (setlocale(LC_ALL, "ru_RU.UTF-8") == NULL) { + test_failed(t, "setlocale failed: %s", strerror(errno)); + } + + wcs = src; + dst = mbs; + cnt = wcsnrtombs(dst, &wcs, 1, 1, &ms); + if (cnt != 0) { + test_failed(t, "gave back a conversion cnt %d != 0", cnt); + } + if (wcs != src) { + test_failed(t, "incorrectly advanced wcs"); + } + + /* we should get just 2 wide characters (expanding to 4 bytes) */ + cnt = wcsnrtombs(dst, &wcs, 2, sizeof (mbs), &ms); + if (cnt != 4) { + test_failed(t, "gave back a conversion cnt %d != 4", cnt); + } + dst += cnt; + + cnt = wcsnrtombs(dst, &wcs, 32, sizeof (mbs) - strlen(mbs), &ms); + if (extra_debug) { + test_debugf(t, "mbs is %s", mbs); + } + if (strcmp(mbs, HELLO_RU_MBS) != 0) { + test_failed(t, "wrong result: %s != %s", mbs, HELLO_RU_MBS); + } + test_passed(t); +} + +void +test_wcsrtombs(void) +{ + for (int i = 0; locales[i].locale != NULL; i++) { + test_wcsrtombs_1(locales[i].locale, locales[i].test); + test_wcsrtombs_l(locales[i].locale, locales[i].test); + } +} + +int +main(int argc, char **argv) +{ + int optc; + + while ((optc = getopt(argc, argv, "dfD")) != EOF) { + switch (optc) { + case 'd': + test_set_debug(); + break; + case 'f': + test_set_force(); + break; + case 'D': + test_set_debug(); + extra_debug++; + break; + default: + (void) fprintf(stderr, "Usage: %s [-dfD]\n", argv[0]); + exit(1); + } + } + + test_wcsrtombs(); + test_wcsrtombs_partial(); + test_wcsrtombs_negative(); + test_wcsrtombs_threaded(); + test_wcsnrtombs_partial(); + + exit(0); +} |