|
|
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 SKIP410 ! 13: #define LIB_TEST 1 ! 14: #include "defs.h" ! 15: ! 16: /* ! 17: * 4.10 - General Utilities <stdlib.h> ! 18: */ ! 19: ! 20: #if ANSI ! 21: #include <stdlib.h> ! 22: #if ANSI8703 ! 23: #include <errno.h> ! 24: #endif /* ANSI8703 */ ! 25: #else /* if !ANSI */ ! 26: #include <stdio.h> /* for NULL, at least */ ! 27: extern int errno; ! 28: double atof(); ! 29: int atoi(); ! 30: long atol(); ! 31: char *calloc(), *malloc(), *realloc(); ! 32: void free(); ! 33: void abort(); ! 34: void exit(); ! 35: char *getenv(); ! 36: int system(); ! 37: #endif /* ANSI */ ! 38: ! 39: int strcmp(); ! 40: size_t strlen(); ! 41: ! 42: #include <math.h> ! 43: static void d4_10_1(); ! 44: static void d4_10_2(); ! 45: static void d4_10_3(); ! 46: static void d4_10_4(); ! 47: static void d4_10_4x(); ! 48: static void d4_10_5(); ! 49: static void d4_10_6(); ! 50: static void d4_10_7(); ! 51: static void d4_10_8(); ! 52: ! 53: ! 54: #ifndef SKIP4_101 ! 55: static char *string1 = "1.234 2.3e99999999999999999999"; ! 56: static char *string2 = " 123 10"; ! 57: static char *string3 = "999999999999999999999999999999999999999999999999999999"; ! 58: static char *string4 = "-99999999999999999999999999999999999999999999999999999"; ! 59: static char *string5 = " XXX"; ! 60: #endif /* SKIP4_101 */ ! 61: ! 62: void d4_10() ! 63: { ! 64: ! 65: Filename = "d410.c"; ! 66: #if ANSI ! 67: { ! 68: /* check existence of types */ ! 69: div_t dummy1; ! 70: ldiv_t dummy2; ! 71: #if WIDE_CHARS ! 72: wchar_t wc; ! 73: #endif /* WIDE_CHARS */ ! 74: size_t si; ! 75: int i; ! 76: ! 77: /* check definition of required macros */ ! 78: #if !defined(EXIT_FAILURE) ! 79: complain(__LINE__); ! 80: #elif !defined(EXIT_SUCCESS) ! 81: complain(__LINE__); ! 82: #elif !defined(RAND_MAX) ! 83: complain(__LINE__); ! 84: #elif !defined(MB_CUR_MAX) ! 85: complain(__LINE__); ! 86: #endif ! 87: ! 88: checkthat(__LINE__, sizeof(div_t) >= 2*sizeof(int)); ! 89: checkthat(__LINE__, sizeof(ldiv_t) >= 2*sizeof(long)); ! 90: #if WIDE_CHARS ! 91: checkthat(__LINE__, MB_CUR_MAX >= 1); ! 92: #endif /* WIDE_CHARS */ ! 93: ! 94: /* make sure that these expand to integral expressions (compile ! 95: * fails if not). ! 96: */ ! 97: i = ivalue(-99); if (i == EXIT_FAILURE) do_nothing(&si); ! 98: i = ivalue(-99); if (i == EXIT_SUCCESS) do_nothing(&si); ! 99: i = ivalue(-99); switch (i) { case RAND_MAX: do_nothing(&si); } ! 100: } ! 101: #endif /* ANSI */ ! 102: d4_10_1(); ! 103: d4_10_2(); ! 104: d4_10_3(); ! 105: d4_10_4(); ! 106: d4_10_5(); ! 107: d4_10_6(); ! 108: d4_10_7(); ! 109: d4_10_8(); ! 110: } ! 111: ! 112: #if ANSI ! 113: #include <limits.h> ! 114: #include <float.h> ! 115: #endif /* ANSI */ ! 116: /* ! 117: * 4.10.1 String conversion functions ! 118: */ ! 119: static void d4_10_1() ! 120: { ! 121: #ifndef SKIP4_101 ! 122: char *p; ! 123: int i; ! 124: long l; ! 125: double d; ! 126: ! 127: /* atof, atoi, atol do not affect errno */ ! 128: errno = 99; ! 129: ! 130: /* 4.10.1.1 atof ! 131: * text to float ! 132: */ ! 133: dequals(__LINE__, atof("XXX"), 0.0); ! 134: dequals(__LINE__, atof("\f\t\n\r\v1.234"), 1.234); ! 135: dequals(__LINE__, atof("1.234"), 1.234); ! 136: dequals(__LINE__, atof(" +1.234"), 1.234); ! 137: dequals(__LINE__, atof(" +1.234"), 1.234); ! 138: dequals(__LINE__, atof(" -1.234"), -1.234); ! 139: dequals(__LINE__, atof(" +1.234e1"), 1.234e1); ! 140: dequals(__LINE__, atof(" +1.234E1"), 1.234E1); ! 141: dequals(__LINE__, atof(" +1.234E-1"), 1.234E-1); ! 142: dequals(__LINE__, atof(" +1.234XE-1"), 1.234); ! 143: ! 144: /* 4.10.1.2 atoi ! 145: * text to int ! 146: */ ! 147: iequals(__LINE__, atoi("XXX"), 0); ! 148: iequals(__LINE__, atoi("123"), 123); ! 149: iequals(__LINE__, atoi("+123"), 123); ! 150: iequals(__LINE__, atoi("-123"), -123); ! 151: iequals(__LINE__, atoi(" +123"), 123); ! 152: iequals(__LINE__, atoi(" 0123"), 123); ! 153: iequals(__LINE__, atoi(" 0x123"), 0); ! 154: iequals(__LINE__, atoi(" 12a3"), 12); ! 155: ! 156: /* 4.10.1.3 atol ! 157: * text to long ! 158: */ ! 159: lequals(__LINE__, atol("XXX"), 0L); ! 160: lequals(__LINE__, atol("123456"), 123456); ! 161: lequals(__LINE__, atol("+123456"), 123456); ! 162: lequals(__LINE__, atol("-123456"), -123456); ! 163: lequals(__LINE__, atol(" +123456"), 123456); ! 164: lequals(__LINE__, atol(" 0123456"), 123456); /* not octal !! */ ! 165: lequals(__LINE__, atol(" 0x123456"), 0L); ! 166: lequals(__LINE__, atol(" 12a3"), 12L); ! 167: ! 168: errno = 0; ! 169: ! 170: #if ANSI ! 171: /* 4.10.1.4 strtod ! 172: * Same as atof, but gets pointer to end character and error checking ! 173: */ ! 174: dequals(__LINE__, strtod("XXX", &p), 0.0); ! 175: dequals(__LINE__, strtod("\f\t\n\r\v1.1", &p), 1.1); ! 176: dequals(__LINE__, strtod("1.234", &p), 1.234); ! 177: dequals(__LINE__, strtod(" +1.234", &p), 1.234); ! 178: dequals(__LINE__, strtod(" +1.234", &p), 1.234); ! 179: dequals(__LINE__, strtod(" -1.234", &p), -1.234); ! 180: dequals(__LINE__, strtod(" +1.234e1", &p), 1.234e1); ! 181: dequals(__LINE__, strtod(" +1.234E1", &p), 1.234E1); ! 182: dequals(__LINE__, strtod(" +1.234E-1", &p), 1.234E-1); ! 183: dequals(__LINE__, strtod(" +1.234XE-1", &p), 1.234); ! 184: ! 185: /* on no conversion, end pointer doesn't move */ ! 186: d = strtod(string5+3, &p); ! 187: aequals(__LINE__, p, string5+3); ! 188: d = strtod(string5, &p); ! 189: aequals(__LINE__, p, string5); ! 190: ! 191: /* endptr gets pointer to remaining string */ ! 192: dequals(__LINE__, strtod(string1, &p), 1.234); ! 193: aequals(__LINE__, p++, string1+5); ! 194: ! 195: /* overflow returns +/- HUGE_VAL */ ! 196: errno = 0; ! 197: dequals(__LINE__, strtod(p, NULL), HUGE_VAL); ! 198: iequals(__LINE__, errno, ERANGE); ! 199: errno = 0; ! 200: dequals(__LINE__, strtod("-1e99999999999999999999", NULL), -HUGE_VAL); ! 201: iequals(__LINE__, errno, ERANGE); ! 202: ! 203: /* underflow returns 0 */ ! 204: errno = 0; ! 205: dequals(__LINE__, strtod("1e-9999999999999999", NULL), 0.0); ! 206: iequals(__LINE__, errno, ERANGE); ! 207: ! 208: /* 4.10.1.5 strtol ! 209: * same as atol but with pointer, base, and error checking ! 210: */ ! 211: lequals(__LINE__, strtol("XXX", &p, 0), 0L); ! 212: lequals(__LINE__, strtol(string2, &p, 8), 0123L); ! 213: aequals(__LINE__, p++, string2+12); ! 214: ! 215: /* check out bases */ ! 216: for (i = 2; i <= 36; ++i) ! 217: lequals(__LINE__, strtol("11", NULL, i), (long)(i+1)); ! 218: lequals(__LINE__, strtol("zzz", NULL, 36), (((35L*36L)+35L)*36L)+35L); ! 219: ! 220: /* 0 base uses default C parsing rules */ ! 221: lequals(__LINE__, strtol("0x12345", NULL, 0), 0x12345L); ! 222: lequals(__LINE__, strtol("0123", NULL, 0), 0123L); ! 223: lequals(__LINE__, strtol(" -123", NULL, 0), -123L); ! 224: lequals(__LINE__, strtol(" +123", NULL, 0), 123L); ! 225: ! 226: /* otherwise, same as atol */ ! 227: lequals(__LINE__, strtol("\f\t\n\r\v7", &p, 10), 7L); ! 228: lequals(__LINE__, strtol("123456", &p, 10), 123456L); ! 229: lequals(__LINE__, strtol("+123456", &p, 10), 123456L); ! 230: lequals(__LINE__, strtol("-123456", &p, 10), -123456L); ! 231: lequals(__LINE__, strtol(" +123456", &p, 10), 123456L); ! 232: lequals(__LINE__, strtol(" 0123456", &p, 10), 123456L); ! 233: lequals(__LINE__, strtol(" 0x123456", &p, 10), 0L); ! 234: lequals(__LINE__, strtol(" 0x123456", &p, 16), 0x123456L); ! 235: lequals(__LINE__, strtol(" -0X123456", &p, 16), -0x123456L); ! 236: lequals(__LINE__, strtol(" 12a3", &p, 10), 12L); ! 237: ! 238: /* on no conversion, end pointer doesn't move */ ! 239: d = strtol(string5+3, &p, 10); ! 240: aequals(__LINE__, p, string5+3); ! 241: d = strtol(string5, &p, 10); ! 242: aequals(__LINE__, p, string5); ! 243: ! 244: /* error checking */ ! 245: errno = 0; ! 246: lequals(__LINE__, strtol(string3, NULL, 0), LONG_MAX); ! 247: iequals(__LINE__, errno, ERANGE); ! 248: errno = 0; ! 249: lequals(__LINE__, strtol(string4, NULL, 0), LONG_MIN); ! 250: iequals(__LINE__, errno, ERANGE); ! 251: ! 252: ! 253: ! 254: /* 4.10.1.6 strtoul ! 255: * same conversions as strtol, but to unsigned long ! 256: */ ! 257: lequals(__LINE__, strtoul("XXX", &p, 0), 0L); ! 258: lequals(__LINE__, strtoul(string2, &p, 8), 0123L); ! 259: aequals(__LINE__, p++, string2+12); ! 260: ! 261: /* check out bases */ ! 262: for (i = 2; i <= 36; ++i) ! 263: lequals(__LINE__, strtoul("11", NULL, i), (long)(i+1)); ! 264: lequals(__LINE__, strtoul("zzz", NULL, 36), (((35L*36L)+35L)*36L)+35L); ! 265: ! 266: /* 0 base uses default C parsing rules */ ! 267: lequals(__LINE__, strtoul("0x12345", NULL, 0), 0x12345L); ! 268: lequals(__LINE__, strtoul("0123", NULL, 0), 0123L); ! 269: ! 270: lequals(__LINE__, strtoul("\f\t\n\r\v7", &p, 10), 7L); ! 271: lequals(__LINE__, strtoul("123456", &p, 10), 123456L); ! 272: lequals(__LINE__, strtoul(" 0123456", &p, 10), 123456L); ! 273: lequals(__LINE__, strtoul(" 0x123456", &p, 10), 0L); ! 274: lequals(__LINE__, strtoul(" 0x123456", &p, 16), 0x123456L); ! 275: lequals(__LINE__, strtoul(" 0X123456", &p, 16), 0x123456L); ! 276: lequals(__LINE__, strtoul(" 12a3", &p, 10), 12L); ! 277: #if ANSI8712 ! 278: lequals(__LINE__, strtoul(" +12", &p, 10), 12L); ! 279: #endif /* ANSI8712 */ ! 280: ! 281: /* on no conversion, end pointer doesn't move */ ! 282: d = strtoul(string5+3, &p, 10); ! 283: aequals(__LINE__, p, string5+3); ! 284: d = strtoul(string5, &p, 10); ! 285: aequals(__LINE__, p, string5); ! 286: ! 287: /* error checking */ ! 288: errno = 0; ! 289: lequals(__LINE__, strtoul(string3, NULL, 0), ULONG_MAX); ! 290: iequals(__LINE__, errno, ERANGE); ! 291: #endif /* ANSI */ ! 292: #endif /* SKIP4_101 */ ! 293: } ! 294: ! 295: /* ! 296: * 4.10.2 - Random number generation functions. ! 297: */ ! 298: static void d4_10_2() ! 299: { ! 300: #ifndef SKIP4_102 ! 301: int i1, i2, i3, j1, j2, j3; ! 302: ! 303: /* 4.10.2.1 rand ! 304: * before ansi, all we can count on is that the sequence exists ! 305: */ ! 306: i1 = rand(); ! 307: i2 = rand(); ! 308: i3 = rand(); ! 309: ! 310: /* 4.10.2.2 srand ! 311: * that it can be reset to the default ! 312: */ ! 313: srand(1); ! 314: j1 = rand(); ! 315: j2 = rand(); ! 316: j3 = rand(); ! 317: iequals(__LINE__, i1, j1); ! 318: iequals(__LINE__, i2, j2); ! 319: iequals(__LINE__, i3, j3); ! 320: ! 321: /* and reset arbitrarily */ ! 322: srand(11); ! 323: i1 = rand(); ! 324: i2 = rand(); ! 325: i3 = rand(); ! 326: srand(11); ! 327: j1 = rand(); ! 328: j2 = rand(); ! 329: j3 = rand(); ! 330: iequals(__LINE__, i1, j1); ! 331: iequals(__LINE__, i2, j2); ! 332: iequals(__LINE__, i3, j3); ! 333: ! 334: #if ANSI ! 335: /* now the range is specified */ ! 336: for (i1 = 0; i1 < 30; ++i1) ! 337: { ! 338: j1 = rand(); ! 339: checkthat(__LINE__, 0 <= j1 && j1 <= RAND_MAX); ! 340: } ! 341: #endif /* ANSI */ ! 342: #endif /* SKIP4_102 */ ! 343: } ! 344: ! 345: ! 346: ! 347: /* ! 348: * 4.10.3 - Memory management functions ! 349: */ ! 350: static void d4_10_3() ! 351: { ! 352: #ifndef SKIP4_103 ! 353: int i; ! 354: char *pc; ! 355: long *pl; ! 356: double d = 9.87; ! 357: union all ! 358: { ! 359: char c; ! 360: short s; ! 361: int i; ! 362: long l; ! 363: double d; ! 364: #if ANSI ! 365: long double ld; ! 366: #endif /* ANSI */ ! 367: char *pc; ! 368: long *pl; ! 369: double *pd; ! 370: } *pu; ! 371: int is_all_zero; ! 372: ! 373: /* 4.10.3.1 calloc ! 374: * Can't do much more than check for existence and see if ! 375: * using them doesn't crash the program. Calloc zeros out ! 376: * the space. ! 377: */ ! 378: pc = calloc(100, sizeof(long)); ! 379: is_all_zero = 1; /* See update item #534, Review Board 8/92 */ ! 380: for (i = 0; i < 100*sizeof(long); ++i) ! 381: { ! 382: if (pc[i] != 0) ! 383: is_all_zero = 0; ! 384: } ! 385: iequals(__LINE__, is_all_zero, 1); ! 386: ! 387: pl = (long *)pc; ! 388: for (i = 0; i < 100; ++i) ! 389: lequals(__LINE__, pl[i], 0L); ! 390: ! 391: free((char *)pl); ! 392: ! 393: /* Check alignment properties ... presumably the program ! 394: * could crash if there is an alignment error. Here is a case ! 395: * where it is important to try to defeat optimizers, so ivalue, etc. ! 396: * are used for the assignments.. ! 397: */ ! 398: pu = (union all *)calloc(100, sizeof(*pu)); ! 399: pu->c = ivalue('a'); ! 400: iequals(__LINE__, pu->c, 'a'); ! 401: pu->s = ivalue(SHRT_MAX); ! 402: iequals(__LINE__, pu->s, SHRT_MAX); ! 403: pu->i = ivalue(INT_MAX); ! 404: iequals(__LINE__, pu->i, INT_MAX); ! 405: pu->l = lvalue(LONG_MAX); ! 406: lequals(__LINE__, pu->l, LONG_MAX); ! 407: pu->d = dvalue(2.34); ! 408: dequals(__LINE__, pu->d, 2.34); ! 409: #if ANSI ! 410: pu->ld = 3.45L; ! 411: ldequals(__LINE__, pu->ld, 3.45L); ! 412: #endif /* ANSI */ ! 413: /* pointer to integral types already checked */ ! 414: pu->pd = (double *)avalue(&d); ! 415: dequals(__LINE__, *(pu->pd), 9.87); ! 416: ! 417: /* check for 0 as arguments */ ! 418: aequals(- __LINE__, calloc(0, 100), NULL); /* ANSI8612: behavior is implem-def; see 4.10.3 P1s1 */ ! 419: aequals(- __LINE__, calloc(100, 0), NULL); /* ANSI8612: behavior is implem-def; see 4.10.3 P1s1 */ ! 420: ! 421: /* 4.10.3.2 free used throughout. ANSI requires free to accept a NULL argument. */ ! 422: #if ANSI ! 423: free(NULL); ! 424: #endif /* ANSI */ ! 425: ! 426: /* 4.10.3.3 malloc ! 427: */ ! 428: pc = malloc(100 * sizeof(long)); ! 429: for (i = 0; i < 100*sizeof(long); ++i) ! 430: pc[i] = i%128; ! 431: for (i = 0; i < 100*sizeof(long); ++i) ! 432: iequals(__LINE__, pc[i], i%128); ! 433: pl = (long *)pc; ! 434: for (i = 0; i < 100; ++i) ! 435: pl[i] = i; ! 436: for (i = 0; i < 100; ++i) ! 437: lequals(__LINE__, pl[i], (long)i); ! 438: ! 439: ! 440: /* check for 0 as arguments */ ! 441: aequals(- __LINE__, malloc(0), NULL); /* ANSI8612: behavior is implem-def; see 4.10.3 P1s1 */ ! 442: ! 443: /* 4.10.3.4 realloc ! 444: * contents should be the same up to the lesser size ! 445: */ ! 446: pc = realloc((char *)pl, 200*sizeof(long)); ! 447: pl = (long *)pc; ! 448: for (i = 0; i < 100; ++i) ! 449: lequals(__LINE__, pl[i], (long)i); ! 450: pc = realloc((char *)pl, 50*sizeof(long)); ! 451: pl = (long *)pc; ! 452: for (i = 0; i < 50; ++i) ! 453: lequals(__LINE__, pl[i], (long)i); ! 454: free(pc); ! 455: #if ANSI ! 456: /* ANSI requires that NULL and 0 are acceptable as arguments */ ! 457: pc = realloc(NULL, 400); ! 458: for (i = 0; i < 400; ++i) ! 459: pc[i] = i%128; ! 460: for (i = 0; i < 400; ++i) ! 461: iequals(__LINE__, pc[i], i%128); ! 462: aequals(- __LINE__, realloc(pc, 0), NULL); /* ANSI8612: behavior is implem-def; see 4.10.3 P1s1 */ ! 463: #endif /* ANSI */ ! 464: #endif /* SKIP4_103 */ ! 465: } ! 466: ! 467: /* ! 468: * 4.10.4 - Communication with the environment. ! 469: */ ! 470: typedef int (*PIF)(); ! 471: #ifndef SKIP4_104 ! 472: static void d4_10_4y(); ! 473: static void d4_10_4z(); ! 474: #endif /* SKIP4_104 */ ! 475: static void d4_10_4() ! 476: { ! 477: #ifndef SKIP4_104 ! 478: PIF p; ! 479: int i; ! 480: void d4_10_4x(); ! 481: ! 482: /* Existence of these functions has been checked in 4.1. ! 483: * Most of these we can't call without terminating the program, ! 484: * in which case no real testing is done. ! 485: */ ! 486: ! 487: #if ANSI ! 488: /* 4.10.4.1 abort ! 489: * terminates the program, so don't call it. ! 490: */ ! 491: p = (PIF)abort; ! 492: ! 493: /* 4.10.4.2 atexit ! 494: * register functions to be called at exit. At least ! 495: * 32 must be allowed. As of ANSI8712 it is required that ! 496: * they be called in reverse order of registry. ! 497: */ ! 498: #if ANSI8712 ! 499: iequals(__LINE__, atexit(d4_10_4x), 0); ! 500: for (i = 0; i < 30; ++i) ! 501: iequals(__LINE__, atexit(d4_10_4y), 0); ! 502: iequals(__LINE__, atexit(d4_10_4z), 0); ! 503: #else ! 504: for (i = 0; i < 32; ++i) ! 505: iequals(__LINE__, atexit(d4_10_4x), 0); ! 506: #endif /* ANSI8712 */ ! 507: #endif /* ANSI */ ! 508: ! 509: /* 4.10.4.3 exit ! 510: * will be tested at the end of main ! 511: */ ! 512: #if ANSI8612 ! 513: checkthat(__LINE__, EXIT_SUCCESS != EXIT_FAILURE); ! 514: #endif /* ANSI8612 */ ! 515: p = (PIF)exit; ! 516: ! 517: /* 4.10.4.4 getenv ! 518: * returns an implementation dependant pointer ! 519: */ ! 520: aequals(- __LINE__, getenv("this is probably a NULL pointer"), NULL); ! 521: ! 522: /* 4.10.4.4 system ! 523: * is very implementation dependent. Does a command processor ! 524: * exist? Return of 0 says not. ! 525: */ ! 526: checkthat(- __LINE__, system(NULL) != 0); ! 527: #endif /* SKIP4_104 */ ! 528: } ! 529: ! 530: static int i = 0; ! 531: #ifndef SKIP4_104 ! 532: static void d4_10_4z() ! 533: { ! 534: Filename = "d410.c"; ! 535: /* this function was registered last, so it should be called first */ ! 536: if (++i != 1) ! 537: complain(__LINE__); ! 538: } ! 539: static void d4_10_4y() ! 540: { ! 541: Filename = "d410.c"; ! 542: /* there should be exactly 30 invocations of this function */ ! 543: if (i < 1 || i > 30) ! 544: complain(__LINE__); ! 545: ++i; ! 546: } ! 547: #if ANSI8712 ! 548: static void d4_10_4x() ! 549: { ! 550: Filename = "d410.c"; ! 551: /* this function was registered first, so it should be called last */ ! 552: if (++i != 32) ! 553: complain(__LINE__); ! 554: } ! 555: #else /* if !ANSI8712 */ ! 556: static void d4_10_4x() ! 557: { ! 558: if (++i == 32) ! 559: printf("ATEXIT successfully registered 32 functions\n"); ! 560: Filename = "d410.c"; ! 561: checkthat(__LINE__, i <= 32); ! 562: } ! 563: #endif /* ANSI8712 */ ! 564: #endif /* SKIP4_104 */ ! 565: ! 566: /* ! 567: * 4.10.5 - Searching and sorting. ! 568: */ ! 569: ! 570: #if !ANSI ! 571: static void d4_10_5() { } ! 572: #else /* if ANSI */ ! 573: int mycmpfn PARMS((const void *, const void *)); ! 574: int mycmpfn(s1, s2) ! 575: const void *s1, *s2; ! 576: { ! 577: return (strcmp((const char *)s1, (const char *)s2)); ! 578: } ! 579: ! 580: static void d4_10_5() ! 581: { ! 582: #ifndef SKIP4_105 ! 583: /* generic_ptr bsearch(); depend upon declaration in <stdlib.h> */ ! 584: char *p; ! 585: static char names[][4] = {"abc", "jkl", "yzz", "def", "stu", "mno", "vwx", "pqr", "ghi"}; ! 586: /* Since we are in a "C" locale, these strings can be expected */ ! 587: /* to collate as abc, def, ghi, jkl, mno, pqr, stu, vwx, yzz. */ ! 588: /* 4.10.5.1 qsort ! 589: * sort using user comparison routine. ! 590: */ ! 591: qsort(names, 9, 4, mycmpfn); ! 592: stequals(__LINE__, names[0], "abc"); ! 593: stequals(__LINE__, names[1], "def"); ! 594: stequals(__LINE__, names[2], "ghi"); ! 595: stequals(__LINE__, names[3], "jkl"); ! 596: stequals(__LINE__, names[4], "mno"); ! 597: stequals(__LINE__, names[5], "pqr"); ! 598: stequals(__LINE__, names[6], "stu"); ! 599: stequals(__LINE__, names[7], "vwx"); ! 600: stequals(__LINE__, names[8], "yzz"); ! 601: /* 4.10.5.2 bsearch ! 602: * find the entries in the array ! 603: */ ! 604: checkthat(__LINE__, bsearch("abc", names, 9, 4, mycmpfn) == names[0]); ! 605: aequals(__LINE__, bsearch("def", names, 9, 4, mycmpfn), names[1]); ! 606: aequals(__LINE__, bsearch("ghi", names, 9, 4, mycmpfn), names[2]); ! 607: aequals(__LINE__, bsearch("jkl", names, 9, 4, mycmpfn), names[3]); ! 608: aequals(__LINE__, bsearch("mno", names, 9, 4, mycmpfn), names[4]); ! 609: aequals(__LINE__, bsearch("pqr", names, 9, 4, mycmpfn), names[5]); ! 610: aequals(__LINE__, bsearch("stu", names, 9, 4, mycmpfn), names[6]); ! 611: aequals(__LINE__, bsearch("vwx", names, 9, 4, mycmpfn), names[7]); ! 612: /* no match returns NULL */ ! 613: aequals(__LINE__, bsearch("123", (char*)names, 9, 4, mycmpfn), NULL); ! 614: #endif /* SKIP4_105 */ ! 615: } ! 616: #endif /* !ANSI */ ! 617: ! 618: /* ! 619: * 4.10.6 - Integer arithmetic functions. ! 620: */ ! 621: static void d4_10_6() ! 622: { ! 623: #ifndef SKIP4_106 ! 624: /* 4.10.6.1 abs ! 625: * absolute value ! 626: */ ! 627: iequals(__LINE__, abs(10), 10); ! 628: iequals(__LINE__, abs(-10), 10); ! 629: ! 630: #if ANSI ! 631: { ! 632: div_t d; ! 633: ldiv_t ld; ! 634: ! 635: /* 4.10.6.2 div ! 636: * get dividend and remainder. ! 637: */ ! 638: d = div(-5, 2); ! 639: iequals(__LINE__, d.quot, -2); ! 640: iequals(__LINE__, d.rem, -1); ! 641: d = div(5, 2); ! 642: iequals(__LINE__, d.quot, 2); ! 643: iequals(__LINE__, d.rem, 1); ! 644: ! 645: /* 4.10.6.3 labs ! 646: * same as abs, but for longs ! 647: */ ! 648: lequals(__LINE__, labs(2147483647), 2147483647); ! 649: lequals(__LINE__, labs(-2147483647), 2147483647); ! 650: ! 651: /* 4.10.6.4 ldiv ! 652: * get long dividend and remainder. ! 653: */ ! 654: ld = ldiv(-5L, 2L); ! 655: lequals(__LINE__, ld.quot, -2L); ! 656: lequals(__LINE__, ld.rem, -1L); ! 657: ld = ldiv(5L, 2L); ! 658: lequals(__LINE__, ld.quot, 2L); ! 659: lequals(__LINE__, ld.rem, 1L); ! 660: } ! 661: #endif /* ANSI */ ! 662: #endif /* SKIP4_106 */ ! 663: } ! 664: ! 665: /* ! 666: * 4.10.7 - Multibyte character functions ! 667: */ ! 668: #if !ANSI ! 669: static void d4_10_7(){} ! 670: #else /* if ANSI */ ! 671: static void d4_10_7() ! 672: { ! 673: #ifndef SKIP4_107 ! 674: const char *s = "Test string"; ! 675: int len = strlen(s); ! 676: const char *ps = s + len; /* points to 0 */ ! 677: #if WIDE_CHARS ! 678: wchar_t wc; ! 679: #endif /* WIDE_CHARS */ ! 680: char buff[10]; ! 681: ! 682: /* Only the "C" locale can be tested here, which has no ! 683: * specific requirements. Vendor specific tests can be added to ! 684: * test actual multibyte encodings. ! 685: */ ! 686: #if WIDE_CHARS ! 687: /* 4.10.7.1 The mblen function */ ! 688: iequals( - __LINE__, mblen(NULL, 1000), 0); /* no multibytes */ ! 689: iequals( - __LINE__, mblen(NULL, 0), 0); /* no multibytes */ ! 690: iequals(__LINE__, mblen(ps, 1), 0); /* pointer to 0 */ ! 691: iequals(__LINE__, mblen(s, len), 1); /* 1 byte per char */ ! 692: ! 693: /* 4.10.7.2 The mbtowc function */ ! 694: iequals(__LINE__, mbtowc(&wc, NULL, 0), 0); /* no multibytes */ ! 695: iequals(__LINE__, mbtowc(&wc, ps, 1), 0); /* pointer to 0 */ ! 696: lequals(__LINE__, (long)wc, 0L); /* big enough for wchar_t */ ! 697: iequals(__LINE__, mbtowc(&wc, s, len), 1); /* pointer to 0 */ ! 698: lequals(__LINE__, (long)wc, (long)'T'); /* big enough for wchar_t */ ! 699: checkthat(__LINE__, MB_CUR_MAX >= 1); ! 700: ! 701: /* 4.10.7.3 The wctomb function */ ! 702: iequals(__LINE__, wctomb(NULL, wc), 0); /* no multibytes */ ! 703: iequals(__LINE__, wctomb(NULL, 0), 0); /* no multibytes */ ! 704: iequals(__LINE__, wctomb(buff, wc), 1); /* 1 byte per char */ ! 705: iequals(__LINE__, buff[0], 'T'); ! 706: wc = 0; ! 707: iequals(__LINE__, wctomb(buff, wc), 1); ! 708: iequals(__LINE__, buff[0], 0); ! 709: #endif /* WIDE_CHARS */ ! 710: #endif /* SKIP4_107 */ ! 711: } ! 712: #endif /* ANSI */ ! 713: ! 714: /* ! 715: * 4.10.8 - Multibyte string functions ! 716: * The size_t checks are done as long because sizeof(long) >= sizeof(size_t). ! 717: * Also, it is assumed that sizeof(long) >= sizeof(wchar_t); ! 718: */ ! 719: #if !ANSI || !WIDE_CHARS ! 720: static void d4_10_8() ! 721: {} ! 722: #else /* if ANSI && WIDE_CHARS */ ! 723: static void d4_10_8() ! 724: { ! 725: #ifndef SKIP4_108 ! 726: int i; ! 727: const char *s = "A test string"; ! 728: long len = (long)strlen(s); ! 729: #define WLEN 20 ! 730: wchar_t warray[WLEN]; ! 731: char buf[WLEN]; ! 732: ! 733: /* if wchar_t is bigger than a long, these tests will not work */ ! 734: if (sizeof(long) < sizeof(wchar_t)) ! 735: { ! 736: complain(- __LINE__); ! 737: return; ! 738: } ! 739: ! 740: /* initialize warray and buf to all 1 */ ! 741: for (i = 0; i < WLEN; ++i) ! 742: { ! 743: warray[i] = 1; ! 744: buf[i] = 1; ! 745: } ! 746: ! 747: /* in the "C" locale it is assumed that the MB representation ! 748: * is the same as the wchar_t representation for printable ! 749: * characters. ! 750: */ ! 751: ! 752: /* 4.10.8.1 the mbstowcs function */ ! 753: lequals(__LINE__, (long) mbstowcs(warray, s, 1), 1L); ! 754: lequals(__LINE__, (long) warray[0], (long)'A'); ! 755: lequals(__LINE__, (long) warray[1], 1L); /* no terminating 0 */ ! 756: lequals(__LINE__, (long) mbstowcs(warray, s, WLEN), len); ! 757: lequals(__LINE__, (long) warray[len-1], (long)'g'); ! 758: lequals(__LINE__, (long) warray[len], 0L); /* terminating 0 */ ! 759: ! 760: /* 4.10.8.2 the wcstombs function */ ! 761: lequals(__LINE__, (long) wcstombs(buf, warray, 1), 1L); ! 762: lequals(__LINE__, (long) buf[0], (long)'A'); ! 763: lequals(__LINE__, (long) buf[1], 1L); /* no terminating 0 */ ! 764: lequals(__LINE__, (long) wcstombs(buf, warray, WLEN), len); ! 765: lequals(__LINE__, (long) buf[len-1], (long)'g'); ! 766: lequals(__LINE__, (long) buf[len], 0L); /* terminating 0 */ ! 767: #endif /* SKIP4_108 */ ! 768: } ! 769: #endif /* ANSI && WIDE_CHARS */ ! 770: ! 771: #else /* if SKIP410 */ ! 772: void d4_10() { pr_skip("d4_10: SKIPPED ENTIRELY\n"); } ! 773: #endif /* SKIP410 */ ! 774:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.