|
|
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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.