1247411Sjhb/*- 2283927Sjhb * Copyright (c) 2013 Hudson River Trading LLC 3247411Sjhb * Written by: John H. Baldwin <jhb@FreeBSD.org> 4247411Sjhb * All rights reserved. 5247411Sjhb * 6247411Sjhb * Redistribution and use in source and binary forms, with or without 7247411Sjhb * modification, are permitted provided that the following conditions 8247411Sjhb * are met: 9247411Sjhb * 1. Redistributions of source code must retain the above copyright 10247411Sjhb * notice, this list of conditions and the following disclaimer. 11247411Sjhb * 2. Redistributions in binary form must reproduce the above copyright 12247411Sjhb * notice, this list of conditions and the following disclaimer in the 13247411Sjhb * documentation and/or other materials provided with the distribution. 14247411Sjhb * 15247411Sjhb * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16247411Sjhb * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17247411Sjhb * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18247411Sjhb * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19247411Sjhb * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20247411Sjhb * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21247411Sjhb * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22247411Sjhb * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23247411Sjhb * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24247411Sjhb * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25247411Sjhb * SUCH DAMAGE. 26247411Sjhb */ 27247411Sjhb 28247411Sjhb#include <sys/cdefs.h> 29247411Sjhb__FBSDID("$FreeBSD: releng/10.2/tools/regression/lib/libc/stdio/test-open_wmemstream.c 283927 2015-06-02 19:20:39Z jhb $"); 30247411Sjhb 31247411Sjhb#include <err.h> 32247411Sjhb#include <errno.h> 33247411Sjhb#include <limits.h> 34247411Sjhb#include <stdint.h> 35247411Sjhb#include <stdio.h> 36247411Sjhb#include <stdlib.h> 37247411Sjhb#include <string.h> 38247411Sjhb#include <wchar.h> 39247411Sjhb 40247411Sjhbstatic wchar_t *buf; 41247411Sjhbstatic size_t len; 42247411Sjhb 43247411Sjhbstatic void 44247411Sjhbassert_stream(const wchar_t *contents) 45247411Sjhb{ 46247411Sjhb if (wcslen(contents) != len) 47247411Sjhb printf("bad length %zd for \"%ls\"\n", len, contents); 48247411Sjhb else if (wcsncmp(buf, contents, wcslen(contents)) != 0) 49247411Sjhb printf("bad buffer \"%ls\" for \"%ls\"\n", buf, contents); 50247411Sjhb} 51247411Sjhb 52247411Sjhbstatic void 53247411Sjhbopen_group_test(void) 54247411Sjhb{ 55247411Sjhb FILE *fp; 56247411Sjhb off_t eob; 57247411Sjhb 58247411Sjhb fp = open_wmemstream(&buf, &len); 59247411Sjhb if (fp == NULL) 60247411Sjhb err(1, "failed to open stream"); 61247411Sjhb 62247411Sjhb fwprintf(fp, L"hello my world"); 63247411Sjhb fflush(fp); 64247411Sjhb assert_stream(L"hello my world"); 65247411Sjhb eob = ftello(fp); 66247411Sjhb rewind(fp); 67247411Sjhb fwprintf(fp, L"good-bye"); 68247411Sjhb fseeko(fp, eob, SEEK_SET); 69247411Sjhb fclose(fp); 70247411Sjhb assert_stream(L"good-bye world"); 71247411Sjhb free(buf); 72247411Sjhb} 73247411Sjhb 74247411Sjhbstatic void 75247411Sjhbsimple_tests(void) 76247411Sjhb{ 77247411Sjhb static const wchar_t zerobuf[] = 78247411Sjhb { L'f', L'o', L'o', 0, 0, 0, 0, L'b', L'a', L'r', 0 }; 79247411Sjhb wchar_t c; 80247411Sjhb FILE *fp; 81247411Sjhb 82247411Sjhb fp = open_wmemstream(&buf, NULL); 83247411Sjhb if (fp != NULL) 84247411Sjhb errx(1, "did not fail to open stream"); 85247411Sjhb else if (errno != EINVAL) 86247411Sjhb err(1, "incorrect error for bad length pointer"); 87247411Sjhb fp = open_wmemstream(NULL, &len); 88247411Sjhb if (fp != NULL) 89247411Sjhb errx(1, "did not fail to open stream"); 90247411Sjhb else if (errno != EINVAL) 91247411Sjhb err(1, "incorrect error for bad buffer pointer"); 92247411Sjhb fp = open_wmemstream(&buf, &len); 93247411Sjhb if (fp == NULL) 94247411Sjhb err(1, "failed to open stream"); 95247411Sjhb fflush(fp); 96247411Sjhb assert_stream(L""); 97247411Sjhb if (fwide(fp, 0) <= 0) 98247411Sjhb printf("stream is not wide-oriented\n"); 99247411Sjhb 100247411Sjhb fwprintf(fp, L"fo"); 101247411Sjhb fflush(fp); 102247411Sjhb assert_stream(L"fo"); 103247411Sjhb fputwc(L'o', fp); 104247411Sjhb fflush(fp); 105247411Sjhb assert_stream(L"foo"); 106247411Sjhb rewind(fp); 107247411Sjhb fflush(fp); 108247411Sjhb assert_stream(L""); 109247411Sjhb fseek(fp, 0, SEEK_END); 110247411Sjhb fflush(fp); 111247411Sjhb assert_stream(L"foo"); 112247411Sjhb 113247411Sjhb /* 114247411Sjhb * Test seeking out past the current end. Should zero-fill the 115247411Sjhb * intermediate area. 116247411Sjhb */ 117247411Sjhb fseek(fp, 4, SEEK_END); 118247411Sjhb fwprintf(fp, L"bar"); 119247411Sjhb fflush(fp); 120247411Sjhb 121247411Sjhb /* 122247411Sjhb * Can't use assert_stream() here since this should contain 123247411Sjhb * embedded null characters. 124247411Sjhb */ 125247411Sjhb if (len != 10) 126247411Sjhb printf("bad length %zd for zero-fill test\n", len); 127247411Sjhb else if (memcmp(buf, zerobuf, sizeof(zerobuf)) != 0) 128247411Sjhb printf("bad buffer for zero-fill test\n"); 129247411Sjhb 130247411Sjhb fseek(fp, 3, SEEK_SET); 131247411Sjhb fwprintf(fp, L" in "); 132247411Sjhb fflush(fp); 133247411Sjhb assert_stream(L"foo in "); 134247411Sjhb fseek(fp, 0, SEEK_END); 135247411Sjhb fflush(fp); 136247411Sjhb assert_stream(L"foo in bar"); 137247411Sjhb 138247411Sjhb rewind(fp); 139247411Sjhb if (fread(&c, sizeof(c), 1, fp) != 0) 140247411Sjhb printf("fread did not fail\n"); 141247411Sjhb else if (!ferror(fp)) 142247411Sjhb printf("error indicator not set after fread\n"); 143247411Sjhb else 144247411Sjhb clearerr(fp); 145247411Sjhb 146247411Sjhb fseek(fp, 4, SEEK_SET); 147247411Sjhb fwprintf(fp, L"bar baz"); 148247411Sjhb fclose(fp); 149247411Sjhb assert_stream(L"foo bar baz"); 150247411Sjhb free(buf); 151247411Sjhb} 152247411Sjhb 153247411Sjhbstatic void 154247411Sjhbseek_tests(void) 155247411Sjhb{ 156247411Sjhb FILE *fp; 157247411Sjhb 158247411Sjhb fp = open_wmemstream(&buf, &len); 159247411Sjhb if (fp == NULL) 160247411Sjhb err(1, "failed to open stream"); 161247411Sjhb#define SEEK_FAIL(offset, whence, error) do { \ 162247411Sjhb errno = 0; \ 163247411Sjhb if (fseeko(fp, (offset), (whence)) == 0) \ 164247411Sjhb printf("fseeko(%s, %s) did not fail, set pos to %jd\n", \ 165247411Sjhb __STRING(offset), __STRING(whence), \ 166247411Sjhb (intmax_t)ftello(fp)); \ 167247411Sjhb else if (errno != (error)) \ 168247411Sjhb printf("fseeko(%s, %s) failed with %d rather than %s\n",\ 169247411Sjhb __STRING(offset), __STRING(whence), errno, \ 170247411Sjhb __STRING(error)); \ 171247411Sjhb} while (0) 172247411Sjhb 173247411Sjhb#define SEEK_OK(offset, whence, result) do { \ 174247411Sjhb if (fseeko(fp, (offset), (whence)) != 0) \ 175247411Sjhb printf("fseeko(%s, %s) failed: %s\n", \ 176247411Sjhb __STRING(offset), __STRING(whence), strerror(errno)); \ 177247411Sjhb else if (ftello(fp) != (result)) \ 178247411Sjhb printf("fseeko(%s, %s) seeked to %jd rather than %s\n", \ 179247411Sjhb __STRING(offset), __STRING(whence), \ 180247411Sjhb (intmax_t)ftello(fp), __STRING(result)); \ 181247411Sjhb} while (0) 182247411Sjhb 183247411Sjhb SEEK_FAIL(-1, SEEK_SET, EINVAL); 184247411Sjhb SEEK_FAIL(-1, SEEK_CUR, EINVAL); 185247411Sjhb SEEK_FAIL(-1, SEEK_END, EINVAL); 186247411Sjhb fwprintf(fp, L"foo"); 187247411Sjhb SEEK_OK(-1, SEEK_CUR, 2); 188247411Sjhb SEEK_OK(0, SEEK_SET, 0); 189247411Sjhb SEEK_OK(-1, SEEK_END, 2); 190247411Sjhb SEEK_OK(OFF_MAX - 1, SEEK_SET, OFF_MAX - 1); 191247411Sjhb SEEK_FAIL(2, SEEK_CUR, EOVERFLOW); 192247411Sjhb fclose(fp); 193247411Sjhb} 194247411Sjhb 195247411Sjhbint 196247411Sjhbmain(int ac, char **av) 197247411Sjhb{ 198247411Sjhb 199247411Sjhb open_group_test(); 200247411Sjhb simple_tests(); 201247411Sjhb seek_tests(); 202247411Sjhb return (0); 203247411Sjhb} 204