static void one_test (const char *message, int error_code, const wchar_t *expected) { wchar_t *buffer = NULL; size_t length = 0; FILE *fp = open_wmemstream (&buffer, &length); TEST_VERIFY_EXIT (fp != NULL); FILE *old_stderr = stderr; stderr = fp; errno = error_code; switch (error_code) { case E2BIG: warn ("%s with padding " PADDING, message); break; case EAGAIN: warn ("%s", message); break; case -1: warnx ("%s", message); break; case -2: warnx ("%s with padding " PADDING, message); break; } stderr = old_stderr; TEST_VERIFY_EXIT (!ferror (fp)); TEST_COMPARE (fclose (fp), 0); if (wcscmp (buffer, expected) != 0) FAIL_EXIT1 ("unexpected output: %ls", buffer); free (buffer); }
/** Testuje zapisywanie słownika. @param state Środowisko testowe. */ static void dictionary_save_test(void** state) { struct dictionary *dict = dictionary_new(); FILE *stream; wchar_t *buf = NULL; size_t len; stream = open_wmemstream(&buf, &len); if (stream == NULL) { fprintf(stderr, "Failed to open memory stream\n"); exit(EXIT_FAILURE); } dictionary_insert(dict, L"ciupaga"); assert_true(dictionary_save(dict, stream) == 0); fflush(stream); assert_true(wcscmp(L"ciupaga*^^^^^^^\n0\n", buf) == 0); fseek(stream, 0, SEEK_SET); fclose(stream); # undef free free(buf); # define free(ptr) _test_free(ptr, __FILE__, __LINE__) dictionary_done(dict); }
TEST(stdio, open_wmemstream_EINVAL) { #if defined(__BIONIC__) wchar_t* p; size_t size; // Invalid buffer. errno = 0; ASSERT_EQ(nullptr, open_wmemstream(nullptr, &size)); ASSERT_EQ(EINVAL, errno); // Invalid size. errno = 0; ASSERT_EQ(nullptr, open_wmemstream(&p, nullptr)); ASSERT_EQ(EINVAL, errno); #else GTEST_LOG_(INFO) << "This test does nothing.\n"; #endif }
TEST(wchar, open_wmemstream) { wchar_t* p = nullptr; size_t size = 0; FILE* fp = open_wmemstream(&p, &size); ASSERT_NE(EOF, fputws(L"hello, world!", fp)); fclose(fp); ASSERT_STREQ(L"hello, world!", p); ASSERT_EQ(wcslen(L"hello, world!"), size); free(p); }
static void seek_tests(void) { FILE *fp; fp = open_wmemstream(&buf, &len); if (fp == NULL) err(1, "failed to open stream"); #define SEEK_FAIL(offset, whence, error) do { \ errno = 0; \ if (fseeko(fp, (offset), (whence)) == 0) \ printf("fseeko(%s, %s) did not fail, set pos to %jd\n", \ __STRING(offset), __STRING(whence), \ (intmax_t)ftello(fp)); \ else if (errno != (error)) \ printf("fseeko(%s, %s) failed with %d rather than %s\n",\ __STRING(offset), __STRING(whence), errno, \ __STRING(error)); \ } while (0) #define SEEK_OK(offset, whence, result) do { \ if (fseeko(fp, (offset), (whence)) != 0) \ printf("fseeko(%s, %s) failed: %s\n", \ __STRING(offset), __STRING(whence), strerror(errno)); \ else if (ftello(fp) != (result)) \ printf("fseeko(%s, %s) seeked to %jd rather than %s\n", \ __STRING(offset), __STRING(whence), \ (intmax_t)ftello(fp), __STRING(result)); \ } while (0) SEEK_FAIL(-1, SEEK_SET, EINVAL); SEEK_FAIL(-1, SEEK_CUR, EINVAL); SEEK_FAIL(-1, SEEK_END, EINVAL); fwprintf(fp, L"foo"); SEEK_OK(-1, SEEK_CUR, 2); SEEK_OK(0, SEEK_SET, 0); SEEK_OK(-1, SEEK_END, 2); SEEK_OK(OFF_MAX - 1, SEEK_SET, OFF_MAX - 1); SEEK_FAIL(2, SEEK_CUR, EOVERFLOW); fclose(fp); }
static void open_group_test(void) { FILE *fp; off_t eob; fp = open_wmemstream(&buf, &len); if (fp == NULL) err(1, "failed to open stream"); fwprintf(fp, L"hello my world"); fflush(fp); assert_stream(L"hello my world"); eob = ftello(fp); rewind(fp); fwprintf(fp, L"good-bye"); fseeko(fp, eob, SEEK_SET); fclose(fp); assert_stream(L"good-bye world"); free(buf); }
/** Testuje zapisywanie drzewa. @param state Środowisko testowe. */ static void trie_save_test(void** state) { Trie *trie = trie_new(); FILE *stream; wchar_t *buf = NULL; size_t len; stream = open_wmemstream(&buf, &len); if (stream == NULL) { fprintf(stderr, "Failed to open memory stream\n"); exit(EXIT_FAILURE); } IO *io = io_new(stdin, stream, stderr); assert_true(trie_save(trie, io) == 0); fflush(stream); assert_true(wcscmp(L"\n", buf) == 0); fseek(stream, 0, SEEK_SET); trie_insert_word(trie, L"ciupaga"); assert_true(trie_save(trie, io) == 0); fflush(stream); assert_true(wcscmp(L"ciupaga*^^^^^^^\n", buf) == 0); fseek(stream, 0, SEEK_SET); trie_delete_word(trie, L"ciupaga"); assert_true(trie_save(trie, io) == 0); fflush(stream); assert_true(wcscmp(L"\n", buf) == 0); fclose(stream); io_done(io); # undef free free(buf); # define free(ptr) _test_free(ptr, __FILE__, __LINE__) trie_done(trie); }
static void simple_tests(void) { static const wchar_t zerobuf[] = { L'f', L'o', L'o', 0, 0, 0, 0, L'b', L'a', L'r', 0 }; wchar_t c; FILE *fp; fp = open_wmemstream(&buf, NULL); if (fp != NULL) errx(1, "did not fail to open stream"); else if (errno != EINVAL) err(1, "incorrect error for bad length pointer"); fp = open_wmemstream(NULL, &len); if (fp != NULL) errx(1, "did not fail to open stream"); else if (errno != EINVAL) err(1, "incorrect error for bad buffer pointer"); fp = open_wmemstream(&buf, &len); if (fp == NULL) err(1, "failed to open stream"); fflush(fp); assert_stream(L""); if (fwide(fp, 0) <= 0) printf("stream is not wide-oriented\n"); fwprintf(fp, L"fo"); fflush(fp); assert_stream(L"fo"); fputwc(L'o', fp); fflush(fp); assert_stream(L"foo"); rewind(fp); fflush(fp); assert_stream(L""); fseek(fp, 0, SEEK_END); fflush(fp); assert_stream(L"foo"); /* * Test seeking out past the current end. Should zero-fill the * intermediate area. */ fseek(fp, 4, SEEK_END); fwprintf(fp, L"bar"); fflush(fp); /* * Can't use assert_stream() here since this should contain * embedded null characters. */ if (len != 10) printf("bad length %zd for zero-fill test\n", len); else if (memcmp(buf, zerobuf, sizeof(zerobuf)) != 0) printf("bad buffer for zero-fill test\n"); fseek(fp, 3, SEEK_SET); fwprintf(fp, L" in "); fflush(fp); assert_stream(L"foo in "); fseek(fp, 0, SEEK_END); fflush(fp); assert_stream(L"foo in bar"); rewind(fp); if (fread(&c, sizeof(c), 1, fp) != 0) printf("fread did not fail\n"); else if (!ferror(fp)) printf("error indicator not set after fread\n"); else clearerr(fp); fseek(fp, 4, SEEK_SET); fwprintf(fp, L"bar baz"); fclose(fp); assert_stream(L"foo bar baz"); free(buf); }
int main(int argc, char *argv[]) { char buffer[BUFSIZ]; wchar_t wbuffer[BUFSIZ]; char *buf; wchar_t *wbuf; FILE *f; off_t off; fpos_t pos; size_t size; int fd, r; char c; wchar_t wc; if ((fd = dup(1)) == -1) err(2, "dup"); if ((dup_stdout = fdopen(fd, "w")) == NULL) err(2, "fdopen"); if ((fd = mkstemp(filename)) == -1) err(2, "mkstemp"); if (write(fd, "0123456789\n\n", 12) != 12 || close(fd)) err(2, "write + close"); /* status */ TEST_UNCHANGED(fwide(f, 0)); TEST_NARROW(fwide(f, -1)); TEST_WIDE(fwide(f, 1)); TEST_UNCHANGED(feof(f)); TEST_UNCHANGED(ferror(f)); TEST_UNCHANGED(fileno(f)); TEST_UNCHANGED(clearerr(f)); /* flush and purge */ TEST_UNCHANGED(fflush(f)); TEST_UNCHANGED(fpurge(f)); /* positioning */ TEST_UNCHANGED(fgetpos(f, &pos)); TEST_UNCHANGED(fgetpos(f, &pos); fsetpos(f, &pos)); TEST_UNCHANGED(ftell(f)); TEST_UNCHANGED(ftello(f)); TEST_UNCHANGED(fseek(f, 1, SEEK_CUR)); TEST_UNCHANGED(fseek(f, 1, SEEK_SET)); TEST_UNCHANGED(fseek(f, 1, SEEK_END)); TEST_UNCHANGED(fseeko(f, 1, SEEK_CUR)); TEST_UNCHANGED(fseeko(f, 1, SEEK_SET)); TEST_UNCHANGED(fseeko(f, 1, SEEK_END)); TEST_UNCHANGED(rewind(f)); /* buffering */ TEST_UNCHANGED(setbuf(f, NULL)); TEST_UNCHANGED(setbuf(f, buffer)); TEST_UNCHANGED(setvbuf(f, buffer, _IONBF, BUFSIZ)); TEST_UNCHANGED(setvbuf(f, buffer, _IOLBF, BUFSIZ)); TEST_UNCHANGED(setvbuf(f, buffer, _IOFBF, BUFSIZ)); TEST_UNCHANGED(setvbuf(f, NULL, _IONBF, 0)); TEST_UNCHANGED(setvbuf(f, NULL, _IOLBF, 0)); TEST_UNCHANGED(setvbuf(f, NULL, _IOFBF, 0)); TEST_UNCHANGED(setbuffer(f, NULL, 0)); TEST_UNCHANGED(setbuffer(f, buffer, BUFSIZ)); TEST_UNCHANGED(setlinebuf(f)); /* locking */ TEST_UNCHANGED(flockfile(f);funlockfile(f)); TEST_UNCHANGED(ftrylockfile(f);funlockfile(f)); /* input */ TEST_NARROW(getc(f)); TEST_NARROW(getc_unlocked(f)); TEST_NARROW(fgetc(f)); TEST_NARROW(c = fgetc(f); ungetc(c, f)); TEST_NARROW(fgets(buffer, BUFSIZ, f)); TEST_NARROW(fscanf(f, "%s\n", buffer)); TEST_NARROW(fgetln(f, &size)); /* output */ TEST_NARROW(putc('c', f)); TEST_NARROW(putc_unlocked('c', f)); TEST_NARROW(fputc('c', f)); TEST_NARROW(fputs("foo", f)); TEST_NARROW(fprintf(f, "%s\n", "foo")); /* input from stdin */ TEST_NARROW_STD(stdin, getchar()); TEST_NARROW_STD(stdin, getchar_unlocked()); TEST_NARROW_STD(stdin, fgets(buffer, BUFSIZ, stdin)); TEST_NARROW_STD(stdin, scanf("%s\n", buffer)); /* output to stdout */ TEST_NARROW_STD(stdout, putchar('c')); TEST_NARROW_STD(stdout, putchar_unlocked('c')); TEST_NARROW_STD(stdout, puts("foo")); TEST_NARROW_STD(stdout, printf("foo")); /* word-size ops */ /* * fread and fwrite are specified as being implemented in * terms of fgetc() and fputc() and therefore must set the * stream orientation to narrow. */ TEST_NARROW(fread(buffer, 4, BUFSIZ / 4, f)); TEST_NARROW(fwrite(buffer, 4, BUFSIZ / 4, f)); /* * getw() and putw() aren't specified anywhere but logically * should behave the same as fread/fwrite. Not all OSes agree: * Solaris 10 has them not changing the orientation. */ TEST_NARROW(getw(f)); TEST_NARROW(putw(1234, f)); /* WIDE CHAR TIME! */ /* input */ TEST_WIDE(getwc(f)); TEST_WIDE(fgetwc(f)); TEST_WIDE(wc = fgetwc(f); ungetwc(wc, f)); TEST_WIDE(fgetws(wbuffer, BUFSIZ, f)); TEST_WIDE(fwscanf(f, L"%s\n", wbuffer)); /* output */ TEST_WIDE(putwc(L'c', f)); TEST_WIDE(fputwc(L'c', f)); TEST_WIDE(fputws(L"foo", f)); TEST_WIDE(fwprintf(f, L"%s\n", L"foo")); /* input from stdin */ TEST_WIDE_STD(stdin, getwchar()); TEST_WIDE_STD(stdin, wscanf(L"%s\n", wbuffer)); /* output to stdout */ TEST_WIDE_STD(stdout, putwchar(L'c')); TEST_WIDE_STD(stdout, wprintf(L"foo")); /* memory streams */ f = open_memstream(&buf, &size); if (!((r = fwide(f, 0)) < 0)) fail(__LINE__, r, "<", "open_memstream()"); fclose(f); f = open_wmemstream(&wbuf, &size); if (!((r = fwide(f, 0)) > 0)) fail(__LINE__, r, ">", "open_wmemstream()"); fclose(f); /* random stuff? */ TEST_UNCHANGED_STD(stderr, perror("foo")); remove(filename); if (failures) exit(1); exit(0); }
static int do_test (void) { size_t size; wchar_t *buf; FILE *fp = open_wmemstream (&buf, &size); if (fp == NULL) { puts ("open_wmemstream failed"); return 1; } off64_t off = ftello64 (fp); if (off != 0) { puts ("initial position wrong"); return 1; } if (fseek (fp, 32768, SEEK_SET) != 0) { puts ("fseek failed"); return 1; } if (fputws (L"foo", fp) == EOF) { puts ("fputws failed"); return 1; } if (fclose (fp) == EOF) { puts ("fclose failed"); return 1; } if (size != 32768 + 3) { printf ("expected size %d, got %zu\n", 32768 + 3, size); return 1; } for (int i = 0; i < 32768; ++i) if (buf[i] != L'\0') { printf ("wide character at offset %d is %#x\n", i, (unsigned int) buf[i]); return 1; } if (wmemcmp (buf + 32768, L"foo", 3) != 0) { puts ("written string incorrect"); return 1; } /* Mark the buffer. */ wmemset (buf, L'A', size); free (buf); /* Try again, this time with write mode enabled before the seek. */ fp = open_wmemstream (&buf, &size); if (fp == NULL) { puts ("2nd open_wmemstream failed"); return 1; } off = ftello64 (fp); if (off != 0) { puts ("2nd initial position wrong"); return 1; } if (fputws (L"bar", fp) == EOF) { puts ("2nd fputws failed"); return 1; } if (fseek (fp, 32768, SEEK_SET) != 0) { puts ("2nd fseek failed"); return 1; } if (fputws (L"foo", fp) == EOF) { puts ("3rd fputws failed"); return 1; } if (fclose (fp) == EOF) { puts ("2nd fclose failed"); return 1; } if (size != 32768 + 3) { printf ("2nd expected size %d, got %zu\n", 32768 + 3, size); return 1; } if (wmemcmp (buf, L"bar", 3) != 0) { puts ("initial string incorrect in 2nd try"); return 1; } for (int i = 3; i < 32768; ++i) if (buf[i] != L'\0') { printf ("wide character at offset %d is %#x in 2nd try\n", i, (unsigned int) buf[i]); return 1; } if (wmemcmp (buf + 32768, L"foo", 3) != 0) { puts ("written string incorrect in 2nd try"); return 1; } return 0; }