Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!cs.utexas.edu!uunet!munnari.oz.au!bruce!cechew
From: cechew@bruce.OZ (Earl Chew)
Newsgroups: comp.os.minix
Subject: Stdio V2 - Part 6 of 6
Message-ID: <1566@bruce.OZ>
Date: 29 Sep 89 06:35:37 GMT
Organization: Monash Uni. Computer Science, Australia
Lines: 817
#! /bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". To overwrite existing
# files, type "sh file -c". You can also feed this as standard input via
# unshar, or by typing "sh 'xercise.c' <<'END_OF_FILE'
X/* E x e r c i s e
X *
X * This program exercises the stdio routines. It does not validate the
X * routines but provides a convenient way to quickly check the functionality
X * of the code.
X */
X
X#include "stdiolib.h"
X
X#define DEC -123
X#define INT 255
X#define UNS (~0)
X#define TESTFILE "test.dat"
X#define LARGEBUFS 16
X#ifdef MSDOS
X# define TTY "con"
X#else
X# define TTY "/dev/tty"
X#endif
X
Xextern void sleep(); /* sleep routine */
Xextern char *strcpy(); /* string copy */
Xextern char *strcat(); /* string concatenation */
Xextern int strcmp(); /* string compare */
Xextern void exit(); /* exit */
X
XFILE *fp; /* per test file pointer */
X
X/*
X * Line Buffered Write Test
X *
X * Write to a terminal. This tests that the output buffer is
X * flushed on receipt of a \n.
X */
X
Xvoid lbw_test()
X
X{
X int i;
X
X puts("\nLine buffered write test");
X if ((fp = fopen(TTY, "w")) != NULL) {
X puts("ABCDEFGH");
X puts("ABCDEFGH");
X for (i = 0; i < 8; i++)
X putc('A'+i, fp), sleep(1);
X putc('\n', fp);
X for (i = 0; i < 8; i++) {
X putc('A'+i, fp);
X if (i == 3)
X fflush(fp);
X sleep(1);
X }
X fclose(fp);
X puts("");
X }
X}
X
X/*
X * Unbuffered Write Test
X *
X * Test that characters are written directly to the output device
X * when the stream is unbuffered.
X */
X
Xvoid ubw_test()
X
X{
X int i;
X
X puts("\nUnbuffered write test");
X if ((fp = fopen(TTY, "w")) != NULL) {
X setbuf(fp, (char *) 0);
X puts("ABCDEFGH");
X puts("ABCDEFGH");
X for (i = 0; i < 8; i++)
X putc('A'+i, fp), sleep(1);
X putc('\n', fp);
X for (i = 0; i < 8; i++)
X putc('A'+i, fp), sleep(1);
X fclose(fp);
X puts("");
X }
X}
X
X/*
X * Buffered Write Test
X *
X * Test that the data is written to the terminal on a per buffer
X * basis.
X */
X
Xvoid bw_test()
X
X{
X int i;
X
X puts("\nFully buffered write test");
X if ((fp = fopen(TTY, "w")) != NULL) {
X setvbuf(fp, (char *) 0, _IOFBF, 4);
X puts("ABCDEFGH");
X puts("ABCDEFGH");
X for (i = 0; i < 8; i++)
X putc('A'+i, fp), sleep(1);
X putc('\n', fp);
X for (i = 0; i < 8; i++)
X putc('A'+i, fp), sleep(1);
X fclose(fp);
X puts("");
X }
X}
X
X/* Formatted Output Test
X *
X * This exercises the output formatting code.
X */
X
Xvoid fp_test()
X
X{
X int i, j, k, l;
X char buf[7];
X char *prefix = buf;
X char tp[20];
X
X puts("\nFormatted output test");
X printf("prefix 6d 6o 6x 6X 6u\n");
X strcpy(prefix, "%");
X for (i = 0; i < 2; i++) {
X for (j = 0; j < 2; j++) {
X for (k = 0; k < 2; k++) {
X for (l = 0; l < 2; l++) {
X strcpy(prefix, "%");
X if (i == 0) strcat(prefix, "-");
X if (j == 0) strcat(prefix, "+");
X if (k == 0) strcat(prefix, "#");
X if (l == 0) strcat(prefix, "0");
X printf("%5s |", prefix);
X strcpy(tp, prefix);
X strcat(tp, "6d |");
X printf(tp, DEC);
X strcpy(tp, prefix);
X strcat(tp, "6o |");
X printf(tp, INT);
X strcpy(tp, prefix);
X strcat(tp, "6x |");
X printf(tp, INT);
X strcpy(tp, prefix);
X strcat(tp, "6X |");
X printf(tp, INT);
X strcpy(tp, prefix);
X strcat(tp, "6u |");
X printf(tp, UNS);
X printf("\n");
X }
X }
X }
X }
X}
X
X/*
X * String Output Test
X *
X * Test the string printf code.
X */
X
Xvoid sw_test()
X
X{
X int i;
X char buf[80];
X
X puts("\nTest sprintf functionality");
X puts("13 bytes in 'Testing 1 2 3'");
X i = sprintf(buf, "Testing %d %d %d", 1, 2, 3);
X printf("%d bytes in '%s'\n", i, buf);
X}
X
X/*
X * String Input Test
X *
X * Test the string scanf code.
X */
X
Xvoid sr_test()
X
X{
X int i, j;
X char buf[80];
X
X puts("\nTest sscanf functionality");
X puts("2 items yielding 25 and 'thompson'");
X i = sscanf("25 thompson", "%d%s", &j, buf);
X printf("%d items yielding %d and '%s'\n", i, j, buf);
X}
X
X/*
X * File Write and Read Test
X *
X * Test that a file can be written to and read from.
X */
X
Xvoid frw_test()
X
X{
X int i, j, k;
X char buf[80];
X
X puts("\nFile write and read check");
X if ((fp = fopen(TESTFILE, "w")) != NULL) {
X puts("3 items yielding 56, 789 and '56'");
X puts("1 item yielding 'a72'");
X fprintf(fp, "56789 0123 56a72");
X if (freopen(TESTFILE, "r", fp) != fp)
X puts("Cannot open file for reading");
X else {
X i = fscanf(fp, "%2d%d%*d %[0-9]", &j, &k, buf);
X printf("%d items yielding %d, %d and '%s'\n", i, j, k, buf);
X i = fscanf(fp, "%s", buf);
X printf("%d item yielding '%s'\n", i, buf);
X fclose(fp);
X }
X }
X}
X
X/*
X * File Seek Test
X *
X * Test that seek operations within files work.
X */
X
Xvoid fs_test()
X
X{
X int i, j;
X
X puts("\nFile seek test");
X if ((fp = fopen(TESTFILE, "w")) != NULL) {
X for (i = 0; i < 256; i++)
X putc(i, fp);
X if (freopen(TESTFILE, "r", fp) != fp)
X puts("Cannot open file for reading");
X else {
X for (i = 1; i <= 255; i++) {
X printf("\r%3d ", i);
X fflush(stdout);
X fseek(fp, (long) -i, SEEK_END);
X if ((j = getc(fp)) != 256-i) {
X printf("SEEK_END failed %d\n", j);
X break;
X }
X if (fseek(fp, (long) i, SEEK_SET)) {
X puts("Cannot SEEK_SET");
X break;
X }
X if ((j = getc(fp)) != i) {
X printf("SEEK_SET failed %d\n", j);
X break;
X }
X if (fseek(fp, (long) i, SEEK_SET)) {
X puts("Cannot SEEK_SET");
X break;
X }
X if (fseek(fp, (long) (i >= 128 ? -128 : 128), SEEK_CUR)) {
X puts("Cannot SEEK_CUR");
X break;
X }
X if ((j = getc(fp)) != (i >= 128 ? i-128 : i+128)) {
X printf("SEEK_CUR failed %d\n", j);
X break;
X }
X }
X if (i > 255)
X puts("ok");
X fclose(fp);
X }
X }
X}
X
X/*
X * Test gets()
X *
X * Checks that gets() works.
X */
X
Xvoid gets_test()
X
X{
X char buf[80];
X
X puts("\nGets functionality");
X puts("... Type a line and have it echoed ...");
X gets(buf);
X puts(buf);
X}
X
X/*
X * Fgets Test
X *
X * Check that fgets() works.
X */
X
Xvoid fgets_test()
X
X{
X char buf[80];
X
X puts("\nFgets functionality");
X puts("a");
X puts("ab");
X puts("abc");
X puts("abcd");
X puts("abcde");
X puts("abcdef");
X puts("abcdefg");
X puts("abcdefgh");
X if ((fp = fopen(TESTFILE, "w")) != NULL) {
X fputs("a\n", fp);
X fputs("ab\n", fp);
X fputs("abc\n", fp);
X fputs("abcd\n", fp);
X fputs("abcde\n", fp);
X fputs("abcdef\n", fp);
X fputs("abcdefg\n", fp);
X fputs("abcdefgh\n", fp);
X fclose(fp);
X if ((fp = fopen(TESTFILE, "r")) != NULL) {
X while (fgets(buf, 8, fp) != NULL) {
X fputs(buf, stdout);
X fflush(stdout);
X sleep(1);
X }
X fclose(fp);
X }
X }
X}
X
X/*
X * Word Read and Write Test
X *
X * Check that putw and getw work.
X */
X
Xvoid word_test()
X
X{
X int i, j;
X
X puts("\nPutw and Readw Test");
X if ((fp = fopen(TESTFILE, "w")) != NULL) {
X for (i = 0; i < 256; i++)
X putw(i, fp);
X putc(0, fp);
X fclose(fp);
X if ((fp = fopen(TESTFILE, "r")) != NULL) {
X for (i = 0; i < 256; i++) {
X printf("\r%3d", i);
X fflush(stdout);
X if ((j = getw(fp)) != i) {
X printf(" failed %d", j);
X break;
X }
X }
X if (i == 256 /* && getw(fp) == EOF && feof(fp)*/)
X fputs(" ok", stdout);
X puts("");
X fclose(fp);
X }
X }
X}
X
X/*
X * Append Test
X *
X * Check that appends go to the end of the file.
X */
X
Xvoid a_test()
X
X{
X puts("\nAppend Test");
X if ((fp = fopen(TESTFILE, "w")) != NULL) {
X putc('a', fp);
X if ((fp = freopen(TESTFILE, "a", fp)) == NULL) {
X puts("Cannot freopen file");
X return;
X }
X if (fseek(fp, 0L, 0) == EOF) {
X puts("Cannot fseek to start");
X return;
X }
X putc('@', fp);
X if ((fp = freopen(TESTFILE, "r", fp)) == NULL) {
X puts("Cannot freopen file");
X return;
X }
X if (getc(fp) != 'a' || getc(fp) != '@' || getc(fp) != EOF)
X puts("Failed");
X else
X puts("Ok");
X fclose(fp);
X return;
X }
X}
X
X/*
X * Write and Read Update Test
X *
X * Write a file in update mode, then try to read it.
X */
X
Xvoid uwr_test()
X
X{
X int i, j;
X
X puts("\nWrite and Read Update Test");
X if ((fp = fopen(TESTFILE, "w+")) != NULL) {
X for (i = 0; i < (3*BUFSIZ)/2; i++)
X putc(i, fp);
X rewind(fp);
X for (i = 0; i < (3*BUFSIZ)/2; i++) {
X printf("\r%4d", i);
X fflush(stdout);
X j = getc(fp);
X if (j != UCHAR(i)) {
X printf(" failed %d\n", j);
X break;
X }
X }
X if (i == (3*BUFSIZ)/2)
X puts(" ok");
X if (getc(fp) != EOF)
X puts(" failed to find eof");
X else {
X for (i = 0; i < BUFSIZ/2; i++)
X putc(i, fp);
X fseek(fp, (long) (3*BUFSIZ)/2, SEEK_SET);
X for (i = 0; i < BUFSIZ/2; i++) {
X printf("\r%4d", i);
X fflush(stdout);
X j = getc(fp);
X if (j != UCHAR(i)) {
X printf(" failed %d\n", j);
X break;
X }
X }
X if (i == BUFSIZ/2)
X puts(" ok");
X }
X fclose(fp);
X }
X}
X
X/*
X * Write, Append and Read Update Test
X *
X * Write a file in update mode, close it, append to it and read it.
X */
X
Xvoid uawr_test()
X
X{
X int i, j;
X
X puts("\nWrite, Append and Read Update Test");
X if ((fp = fopen(TESTFILE, "w")) != NULL) {
X for (i = 0; i < (3*BUFSIZ)/2; i++)
X putc(i, fp);
X fclose(fp);
X if ((fp = fopen(TESTFILE, "a+")) != NULL) {
X for (i = 0; i < BUFSIZ/2; i++)
X putc(i, fp);
X fseek(fp, (long) (3*BUFSIZ)/2, SEEK_SET);
X for (i = 0; i < BUFSIZ/2; i++) {
X printf("\r%4d", i);
X fflush(stdout);
X j = getc(fp);
X if (j != UCHAR(i)) {
X printf(" failed %d\n", j);
X break;
X }
X }
X if (i == BUFSIZ/2)
X puts(" ok");
X rewind(fp);
X for (i = 0; i < (3*BUFSIZ)/2; i++) {
X printf("\r%4d", i);
X fflush(stdout);
X j = getc(fp);
X if (j != UCHAR(i)) {
X printf(" failed at %d\n", j);
X break;
X }
X }
X if (i == (3*BUFSIZ)/2)
X puts(" ok");
X }
X fclose(fp);
X }
X}
X
X/*
X * Write, Read, Write and Read Update Test
X *
X * Write a file in update mode, read it, write it and read it.
X */
X
Xvoid uwrwr_test()
X
X{
X int i, j;
X
X puts("\nWrite, Read, Write and Read Update Test");
X if ((fp = fopen(TESTFILE, "w")) != NULL) {
X for (i = 0; i < (3*BUFSIZ)/2; i++)
X putc(i, fp);
X fclose(fp);
X if ((fp = fopen(TESTFILE, "r+")) != NULL) {
X for (i = 0; i < (3*BUFSIZ)/2; i++) {
X printf("\r%4d", i);
X fflush(stdout);
X j = getc(fp);
X if (j != UCHAR(i)) {
X printf(" failed %d\n", j);
X break;
X }
X }
X if (i == (3*BUFSIZ)/2)
X puts(" ok");
X if (getc(fp) != EOF)
X puts(" failed to find eof");
X else {
X for (i = 0; i < BUFSIZ/2; i++)
X putc(i, fp);
X rewind(fp);
X for (i = 0; i < (3*BUFSIZ)/2; i++)
X putc((3*BUFSIZ)/2-i, fp);
X fseek(fp, (long) (3*BUFSIZ)/2, SEEK_SET);
X for (i = 0; i < BUFSIZ/2; i++) {
X printf("\r%4d", i);
X fflush(stdout);
X j = getc(fp);
X if (j != UCHAR(i)) {
X printf(" failed %d\n", j);
X break;
X }
X }
X if (i == BUFSIZ/2)
X puts(" ok");
X rewind(fp);
X for (i = 0; i < (3*BUFSIZ)/2; i++) {
X printf("\r%4d", i);
X fflush(stdout);
X j = getc(fp);
X if (j != UCHAR((3*BUFSIZ)/2-i)) {
X printf(" failed %d\n", j);
X break;
X }
X }
X if (i == (3*BUFSIZ)/2)
X puts(" ok");
X }
X fclose(fp);
X }
X }
X}
X
X/*
X * Fwrite Test
X *
X * Test fwrite with small loads and large loads.
X */
X
Xvoid fwrite_test()
X
X{
X int i, j;
X char buf[1023];
X char bbuf[3071];
X double sqrt();
X void free();
X char *p;
X
X puts("\nFwrite Test");
X if ((fp = fopen(TESTFILE, "w+")) != NULL) {
X
X for (i = 0; i < sizeof(buf); i++)
X buf[i] = i;
X for (i = 0; i < sizeof(bbuf); i++)
X bbuf[i] = 19-i;
X
X for (i = 0; i < 256; i++) {
X printf("\r%4d", i);
X fflush(stdout);
X if (fwrite(buf, 1, sizeof(buf), fp) != sizeof(buf)) {
X puts(" failed\n");
X return;
X }
X putc(0, fp);
X }
X puts(" small write ok");
X rewind(fp);
X for (i = 0; i < 256; i++) {
X printf("\r%4d", i);
X fflush(stdout);
X for (j = 0; j < sizeof(buf); j++) {
X if (getc(fp) != UCHAR(j)) {
X puts(" failed\n");
X return;
X }
X }
X if (getc(fp) != 0) {
X puts(" failed\n");
X return;
X }
X }
X puts(" verified ok");
X
X rewind(fp);
X for (i = 0; i < 256; i++) {
X printf("\r%4d", i);
X fflush(stdout);
X if (fwrite(bbuf, 1, sizeof(bbuf), fp) != sizeof(bbuf)) {
X puts(" failed\n");
X return;
X }
X putc(0, fp);
X }
X puts(" large write ok");
X rewind(fp);
X for (i = 0; i < 256; i++) {
X printf("\r%4d", i);
X fflush(stdout);
X for (j = 0; j < sizeof(bbuf); j++) {
X if (getc(fp) != UCHAR(19-j)) {
X puts(" failed\n");
X return;
X }
X }
X if (getc(fp) != 0) {
X puts(" failed\n");
X return;
X }
X }
X puts(" verified ok");
X
X rewind(fp);
X if ((p = (char *) malloc(48*1024)) == 0) {
X puts("No memory for large write test");
X return;
X }
X for (j = 13, i = 48*1024; --i; j++)
X p[i] = j;
X fwrite(p, 48*1024, 1, fp);
X rewind(fp);
X for (i = 48*1024; --i; )
X p[i] = 0;
X fread(p, 48*1024, 1, fp);
X for (j = 13, i = 48*1024; --i; j++) {
X if (i % 1024 == 0) {
X printf("\r%5u", i);
X fflush(stdout);
X }
X if (p[i] != (char) j) {
X printf("\r%5u failed %d instead of %d\n", i, p[i], UCHAR(j));
X free(p);
X return;
X }
X }
X printf("\r%5u ok\n", i);
X free(p);
X }
X}
X
X/*
X * Test the exit code
X *
X * Load an exit handler and check buffer flushing.
X */
X
Xstatic void handler()
X
X{
X fputs("Exit handler called ok\n", fp);
X fflush(fp);
X fputs("Buffer flush ok\n", fp);
X sleep(2);
X}
X
Xvoid exit_test()
X
X{
X int atexit();
X
X puts("\nExit Test");
X if ((fp = fopen(TTY, "w")) == NULL) {
X puts("Cannot open tty for exit test");
X return;
X }
X setvbuf(fp, (char *) 0, _IOFBF, BUFSIZ);
X if (atexit(handler) != 0)
X puts("Exit handler not lodged");
X}
X
X/* Temporary File Test
X *
X * Check the names produced by tmpnam.
X */
X
Xvoid tmp_test()
X
X{
X int i;
X char buf[20];
X char *tf;
X
X puts("\nTemporary File Names");
X for (i = 10; i--; ) {
X tf = tmpnam((char *) 0);
X fputs(tf, stdout);
X if (strlen(tf) == L_tmpnam-1)
X puts(" ok");
X else
X puts(" failed");
X }
X if ((fp = tmpfile()) == 0) {
X puts("Cannot make temporary file");
X return;
X }
X printf("Temporary file");
X fputs("123456", fp);
X rewind(fp);
X fgets(buf, 20, fp);
X if (strcmp(buf, "123456") != 0)
X puts(" failed");
X else
X puts(" ok");
X}
X
X/* Id test
X */
X
Xvoid id_test()
X
X{
X fputs("User id : ", stdout);
X puts(cuserid((char *) 0));
X fputs("Terminal : ", stdout);
X puts(ctermid((char *) 0));
X}
X
Xint main()
X
X{
X id_test();
X lbw_test();
X ubw_test();
X bw_test();
X fp_test();
X sw_test();
X sr_test();
X frw_test();
X fs_test();
X gets_test();
X fgets_test();
X word_test();
X fwrite_test();
X a_test();
X uwr_test();
X uawr_test();
X uwrwr_test();
X tmp_test();
X exit_test();
X return 0;
X}
END_OF_FILE
if test 14520 -ne `wc -c <'xercise.c'`; then
echo shar: \"'xercise.c'\" unpacked with wrong size!
fi
# end of 'xercise.c'
fi
echo shar: End of archive 6 \(of 6\).
cp /dev/null ark6isdone
MISSING=""
for I in 1 2 3 4 5 6 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 6 archives.
rm -f ark[1-9]isdone
else
echo You still need to unpack the following archives:
echo " " ${MISSING}
fi
## End of shell archive.
exit 0
--
Earl Chew, Dept of Computer Science, Monash University, Australia 3168
ARPA: cechew%bruce.cs.monash.oz.au@uunet.uu.net ACS : cechew@bruce.oz