Annotation of researchv10dc/cmd/lcc/ph/d49.c, revision 1.1.1.1

1.1       root        1: /* The Plum Hall Validation Suite for C
                      2:  * Unpublished copyright (c) 1986-1991, Chiron Systems Inc and Plum Hall Inc.
                      3:  * VERSION: 4
                      4:  * DATE: 1993-01-01
                      5:  * The "ANSI" mode of this suite corresponds to official ANSI C, X3.159-1989.
                      6:  * As per your license agreement, your distribution is not to be moved or copied outside the Designated Site
                      7:  * without specific permission from Plum Hall Inc.
                      8:  */
                      9: 
                     10: 
                     11: #include "flags.h"
                     12: #ifndef SKIP49
                     13: #define LIB_TEST 1
                     14: /*
                     15:  * 4.9 - Input / Output <stdio.h>
                     16:  */
                     17: #include <stdio.h>
                     18: #include <ctype.h>
                     19: #include "defs.h"
                     20: #if ANSI
                     21: #include <stdarg.h>
                     22: #include <stddef.h>
                     23: #define W_BIN "wb"
                     24: #define R_BIN "rb"
                     25: #define A_BIN "ab"
                     26: #define WU_BIN "w+b"
                     27: #define RU_BIN "r+b"
                     28: #define AU_BIN "a+b"
                     29: #define W_BIN_U "wb+"
                     30: #define R_BIN_U "rb+"
                     31: #define A_BIN_U "ab+"
                     32: static void d4_9_6_9(char *, char *, ...);
                     33: #define L_FirstName L_tmpnam
                     34: #else
                     35: #define L_FirstName 256
                     36: #endif
                     37: static char FirstName[L_FirstName] = {0};
                     38: char names[25+1][L_FirstName] = {0};
                     39: int next_name = 0;
                     40: char *save_name(p)
                     41:        char *p;
                     42:        {
                     43:        if (next_name < 25)
                     44:                str_cpye(names[next_name++], p);
                     45:        return (p);
                     46:        }
                     47: #if !ANSI && !V7
                     48: extern int errno;
                     49: #endif
                     50: #if ANSI8703 || V7
                     51: #include <errno.h>
                     52: #endif
                     53: /* if ANSI, but prior to 87/03, errno will be found in <stddef.h> */
                     54: #if !ANSI
                     55: #define remove unlink
                     56: #define rename(old, new) ((link(old, new) == 0 && unlink(old) == 0) ? 0 : -1)
                     57: #define SEEK_SET 0
                     58: #define SEEK_CUR 1
                     59: #define SEEK_END 2
                     60: #define W_BIN "w"
                     61: #define R_BIN "r"
                     62: #define A_BIN "a"
                     63: #define WU_BIN "w+"
                     64: #define RU_BIN "r+"
                     65: #define AU_BIN "a+"
                     66: #define W_BIN_U "w+"
                     67: #define R_BIN_U "r+"
                     68: #define A_BIN_U "a+"
                     69: #endif
                     70: static int c;  /* for use in various SKIPNULLS */
                     71: static void d4_9_1();
                     72: static void d4_9_2();
                     73: static void d4_9_3();
                     74: static void d4_9_4();
                     75: static void d4_9_4_4();
                     76: static void d4_9_5();
                     77: static void d4_9_5_3();
                     78: static void d4_9_6();
                     79: static void d4_9_7();
                     80: static void d4_9_7_11();
                     81: static void d4_9_8();
                     82: static void d4_9_9();
                     83: static void d4_9_10();
                     84: void print();  /* in d49a.c */
                     85: void scan();   /* in d49a.c */
                     86: 
                     87: void d4_9()
                     88:        {
                     89:        Filename = "d49.c";
                     90:        d4_9_1();
                     91:        d4_9_2();
                     92:        d4_9_3();
                     93:        d4_9_4();
                     94:        d4_9_5();
                     95:        d4_9_6();
                     96:        d4_9_7();
                     97:        d4_9_8();
                     98:        d4_9_9();
                     99:        d4_9_10();
                    100:        d4_9_4_4();     /* do after all tmpnam calls are completed */
                    101:        }
                    102: /*
                    103:  * 4.9.1 - Introduction
                    104:  */
                    105: static void d4_9_1()
                    106:        {
                    107: #ifndef SKIP491
                    108: #if ANSI
                    109: 
                    110:        int i, j, k;
                    111:        FILE *files[FOPEN_MAX-3];
                    112:        int open_success = 1;
                    113: 
                    114:        /* check for existence of required macros */
                    115:        i = _IOFBF;
                    116:        j = _IOLBF;
                    117:        k = _IONBF;
                    118:        checkthat(__LINE__, EOF < 0);
                    119: 
                    120:        /* size_t is defined here (and elsewhere) */
                    121:        iequals(__LINE__, sizeof(size_t), sizeof(sizeof(size_t)));
                    122: 
                    123: #ifndef FILENAME_MAX
                    124:        complain(__LINE__);
                    125: #endif
                    126:        /* make sure that FOPEN_MAX-3 files can be opened simultaneously ...
                    127:         * the -3 allows for stdin, stdout, and stderr.
                    128:         *
                    129:         * IT HAS BEEN DETERMINED THAT THE STANDARD DOES NOT MANDATE THAT
                    130:         * CALLING  tmpfile  FOR  FOPEN_MAX-3  TIMES MUST SUCCEED.
                    131:         * AN IMPLEMENTATION WHICH FAILS THIS FORM OF THE TEST MAY SUPPLY
                    132:         * AN ALTERNATIVE PROGRAM TO DEMONSTRATE THAT  FOPEN_MAX-3  FILES
                    133:         * CAN BE OPENED SUCCESSFULLY.
                    134:         */
                    135:        open_success = 1;
                    136:        for (i = 0; i < FOPEN_MAX-3; ++i)
                    137:                {
                    138:                files[i] = tmpfile();
                    139:                if (files[i] == NULL)
                    140:                        {
                    141:                        open_success = 0;
                    142:                        break;
                    143:                        }
                    144:                }
                    145:        checkthat(__LINE__, open_success == 1);  /* success at fopen'ing FOPEN_MAX files */
                    146: 
                    147: 
                    148:        /* now clean it up */
                    149:        while (--i >= 0)
                    150:                fclose(files[i]);
                    151: #endif
                    152: #endif /* SKIP491 */
                    153:        }
                    154: 
                    155: /*
                    156:  * 4.9.2 - Streams
                    157:  */
                    158: static void d4_9_2()
                    159:        {
                    160: #ifndef SKIP492
                    161:        int i;
                    162:        char to[254], from[254];
                    163:        FILE *fd;
                    164: 
                    165:        save_name(tmpnam(FirstName));
                    166: 
                    167:        /* in text mode, we are guaranteed to get back chars in the
                    168:         * same order as written if they are printable, HT, NL, VT, or FF
                    169:         */
                    170:        fd = fopen(FirstName, "w");
                    171:        for (i = 0; i < 256; ++i)
                    172:                if (isprint(i) || i == '\t' || i == '\v' || i == '\n' || i == '\f')
                    173:                        fputc(i, fd);
                    174:        fputc('\n', fd); 
                    175:        fclose(fd);
                    176:        fd = fopen(FirstName, "r");
                    177:        for (i = 0; i < 256; ++i)
                    178:                if (isprint(i) || i == '\t' || i == '\v' || i == '\n' || i == '\f')
                    179:                        if (!iequals(__LINE__, fgetc(fd), i))
                    180:                                break;
                    181:        iequals(__LINE__, fgetc(fd), '\n');
                    182:        iequals(__LINE__, fgetc(fd), EOF);
                    183:        fclose(fd);
                    184:        remove(FirstName);
                    185: 
                    186:        /* in binary mode, the characters must all match */
                    187:        fd = fopen(FirstName, W_BIN);
                    188:        for (i = 0; i < 256; ++i)
                    189:                fputc(i, fd);
                    190:        fclose(fd);
                    191:        fd = fopen(FirstName, R_BIN);
                    192:        for (i = 0; i < 256; ++i)
                    193:                if (!iequals(__LINE__, fgetc(fd), i))
                    194:                        break;
                    195: #define SKIPNULLS(fd, i) \
                    196:        if ((i = fgetc(fd)) == 0) \
                    197:                { complain(- __LINE__); while ((i = fgetc(fd)) == 0) ; }
                    198:        SKIPNULLS(fd, i);
                    199:                        
                    200:        iequals(__LINE__, i, EOF);
                    201:                
                    202:        fclose(fd);
                    203:        remove(FirstName);
                    204: 
                    205:        /* make sure that a text mode file can support a line == 254 chars */
                    206:        fd = fopen(FirstName, "w");
                    207:        for (i = 0; i < 253; ++i)
                    208:                to[i] = "0123456789"[i % 10];
                    209:        to[253] = '\n';
                    210:        fwrite(to, 254, 1, fd);
                    211:        fwrite(" \n", 2, 1, fd);        /* ANSI8612 write whitespace before newline */
                    212:        fclose(fd);
                    213:        fd = fopen(FirstName, "r");
                    214:        fread(from, 254, 1, fd);
                    215:        for (i = 0; i < 253; ++i)
                    216:                if (!iequals(__LINE__, from[i], "0123456789"[i % 10]))
                    217:                        break;
                    218:        iequals(__LINE__, from[253], '\n');
                    219:        fread(from, 2, 1, fd);          /* ANSI8612 read the whitespace */
                    220:        from[2] = '\0';
                    221:        if (str_cmp(from, " \n") != 0)  /* 4.9.2 P2s1 */
                    222:                {
                    223:                complain(- __LINE__);           /* whether the blank reads back is implem-def */
                    224:                iequals(__LINE__, from[0], '\n');       /* but if it does not, the line must be just newline */
                    225:                }
                    226:        fclose(fd);
                    227:        remove(FirstName);
                    228: 
                    229:        checkthat(__LINE__, BUFSIZ >= 256);
                    230: #endif /* SKIP492 */
                    231:        }
                    232: 
                    233: /*
                    234:  * 4.9.3 - Files
                    235:  */
                    236: static void d4_9_3()
                    237:        {
                    238: #ifndef SKIP493
                    239:        char *name;
                    240:        FILE *fd;
                    241: 
                    242:        /* just check existence */
                    243:        FILE *f1 = stdin;
                    244:        FILE *f2 = stdout;
                    245:        FILE *f3 = stderr;
                    246: 
                    247: #if ANSI
                    248: #if ANSI8712
                    249:        checkthat(__LINE__, FOPEN_MAX >= 8);
                    250: #else
                    251:        checkthat(__LINE__, OPEN_MAX >= 8);
                    252: #endif
                    253: 
                    254:        /* whether a file of 0 length actually exists is implementation defined */
                    255:        name = save_name(tmpnam(NULL));
                    256:        fd = fopen(name, "w");
                    257:        fclose(fd);
                    258:        fd = fopen(name, "r");
                    259:        checkthat(- __LINE__, fd != NULL);
                    260:        fclose(fd);
                    261:        remove(name);
                    262: #endif
                    263: #endif /* SKIP493 */
                    264:        }
                    265: 
                    266: /*
                    267:  * 4.9.4 Operations on files
                    268:   */
                    269: static void d4_9_4()
                    270:        {
                    271: #ifndef SKIP494
                    272:        FILE *f;
                    273:        char *old, *new, *tmp;
                    274: #if ANSI
                    275:        char name[L_tmpnam], buf1[L_tmpnam], buf2[L_tmpnam], buf3[L_tmpnam];
                    276: #else
                    277:        static char name[] = "dXXXXXX";
                    278:        extern char *mktemp();
                    279: #endif
                    280: 
                    281:        /* 4.9.4.1 - remove */
                    282:        /* remove of non-existent file returns non-zero */
                    283:        inotequals(__LINE__, remove(save_name(tmpnam(NULL))), 0);
                    284: 
                    285:        /* successful remove returns 0 */
                    286:        f = fopen(new=save_name(tmpnam(NULL)), "w");
                    287:        fputc('a', f); fputc('\n', f);
                    288:        fclose(f);
                    289:        iequals(__LINE__, remove(new), 0);
                    290: 
                    291:        /* 4.9.4.2 The rename function */
                    292: #if ANSI
                    293:        old = save_name(tmpnam(buf1));
                    294:        new = save_name(tmpnam(buf2));
                    295:        tmp = save_name(tmpnam(buf3));
                    296: #else
                    297:        old = mktemp("aXXXXXX");
                    298:        new = mktemp("bXXXXXX");
                    299:        tmp = mktemp("cXXXXXX");
                    300: #endif
                    301:        /* make a file, write to it, rename it, check it, clean up */
                    302:        checkthat(__LINE__, (f = fopen(old, "w")) != NULL);
                    303:        fputc('x', f); fputc('\n', f);
                    304:        fclose(f);
                    305:        iequals(__LINE__, rename(old, new), 0);
                    306:        checkthat(__LINE__, (f = fopen(new, "r")) != NULL);
                    307:        iequals(__LINE__, fgetc(f), 'x');
                    308:        iequals(__LINE__, fgetc(f), '\n');
                    309:        fclose(f);
                    310: 
                    311:        /* make sure that the old file is effectively removed */
                    312:        checkthat(__LINE__, (f = fopen(old, "r")) == NULL);
                    313: 
                    314:        /* attempt to rename non-existent file should fail and return non 0 */
                    315:        inotequals(__LINE__, rename(tmp, old), 0);
                    316:        
                    317:        /* if the new file exists, the behavior is implementation defined */
                    318:        checkthat(__LINE__, (f = fopen(tmp, "w")) != NULL);
                    319:        fputc('x', f); fputc('\n', f);
                    320:        fclose(f);
                    321:        inotequals(- __LINE__, rename(new, tmp), 0);
                    322: 
                    323:        /* clean up */
                    324:        remove(new);
                    325:        remove(tmp);
                    326: #if ANSI
                    327:        /* 4.9.4.3 The tmpfile function */
                    328:        /* temporary file creation */
                    329:        f = tmpfile();
                    330:        fputc('y', f);
                    331:        fputc('\n', f);
                    332:        iequals(__LINE__, ferror(f), 0);
                    333:        fseek(f, 0L, SEEK_SET);
                    334:        iequals(__LINE__, fgetc(f), 'y');
                    335:        fclose(f);
                    336: #endif
                    337:        /* 4.9.4.4 The tmpnam function */
                    338: #if ANSI
                    339:        checkthat(__LINE__, TMP_MAX >= 25);
                    340:        old = save_name(tmpnam(buf1));
                    341:        aequals(__LINE__, old, buf1);
                    342: #else
                    343:        old = mktemp(name);
                    344:        aequals(__LINE__, old, name);
                    345: #endif
                    346:        /* old and new above should have created unique names */
                    347:        checkthat(__LINE__, str_cmp(old, new) != 0);
                    348: #endif /* SKIP494 */
                    349:        }
                    350: 
                    351: /*
                    352:  * 4.9.5 - File access functions
                    353:  */
                    354: char details[BUFSIZ] = {0};
                    355: static void d4_9_5()
                    356:        {
                    357: #ifndef SKIP495
                    358:        FILE *f, *g;
                    359: #if ANSI
                    360:        char buf1[L_tmpnam];
                    361:        char buf2[L_tmpnam];
                    362:        char *afile = save_name(tmpnam(buf1));
                    363:        char *bfile = save_name(tmpnam(buf2));
                    364: #else
                    365:        char *afile = mktemp("aXXXXXX");
                    366:        char *bfile = mktemp("bXXXXXX");
                    367: #endif
                    368: 
                    369:        /* 4.9.5.1 The fclose function */
                    370:        f = fopen(afile, "w");
                    371:        fputc('z', f);
                    372:        fputc('\n', f);
                    373:        iequals(__LINE__, fclose(f), 0);
                    374: 
                    375:        /* 4.9.5.2 The fflush function */
                    376:        /* fflush undoes the effects of an ungetc ... tested in 4.9.7.11 */
                    377: #if ANSI8804
                    378:        iequals(__LINE__, fflush(NULL), 0);     /* flush all output streams */
                    379: #endif /* ANSI8804 */
                    380:        /* make sure the previous write worked OK */
                    381:        f = fopen(afile, "r");
                    382:        iequals(__LINE__, fgetc(f), 'z');
                    383:        iequals(__LINE__, fgetc(f), '\n');
                    384:        fgetc(f);
                    385:        inotequals(__LINE__, feof(f), 0); 
                    386:        fclose(f);
                    387:        iequals(__LINE__, remove(afile), 0);
                    388: 
                    389:        /* 4.9.5.3 The fopen function */
                    390:        d4_9_5_3();
                    391: 
                    392:        /* 4.9.5.4 The reopen function */
                    393:        f = fopen(afile, "wb");
                    394:        fputc('a', f);
                    395:        fclose(f);
                    396:        f = fopen(bfile, "w+b");
                    397:        fputc('b', f);
                    398:        rewind(f);
                    399:        checkthat(__LINE__, (f = freopen(afile, "rb", f)) != NULL);
                    400: 
                    401:        /* should now be reading from afile, not bfile */
                    402:        iequals(__LINE__, fgetc(f), 'a');
                    403:        fclose(f);
                    404: 
                    405:        /* do reopens to change modes */
                    406:        checkthat(__LINE__, (f = fopen(afile, "rb")) != NULL);
                    407:        iequals(__LINE__, fgetc(f), 'a');
                    408:        checkthat(__LINE__, (f = freopen(afile, "wb", f)) != NULL);
                    409:        iequals(__LINE__, fputc('c', f), 'c');
                    410:        checkthat(__LINE__, (f = freopen(afile, "rb", f)) != NULL);
                    411:        iequals(__LINE__, fgetc(f), 'c');
                    412:        checkthat(__LINE__, (f = freopen(afile, "ab", f)) != NULL);
                    413:        iequals(__LINE__, fputc('d', f), 'd');
                    414:        if (checkthat(__LINE__, (f = freopen(afile, "r+b", f)) != NULL))
                    415:                {
                    416:                iequals(__LINE__, fgetc(f), 'c');
                    417:                SKIPNULLS(f, c); iequals(__LINE__, c, 'd');
                    418:                rewind(f);
                    419:                iequals(__LINE__, fputc('e', f), 'e');
                    420:                iequals(__LINE__, fputc('f', f), 'f');
                    421:                checkthat(__LINE__, (f = freopen(afile, "rb", f)) != NULL);
                    422:                iequals(__LINE__, fgetc(f), 'e');
                    423:                iequals(__LINE__, fgetc(f), 'f');
                    424:                SKIPNULLS(f, c);
                    425:                if (c == 'd')
                    426:                        SKIPNULLS(f, c);
                    427:                iequals(__LINE__, c, EOF);
                    428:                checkthat(__LINE__, (f = freopen(afile, "w+b", f)) != NULL);
                    429:                iequals(__LINE__, fputc('g', f), 'g');
                    430:                rewind(f);
                    431:                iequals(__LINE__, fgetc(f), 'g');
                    432:                SKIPNULLS(f, c);
                    433:                if (c == 'f')
                    434:                        SKIPNULLS(f, c);
                    435:                iequals(__LINE__, c, EOF);
                    436:                }
                    437:        fclose(f);
                    438:        /* get NULL pointer on failure ? */
                    439:        remove(bfile);
                    440:        f = fopen(afile, "rb");
                    441:        if (freopen(bfile, "rb", f) != NULL)
                    442:                {
                    443:                complain(__LINE__);     /* freopen should have failed: no bfile */
                    444:                fclose(f);
                    445:                }
                    446:        /* 4.9.5.5 The setbuf function */
                    447:        /* we have already checked for existence ... about all we can do is 
                    448:         * call it and make sure that it doesn't crash the program.
                    449:         */
                    450:        f = fopen(afile, "rb");
                    451:        setbuf(f, NULL);
                    452:        setbuf(f, details);
                    453:        /* 4.9.5.6 The setvbuf function */
                    454: #if ANSI
                    455:        /* not much that can be done except check for 0/nonzero return */
                    456:        /* ANSI8809 - re-affirms that setvbuf is allowed to be "unable to perform" */
                    457:        iequals( - __LINE__, setvbuf(f, details, _IOFBF, BUFSIZ/2), 0);
                    458:        iequals( - __LINE__, setvbuf(f, details, _IOLBF, BUFSIZ/2), 0);
                    459:        iequals( - __LINE__, setvbuf(f, details, _IONBF, BUFSIZ/2), 0);
                    460:        iequals( - __LINE__, setvbuf(f, NULL, _IOFBF, BUFSIZ/2), 0);
                    461:        iequals( - __LINE__, setvbuf(f, NULL, _IOLBF, BUFSIZ/2), 0);
                    462:        iequals( - __LINE__, setvbuf(f, NULL, _IONBF, BUFSIZ/2), 0);
                    463: 
                    464:        /* force an illegal size and mode */
                    465:        checkthat( - __LINE__, setvbuf(f, NULL, _IOFBF, -1) != 0);
                    466:        checkthat(__LINE__, setvbuf(f, NULL, _IOFBF+_IOLBF+_IONBF, 0) != 0);
                    467: #endif
                    468: 
                    469:        fclose(f);
                    470:        remove(afile);
                    471: #endif /* SKIP495 */
                    472:        }
                    473: 
                    474: /* 
                    475:  * 4.9.5.3 - test all of the file open modes.
                    476:  */
                    477: static void d4_9_5_3()
                    478:        {
                    479: #ifndef SKIP4953  /* note: if SKIP495 is defined, 4953 isn't called */
                    480:        FILE *f;
                    481: #if ANSI
                    482:        fpos_t pos;
                    483:        char *afile = save_name(tmpnam(NULL));
                    484: #else
                    485:        char *afile = mktemp("aXXXXXX");
                    486: #endif
                    487:        int c;
                    488: 
                    489:        /* open with "r" and non-existent file fails */
                    490:        aequals(__LINE__, fopen(afile, "r"), NULL);
                    491:        
                    492:        /* TEXT MODE
                    493:         * open(write), write a char, close.
                    494:         * open(read), read a char, check value, close.
                    495:         * open(append), seek, 0, write a char, 
                    496:         * open(read), check that write was to end of file
                    497:         */
                    498:        checkthat(__LINE__, (f = fopen(afile, "w")) != NULL);
                    499: 
                    500:        /* make sure that ferror and feof are 0 at this point */
                    501:        iequals(__LINE__, ferror(f), 0);
                    502:        iequals(__LINE__, feof(f), 0);
                    503: 
                    504:        fputc('d', f); fputc('\n', f);
                    505:        fclose(f);
                    506: 
                    507:        checkthat(__LINE__, (f = fopen(afile, "r")) != NULL);
                    508:        iequals(__LINE__, fgetc(f), 'd');
                    509:        fclose(f);
                    510: 
                    511:        checkthat(__LINE__, (f = fopen(afile, "a")) != NULL);
                    512:        fseek(f, 0L, SEEK_SET);
                    513:        fputc('e', f); fputc('\n', f);
                    514:        fclose(f);
                    515:        checkthat(__LINE__, (f = fopen(afile, "r")) != NULL);
                    516:        iequals(__LINE__, fgetc(f), 'd');
                    517:        iequals(__LINE__, fgetc(f), '\n');
                    518:        iequals(__LINE__, fgetc(f), 'e');
                    519:        iequals(__LINE__, fgetc(f), '\n');
                    520:        fclose(f);
                    521:        remove(afile);
                    522: 
                    523:        /* BINARY MODE
                    524:         * same sequence, but with binary mode opens
                    525:         */
                    526:        checkthat(__LINE__, (f = fopen(afile, W_BIN)) != NULL);
                    527:        fputc(1, f);
                    528:        fclose(f);
                    529: 
                    530:        checkthat(__LINE__, (f = fopen(afile, R_BIN)) != NULL);
                    531:        iequals(__LINE__, fgetc(f), 1);
                    532:        fclose(f);
                    533: 
                    534:        checkthat(__LINE__, (f = fopen(afile, A_BIN)) != NULL);
                    535:        fseek(f, 0L, SEEK_SET);
                    536:        fputc(2, f);
                    537:        fclose(f);
                    538:        {
                    539:        char c;
                    540: 
                    541:        checkthat(__LINE__, (f = fopen(afile, R_BIN)) != NULL);
                    542:        iequals(__LINE__, fgetc(f), 1);
                    543:        SKIPNULLS(f, c);
                    544:        iequals(__LINE__, c, 2);
                    545:        fclose(f);
                    546:        remove(afile);
                    547:        }
                    548: 
                    549:        /* UPDATE TEXT
                    550:         * open(write update), write, seek 0, read, check, close.
                    551:         * open(read update), read, check, seek 0, write, seek 0, check, close.
                    552:         * open(append update), seek 0, write, seek 0, read, check, close
                    553:         * open(read), read, check.
                    554:         */
                    555:        checkthat(__LINE__, (f = fopen(afile, "w+")) != NULL);
                    556:        fputc('f', f); fputc('\n', f);
                    557:        fseek(f, 0L, SEEK_SET);
                    558:        iequals(__LINE__, fgetc(f), 'f');
                    559:        fclose(f);
                    560:        checkthat(__LINE__, (f = fopen(afile, "r+")) != NULL);
                    561:        iequals(__LINE__, fgetc(f), 'f');
                    562:        fseek(f, 0L, SEEK_SET);
                    563:        fputc('g', f);
                    564:        fseek(f, 0L, SEEK_SET);
                    565:        iequals(__LINE__, fgetc(f), 'g');
                    566:        fclose(f);
                    567:        checkthat(__LINE__, (f = fopen(afile, "a+")) != NULL);
                    568:        fseek(f, 0L, SEEK_SET);
                    569:        fputc('h', f);
                    570:        fputc('\n', f);
                    571:        fseek(f, 0L, SEEK_SET);
                    572:        iequals(__LINE__, fgetc(f), 'g');
                    573:        iequals(__LINE__, fgetc(f), '\n');
                    574:        SKIPNULLS(f, c); iequals(__LINE__, c, 'h'); /* open might be binary */
                    575:        iequals(__LINE__, fgetc(f), '\n');
                    576:        fclose(f);
                    577:        remove(afile);
                    578: 
                    579:        /* UPDATE BINARY (X+B form)
                    580:         * open(write update), write, seek 0, read, check, close.
                    581:         * open(read update), read, check, seek 0, write, seek 0, check, close.
                    582:         * open(append update), seek 0, write, seek -2, read, check, close
                    583:         * open(read), read, check.
                    584:         */
                    585:        checkthat(__LINE__, (f = fopen(afile, WU_BIN)) != NULL);
                    586:        fputc('f', f);
                    587:        fseek(f, 0L, SEEK_SET);
                    588:        /* we wrote 'f' ... go back to zero and check that it is there */
                    589:        iequals(__LINE__, fgetc(f), 'f');
                    590:        fclose(f);
                    591:        checkthat(__LINE__, (f = fopen(afile, RU_BIN)) != NULL);
                    592:        /* close and reopen (for read-write) ... check that it is 'f' */
                    593:        iequals(__LINE__, fgetc(f), 'f');
                    594:        fseek(f, 0L, SEEK_SET);
                    595:        fputc('g', f);
                    596:        fseek(f, 0L, SEEK_SET);
                    597: 
                    598:        /* we wrote over it with a 'g' ... check that out */
                    599:        iequals(__LINE__, fgetc(f), 'g');
                    600:        fclose(f);
                    601:        checkthat(__LINE__, (f = fopen(afile, AU_BIN)) != NULL);
                    602:        fseek(f, 0L, SEEK_SET);
                    603:        fputc('h', f);
                    604:        fseek(f, -2L, SEEK_CUR);
                    605:        iequals( - __LINE__, fgetc(f), 'g');
                    606:        iequals(__LINE__, fgetc(f), 'h');
                    607:        fclose(f);
                    608:        checkthat(__LINE__, (f = fopen(afile, R_BIN)) != NULL);
                    609:        /* by now the file should have a 'g' and an 'h' in it */
                    610:        iequals(__LINE__, fgetc(f), 'g');
                    611:        SKIPNULLS(f, c); iequals(__LINE__, c, 'h');
                    612:        fclose(f);
                    613: 
                    614:        /* In update mode, there must be a fseek,rewind,fpos, or EOF between
                    615:         * input and output, or an fflush between output and input.
                    616:         * Diagrams use _ for file position, N for possible nul-padding, 
                    617:         * and  n  for new-line 
                    618:         */
                    619:        checkthat(__LINE__, (f = fopen(afile, W_BIN)) != NULL);
                    620:        fputc('g', f);                                                          /*  g_  */
                    621:        fputc('\n', f);                                                         /*  g n_ */
                    622:        fclose(f);                                                                      /*  g n N */
                    623: 
                    624:        checkthat(__LINE__, (f = fopen(afile, R_BIN_U)) != NULL);
                    625:        iequals(__LINE__, fgetc(f), 'g');                       /*  g_n N */
                    626:        fseek(f, 0L, SEEK_SET);                                         /* _g n N */
                    627:        iequals(__LINE__, fgetc(f), 'g');                       /*  g_n N */
                    628:        iequals(__LINE__, fgetc(f), '\n');                      /*  g n_N */
                    629:        SKIPNULLS(f, c); iequals(__LINE__, c, EOF);     /*  g n N_ */
                    630:        fseek(f, 0L, SEEK_SET);                                         /* _g n N */
                    631:        fputc('i', f);                                                          /*  i_n N */
                    632: 
                    633:        /* now make sure that these work */
                    634:        fseek(f, 0L, SEEK_SET);                                         /* _i n N */
                    635:        iequals(__LINE__, fgetc(f), 'i');                       /*  i_n N */
                    636:        fseek(f, 0L, SEEK_SET);                                         /* _i n N */
                    637:        fputc('j', f);                                                          /*  j_n N */
                    638:        fseek(f, 0L, SEEK_SET);                                         /* _j n N */
                    639:        iequals(__LINE__, fgetc(f), 'j');                       /*  j_n N */
                    640:        iequals(__LINE__, fgetc(f), '\n');                      /*  j n_N */
                    641:        SKIPNULLS(f, c); iequals(__LINE__, c, EOF);     /*  j n N_ */
                    642:        fseek(f, 0L, SEEK_CUR);                                         /*  j n N_*/
                    643:        fputc('z', f);                                                          /*  j n N z_ */
                    644:        fseek(f, 0L, SEEK_SET);                                         /* _j n N z N */
                    645:        iequals(__LINE__, fgetc(f), 'j');                       /*  j_n N z N */
                    646:        rewind(f);                                                                      /* _j n N z N */
                    647:        fputc('k', f);                                                          /*  k_n N z N */
                    648:        rewind(f);                                                                      /* _k n N z N */
                    649:        iequals(__LINE__, fgetc(f), 'k');                       /*  k_n N z N */
                    650:        iequals(__LINE__, fgetc(f), '\n');                      /*  k n_N z N */
                    651:        SKIPNULLS(f, c); iequals(__LINE__, c, 'z');     /*  k n N z_N */
                    652:        SKIPNULLS(f, c); iequals(__LINE__, c, EOF);     /*  k n N z N_ */
                    653: #if ANSI
                    654:        fseek(f, 0L, SEEK_SET);                                         /* _k n N z N */
                    655:        iequals(__LINE__, fgetc(f), 'k');                       /*  k_n N z N */
                    656:        fseek(f, 0L, SEEK_CUR); /* allow writing */     /*  k_n N z N */
                    657:        fputc('l', f);                                                          /*  k l_N z N */
                    658:        fputc('\n', f);                                                         /*  k l n_N z N */
                    659:        rewind(f);                                                                      /* _k l n N z N */
                    660:        iequals(__LINE__, fgetc(f), 'k');                       /*  k_l n N z N */
                    661:        iequals(__LINE__, fgetc(f), 'l');                       /*  k l_n N z N */
                    662:        iequals(__LINE__, fgetc(f), '\n');                      /*  k l n_N z N */
                    663: 
                    664:        fseek(f, 0L, SEEK_SET);                                         /* _k l n N z N */
                    665:        fgetpos(f, &pos);                                                       /* _k l n N z N */
                    666:        iequals(__LINE__, fgetc(f), 'k');                       /*  k_l n N z N */
                    667:        fsetpos(f, &pos);                                                       /* _k l n N z N */
                    668:        fputc('m', f);                                                          /*  m_l n N z N */
                    669:        fsetpos(f, &pos);                                                       /* _m l n N z N */
                    670:        iequals(__LINE__, fgetc(f), 'm');                       /*  m_l n N z N */
                    671:        iequals(__LINE__, fgetc(f), 'l');                       /*  m l_n N z N */
                    672:        iequals(__LINE__, fgetc(f), '\n');                      /*  m l n_N z N */
                    673: 
                    674: #endif
                    675:        fclose(f);                                                                      /*  m l n N z N */
                    676:        remove(afile);                                                          /*  removed */
                    677: 
                    678:        /* UPDATE BINARY (using  XB+ form)
                    679:         * open(write update), write, seek 0, read, check, close.
                    680:         * open(read update), read, check, seek 0, write, seek -1, check, close.
                    681:         * open(append update), seek 0, write, seek -1, read, check, close
                    682:         * open(read), read, check.
                    683:         */
                    684:        checkthat(__LINE__, (f = fopen(afile, W_BIN_U)) != NULL);
                    685:        fputc('f', f);                                                          /*  f_ */
                    686:        fseek(f, 0L, SEEK_SET);                                         /* _f */
                    687:        /* we wrote 'f' ... go back to zero and check that it is there */
                    688:        iequals(__LINE__, fgetc(f), 'f');                       /*  f_ */
                    689:        fclose(f);                                                                      /*  f N */
                    690:        checkthat(__LINE__, (f = fopen(afile, R_BIN_U)) != NULL);
                    691:        /* close and reopen (for read-write) */         /* _f N */
                    692:        iequals(__LINE__, fgetc(f), 'f');                       /*  f_N */
                    693:        fseek(f, 0L, SEEK_SET);                                         /* _f N */
                    694:        fputc('g', f);                                                          /*  g_N */
                    695:        fseek(f, -1L, SEEK_CUR);                                        /* _g N */
                    696:        iequals(__LINE__, fgetc(f), 'g');                       /*  g_N */
                    697:        /* we wrote over it with a 'g' */
                    698:        fclose(f);                                                                      /*  g N */
                    699:        checkthat(__LINE__, (f = fopen(afile, A_BIN_U)) != NULL);
                    700:        fseek(f, 0L, SEEK_SET);                                         /* _g N */
                    701:        fputc('h', f);  /* appended */                          /* _g N h */
                    702:        fseek(f, 1L, SEEK_SET);                                         /*  g_N h */
                    703:        SKIPNULLS(f, c);                                                        /*  g N h_ */
                    704:        iequals(__LINE__, c, 'h');                                      /*  g N h_ */
                    705:        fclose(f);                                                                      /*  g N h N */
                    706:        checkthat(__LINE__, (f = fopen(afile, R_BIN)) != NULL);
                    707:        /* should have a 'g' and an 'h' */                      /* _g N h N */
                    708:        iequals(__LINE__, fgetc(f), 'g');                       /*  g_N h N */
                    709:        SKIPNULLS(f, c);                                                        /*  g N h_N */
                    710:        iequals(__LINE__, c, 'h');                                      /*  g N h_N */
                    711:        fclose(f);                                                                      /*  g N h N */
                    712: 
                    713:        remove(afile);                                                          /*  removed */
                    714: #endif /* SKIP4953 */
                    715:        }
                    716: 
                    717: /*
                    718:  * 4.9.6 Formatted input/output functions
                    719:  */
                    720: static void d4_9_6()
                    721:        {
                    722: #ifndef SKIP496
                    723:        int i, j;
                    724:        char buff[20];
                    725:        char *p;
                    726: 
                    727:        /* 4.9.6.1 The fprintf function */
                    728:        /* 4.9.6.2 The fscanf function */
                    729:        /* 4.9.6.3 The printf function */
                    730:        /* 4.9.6.4 The scanf function */
                    731:        /* 4.9.6.5 The sprintf function */
                    732:        /* make sure that excess args are evaluated */
                    733:        sprintf(buff, "%d", 3, i = 17);
                    734:        stequals(__LINE__, buff, "3");
                    735:        iequals(__LINE__, i, 17);
                    736: 
                    737:        /* returns number of characters transmitted */
                    738:        iequals(__LINE__, sprintf(buff, "%d", 17), 2);
                    739:        iequals(__LINE__, sprintf(buff, "%d %d", 17, 123), 6);
                    740:        iequals(__LINE__, sprintf(buff, "%s", ""), 0);
                    741:        iequals(__LINE__, sprintf(buff, "%%"), 1);
                    742: 
                    743:        /* now check all of the formatting primitives */
                    744:        print();
                    745:        Filename = "d49.c";
                    746: 
                    747:        /* 4.9.6.6 The sscanf function */
                    748:        scan();
                    749:        Filename = "d49.c";
                    750:        /* return number of items converted */
                    751:        iequals(__LINE__, sscanf("def", "abc", &p), 0); 
                    752:        iequals(__LINE__, sscanf("7", "%d", &i, &j), 1); 
                    753:        iequals(__LINE__, sscanf("7 8", "%d", &i, &j), 1); 
                    754:        iequals(__LINE__, sscanf("7 8", "%d %d", &i, &j), 2); 
                    755: 
                    756:        /* 4.9.6.7 The vfprintf function */
                    757:        /* 4.9.6.8 The vprintf function */
                    758:        /* 4.9.6.9 The vsprintf function */
                    759: #if ANSI
                    760:        d4_9_6_9(buff, "%s %d %s", "string1", 23, "string2");
                    761:        stequals(__LINE__, buff, "string1 23 string2");
                    762: #endif
                    763: #endif /* SKIP496 */
                    764:        }
                    765: 
                    766: /*
                    767:  * 4.9.6.9 - check out the varargs form of formatting. */
                    768: #if ANSI
                    769: #if NEW_STYLE_FN_DEF
                    770: static void d4_9_6_9(char *buff, char *fmt, ...)
                    771: #else
                    772: static void d4_9_6_9(buff, fmt)
                    773:        char *buff;
                    774:        char *fmt;
                    775: #endif
                    776:        {
                    777:        va_list args;
                    778: 
                    779:        va_start(args, fmt);
                    780:        vsprintf(buff, fmt, args);
                    781:        va_end(args);
                    782:        }
                    783: #endif
                    784: 
                    785: /*
                    786:  * 4.9.7 Character input/output
                    787:  */
                    788: static void d4_9_7()
                    789:        {
                    790: #ifndef SKIP497
                    791:        FILE *f;
                    792:        char buff[65];
                    793:        int c, i;
                    794: #if ANSI
                    795:        char *afile = save_name(tmpnam(NULL));
                    796: #else
                    797:        char *afile = mktemp("aXXXXXX");
                    798: #endif
                    799: 
                    800:        /* 4.9.7.1 The fgetc function */
                    801:        /* 4.9.7.2 The fgets function */
                    802:        /* 4.9.7.3 The fputc function */
                    803:        /* 4.9.7.4 The fputs function */
                    804: 
                    805:        /* fgetc and fputc */
                    806:        f = fopen(afile, W_BIN);
                    807:        iequals(__LINE__, fputc(255, f), 255);
                    808:        iequals(__LINE__, fputc(0, f), 0);
                    809:        fclose(f);
                    810:        f = fopen(afile, R_BIN);
                    811:        /* make sure that there is no sign extension */
                    812:        iequals(__LINE__, fgetc(f), 255);
                    813:        iequals(__LINE__, fgetc(f), 0);
                    814:        SKIPNULLS(f, c);
                    815:        iequals(__LINE__, c, EOF);
                    816:        fclose(f);
                    817:        remove(afile);
                    818: 
                    819:        /* fputs and fgets */
                    820:        f = fopen(afile, "w");
                    821:        checkthat(__LINE__, fputs("string1\nstring2\nstring3\n", f) >= 0);      /* ANSI8709: weakened requirement */
                    822:        fclose(f);
                    823:        f = fopen(afile, "r");
                    824:        aequals(__LINE__, fgets(buff, 40, f), buff);
                    825:        iequals(__LINE__, str_cmp(buff, "string1\n"), 0);
                    826:        fgets(buff, 3, f);
                    827:        iequals(__LINE__, str_cmp(buff, "st"), 0);
                    828:        fgets(buff, 40, f);
                    829:        iequals(__LINE__, str_cmp(buff, "ring2\n"), 0);
                    830:        fgets(buff, 40, f);
                    831:        iequals(__LINE__, str_cmp(buff, "string3\n"), 0);
                    832:        aequals(__LINE__, fgets(buff, 40, f), NULL);
                    833:        /* buffer remains unchanged upon end of file */
                    834:        iequals(__LINE__, str_cmp(buff, "string3\n"), 0);
                    835:        fclose(f);
                    836: 
                    837:        /* error returns NULL */
                    838:        f = fopen(afile, "w");
                    839:        aequals(__LINE__, fgets(buff, 40, f), NULL);
                    840:        /* error returns non zero */
                    841:        f = freopen(afile, "r", f);
                    842: /*     inotequals( - __LINE__, fputs(buff, f), 0); */
                    843:        fclose(f);
                    844:        remove(afile);
                    845: 
                    846:        /* 4.9.7.5 The getc function */
                    847:        /* 4.9.7.6 The getchar function */
                    848:        /* 4.9.7.7 The gets function */
                    849:        /* 4.9.7.8 The putc function */
                    850:        /* 4.9.7.9 The putchar function */
                    851:        /* 4.9.7.10 The puts function */
                    852:        /* getc and putc */
                    853:        f = fopen(afile, W_BIN);
                    854:        iequals(__LINE__, putc(255, f), 255);
                    855:        iequals(__LINE__, putc(0, f), 0);
                    856:        fclose(f);
                    857:        f = fopen(afile, R_BIN);
                    858:        /* make sure that there is no sign extension */
                    859:        iequals(__LINE__, getc(f), 255);
                    860:        iequals(__LINE__, getc(f), 0);
                    861:        SKIPNULLS(f, c);
                    862:        iequals(__LINE__, c, EOF);
                    863:        fclose(f); remove(afile);
                    864:        /* getchar, putchar, puts, gets not tested; we don't want to lose stdin and stdout. */
                    865:        /* 4.9.7.11 The ungetc function */
                    866:        f = fopen(afile, "w");
                    867:        iequals(__LINE__, fputc('a', f), 'a');
                    868:        iequals(__LINE__, fputc('z', f), 'z');
                    869:        fclose(f);
                    870:        d4_9_7_11(afile, "r");
                    871:        f = fopen(afile, "w+");
                    872:        iequals(__LINE__, fputc('a', f), 'a');
                    873:        iequals(__LINE__, fputc('z', f), 'z');
                    874:        fclose(f);
                    875:        d4_9_7_11(afile, "r+");remove(afile);
                    876: 
                    877:        f = fopen(afile, W_BIN);
                    878:        iequals(__LINE__, fputc('a', f), 'a');
                    879:        iequals(__LINE__, fputc('z', f), 'z');
                    880:        fclose(f);
                    881:        d4_9_7_11(afile, R_BIN);
                    882:        d4_9_7_11(afile, R_BIN_U);
                    883: #if ANSI
                    884:        /* it should be possible to do an ungetc on an empty file */
                    885:        f = fopen(afile, W_BIN_U);
                    886:        iequals(__LINE__, ungetc('b', f), 'b');
                    887:        iequals(__LINE__, getc(f), 'b');
                    888:        /* fscanf and ungetc should not get in each others way */
                    889:        rewind(f);
                    890:        fprintf(f, "123abc\n");
                    891:        rewind(f);
                    892:        fscanf(f, "%d", &i);
                    893:        ungetc('x', f);
                    894:        iequals(__LINE__, getc(f), 'x');
                    895:        iequals(__LINE__, getc(f), 'a');
                    896:        fclose(f);
                    897: #endif
                    898:        remove(afile);
                    899: #endif /* SKIP497 */
                    900:        }
                    901: 
                    902: /*
                    903:  * 4.9.7.11 - the ungetc code will get executed for several
                    904:  * different file open modes.
                    905:  */
                    906: static void d4_9_7_11(afile, mode)
                    907:        char *afile;
                    908:        char *mode;
                    909:        {
                    910: #ifndef SKIP497_11 /* note: if SKIP497 is defined, 497_11 isn't called */
                    911:        long oldpos;
                    912:        int c;
                    913:        FILE *f;
                    914: #if ANSI
                    915:        fpos_t pos;
                    916: #endif
                    917: 
                    918:        f = fopen(afile, mode);
                    919: #if ANSI
                    920:        fgetpos(f, &pos);
                    921: #endif
                    922:        iequals(__LINE__, fgetc(f), 'a');
                    923:        iequals(__LINE__, ungetc('b', f), 'b');
                    924:        iequals(__LINE__, getc(f), 'b');
                    925:        iequals(__LINE__, ungetc('c', f), 'c');
                    926: 
                    927:        /* fseek, rewind, and fsetpos lose ungot character */
                    928:        fseek(f, 0L, SEEK_SET);
                    929:        iequals( - __LINE__, getc(f), 'a');
                    930:        iequals(__LINE__, getc(f), 'z');
                    931:        iequals(__LINE__, ungetc('b', f), 'b');
                    932:        rewind(f);
                    933:        iequals(__LINE__, getc(f), 'a');
                    934:        iequals(__LINE__, getc(f), 'z');
                    935: #if ANSI
                    936:        ungetc('b', f);
                    937:        fsetpos(f, &pos);
                    938:        iequals(__LINE__, getc(f), 'a');
                    939:        iequals(__LINE__, getc(f), 'z');
                    940: #endif
                    941: 
                    942:        /* the external file remains unchanged */
                    943:        iequals(__LINE__, ungetc('b', f), 'b');
                    944:        fclose(f);
                    945:        f = fopen(afile, mode);
                    946:        iequals(__LINE__, fgetc(f), 'a');
                    947:        iequals(__LINE__, fgetc(f), 'z');
                    948:        SKIPNULLS(f, c);
                    949:        /* record oriented systems might add this newline */
                    950:        if (c == '\n')
                    951:                c = fgetc(f);
                    952:        iequals(__LINE__, c, EOF);
                    953:        fclose(f);
                    954: 
                    955:        /* ungetc of EOF has no effect */
                    956:        f = fopen(afile, mode);
                    957:        iequals(__LINE__, fgetc(f), 'a');
                    958:        iequals(__LINE__, ungetc(EOF, f), EOF);
                    959:        iequals(__LINE__, fgetc(f), 'z');
                    960:        SKIPNULLS(f, c);
                    961:        /* record oriented systems might add this newline */
                    962:        if (c == '\n')
                    963:                c = fgetc(f);
                    964:        iequals(__LINE__, c, EOF);
                    965: #if ANSI
                    966:        /* a successful ungetc clears the EOF indicator */
                    967:        iequals(__LINE__, ungetc('b', f), 'b');
                    968:        iequals(__LINE__, feof(f), 0);
                    969:        iequals(__LINE__, fgetc(f), 'b');
                    970: #endif
                    971:        /* after ungetc then read, the file position is restored */
                    972:        oldpos = ftell(f);
                    973:        iequals(__LINE__, ungetc('b', f), 'b');
                    974:        iequals(__LINE__, fgetc(f), 'b');
                    975:        lequals(__LINE__, ftell(f), oldpos);
                    976: 
                    977:        /* if binary, the file position decrements by 1 */
                    978:        if (str_str(mode, "b") != NULL)
                    979:                {
                    980:                oldpos = ftell(f);
                    981:                iequals(__LINE__, ungetc('a', f), 'a');
                    982:                lequals(__LINE__, ftell(f), oldpos - 1L);
                    983:                }
                    984: #if ANSI
                    985:        /* ANSI requires ability to do an ungetc at the start of a file */
                    986:        rewind(f);
                    987:        iequals(__LINE__, ungetc('b', f), 'b');
                    988:        iequals(__LINE__, fgetc(f), 'b');
                    989:        iequals(__LINE__, fgetc(f), 'a');
                    990: #endif
                    991:        fclose(f);
                    992: #endif /* SKIP497_11 */
                    993:        }
                    994: 
                    995: /*
                    996:  * 4.9.8 - Direct input/output functions
                    997:  */
                    998: static long array1[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
                    999: static long array2[11] = {0};
                   1000: static void d4_9_8()
                   1001:        {
                   1002: #ifndef SKIP498
                   1003:        FILE *f;
                   1004:        int i;
                   1005: #if ANSI
                   1006:        char *afile = save_name(tmpnam(NULL));
                   1007: #else
                   1008:        char *afile = mktemp("aXXXXXX");
                   1009: #endif
                   1010:        int c;
                   1011: 
                   1012:        /* 4.9.8.1 The fread function */
                   1013:        /* 4.9.8.2 The fwrite function */
                   1014: 
                   1015:        f = fopen(afile, W_BIN);
                   1016:        iequals(__LINE__, fwrite(array1, sizeof(long), 10, f), 10);
                   1017:        fclose(f);
                   1018:        f = fopen(afile, R_BIN);
                   1019:        iequals(__LINE__, fread(array2, sizeof(long), 6, f), 6);
                   1020: 
                   1021:        /* zero size or nelem leaves array unchanged */
                   1022:        iequals(__LINE__, fread(array2, 0, sizeof(long), f), 0);
                   1023:        iequals(__LINE__, fread(array2, 10, 0, f), 0);
                   1024: 
                   1025:        /* incomplete read */
                   1026:        iequals(__LINE__, fread(array2+6, sizeof(long), 4, f), 4);
                   1027:        for (i = 0; i < 10; ++i)
                   1028:                lequals(__LINE__, array2[i], array1[i]);
                   1029:        SKIPNULLS(f, c);
                   1030: 
                   1031:        /* at end of file */
                   1032:        iequals(__LINE__, fread(array2, 10, sizeof(long), f), 0);
                   1033:        fclose(f);
                   1034:        remove(afile);
                   1035: #endif /* SKIP498 */
                   1036:        }
                   1037: 
                   1038: /*
                   1039:  * 4.9.9 - Random-access functions
                   1040:  */
                   1041: static char buffer[] = "     this is a test string of no particular significance\n";
                   1042: static char xchar[] = "abcdefghijklmnopqrstuvwxyz";
                   1043: static void d4_9_9()
                   1044:        {
                   1045: #ifndef SKIP499
                   1046:        FILE *f;
                   1047:        int i;
                   1048:        long array[100];
                   1049: #if ANSI
                   1050:        fpos_t pos[100];
                   1051:        char *afile = save_name(tmpnam(NULL));
                   1052: #else
                   1053:        char *afile = mktemp("aXXXXXX");
                   1054: #endif
                   1055: 
                   1056:        /* 4.9.9.1 The fgetpos function */
                   1057:        /* 4.9.9.2 The fseek function */
                   1058:        /* 4.9.9.3 The fsetpos function */
                   1059:        /* 4.9.9.4 The ftell function */
                   1060: 
                   1061:        /* 
                   1062:         * create a file with 100 strings, mark the "ftell" position
                   1063:         * of each one, and read them in backwards.
                   1064:         */
                   1065:        f = fopen(afile, "w+");
                   1066:        for (i = 0; i < 100; ++i)
                   1067:                {
                   1068:                array[i] = ftell(f);
                   1069:                buffer[0] = xchar[i%26];
                   1070:                fwrite(buffer, sizeof(buffer), 1, f);
                   1071:                }
                   1072:        for (i = 99; i >= 0; --i)
                   1073:                {
                   1074:                fseek(f, array[i], SEEK_SET);
                   1075:                fread(buffer, sizeof(buffer), 1, f);
                   1076:                iequals(__LINE__, xchar[i%26], buffer[0]);
                   1077:                }
                   1078:        fclose(f); remove(afile);
                   1079: 
                   1080:        /* for binary files, ftell can compute offsets */
                   1081:        f = fopen(afile, WU_BIN);
                   1082:        fwrite(array, sizeof(long), 100, f);
                   1083:        lequals(__LINE__, ftell(f), 100L*sizeof(long));
                   1084: 
                   1085:        fseek(f, 50L, SEEK_SET);
                   1086:        lequals(__LINE__, ftell(f), 50L);
                   1087:        fseek(f, 40L, SEEK_CUR);
                   1088:        lequals(__LINE__, ftell(f), 90L);
                   1089:        fseek(f, -40L, SEEK_END);
                   1090:        lequals( - __LINE__, ftell(f), 100*sizeof(long)-40L);   /* "remark" only - could be nul-padded */
                   1091: 
                   1092:        /* fseek clears the end of file indicator */
                   1093:        fseek(f, 0L, SEEK_END);
                   1094:        iequals(__LINE__, fgetc(f), EOF);
                   1095:        fseek(f, 0L, SEEK_END);
                   1096:        iequals(__LINE__, feof(f), 0);
                   1097: 
                   1098:        /* fseek: bad requests return non-zero 
                   1099:         * ftell: bad requests return -1L and set errno
                   1100:         */
                   1101:        inotequals(__LINE__, fseek(f, -1L, SEEK_SET), 0);
                   1102:        fclose(f); remove(afile);
                   1103:        errno = 0;
                   1104: 
                   1105: #if ANSI
                   1106:        lequals(__LINE__, ftell(f), -1L);
                   1107:        inotequals(__LINE__, errno, 0);
                   1108: #endif
                   1109: 
                   1110:        f = fopen(afile, W_BIN_U);
                   1111: #if ANSI
                   1112:        /* 
                   1113:         * create a file with 100 strings, mark the "getpos" position
                   1114:         * of each one, and read them in backwards.
                   1115:         */
                   1116:        for (i = 0; i < 100; ++i)
                   1117:                {
                   1118:                fgetpos(f, &pos[i]);
                   1119:                buffer[0] = xchar[i%26];
                   1120:                fwrite(buffer, sizeof(buffer), 1, f);
                   1121:                }
                   1122:        for (i = 99; i >= 0; --i)
                   1123:                {
                   1124:                fsetpos(f, &pos[i]);
                   1125:                fread(buffer, sizeof(buffer), 1, f);
                   1126:                iequals(__LINE__, xchar[i%26], buffer[0]);
                   1127:                }
                   1128: 
                   1129:        /* successful return is 0, unsuccessful is non-zero + errno */
                   1130:        iequals(__LINE__, fgetpos(f, &pos[0]), 0);
                   1131:        iequals(__LINE__, fsetpos(f, &pos[0]), 0);
                   1132: #endif
                   1133:        fputs("a\n", f);        /* be sure that following tests work, even for non-ANSI */
                   1134:        fclose(f);
                   1135: 
                   1136:        /* 4.9.9.5 The rewind function */
                   1137:        /* rewind is the same as fseek(f, 0L, SEEK_SET) */
                   1138:        /* in order for  ftell(f)  to be well-defined, */
                   1139:        /* file  f  must be binary (and must be created as binary) */
                   1140:        f = fopen(afile, R_BIN);
                   1141:        if (f == NULL)
                   1142:                complain(__LINE__);
                   1143:        else
                   1144:                {
                   1145:                fseek(f, 0L, SEEK_END);
                   1146:                iequals(__LINE__, fgetc(f), EOF);
                   1147:                rewind(f);
                   1148:                lequals(__LINE__, ftell(f), 0L);
                   1149:                fclose(f);
                   1150:                }
                   1151:        remove(afile);
                   1152: #endif /* SKIP499 */
                   1153:        }
                   1154: 
                   1155: /*
                   1156:  * 4.9.10 - Error-handling functions
                   1157:  */
                   1158: static void d4_9_10()
                   1159:        {
                   1160: #ifndef SKIP49_10
                   1161:        FILE *f;
                   1162:        char * (*fp)();
                   1163: #if ANSI
                   1164:        char *afile = save_name(tmpnam(NULL));
                   1165: #else
                   1166:        char *afile = mktemp("aXXXXXX");
                   1167:        extern void perror();
                   1168: #endif
                   1169:        char c;
                   1170: 
                   1171:        /* 4.9.9.1 The clearerr function */
                   1172:        /* 4.9.9.2 The feof function */
                   1173: 
                   1174:        f = fopen(afile, W_BIN);
                   1175:        fputc('x', f);
                   1176:        fclose(f);
                   1177:        f = fopen(afile, R_BIN);
                   1178:        iequals(__LINE__, feof(f), 0);
                   1179:        fgetc(f);
                   1180:        SKIPNULLS(f, c);
                   1181:        inotequals(__LINE__, feof(f), 0);
                   1182:        clearerr(f);
                   1183:        iequals(__LINE__, feof(f), 0);
                   1184: 
                   1185:        /* 4.9.9.3 The ferror function */
                   1186:        iequals(__LINE__, ferror(f), 0);
                   1187: 
                   1188:        /* There is unfortunately no portable way to force an "I/O error" for testing ferror */
                   1189: 
                   1190: #if ANSI
                   1191:        /* 4.9.9.4 The perror function */
                   1192:        /* just check for existence */
                   1193:        errno = 0;
                   1194:        perror(NULL);
                   1195: #endif
                   1196: 
                   1197:        fclose(f);
                   1198:        remove(afile);
                   1199: #endif /* SKIP49_10 */
                   1200:        }
                   1201: 
                   1202: /*
                   1203:  * 4.9.4.4 - Now that tmpnam() is no longer needed, verify that
                   1204: * we can get at least 25 unique names (the min-max for TMP_MAX).
                   1205:  * next_name is how many have been used so far.
                   1206:  */
                   1207: static void d4_9_4_4()
                   1208:        {
                   1209: #ifndef SKIP4944
                   1210:        int i, j;
                   1211: 
                   1212: #if ANSI
                   1213:        for (i = 0; i < next_name; ++i)
                   1214:                for (j = 0; j < i; ++j)
                   1215:                        if (str_cmp(names[i], names[j]) == 0)
                   1216:                                {
                   1217:                                complain(__LINE__);
                   1218:                                return;
                   1219:                                }
                   1220:        for (i = next_name; i < 25; ++i)
                   1221:                {
                   1222:                if (checkthat(__LINE__, tmpnam(names[i]) != NULL) != 0)
                   1223:                        return;
                   1224:                for (j = 0; j < i; ++j)
                   1225:                        if (str_cmp(names[i], names[j]) == 0)
                   1226:                                {
                   1227:                                complain(__LINE__);
                   1228:                                return;
                   1229:                                }
                   1230:                }
                   1231: #endif 
                   1232: #endif /* SKIP4944 */
                   1233:        }
                   1234: 
                   1235: #else /* if SKIP49 */
                   1236: void d4_9() { pr_skip("d4_9: SKIPPED ENTIRELY\n"); }
                   1237: #endif
                   1238: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.